|
@@ -116,6 +116,8 @@ const (
|
|
|
// that's resident in a blockchain.
|
|
// that's resident in a blockchain.
|
|
|
type CacheConfig struct {
|
|
type CacheConfig struct {
|
|
|
TrieCleanLimit int // Memory allowance (MB) to use for caching trie nodes in memory
|
|
TrieCleanLimit int // Memory allowance (MB) to use for caching trie nodes in memory
|
|
|
|
|
+ TrieCleanJournal string // Disk journal for saving clean cache entries.
|
|
|
|
|
+ TrieCleanRejournal time.Duration // Time interval to dump clean cache to disk periodically
|
|
|
TrieCleanNoPrefetch bool // Whether to disable heuristic state prefetching for followup blocks
|
|
TrieCleanNoPrefetch bool // Whether to disable heuristic state prefetching for followup blocks
|
|
|
TrieDirtyLimit int // Memory limit (MB) at which to start flushing dirty trie nodes to disk
|
|
TrieDirtyLimit int // Memory limit (MB) at which to start flushing dirty trie nodes to disk
|
|
|
TrieDirtyDisabled bool // Whether to disable trie write caching and GC altogether (archive node)
|
|
TrieDirtyDisabled bool // Whether to disable trie write caching and GC altogether (archive node)
|
|
@@ -220,7 +222,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
|
|
|
cacheConfig: cacheConfig,
|
|
cacheConfig: cacheConfig,
|
|
|
db: db,
|
|
db: db,
|
|
|
triegc: prque.New(nil),
|
|
triegc: prque.New(nil),
|
|
|
- stateCache: state.NewDatabaseWithCache(db, cacheConfig.TrieCleanLimit),
|
|
|
|
|
|
|
+ stateCache: state.NewDatabaseWithCache(db, cacheConfig.TrieCleanLimit, cacheConfig.TrieCleanJournal),
|
|
|
quit: make(chan struct{}),
|
|
quit: make(chan struct{}),
|
|
|
shouldPreserve: shouldPreserve,
|
|
shouldPreserve: shouldPreserve,
|
|
|
bodyCache: bodyCache,
|
|
bodyCache: bodyCache,
|
|
@@ -328,6 +330,19 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
|
|
|
bc.txLookupLimit = *txLookupLimit
|
|
bc.txLookupLimit = *txLookupLimit
|
|
|
go bc.maintainTxIndex(txIndexBlock)
|
|
go bc.maintainTxIndex(txIndexBlock)
|
|
|
}
|
|
}
|
|
|
|
|
+ // If periodic cache journal is required, spin it up.
|
|
|
|
|
+ if bc.cacheConfig.TrieCleanRejournal > 0 {
|
|
|
|
|
+ if bc.cacheConfig.TrieCleanRejournal < time.Minute {
|
|
|
|
|
+ log.Warn("Sanitizing invalid trie cache journal time", "provided", bc.cacheConfig.TrieCleanRejournal, "updated", time.Minute)
|
|
|
|
|
+ bc.cacheConfig.TrieCleanRejournal = time.Minute
|
|
|
|
|
+ }
|
|
|
|
|
+ triedb := bc.stateCache.TrieDB()
|
|
|
|
|
+ bc.wg.Add(1)
|
|
|
|
|
+ go func() {
|
|
|
|
|
+ defer bc.wg.Done()
|
|
|
|
|
+ triedb.SaveCachePeriodically(bc.cacheConfig.TrieCleanJournal, bc.cacheConfig.TrieCleanRejournal, bc.quit)
|
|
|
|
|
+ }()
|
|
|
|
|
+ }
|
|
|
return bc, nil
|
|
return bc, nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -919,6 +934,12 @@ func (bc *BlockChain) Stop() {
|
|
|
log.Error("Dangling trie nodes after full cleanup")
|
|
log.Error("Dangling trie nodes after full cleanup")
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+ // Ensure all live cached entries be saved into disk, so that we can skip
|
|
|
|
|
+ // cache warmup when node restarts.
|
|
|
|
|
+ if bc.cacheConfig.TrieCleanJournal != "" {
|
|
|
|
|
+ triedb := bc.stateCache.TrieDB()
|
|
|
|
|
+ triedb.SaveCache(bc.cacheConfig.TrieCleanJournal)
|
|
|
|
|
+ }
|
|
|
log.Info("Blockchain stopped")
|
|
log.Info("Blockchain stopped")
|
|
|
}
|
|
}
|
|
|
|
|
|