-
Notifications
You must be signed in to change notification settings - Fork 57
Description
Context
Inventory exchange protocol
The inventory exchange protocol describes the interaction between nodes in order to synchronize themselves with the network and reestablish the full blockchain (in terms of blocks and transactions).
Inventory exchanges envision 2 main scenarios:
-
Block Download, for nodes in need of synchronizing their blockchains by requesting and downloading blocks.
-
Inventory Broadcasting, for nodes willing to broadcast transactional information, such as blocks and transactions.
Block Download
Block Download is performed by nodes that need to catch up with other nodes by downloading missing blocks in order to reconstruct their blockchains. For example, this is the case of nodes connecting to the blockchain for the first time or after a significant amount of downtime.
Starting from the block #0 (the hardcoded genesis block), the nodes need to validate all blocks up to the current tip of the blockchain. Therefore, in case of missing blocks, a local node will initiate the following process of synchronization with its outbound peers:
-
The local node will have already exchanged
versionmessages with its remote outbound peers. Thoseversionmessages contain the last epoch known to others peers, i.e. the local peer can already compare how many blocks they each have and identify how many are missing. -
The local node will send a
get_blocksmessage to all its outbound nodes (after successful handshake protocol). These messages contain the hash of the top block of the local blockchain. -
Remote peers will reply by sending another
get_blocksmessage containing the hash of their top block of their respective blockchains. -
The peer with the longest blockchain will identify which blocks are required by the other peer in order to allow it to synchronize to its blockchain. The peer will select up to the first consecutive 500 blocks and it will transmit their hashes using an
inv(inventory) message. -
After identifying which blocks are missing (it may already have some of them), the node may request them by using a
get_datamessage, containing the hashes of the needed blocks. This message will help the node to catch up with the current full blockchain. -
After receiving the
get_datamessage, the peer sends the requested blocks individually by usingblockmessages.
The following diagram depicts the previously described process under the assumption that the peer with the longest blockchain isNodeB(step 4).
NodeA NodeB
+ +
| GET_BLOCKS |
+------------------------------->+
| GET_BLOCKS |
+<-------------------------------+
| INV |
+<-------------------------------+
| |
| |
| GET_DATA |
+------------------------------->+
| BLOCK |
+<-------------------------------+
| BLOCK |
+<-------------------------------+
| BLOCK |
+<-------------------------------+
| |
+ +
Inventory Broadcasting
Similarly to the previously described process of synchronization, any node may contribute to the synchronization of their outbound peers by advertising inventory objects such as blocks and transactions. Inventory broadcasting is also used in case a node creates transactions or mine blocks.
The inventory broadcasting can be described as the following sequence of steps:
-
A remote node broadcasts its inventory by sending an
invmessage, containing all the hashes of the advertised inventory objects. -
After receiving an
invmessage and filtering the inventory objects that may be missing in the local blockchain, the local node sends aget_datamessage with the hashes of the needed objects. -
The remote note receives the
get_datamessage and sends ablockortxmessage per requested inventory object (identified by a hash).
The following diagram depicts the previous step under the assumption that the local node (NodeA) sends a get_data message requesting 3 blocks and 2 transactions.
NodeA NodeB
+ +
| INV |
+<-------------------------------+
| |
| GET_DATA |
+------------------------------->+
| |
| BLOCK |
+<-------------------------------+
| BLOCK |
+<-------------------------------+
| BLOCK |
+<-------------------------------+
| |
+ +
block message
The block message is used to transmit a single serialized block as a response to a get_data message.
The block message consists of a message header with the BLOCK command and a payload formatted as follows:
| Field | Type | Description |
|---|---|---|
header |
block_header |
Block header, as described in the [Block] section |
txn_count |
u32 |
Total number of transactions in the block |
txns |
tx[] |
Block transactions as described in the transaction section |
Actionables
- Implement
blockas aCommandin the FlatBuffers schema. - Implement
blockas a native data structure - Implement
blockand its builder as aWitnetMessageinwitnet_data_structures::types::Message.