Skip to content

Commit

Permalink
fix: allow fast node to rewind after abnormal shutdown
Browse files Browse the repository at this point in the history
  • Loading branch information
buddh0 committed Apr 18, 2024
1 parent cbcd26c commit 1ad737a
Showing 1 changed file with 19 additions and 3 deletions.
22 changes: 19 additions & 3 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -411,10 +411,11 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
if err := bc.loadLastState(); err != nil {
return nil, err
}

// Make sure the state associated with the block is available, or log out
// if there is no available state, waiting for state sync.
head := bc.CurrentBlock()
if !bc.NoTries() && !bc.HasState(head.Root) {
if !bc.HasState(head.Root) {
if head.Number.Uint64() == 0 {
// The genesis state is missing, which is only possible in the path-based
// scheme. This situation occurs when the initial state sync is not finished
Expand All @@ -430,7 +431,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
if bc.cacheConfig.SnapshotLimit > 0 {
diskRoot = rawdb.ReadSnapshotRoot(bc.db)
}
if bc.triedb.Scheme() == rawdb.PathScheme {
if bc.triedb.Scheme() == rawdb.PathScheme && !bc.NoTries() {
recoverable, _ := bc.triedb.Recoverable(diskRoot)
if !bc.HasState(diskRoot) && !recoverable {
diskRoot = bc.triedb.Head()
Expand Down Expand Up @@ -532,6 +533,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
}
bc.snaps, _ = snapshot.New(snapconfig, bc.db, bc.triedb, head.Root, int(bc.cacheConfig.TriesInMemory), bc.NoTries())
}

// do options before start any routine
for _, option := range options {
bc, err = option(bc)
Expand Down Expand Up @@ -861,6 +863,7 @@ func (bc *BlockChain) rewindHashHead(head *types.Header, root common.Hash) (*typ
} else if head.Number.Uint64() > params.FullImmutabilityThreshold {
limit = head.Number.Uint64() - params.FullImmutabilityThreshold
}

for {
logger := log.Trace
if time.Since(logged) > time.Second*8 {
Expand Down Expand Up @@ -993,7 +996,7 @@ func (bc *BlockChain) rewindPathHead(head *types.Header, root common.Hash) (*typ
// then block number zero is returned, indicating that snapshot recovery is disabled
// and the whole snapshot should be auto-generated in case of head mismatch.
func (bc *BlockChain) rewindHead(head *types.Header, root common.Hash) (*types.Header, uint64) {
if bc.triedb.Scheme() == rawdb.PathScheme {
if bc.triedb.Scheme() == rawdb.PathScheme && !bc.NoTries() {
return bc.rewindPathHead(head, root)
}
return bc.rewindHashHead(head, root)
Expand Down Expand Up @@ -1030,6 +1033,19 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64, time uint64, root common.Ha
// block. Note, depth equality is permitted to allow using SetHead as a
// chain reparation mechanism without deleting any data!
if currentBlock := bc.CurrentBlock(); currentBlock != nil && header.Number.Uint64() <= currentBlock.Number.Uint64() {
// load bc.snaps for the judge `HasState`
if bc.NoTries() {
if bc.cacheConfig.SnapshotLimit > 0 {
snapconfig := snapshot.Config{
CacheSize: bc.cacheConfig.SnapshotLimit,
NoBuild: bc.cacheConfig.SnapshotNoBuild,
AsyncBuild: !bc.cacheConfig.SnapshotWait,
}
bc.snaps, _ = snapshot.New(snapconfig, bc.db, bc.triedb, header.Root, int(bc.cacheConfig.TriesInMemory), bc.NoTries())
}
defer func() { bc.snaps = nil }()
}

var newHeadBlock *types.Header
newHeadBlock, rootNumber = bc.rewindHead(header, root)
rawdb.WriteHeadBlockHash(db, newHeadBlock.Hash())
Expand Down

0 comments on commit 1ad737a

Please sign in to comment.