I would like to know if there's a way to download a blockchain without knowing block headers. This could be achieved by asking NEXT_BLOCK_HASH from the genesis block. But is this even possible ?
1 Answer
Yes, this is supported by the P2P protocol. In fact, in the very first release of the Bitcoin software there was no way to ask for headers separately.
The process works roughly like this:
- A sends
getblocks
to B (with a "locator", that roughly informs B about what the last block is that A already has). - B responds with
inv
message containing (up to) 500 block hashes (just the hashes, not the full headers), starting from the last block A and B have in common. - A then decides which of those block hashes it does not yet know, and sends a
getdata
request to fetch those. - B then responds by sending
block
messages for each of the requested blocks. - When A reaches the end of the 500 hashes in the
inv
, it issues anothergetblocks
, now with an updated locator, so the process can restart with further blocks.
The big downside of this approach is that the progress is "in the dark" - A does not know if the blocks it is receiving from B will amount to anything interesting (e.g. they could be from an old fork, or even a low-work attack chain), which A will only notice when it has downloaded and processed them all. The headers-first synchronization gives A the ability to decide whether the chain is interesting before trying to actually download it, with only a marginal bandwidth increase (block hashes are 32 bytes, block headers are 81 bytes each). With headers-first, the process is instead:
- A sends a
getheaders
to B, with a locator corresponds to the best header it has so far. - B responds with a
headers
message, containing up to 2000 headers starting at the last common header A and B have. - A processes those headers, and sends another
getheaders
from the newly updated best header it has, repeating the process, gathering all the headers. - At some point, A decides that the headers it has received from B are a sufficiently interesting chain (= its accumulated proof of work is high enough). When this happens, it starts sending
getdata
messages to B for the blocks along the header chain it lacks. - B responds to those using
block
messages, which A can process normally.
-
Fine. And how a peer identify a "chain" on the network ? Because there's no "chain message", there's no peer who suggests his chain-work.– LoopiteSep 4 at 15:51
-
@Loopite Using exactly the same mechanism! Nodes are always synchronizing. All they have to do is start this synchronization mechanism to learn about whatever chains their peers have (thus, sending
getblocks
orgetheaders
). Sep 4 at 15:54 -
I already got that part. However, I don't understand to whom peer the client will ask ? If I'm connected to 110 peers ? Who must receive header requests ?– LoopiteSep 4 at 16:06
-
1You ask all your peers for their headers/blocks. If they don't have any you don't have, no problem, the process will be very fast. To avoid duplicate work, Bitcoin Core only starts header sync from one random peer (switching over to another if it's too slow) when it's a lot behind, but eventually will ask all of them. Sep 4 at 16:16