|
|
|
@ -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.
|
|
|
|
|
|
|
|
|
|
[[inventory_synchronization]]
|
|
|
|
|
[role="smallerfifty"]
|
|
|
|
|
.Node synchronizing the blockchain by retrieving blocks from a peer
|
|
|
|
|
image::images/mbc2_0806.png["InventorySynchronization"]
|
|
|
|
|
an extended period of time.
|
|
|
|
|
|
|
|
|
|
//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
|
|
|
|
|