witnet-rust icon indicating copy to clipboard operation
witnet-rust copied to clipboard

Error while synchronizing:Error processing block: Ignoring block because its epoch (x) is older than highest block checkpoint (y)

Open girazoki opened this issue 4 years ago • 2 comments

log.txt

girazoki avatar Sep 11 '20 09:09 girazoki

I think this is because the node uses the LAST_BEACON message to request blocks, and it also uses the same message on every epoch to calculate the consensus between its peers.

So the events are as follows:

  • Send LAST_BEACON to random peer to begin synchronization
  • Receive INVENTORY_ANNOUNCEMENT (500 blocks)
  • Send INVENTORY_REQUEST (500 blocks)
  • Receive BLOCK 1
  • Receive BLOCK 2
  • Receive BLOCK ...

And while receiving blocks, a new epoch notification occurs:

  • [Checkpoints] We are now in epoch #6190
  • Send LAST_BEACON to all peers
  • Receive LAST_BEACON from all peers
  • One or more peers interpret this LAST_BEACON as the start of the synchronization protocol and reply with INVENTORY_ANNOUNCEMENT
  • Our node wrongly assumes that it must request all the blocks, so it replies with INVENTORY_REQUEST and starts receiving the same blocks again
  • Receive BLOCK 1
  • Receive BLOCK 2
  • Receive BLOCK ...

While receiving blocks again, the first batch of 500 blocks finishes and the ChainManager receives an AddBlocks message. It processes all the blocks successfully and sets the new checkpoint beacon to 500. It now should start receiving blocks 501 to 1000. But the second blocks batch also finishes, so the ChainManager receives an AddBlocks message with blocks 1 to 500. This is wrong, so it shows an error and restores to the last valid chain state.

tmpolaczyk avatar Sep 11 '20 14:09 tmpolaczyk

How to avoid receiving the same blocks again?

The node should store a flag in the Session actor, something like waiting_for_inventory_announcement_from_this_peer, initialized to false. This flag should be set to true before sending the LAST_BEACON to begin synchronization, and it should be set to false after receiving the INVENTORY_ANNOUNCEMENT (and replying with INVENTORY_REQUEST), or after the blocks timeout is reached.

If an INVENTORY_ANNOUNCEMENT message is received and waiting_for_inventory_announcement_from_this_peer is set to false, the message should just be ignored.

tmpolaczyk avatar Sep 14 '20 13:09 tmpolaczyk