From 28cfc751c18a2a8966964e85607b434f7aeedf89 Mon Sep 17 00:00:00 2001 From: "David A. Harding" Date: Thu, 11 May 2023 09:51:30 -1000 Subject: [PATCH] CH10: Inventory section Update for headers-first sync rather than the old blocks-first sync. --- ch08.asciidoc | 57 +++++++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/ch08.asciidoc b/ch08.asciidoc index fe116e45..6bffe33a 100644 --- a/ch08.asciidoc +++ b/ch08.asciidoc @@ -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 <>. 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. <> -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