Merge pull request #23949 from karalabe/fix-repair-heuristic

core, eth/downloader: fix resetting below freezer threshold
verkle/onleaf
Péter Szilágyi 3 years ago committed by GitHub
commit 17f1c2dc0f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 16
      core/blockchain.go
  2. 2
      eth/downloader/downloader.go

@ -296,7 +296,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
if diskRoot != (common.Hash{}) { if diskRoot != (common.Hash{}) {
log.Warn("Head state missing, repairing", "number", head.Number(), "hash", head.Hash(), "snaproot", diskRoot) log.Warn("Head state missing, repairing", "number", head.Number(), "hash", head.Hash(), "snaproot", diskRoot)
snapDisk, err := bc.SetHeadBeyondRoot(head.NumberU64(), diskRoot) snapDisk, err := bc.setHeadBeyondRoot(head.NumberU64(), diskRoot, true)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -306,7 +306,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
} }
} else { } else {
log.Warn("Head state missing, repairing", "number", head.Number(), "hash", head.Hash()) log.Warn("Head state missing, repairing", "number", head.Number(), "hash", head.Hash())
if err := bc.SetHead(head.NumberU64()); err != nil { if _, err := bc.setHeadBeyondRoot(head.NumberU64(), common.Hash{}, true); err != nil {
return nil, err return nil, err
} }
} }
@ -482,11 +482,11 @@ func (bc *BlockChain) loadLastState() error {
// was fast synced or full synced and in which state, the method will try to // was fast synced or full synced and in which state, the method will try to
// delete minimal data from disk whilst retaining chain consistency. // delete minimal data from disk whilst retaining chain consistency.
func (bc *BlockChain) SetHead(head uint64) error { func (bc *BlockChain) SetHead(head uint64) error {
_, err := bc.SetHeadBeyondRoot(head, common.Hash{}) _, err := bc.setHeadBeyondRoot(head, common.Hash{}, false)
return err return err
} }
// SetHeadBeyondRoot rewinds the local chain to a new head with the extra condition // setHeadBeyondRoot rewinds the local chain to a new head with the extra condition
// that the rewind must pass the specified state root. This method is meant to be // that the rewind must pass the specified state root. This method is meant to be
// used when rewinding with snapshots enabled to ensure that we go back further than // used when rewinding with snapshots enabled to ensure that we go back further than
// persistent disk layer. Depending on whether the node was fast synced or full, and // persistent disk layer. Depending on whether the node was fast synced or full, and
@ -494,7 +494,7 @@ func (bc *BlockChain) SetHead(head uint64) error {
// retaining chain consistency. // retaining chain consistency.
// //
// The method returns the block number where the requested root cap was found. // The method returns the block number where the requested root cap was found.
func (bc *BlockChain) SetHeadBeyondRoot(head uint64, root common.Hash) (uint64, error) { func (bc *BlockChain) setHeadBeyondRoot(head uint64, root common.Hash, repair bool) (uint64, error) {
if !bc.chainmu.TryLock() { if !bc.chainmu.TryLock() {
return 0, errChainStopped return 0, errChainStopped
} }
@ -509,7 +509,7 @@ func (bc *BlockChain) SetHeadBeyondRoot(head uint64, root common.Hash) (uint64,
frozen, _ := bc.db.Ancients() frozen, _ := bc.db.Ancients()
updateFn := func(db ethdb.KeyValueWriter, header *types.Header) (uint64, bool) { updateFn := func(db ethdb.KeyValueWriter, header *types.Header) (uint64, bool) {
// Rewind the block chain, ensuring we don't end up with a stateless head // Rewind the blockchain, ensuring we don't end up with a stateless head
// block. Note, depth equality is permitted to allow using SetHead as a // block. Note, depth equality is permitted to allow using SetHead as a
// chain reparation mechanism without deleting any data! // chain reparation mechanism without deleting any data!
if currentBlock := bc.CurrentBlock(); currentBlock != nil && header.Number.Uint64() <= currentBlock.NumberU64() { if currentBlock := bc.CurrentBlock(); currentBlock != nil && header.Number.Uint64() <= currentBlock.NumberU64() {
@ -610,8 +610,8 @@ func (bc *BlockChain) SetHeadBeyondRoot(head uint64, root common.Hash) (uint64,
} }
// If SetHead was only called as a chain reparation method, try to skip // If SetHead was only called as a chain reparation method, try to skip
// touching the header chain altogether, unless the freezer is broken // touching the header chain altogether, unless the freezer is broken
if block := bc.CurrentBlock(); block.NumberU64() == head { if repair {
if target, force := updateFn(bc.db, block.Header()); force { if target, force := updateFn(bc.db, bc.CurrentBlock().Header()); force {
bc.hc.SetHead(target, updateFn, delFn) bc.hc.SetHead(target, updateFn, delFn)
} }
} else { } else {

@ -535,7 +535,7 @@ func (d *Downloader) syncWithPeer(p *peerConnection, hash common.Hash, td *big.I
} }
// Rewind the ancient store and blockchain if reorg happens. // Rewind the ancient store and blockchain if reorg happens.
if origin+1 < frozen { if origin+1 < frozen {
if err := d.lightchain.SetHead(origin + 1); err != nil { if err := d.lightchain.SetHead(origin); err != nil {
return err return err
} }
} }

Loading…
Cancel
Save