@@ -1239,64 +1239,69 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
12391239 if err != nil {
12401240 return err
12411241 }
1242- triedb := bc .stateCache .TrieDB ()
1243-
1244- freq := atomic .LoadUint64 (& bc .trieFlushFreq )
1242+ var (
1243+ triedb = bc .stateCache .TrieDB ()
1244+ freq = atomic .LoadUint64 (& bc .trieFlushFreq )
1245+ )
12451246 // If we're running an archive node, always flush
12461247 if freq == 1 {
12471248 return triedb .Commit (root , false , nil )
1248- } else {
1249- // Full but not archive node, do proper garbage collection
1250- triedb .Reference (root , common.Hash {}) // metadata reference to keep trie alive
1251- bc .triegc .Push (root , - int64 (block .NumberU64 ()))
1252-
1253- // Note: flush frequency is not considered for the first TriesInMemory blocks.
1254- if current := block .NumberU64 (); current > TriesInMemory {
1255- // If we exceeded our memory allowance, flush matured singleton nodes to disk
1256- var (
1257- nodes , imgs = triedb .Size ()
1258- limit = common .StorageSize (bc .cacheConfig .TrieDirtyLimit ) * 1024 * 1024
1259- )
1260- if nodes > limit || imgs > 4 * 1024 * 1024 {
1261- triedb .Cap (limit - ethdb .IdealBatchSize )
1262- }
1263- // Find the next state trie we need to commit
1264- chosen := current - TriesInMemory
1265- doFlush := bc .gcproc > bc .cacheConfig .TrieTimeLimit
1266- if freq > 1 {
1267- sinceFlush := chosen - lastWrite
1268- doFlush = doFlush || sinceFlush >= freq
1269- }
1270- // If we exceeded out time allowance or passed number of blocks threshold,
1271- // then flush an entire trie to disk
1272- if doFlush {
1273- // If the header is missing (canonical chain behind), we're reorging a low
1274- // diff sidechain. Suspend committing until this operation is completed.
1275- header := bc .GetHeaderByNumber (chosen )
1276- if header == nil {
1277- log .Warn ("Reorg in progress, trie commit postponed" , "number" , chosen )
1278- } else {
1279- // If we're exceeding limits but haven't reached a large enough memory gap,
1280- // warn the user that the system is becoming unstable.
1281- if chosen < lastWrite + TriesInMemory && bc .gcproc >= 2 * bc .cacheConfig .TrieTimeLimit {
1282- log .Info ("State in memory for too long, committing" , "time" , bc .gcproc , "allowance" , bc .cacheConfig .TrieTimeLimit , "optimum" , float64 (chosen - lastWrite )/ TriesInMemory )
1283- }
1284- // Flush an entire trie and restart the counters
1285- triedb .Commit (header .Root , true , nil )
1286- lastWrite = chosen
1287- bc .gcproc = 0
1288- }
1289- }
1290- // Garbage collect anything below our required write retention
1291- for ! bc .triegc .Empty () {
1292- root , number := bc .triegc .Pop ()
1293- if uint64 (- number ) > chosen {
1294- bc .triegc .Push (root , number )
1295- break
1296- }
1297- triedb .Dereference (root .(common.Hash ))
1249+ }
1250+
1251+ // Full but not archive node, do proper garbage collection
1252+ triedb .Reference (root , common.Hash {}) // metadata reference to keep trie alive
1253+ bc .triegc .Push (root , - int64 (block .NumberU64 ()))
1254+
1255+ // Note: flush frequency is not considered for the first TriesInMemory blocks.
1256+ current := block .NumberU64 ()
1257+ if current <= TriesInMemory {
1258+ return nil
1259+ }
1260+ // If we exceeded our memory allowance, flush matured singleton nodes to disk
1261+ var (
1262+ nodes , imgs = triedb .Size ()
1263+ limit = common .StorageSize (bc .cacheConfig .TrieDirtyLimit ) * 1024 * 1024
1264+ )
1265+ if nodes > limit || imgs > 4 * 1024 * 1024 {
1266+ triedb .Cap (limit - ethdb .IdealBatchSize )
1267+ }
1268+ // Find the next state trie we need to commit
1269+ var (
1270+ chosen = current - TriesInMemory
1271+ sinceFlush = chosen - lastWrite
1272+ doFlush = bc .gcproc > bc .cacheConfig .TrieTimeLimit
1273+ )
1274+ if freq > 1 {
1275+ doFlush = doFlush || sinceFlush >= freq
1276+ }
1277+ // If we exceeded out time allowance or passed number of blocks threshold,
1278+ // then flush an entire trie to disk
1279+ if doFlush {
1280+ // If the header is missing (canonical chain behind), we're reorging a low
1281+ // diff sidechain. Suspend committing until this operation is completed.
1282+ header := bc .GetHeaderByNumber (chosen )
1283+ if header == nil {
1284+ log .Warn ("Reorg in progress, trie commit postponed" , "number" , chosen )
1285+ } else {
1286+ // If we're exceeding limits but haven't reached a large enough memory gap,
1287+ // warn the user that the system is becoming unstable.
1288+ if chosen < lastWrite + TriesInMemory && bc .gcproc >= 2 * bc .cacheConfig .TrieTimeLimit {
1289+ log .Info ("State in memory for too long, committing" , "time" , bc .gcproc , "allowance" , bc .cacheConfig .TrieTimeLimit , "optimum" , float64 (chosen - lastWrite )/ TriesInMemory )
12981290 }
1291+ // Flush an entire trie and restart the counters
1292+ triedb .Commit (header .Root , true , nil )
1293+ lastWrite = chosen
1294+ bc .gcproc = 0
1295+ }
1296+ }
1297+ // Garbage collect anything below our required write retention
1298+ for ! bc .triegc .Empty () {
1299+ root , number := bc .triegc .Pop ()
1300+ if uint64 (- number ) > chosen {
1301+ bc .triegc .Push (root , number )
1302+ break
12991303 }
1304+ triedb .Dereference (root .(common.Hash ))
13001305 }
13011306 return nil
13021307}
0 commit comments