diff --git a/core/blockchain.go b/core/blockchain.go index 09c93bedc3..ec2e5ae472 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -411,10 +411,33 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis if err := bc.loadLastState(); err != nil { return nil, err } + + // Load any existing snapshot, regenerating it if loading failed + if bc.cacheConfig.SnapshotLimit > 0 { + // If the chain was rewound past the snapshot persistent layer (causing + // a recovery block number to be persisted to disk), check if we're still + // in recovery mode and in that case, don't invalidate the snapshot on a + // head mismatch. + var recover bool + + head := bc.CurrentBlock() + if layer := rawdb.ReadSnapshotRecoveryNumber(bc.db); layer != nil && *layer >= head.Number.Uint64() { + log.Warn("Enabling snapshot recovery", "chainhead", head.Number, "diskbase", *layer) + recover = true + } + snapconfig := snapshot.Config{ + CacheSize: bc.cacheConfig.SnapshotLimit, + Recovery: recover, + NoBuild: bc.cacheConfig.SnapshotNoBuild, + AsyncBuild: !bc.cacheConfig.SnapshotWait, + } + bc.snaps, _ = snapshot.New(snapconfig, bc.db, bc.triedb, head.Root, int(bc.cacheConfig.TriesInMemory), bc.NoTries()) + } + // 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 @@ -430,7 +453,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() @@ -511,27 +534,6 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis } } - // Load any existing snapshot, regenerating it if loading failed - if bc.cacheConfig.SnapshotLimit > 0 { - // If the chain was rewound past the snapshot persistent layer (causing - // a recovery block number to be persisted to disk), check if we're still - // in recovery mode and in that case, don't invalidate the snapshot on a - // head mismatch. - var recover bool - - head := bc.CurrentBlock() - if layer := rawdb.ReadSnapshotRecoveryNumber(bc.db); layer != nil && *layer >= head.Number.Uint64() { - log.Warn("Enabling snapshot recovery", "chainhead", head.Number, "diskbase", *layer) - recover = true - } - snapconfig := snapshot.Config{ - CacheSize: bc.cacheConfig.SnapshotLimit, - Recovery: recover, - NoBuild: bc.cacheConfig.SnapshotNoBuild, - AsyncBuild: !bc.cacheConfig.SnapshotWait, - } - 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) @@ -993,7 +995,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)