Author

Topic: Whats the command to ping my Bitcoin node to send me X amount of blocks? (Read 1545 times)

full member
Activity: 125
Merit: 100
Here's a basic sample of connecting to the P2P interface in Perl, this just connects and spits out any new blocks in raw format on STDOUT and debug information about the connection on STDERR but once you've got the connection running you can send any commands through it, just need to be careful about the network byte orders that bitcoin uses.

Code:
#!/usr/bin/perl

use IO::Socket;use IO::Select;
use Digest::SHA;$|=1;

$btc=IO::Socket::INET->new(PeerAddr=>"localhost",PeerPort=>'8333',Proto=>'tcp') or die "Socket";
$sel=IO::Select->new();$sel->add($btc);

$p="\x2c\x7e\x00\x00"; # Version
$p.="\x01\x00\x00\x00\x00\x00\x00\x00"; # Services
$h=sprintf('%x',time());while(length($h)<16){$h="0".$h;}
$h=reverse($h);$p.=pack('h*',$h); # Unix Timestamp
$p.="\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"; # To IP
$p.="\x7f\x00\x00\x01\x20\x8d"; # 127.0.0.1 - Port 8333
$p.="\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"; # From IP
$p.="\x00\x00\x00\x00\x20\x8d"; # 0.0.0.0 - Port 8333
@chars=('a'..'f', 0..9);$rr=join '',map {$chars[rand @chars]} 1..16;
$p.=pack('H*',$rr); # Random Unique ID
$p.="\x00\x00\x00\x00\x00"; # No UA/Blocks

sendpacket('version',$p);
while($gotver==0){
  ($c,$p)=readpacket();
  if($c eq 'version'){$gotver=1;}
sleep(1);}
sendpacket('verack','');

while(1){
  ($c,$p)=readpacket();
  if($c eq 'inv'){
    sendpacket('getdata',$p);
  }
  if($c eq 'block'){
    $blk=unpack('H*',$p);print $blk."\n";
  }
sleep(1);}
close($btc);

sub sendpacket{my $c=shift(@_);my $p=shift(@_);
  my $o="\xf9\xbe\xb4\xd9"; # Magic for main network
  while(length($c)<12){$c.="\x00";}$o.=$c; #Command
  my $h=sprintf('%x',length($p));while(length($h)<8){$h="0".$h;}
  $h=reverse($h);$o.=pack('h*',$h); # Payload length
  $h=Digest::SHA::sha256(Digest::SHA::sha256($p));
  $h=unpack('H*',$h);$o.=pack('H*',substr($h,0,8)); # Checksum
  $o.=$p; # Payload
  print $btc $o;print STDERR "Sent $c (".length($p)." byte payload)\n";
}
sub readpacket{
  if(!$sel->can_read(1)){return 0;}
  my @x;my $x;while(1){read($btc,$x,1);$x=unpack('H*',$x);
    push(@x,$x);if($#x>3){shift(@x);}
    if(join('.',@x) eq "f9.be.b4.d9"){
      my $cmd;my $len;
      read($btc,$cmd,12);read($btc,$len,4);read($btc,$x,4);
      $x=unpack('h*',$len);$x=reverse($x);$len=hex($x);
      $x=chop($cmd);while($x eq "\x00"){$x=chop($cmd);}$cmd.=$x;
      print STDERR "Read $cmd ($len byte payload)\n";
      if($len>0){read($btc,$x,$len);return ($cmd,$x);}
      else{return ($cmd,'');}
    }
  }
}
kjj
legendary
Activity: 1302
Merit: 1026
To use the p2p protocol to spew blocks, you'll have to implement a fair chunk of the protocol; enough to convince your node that it is talking to another node.

If you just want to see the blocks, parsing the block files is super easy.  The only catch is that you'll need to build your own index as you go.  The satoshi client keeps an index, but it is in the BDB system, and interfacing with that is probably much more work than doing it yourself.
legendary
Activity: 980
Merit: 1003
I'm not just any shaman, I'm a Sha256man
Thanks for the information everyone!
All this information is going towards the Bitcoin Pseudocode Client Documentation project: https://github.com/Xenland/Bitcoin-Pseudocode-Client/tree/gh-pages

Does anyone know how to query a Bitcoin node from the outside with getblocks?

I tried to curl request with my Bitcoin node in "JSON" formate and bitcoin client says unknown message or invalid message. Any BTC source code references for connecting to the p2p interface?
full member
Activity: 125
Merit: 100
That is correct, as far as I know there isn't any way to get multiple blocks out of the RPC interface (unless that has changed in recent versions)

Recent versions support JSON-2.0 "batch" queries, so you can combine multiple RPC calls into one batch and get a list of responses.


Ah, very nice.  I've been using the P2P interface to get raw block data since before the getblock RPC calls were standard (seemed preferable to vetting various getblock patches and keeping up with changing arguments for them) and even in fairly recent releases the performance seems to be much better connecting that way, but I will admit I haven't tried it again that recently.
legendary
Activity: 1652
Merit: 2301
Chief Scientist
That is correct, as far as I know there isn't any way to get multiple blocks out of the RPC interface (unless that has changed in recent versions)

Recent versions support JSON-2.0 "batch" queries, so you can combine multiple RPC calls into one batch and get a list of responses.

full member
Activity: 125
Merit: 100
https://en.bitcoin.it/wiki/Protocol_specification#getblocks

Not really set up to give a certain number, you just give it the hash for the last block you have (or a couple of the latest) and it will send a list of anything newer (up to 500 blocks).

that is actual code, for the protocol, that has nothing to do with the API of the bitcoin node

That is correct, as far as I know there isn't any way to get multiple blocks out of the RPC interface (unless that has changed in recent versions) but if you connect via the P2P interface it will spit out a list fairly quickly.  Depends on your application which is easier and the original question wasn't very specific.
full member
Activity: 125
Merit: 100
https://en.bitcoin.it/wiki/Protocol_specification#getblocks

Not really set up to give a certain number, you just give it the hash for the last block you have (or a couple of the latest) and it will send a list of anything newer (up to 500 blocks).
legendary
Activity: 980
Merit: 1003
I'm not just any shaman, I'm a Sha256man
 Whats the command to ping my Bitcoin node to send me X amount of blocks?
Jump to: