Author

Topic: When to send another "getblocks" (Read 1095 times)

hero member
Activity: 504
Merit: 502
December 14, 2011, 03:42:58 AM
#5
Interesting...is the "tips" of the chains part documented?

From reading this that doesn't appear to be the case:
https://en.bitcoin.it/wiki/Protocol_specification#getblocks

It looks like it gives you the 10 most recent hashes and then starts skipping in greater and greater intervals back to the genesis.  It gives a pseudo code implementation there.

The spec you posted was helpful. Thank you. I was wrong about the tips part. Though I think my method would be correct, the real client deals with forks by (as you note) a geometric search of the old blocks for a common ancestor. Seems wasteful to me but it is what it is.

The rest of my explanation appears to be correct.
newbie
Activity: 37
Merit: 0
December 14, 2011, 12:33:46 AM
#4
Oh wow - just found this and have been reading through it:

https://en.bitcoin.it/wiki/Satoshi_Client_Block_Exchange

It describes exactly what I was wondering.
newbie
Activity: 37
Merit: 0
December 13, 2011, 09:31:33 PM
#3
Interesting...is the "tips" of the chains part documented?

From reading this that doesn't appear to be the case:
https://en.bitcoin.it/wiki/Protocol_specification#getblocks

It looks like it gives you the 10 most recent hashes and then starts skipping in greater and greater intervals back to the genesis.  It gives a pseudo code implementation there.
hero member
Activity: 504
Merit: 502
December 13, 2011, 06:02:45 AM
#2
This is my understanding:

At any point, your client will know the hashes of the tips of all the chains it knows about (there is more than one as you have to cope with chain forks).  When you start up, you send all those tips in a 'getblocks' command.  The messages in bitcoin are all very badly named.  'getblocks' doesn't get blocks at all; it is an announcement to your peer of blocks you do have.

The peer will look at the chain tips you have and will see which of them falls on what it considers the current "best" chain.  It will return an 'inv' with N block hashes that follow the best one.  The hashes of the blocks it doesn't think are on the best chain will be ignored.  Here's the extra bit: if it runs out of space in the 'inv' before it runs out of blocks it notes the last block hash it's sending you as a "continuation hash".

Your client then starts grabbing those 'inv' offered blocks using 'getdata' for a full block or 'getheaders' for the header only.

The peer will respond normally to most of the 'getdata' requests you send.  However, when you request the hash it previously noted as a "continuation hash"; it then sends an 'inv' containing the hash of what it considers the current best chain.

Your client requests that block (since it doesn't have it) and notes that it doesn't have the parent either; therefore there are blocks missing from your chain, and you must start the process again -- sending another 'getblocks' listing it's current chain tips (probably only one at this point).

Personally, I think it's not a good way of doing it, and would prefer that the chain was downloaded backwards (since every block lists its parent there would be no need for the hoops this "continuation hash" stuff); but it is what it is.

My own woefully incomplete (but I hope clearer and better commented than the official client) client is available here:

https://github.com/andyparkins/additup
newbie
Activity: 37
Merit: 0
December 13, 2011, 02:10:33 AM
#1
Hi, I'm working on coding up a prototype client to better understand bitcoin.

I understand the first steps as:
1. send initial "getblocks" (I only have the genesis block preloaded to start)
2. peer sends me "inv" with 500 blocks
3. I call "getdata" on each

I know I need to call getblocks again, but does it make sense to queue up another "getblocks" again after every "inv"?  My implementation for inv handling is generalized so it's not just for the initial blockchain download, so I wasn't sure if this was the best route.
Jump to: