mirror of
https://github.com/bitcoinbook/bitcoinbook
synced 2024-12-23 07:08:13 +00:00
CH10: Inventory section
Update for headers-first sync rather than the old blocks-first sync.
This commit is contained in:
parent
7d2ba06209
commit
28cfc751c1
@ -467,7 +467,7 @@ command +getpeerinfo+ as we saw earlier; for example, +/Satoshi:24.0.1/+.
|
||||
|
||||
((("Bitcoin network", "syncing the blockchain")))The first thing a full
|
||||
node will do once it connects to peers is try to construct a complete
|
||||
blockchain. If it is a brand-new node and has no blockchain at all, it
|
||||
chain of block headers. If it is a brand-new node and has no blockchain at all, it
|
||||
only knows one block, the genesis block, which is statically embedded in
|
||||
the client software. Starting with block #0 (the genesis block), the new
|
||||
node will have to download hundreds of thousands of blocks to
|
||||
@ -479,47 +479,50 @@ because that contains +BestHeight+, a node's current blockchain height
|
||||
(number of blocks). A node will see the +version+ messages from its
|
||||
peers, know how many blocks they each have, and be able to compare to
|
||||
how many blocks it has in its own blockchain. Peered nodes will exchange
|
||||
a +getblocks+ message that contains the hash (fingerprint) of the top
|
||||
a +getheaders+ message that contains the hash (fingerprint) of the top
|
||||
block on their local blockchain. One of the peers will be able to
|
||||
identify the received hash as belonging to a block that is not at the
|
||||
top, but rather belongs to an older block, thus deducing that its own
|
||||
local blockchain is longer than its peer's.
|
||||
|
||||
The peer that has the longer blockchain has more blocks than the other
|
||||
node and can identify which blocks the other node needs in order to
|
||||
"catch up." It will identify the first 500 blocks to share and transmit
|
||||
their hashes using an +inv+ (inventory) message. The node missing these
|
||||
blocks will then retrieve them, by issuing a series of +getdata+
|
||||
messages requesting the full block data and identifying the requested
|
||||
blocks using the hashes from the +inv+ message.
|
||||
node and can identify which headers the other node needs in order to
|
||||
"catch up." It will identify the first 2,000 headers to share using a
|
||||
+headers+ message. The node will keep requesting additional headers
|
||||
until it has received one for every block the remote peer claims to
|
||||
have.
|
||||
|
||||
In parallel, the node will begin requesting the blocks for each header
|
||||
it previously received using a +getdata+ message. The node will request
|
||||
different blocks from each of its peers, which allows it to drop
|
||||
connections to peers that are significantly slower than the average in
|
||||
order to find newer (and possibly faster) peers.
|
||||
|
||||
Let's assume, for example, that a node only has the genesis block. It
|
||||
will then receive an +inv+ message from its peers containing the hashes
|
||||
of the next 500 blocks in the chain. It will start requesting blocks
|
||||
from all of its connected peers, spreading the load and ensuring that it
|
||||
doesn't overwhelm any peer with requests. The node keeps track of how
|
||||
many blocks are "in transit" per peer connection, meaning blocks that it
|
||||
has requested but not received, checking that it does not exceed a limit
|
||||
(+MAX_BLOCKS_IN_TRANSIT_PER_PEER+). This way, if it needs a lot of
|
||||
blocks, it will only request new ones as previous requests are
|
||||
fulfilled, allowing the peers to control the pace of updates and not
|
||||
overwhelm the network. As each block is received, it is added to the
|
||||
will then receive an +headers+ message from its peers containing the headers
|
||||
of the next 2,000 blocks in the chain. It will start requesting blocks
|
||||
from all of its connected peers, keeping a queue of up to 1,024 blocks.
|
||||
Blocks need to be validated in order, so if the oldest block in the
|
||||
queue--the block the node next needs to validate--hasn't been received
|
||||
yet, the node drops the connection to the peer that was supposed to
|
||||
provide that block. It then finds a new peer that may be able to
|
||||
provide one block before all of the node's other peers are able to
|
||||
provide 1,023 blocks.
|
||||
|
||||
As each block is received, it is added to the
|
||||
blockchain, as we will see in <<blockchain>>. As the local blockchain is
|
||||
gradually built up, more blocks are requested and received, and the
|
||||
process continues until the node catches up to the rest of the network.
|
||||
|
||||
This process of comparing the local blockchain with the peers and
|
||||
retrieving any missing blocks happens any time a node goes offline for
|
||||
any period of time. Whether a node has been offline for a few minutes
|
||||
and is missing a few blocks, or a month and is missing a few thousand
|
||||
blocks, it starts by sending +getblocks+, gets an +inv+ response, and
|
||||
starts downloading the missing blocks. <<inventory_synchronization>>
|
||||
shows the inventory and block propagation protocol.
|
||||
an extended period of time.
|
||||
|
||||
[[inventory_synchronization]]
|
||||
[role="smallerfifty"]
|
||||
.Node synchronizing the blockchain by retrieving blocks from a peer
|
||||
image::images/mbc2_0806.png["InventorySynchronization"]
|
||||
//FIXME?
|
||||
//[[inventory_synchronization]]
|
||||
//[role="smallerfifty"]
|
||||
//.Node synchronizing the blockchain by retrieving blocks from a peer
|
||||
//image::images/mbc2_0806.png["InventorySynchronization"]
|
||||
|
||||
[[spv_nodes]]
|
||||
=== Simplified Payment Verification (SPV) Nodes
|
||||
|
Loading…
Reference in New Issue
Block a user