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

Invalid double vote error after restoring chain state #1570

Open tmpolaczyk opened 3 years ago

tmpolaczyk commented 3 years ago

Restoring the chain state also restores the superblock votes, which are no longer needed because only superblocks with a majority of votes will be persisted to storage. This leads to comparing new votes to old votes, marking the new votes incorrectly as DoubleVote:

[<] Received SUPERBLOCK_VOTE twit1zrgs2phrfs0n2s5r9hyz0llwlpdlxmlr689kqv #6: cf7e0ecac850c749bdeaab120c6e8bb2edb5268ee4985a4fc973b9edaaae2547
Add vote: ValidWithSameHash
...
Persisting chain state for superblock #6 with chain beacon CheckpointBeacon { checkpoint: 59, hash_prev_block: 49d6b7dd0b742593f5429d302bf80f2921a3b2520876d70101c77505ffaf125b } and super beacon CheckpointBeacon { checkpoint: 6, hash_prev_block: cf7e0ecac850c749bdeaab120c6e8bb2edb5268ee4985a4fc973b9edaaae2547 }
Taking snapshot at superblock #7. Chain beacon CheckpointBeacon { checkpoint: 69, hash_prev_block: d282571ae2ad7d7a7e2e4abde0747dd2c883020a0329fac7568f627d44f4ae1e }, superblock beacon CheckpointBeacon { checkpoint: 6, hash_prev_block: cf7e0ecac850c749bdeaab120c6e8bb2edb5268ee4985a4fc973b9edaaae2547 }
GetBlocksEpochRange received (Included(50), Excluded(60))
Consensus reached for Superblock #6
...
Superblock consensus unknown
State machine is transitioning from Synced into WaitingConsensus
ChainInfo successfully obtained from storage
Actual ChainState CheckpointBeacon: epoch (59), hash_block (49d6b7dd0b742593f5429d302bf80f2921a3b2520876d70101c77505ffaf125b)
...
[<] Received SUPERBLOCK_VOTE twit1zrgs2phrfs0n2s5r9hyz0llwlpdlxmlr689kqv #8: d4a95c8171b58701fcacf93eb34a87e6249e37668112dda7f46f43dd9423636e
Add vote: DoubleVote

Solution: call votes_mempool.clear_and_remove_votes() after restoring from storage, or before saving the chain state to storage.

girazoki commented 3 years ago

The vote for superblock 8 should never have happened in the first place, as this was the checkpoint at which the chain was reverted. This probably means that whoever voted for that checkpoint was forked