Skip to content

WIP: Initial Block Download

Nicolas NARDONE requested to merge feat/ibd into dev

IBD: Initial Block Download using a kind of Bitcoin's Blocks First algorithm

Process

  1. Once the node is started, it starts by asking all known peer nodes the next 10 blocks starting with its last block
  • if the node has no chain, it sends the hash of the genesis block expecting to receive the next 10 blocks.
  • if the node already has a chain, it sends the hash of its last block expecting to receive up to 10 blocks after the given block
  1. Uppon receiving the request, the sync node lookups the given block hash in its chain, starting from genesis block.
  • if the hash is found, it sends this blocks + next 9 blocks
  • if the hash is not found, it sends no blocks.
  1. The node expects to receive a chain with 10 blocks.
  • if it receives a chain of 10 blocks, it starts validating the chain.
  • if it receives a chain with < 10 blocks, it waits for a longer chain to come.
  • if no longer chain comes within a certain amount of time. The node gives up asking peers and integrates the < 10 block chain.
  1. To be integrated, every block received is validated one by one by the node.
  • if the block is valid, it is added to the node's chain.
  • if the block is invalid, node is removed from known nodes. IBD process starts again.
  1. When the node has received the last mined block, no node sends a block in response. The node only receives empty lists within time frame => The node understands it has synced, and stops the IBD process.

Implementation:

  • Chain.find_block(hash):block -> returns block with given hash inside chain.

  • Chain.next_blocks(hash):block -> returns block with given hash inside chain.

  • Refactor node_list using 2 processes

    • node_list -> Node.Network.PeerList : Agent that maintains a list of peers
    • node_list -> Node.Network.ActivePeersWorker : GenServer using worker pattern to loop through nodes
      • Add peers if they respond to /ping queries
      • Remove peers if don't respond to /ping queries
  • Create a new GenServer (Node.Chain.InitialDownloadWorker) that handles Chain Sync and exposes 2 methods

    • run(): to register the worker and start the sync process if node only has Genesis block
    • download_chain(): alternatively ask peers their next 10 blocks
  • Refactor _consensus_using this worker pattern:

    • consensus -> Node.Chain.ConsensusWorker
  • Define a new env variable SYNC_BLOCKS_COUNT set to 10 (default number of blocks returned per sync request)

Edited by Nicolas NARDONE

Merge request reports