Recreate trie after revert. (#4608)

pull/4615/head
Konstantin 10 months ago committed by GitHub
parent e15bae129b
commit 17a2522391
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      api/service/legacysync/syncing.go
  2. 2
      core/block_validator.go
  3. 24
      core/blockchain_impl.go

@ -912,6 +912,7 @@ func (ss *StateSync) UpdateBlockAndStatus(block *types.Block, bc core.BlockChain
Uint64("blockEpoch", block.Epoch().Uint64()). Uint64("blockEpoch", block.Epoch().Uint64()).
Str("blockHex", block.Hash().Hex()). Str("blockHex", block.Hash().Hex()).
Uint32("ShardID", block.ShardID()). Uint32("ShardID", block.ShardID()).
Err(err).
Msg("[SYNC] UpdateBlockAndStatus: Block exists") Msg("[SYNC] UpdateBlockAndStatus: Block exists")
return nil return nil
case err != nil: case err != nil:

@ -56,7 +56,7 @@ func NewBlockValidator(blockchain BlockChain) *BlockValidator {
func (v *BlockValidator) ValidateBody(block *types.Block) error { func (v *BlockValidator) ValidateBody(block *types.Block) error {
// Check whether the block's known, and if not, that it's linkable // Check whether the block's known, and if not, that it's linkable
if v.bc.HasBlockAndState(block.Hash(), block.NumberU64()) { if v.bc.HasBlockAndState(block.Hash(), block.NumberU64()) {
return ErrKnownBlock return errors.WithMessage(ErrKnownBlock, "validate body: has block and state")
} }
if !v.bc.HasBlockAndState(block.ParentHash(), block.NumberU64()-1) { if !v.bc.HasBlockAndState(block.ParentHash(), block.NumberU64()-1) {
if !v.bc.HasBlock(block.ParentHash(), block.NumberU64()-1) { if !v.bc.HasBlock(block.ParentHash(), block.NumberU64()-1) {

@ -782,6 +782,20 @@ func (bc *BlockChainImpl) resetWithGenesisBlock(genesis *types.Block) error {
return nil return nil
} }
func (bc *BlockChainImpl) repairRecreateStateTries(head **types.Block) error {
for {
blk := bc.GetBlockByNumber((*head).NumberU64() + 1)
if blk != nil {
_, _, _, err := bc.insertChain([]*types.Block{blk}, true)
if err != nil {
return err
}
*head = blk
continue
}
}
}
// repair tries to repair the current blockchain by rolling back the current block // repair tries to repair the current blockchain by rolling back the current block
// until one with associated state is found. This is needed to fix incomplete db // until one with associated state is found. This is needed to fix incomplete db
// writes caused either by crashes/power outages, or simply non-committed tries. // writes caused either by crashes/power outages, or simply non-committed tries.
@ -789,6 +803,16 @@ func (bc *BlockChainImpl) resetWithGenesisBlock(genesis *types.Block) error {
// This method only rolls back the current block. The current header and current // This method only rolls back the current block. The current header and current
// fast block are left intact. // fast block are left intact.
func (bc *BlockChainImpl) repair(head **types.Block) error { func (bc *BlockChainImpl) repair(head **types.Block) error {
if err := bc.repairValidatorsAndCommitSigs(head); err != nil {
return errors.WithMessage(err, "failed to repair validators and commit sigs")
}
if err := bc.repairRecreateStateTries(head); err != nil {
return errors.WithMessage(err, "failed to recreate state tries")
}
return nil
}
func (bc *BlockChainImpl) repairValidatorsAndCommitSigs(head **types.Block) error {
valsToRemove := map[common.Address]struct{}{} valsToRemove := map[common.Address]struct{}{}
for { for {
// Abort if we've rewound to a head block that does have associated state // Abort if we've rewound to a head block that does have associated state

Loading…
Cancel
Save