@@ -160,8 +160,9 @@ type CacheConfig struct {
160
160
SnapshotRestoreMaxGas uint64 // Rollback up to this much gas to restore snapshot (otherwise snapshot recalculated from nothing)
161
161
162
162
// Arbitrum: configure GC window
163
- TriesInMemory uint64 // Height difference before which a trie may not be garbage-collected
164
- TrieRetention time.Duration // Time limit before which a trie may not be garbage-collected
163
+ TriesInMemory uint64 // Height difference before which a trie may not be garbage-collected
164
+ TrieRetention time.Duration // Time limit before which a trie may not be garbage-collected
165
+ TrieTimeLimitRandomOffset time.Duration // Range of random offset of each commit due to TrieTimeLimit period
165
166
166
167
MaxNumberOfBlocksToSkipStateSaving uint32
167
168
MaxAmountOfGasToSkipStateSaving uint64
@@ -203,6 +204,7 @@ var defaultCacheConfig = &CacheConfig{
203
204
// Arbitrum Config Options
204
205
TriesInMemory : state .DefaultTriesInMemory ,
205
206
TrieRetention : 30 * time .Minute ,
207
+ TrieTimeLimitRandomOffset : 0 ,
206
208
MaxNumberOfBlocksToSkipStateSaving : 0 ,
207
209
MaxAmountOfGasToSkipStateSaving : 0 ,
208
210
@@ -295,8 +297,10 @@ type BlockChain struct {
295
297
vmConfig vm.Config
296
298
logger * tracing.Hooks
297
299
300
+ // Arbitrum:
298
301
numberOfBlocksToSkipStateSaving uint32
299
302
amountOfGasInBlocksToSkipStateSaving uint64
303
+ gcprocRandOffset time.Duration // random offset for gcproc time
300
304
}
301
305
302
306
type trieGcEntry struct {
@@ -376,6 +380,8 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
376
380
bc .prefetcher = newStatePrefetcher (chainConfig , bc .hc )
377
381
bc .processor = NewStateProcessor (chainConfig , bc .hc )
378
382
383
+ bc .gcprocRandOffset = bc .generateGcprocRandOffset ()
384
+
379
385
bc .genesisBlock = bc .GetBlockByNumber (0 )
380
386
if bc .genesisBlock == nil {
381
387
return nil , ErrNoGenesis
@@ -1627,8 +1633,9 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
1627
1633
}
1628
1634
flushInterval := time .Duration (bc .flushInterval .Load ())
1629
1635
// If we exceeded out time allowance, flush an entire trie to disk
1636
+ // The time threshold can be offset by gcprocRandOffset if TrieTimeLimitRandomOffset > 0; the offset is re-generated after each full trie flush
1630
1637
// In case of archive node that skips some trie commits we don't flush tries here
1631
- if bc .gcproc > flushInterval && prevEntry != nil && ! archiveNode {
1638
+ if bc .gcproc + bc . gcprocRandOffset > flushInterval && prevEntry != nil && ! archiveNode {
1632
1639
// If the header is missing (canonical chain behind), we're reorging a low
1633
1640
// diff sidechain. Suspend committing until this operation is completed.
1634
1641
header := bc .GetHeaderByNumber (prevNum )
@@ -1644,6 +1651,7 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
1644
1651
bc .triedb .Commit (header .Root , true )
1645
1652
bc .lastWrite = prevNum
1646
1653
bc .gcproc = 0
1654
+ bc .gcprocRandOffset = bc .generateGcprocRandOffset ()
1647
1655
}
1648
1656
}
1649
1657
if prevEntry != nil {
0 commit comments