@@ -169,10 +169,12 @@ type BlockChain struct {
169169 chainConfig * params.ChainConfig // Chain & network configuration
170170 cacheConfig * CacheConfig // Cache configuration for pruning
171171
172- db ethdb.Database // Low level persistent database to store final content in
173- snaps * snapshot.Tree // Snapshot tree for fast trie leaf access
174- triegc * prque.Prque // Priority queue mapping block numbers to tries to gc
175- gcproc time.Duration // Accumulates canonical block processing for trie dumping
172+ db ethdb.Database // Low level persistent database to store final content in
173+ snaps * snapshot.Tree // Snapshot tree for fast trie leaf access
174+ triegc * prque.Prque // Priority queue mapping block numbers to tries to gc
175+ gcproc time.Duration // Accumulates canonical block processing for trie dumping
176+ triedb * trie.Database // The database handler for maintaining trie nodes.
177+ stateCache state.Database // State database to reuse between imports (contains state cache)
176178
177179 // txLookupLimit is the maximum number of blocks from head whose tx indices
178180 // are reserved:
@@ -200,7 +202,6 @@ type BlockChain struct {
200202 currentFinalizedBlock atomic.Value // Current finalized head
201203 currentSafeBlock atomic.Value // Current safe head
202204
203- stateCache state.Database // State database to reuse between imports (contains state cache)
204205 bodyCache * lru.Cache [common.Hash , * types.Body ]
205206 bodyRLPCache * lru.Cache [common.Hash , rlp.RawValue ]
206207 receiptsCache * lru.Cache [common.Hash , []* types.Receipt ]
@@ -231,10 +232,16 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
231232 cacheConfig = defaultCacheConfig
232233 }
233234
235+ // Open trie database with provided config
236+ triedb := trie .NewDatabaseWithConfig (db , & trie.Config {
237+ Cache : cacheConfig .TrieCleanLimit ,
238+ Journal : cacheConfig .TrieCleanJournal ,
239+ Preimages : cacheConfig .Preimages ,
240+ })
234241 // Setup the genesis block, commit the provided genesis specification
235242 // to database if the genesis block is not present yet, or load the
236243 // stored one from database.
237- chainConfig , genesisHash , genesisErr := SetupGenesisBlockWithOverride (db , genesis , overrides )
244+ chainConfig , genesisHash , genesisErr := SetupGenesisBlockWithOverride (db , triedb , genesis , overrides )
238245 if _ , ok := genesisErr .(* params.ConfigCompatError ); genesisErr != nil && ! ok {
239246 return nil , genesisErr
240247 }
@@ -247,15 +254,11 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
247254 log .Info ("" )
248255
249256 bc := & BlockChain {
250- chainConfig : chainConfig ,
251- cacheConfig : cacheConfig ,
252- db : db ,
253- triegc : prque .New (nil ),
254- stateCache : state .NewDatabaseWithConfig (db , & trie.Config {
255- Cache : cacheConfig .TrieCleanLimit ,
256- Journal : cacheConfig .TrieCleanJournal ,
257- Preimages : cacheConfig .Preimages ,
258- }),
257+ chainConfig : chainConfig ,
258+ cacheConfig : cacheConfig ,
259+ db : db ,
260+ triedb : triedb ,
261+ triegc : prque .New (nil ),
259262 quit : make (chan struct {}),
260263 chainmu : syncx .NewClosableMutex (),
261264 bodyCache : lru.NewCache [common.Hash , * types.Body ](bodyCacheLimit ),
@@ -268,6 +271,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
268271 vmConfig : vmConfig ,
269272 }
270273 bc .forker = NewForkChoice (bc , shouldPreserve )
274+ bc .stateCache = state .NewDatabaseWithNodeDB (bc .db , bc .triedb )
271275 bc .validator = NewBlockValidator (chainConfig , bc , engine )
272276 bc .prefetcher = newStatePrefetcher (chainConfig , bc , engine )
273277 bc .processor = NewStateProcessor (chainConfig , bc , engine )
@@ -300,7 +304,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
300304 }
301305 // Make sure the state associated with the block is available
302306 head := bc .CurrentBlock ()
303- if _ , err := state . New (head .Root (), bc . stateCache , bc . snaps ); err != nil {
307+ if ! bc . HasState (head .Root ()) {
304308 // Head state is missing, before the state recovery, find out the
305309 // disk layer point of snapshot(if it's enabled). Make sure the
306310 // rewound point is lower than disk layer.
@@ -388,7 +392,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
388392 var recover bool
389393
390394 head := bc .CurrentBlock ()
391- if layer := rawdb .ReadSnapshotRecoveryNumber (bc .db ); layer != nil && * layer > head .NumberU64 () {
395+ if layer := rawdb .ReadSnapshotRecoveryNumber (bc .db ); layer != nil && * layer >= head .NumberU64 () {
392396 log .Warn ("Enabling snapshot recovery" , "chainhead" , head .NumberU64 (), "diskbase" , * layer )
393397 recover = true
394398 }
@@ -398,7 +402,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
398402 NoBuild : bc .cacheConfig .SnapshotNoBuild ,
399403 AsyncBuild : ! bc .cacheConfig .SnapshotWait ,
400404 }
401- bc .snaps , _ = snapshot .New (snapconfig , bc .db , bc .stateCache . TrieDB () , head .Root ())
405+ bc .snaps , _ = snapshot .New (snapconfig , bc .db , bc .triedb , head .Root ())
402406 }
403407
404408 // Start future block processor.
@@ -411,11 +415,10 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
411415 log .Warn ("Sanitizing invalid trie cache journal time" , "provided" , bc .cacheConfig .TrieCleanRejournal , "updated" , time .Minute )
412416 bc .cacheConfig .TrieCleanRejournal = time .Minute
413417 }
414- triedb := bc .stateCache .TrieDB ()
415418 bc .wg .Add (1 )
416419 go func () {
417420 defer bc .wg .Done ()
418- triedb .SaveCachePeriodically (bc .cacheConfig .TrieCleanJournal , bc .cacheConfig .TrieCleanRejournal , bc .quit )
421+ bc . triedb .SaveCachePeriodically (bc .cacheConfig .TrieCleanJournal , bc .cacheConfig .TrieCleanRejournal , bc .quit )
419422 }()
420423 }
421424 // Rewind the chain in case of an incompatible config upgrade.
@@ -594,7 +597,7 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64, root common.Hash, repair bo
594597 if root != (common.Hash {}) && ! beyondRoot && newHeadBlock .Root () == root {
595598 beyondRoot , rootNumber = true , newHeadBlock .NumberU64 ()
596599 }
597- if _ , err := state . New (newHeadBlock .Root (), bc . stateCache , bc . snaps ); err != nil {
600+ if ! bc . HasState (newHeadBlock .Root ()) {
598601 log .Trace ("Block state missing, rewinding further" , "number" , newHeadBlock .NumberU64 (), "hash" , newHeadBlock .Hash ())
599602 if pivot == nil || newHeadBlock .NumberU64 () > * pivot {
600603 parent := bc .GetBlock (newHeadBlock .ParentHash (), newHeadBlock .NumberU64 ()- 1 )
@@ -617,7 +620,7 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64, root common.Hash, repair bo
617620 // if the historical chain pruning is enabled. In that case the logic
618621 // needs to be improved here.
619622 if ! bc .HasState (bc .genesisBlock .Root ()) {
620- if err := CommitGenesisState (bc .db , bc .genesisBlock .Hash ()); err != nil {
623+ if err := CommitGenesisState (bc .db , bc .triedb , bc . genesisBlock .Hash ()); err != nil {
621624 log .Crit ("Failed to commit genesis state" , "err" , err )
622625 }
623626 log .Debug ("Recommitted genesis state to disk" )
@@ -900,7 +903,7 @@ func (bc *BlockChain) Stop() {
900903 // - HEAD-1: So we don't do large reorgs if our HEAD becomes an uncle
901904 // - HEAD-127: So we have a hard limit on the number of blocks reexecuted
902905 if ! bc .cacheConfig .TrieDirtyDisabled {
903- triedb := bc .stateCache . TrieDB ()
906+ triedb := bc .triedb
904907
905908 for _ , offset := range []uint64 {0 , 1 , TriesInMemory - 1 } {
906909 if number := bc .CurrentBlock ().NumberU64 (); number > offset {
@@ -932,8 +935,7 @@ func (bc *BlockChain) Stop() {
932935 // Ensure all live cached entries be saved into disk, so that we can skip
933936 // cache warmup when node restarts.
934937 if bc .cacheConfig .TrieCleanJournal != "" {
935- triedb := bc .stateCache .TrieDB ()
936- triedb .SaveCache (bc .cacheConfig .TrieCleanJournal )
938+ bc .triedb .SaveCache (bc .cacheConfig .TrieCleanJournal )
937939 }
938940 log .Info ("Blockchain stopped" )
939941}
@@ -1306,24 +1308,22 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
13061308 if err != nil {
13071309 return err
13081310 }
1309- triedb := bc .stateCache .TrieDB ()
1310-
13111311 // If we're running an archive node, always flush
13121312 if bc .cacheConfig .TrieDirtyDisabled {
1313- return triedb .Commit (root , false , nil )
1313+ return bc . triedb .Commit (root , false , nil )
13141314 } else {
13151315 // Full but not archive node, do proper garbage collection
1316- triedb .Reference (root , common.Hash {}) // metadata reference to keep trie alive
1316+ bc . triedb .Reference (root , common.Hash {}) // metadata reference to keep trie alive
13171317 bc .triegc .Push (root , - int64 (block .NumberU64 ()))
13181318
13191319 if current := block .NumberU64 (); current > TriesInMemory {
13201320 // If we exceeded our memory allowance, flush matured singleton nodes to disk
13211321 var (
1322- nodes , imgs = triedb .Size ()
1322+ nodes , imgs = bc . triedb .Size ()
13231323 limit = common .StorageSize (bc .cacheConfig .TrieDirtyLimit ) * 1024 * 1024
13241324 )
13251325 if nodes > limit || imgs > 4 * 1024 * 1024 {
1326- triedb .Cap (limit - ethdb .IdealBatchSize )
1326+ bc . triedb .Cap (limit - ethdb .IdealBatchSize )
13271327 }
13281328 // Find the next state trie we need to commit
13291329 chosen := current - TriesInMemory
@@ -1342,7 +1342,7 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
13421342 log .Info ("State in memory for too long, committing" , "time" , bc .gcproc , "allowance" , bc .cacheConfig .TrieTimeLimit , "optimum" , float64 (chosen - lastWrite )/ TriesInMemory )
13431343 }
13441344 // Flush an entire trie and restart the counters
1345- triedb .Commit (header .Root , true , nil )
1345+ bc . triedb .Commit (header .Root , true , nil )
13461346 lastWrite = chosen
13471347 bc .gcproc = 0
13481348 }
@@ -1354,7 +1354,7 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
13541354 bc .triegc .Push (root , number )
13551355 break
13561356 }
1357- triedb .Dereference (root .(common.Hash ))
1357+ bc . triedb .Dereference (root .(common.Hash ))
13581358 }
13591359 }
13601360 }
@@ -1760,7 +1760,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals, setHead bool)
17601760 stats .processed ++
17611761 stats .usedGas += usedGas
17621762
1763- dirty , _ := bc .stateCache . TrieDB () .Size ()
1763+ dirty , _ := bc .triedb .Size ()
17641764 stats .report (chain , it .index , dirty , setHead )
17651765
17661766 if ! setHead {
0 commit comments