witnet / witnet-rust

Open source Rust implementation of the Witnet decentralized oracle protocol, including full node and wallet backend 👁️🦀
https://docs.witnet.io
GNU General Public License v3.0
179 stars 56 forks source link

Implement INV protocol message and FlatBuffers builder #162

Closed aesedepece closed 5 years ago

aesedepece commented 5 years ago

Context

Inventory protocol

Initial synchronization

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:

  1. The local node will have already exchanged version messages with its remote outbound peers. Those version messages contain the checkpoint of the last block known to others peers, i.e. the local peer can already compare how many blocks they each have and identify how many are missing.

  2. The local node will send a get_blocks message to all its outbound nodes (after successful handshake protocol). These messages contain the hash of the top block of the local blockchain.

  3. Remote peers will reply by sending another get_blocks message containing the hash of their top block of their respective blockchains.

  4. 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.

(the protocol continues, but it is not relevant for the scope of this issue)

The following diagram depicts the previously described process under the assumption that the peer with the longest blockchain is NodeB (step 4).

         NodeA                            NodeB
           +                                +
           |           GET_BLOCKS           |
           +------------------------------->+
           |           GET_BLOCKS           |
           +<-------------------------------+
           |              INV               |
           +<-------------------------------+
           |                                |
           +                                +

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:

  1. A remote node broadcasts its inventory by sending an inv message, containing all the hashes of the advertised inventory objects.

(the protocol continues, but it is not relevant for the scope of this issue)

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               |
           +<-------------------------------+
           |                                |
           +                                +

inv message

The inv message is used to advertise the knowledge of one or more objects (e.g. blocks, transactions, ...). The inventory message can be received unsolicited or in reply to a get_blocks message.

The inv message consists of a message header with the INV command and a payload containing one or more inventory entries:

Field Type Description
count u16 Number of inventory entries
inventory inv_vect[] Inventory vectors

The inv_vect (inventory vector) data structure has the following schema:

Field Type Description
type u8 Type of object linked to the inventory entry
hash [u32; 8] Hash of the object

The possible values for the type field are:

Value Name Description
0 ERROR Data with this number may be ignored
1 TX Hash is related to a transaction
2 BLOCK Hash is related to a block
3 DATA_REQUEST Hash is related to a data request
4 DATA_RESULT Hash is related to the result of a data request

In the future, the type values may be extended in order to consider additional features.

Actionables

aesedepece commented 5 years ago

Solved by #184