From 94e1505ccdd6b452baa530d15b2b21b3b00ae247 Mon Sep 17 00:00:00 2001 From: fudongbai <296179868@qq.com> Date: Wed, 14 Jul 2021 19:55:48 +0800 Subject: [PATCH] fix can not repair --- core/blockchain.go | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index d627f9bf7a..be29afe3c1 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -88,7 +88,8 @@ const ( maxFutureBlocks = 256 maxTimeFutureBlocks = 30 badBlockLimit = 10 - preLoadLimit = 32 + preLoadLimit = 64 + maxBeyondBlocks = 2048 // BlockChainVersion ensures that an incompatible database forces a resync from scratch. // @@ -514,6 +515,7 @@ func (bc *BlockChain) SetHeadBeyondRoot(head uint64, root common.Hash) (uint64, // chain reparation mechanism without deleting any data! if currentBlock := bc.CurrentBlock(); currentBlock != nil && header.Number.Uint64() <= currentBlock.NumberU64() { newHeadBlock := bc.GetBlock(header.Hash(), header.Number.Uint64()) + lastBlockNum := header.Number.Uint64() if newHeadBlock == nil { log.Error("Gap in the chain, rewinding to genesis", "number", header.Number, "hash", header.Hash()) newHeadBlock = bc.genesisBlock @@ -522,12 +524,17 @@ func (bc *BlockChain) SetHeadBeyondRoot(head uint64, root common.Hash) (uint64, // keeping rewinding until we exceed the optional threshold // root hash beyondRoot := (root == common.Hash{}) // Flag whether we're beyond the requested root (no root, always true) - + enoughBeyondCount := false + beyondCount := 0 for { + beyondCount++ // If a root threshold was requested but not yet crossed, check if root != (common.Hash{}) && !beyondRoot && newHeadBlock.Root() == root { beyondRoot, rootNumber = true, newHeadBlock.NumberU64() } + + enoughBeyondCount = beyondCount > maxBeyondBlocks + if _, err := state.New(newHeadBlock.Root(), bc.stateCache, bc.snaps); err != nil { log.Trace("Block state missing, rewinding further", "number", newHeadBlock.NumberU64(), "hash", newHeadBlock.Hash()) if pivot == nil || newHeadBlock.NumberU64() > *pivot { @@ -543,7 +550,20 @@ func (bc *BlockChain) SetHeadBeyondRoot(head uint64, root common.Hash) (uint64, newHeadBlock = bc.genesisBlock } } - if beyondRoot || newHeadBlock.NumberU64() == 0 { + if beyondRoot || (enoughBeyondCount && root != common.Hash{}) || newHeadBlock.NumberU64() == 0 { + if enoughBeyondCount && (root != common.Hash{}) && rootNumber == 0 { + for { + lastBlockNum++ + block := bc.GetBlockByNumber(lastBlockNum) + if block == nil { + break + } + if block.Root() == root { + rootNumber = block.NumberU64() + break + } + } + } log.Debug("Rewound to block with state", "number", newHeadBlock.NumberU64(), "hash", newHeadBlock.Hash()) break }