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.
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
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:
Solution: call
votes_mempool.clear_and_remove_votes()
after restoring from storage, or before saving the chain state to storage.