@@ -163,7 +163,9 @@ type CacheConfig struct {
163163 StateHistory uint64 // Number of blocks from head whose state histories are reserved.
164164 StateScheme string // Scheme used to store ethereum states and merkle tree nodes on top
165165
166+ // Arbitrum: configure head rewinding limits
166167 SnapshotRestoreMaxGas uint64 // Rollback up to this much gas to restore snapshot (otherwise snapshot recalculated from nothing)
168+ HeadRewindBlocksLimit uint64 // Rollback up to this many blocks to restore chain head (0 = preserve default upstream behaviour), only for HashScheme
167169
168170 // Arbitrum: configure GC window
169171 TriesInMemory uint64 // Height difference before which a trie may not be garbage-collected
@@ -212,6 +214,11 @@ func (c *CacheConfig) triedbConfig(isVerkle bool) *triedb.Config {
212214var defaultCacheConfig = & CacheConfig {
213215
214216 // Arbitrum Config Options
217+ // note: some of the defaults are overwritten by nitro side config defaults
218+
219+ SnapshotRestoreMaxGas : 0 ,
220+ HeadRewindBlocksLimit : 0 ,
221+
215222 TriesInMemory : state .DefaultTriesInMemory ,
216223 TrieRetention : 30 * time .Minute ,
217224 TrieTimeLimitRandomOffset : 0 ,
@@ -782,7 +789,7 @@ func (bc *BlockChain) SetSafe(header *types.Header) {
782789}
783790
784791// rewindHashHead implements the logic of rewindHead in the context of hash scheme.
785- func (bc * BlockChain ) rewindHashHead (head * types.Header , root common.Hash , rewindLimit uint64 ) (* types.Header , uint64 , bool ) {
792+ func (bc * BlockChain ) rewindHashHead (head * types.Header , root common.Hash , rewindGasLimit uint64 ) (* types.Header , uint64 , bool ) {
786793 var (
787794 limit uint64 // The oldest block that will be searched for this rewinding
788795 rootFound = root == common.Hash {} // Flag whether we're beyond the requested root (no root, always true)
@@ -809,6 +816,12 @@ func (bc *BlockChain) rewindHashHead(head *types.Header, root common.Hash, rewin
809816 } else if head .Number .Uint64 () > params .FullImmutabilityThreshold {
810817 limit = head .Number .Uint64 () - params .FullImmutabilityThreshold
811818 }
819+
820+ // arbitrum: overwrite the oldest block limit if pivot block is not available and HeadRewindBlocksLimit is configured
821+ if pivot == nil && bc .cacheConfig .HeadRewindBlocksLimit > 0 && head .Number .Uint64 () > bc .cacheConfig .HeadRewindBlocksLimit {
822+ limit = head .Number .Uint64 () - bc .cacheConfig .HeadRewindBlocksLimit
823+ }
824+
812825 lastFullBlock := uint64 (0 )
813826 lastFullBlockHash := common.Hash {}
814827 gasRolledBack := uint64 (0 )
@@ -820,7 +833,7 @@ func (bc *BlockChain) rewindHashHead(head *types.Header, root common.Hash, rewin
820833 }
821834 logger ("Block state missing, rewinding further" , "number" , head .Number , "hash" , head .Hash (), "elapsed" , common .PrettyDuration (time .Since (start )))
822835
823- if rewindLimit > 0 && lastFullBlock != 0 {
836+ if rewindGasLimit > 0 && lastFullBlock != 0 {
824837 // Arbitrum: track the amount of gas rolled back and stop the rollback early if necessary
825838 gasUsedInBlock := head .GasUsed
826839 if bc .chainConfig .IsArbitrum () {
@@ -830,7 +843,7 @@ func (bc *BlockChain) rewindHashHead(head *types.Header, root common.Hash, rewin
830843 }
831844 }
832845 gasRolledBack += gasUsedInBlock
833- if gasRolledBack >= rewindLimit {
846+ if gasRolledBack >= rewindGasLimit {
834847 rootNumber = lastFullBlock
835848 head = bc .GetHeader (lastFullBlockHash , lastFullBlock )
836849 log .Debug ("Rewound to block with state but not snapshot" , "number" , head .Number .Uint64 (), "hash" , head .Hash ())
@@ -964,17 +977,17 @@ func (bc *BlockChain) rewindPathHead(head *types.Header, root common.Hash) (*typ
964977// representing the state corresponding to snapshot disk layer, is deemed impassable,
965978// then block number zero is returned, indicating that snapshot recovery is disabled
966979// and the whole snapshot should be auto-generated in case of head mismatch.
967- func (bc * BlockChain ) rewindHead (head * types.Header , root common.Hash , rewindLimit uint64 ) (* types.Header , uint64 , bool ) {
980+ func (bc * BlockChain ) rewindHead (head * types.Header , root common.Hash , rewindGasLimit uint64 ) (* types.Header , uint64 , bool ) {
968981 if bc .triedb .Scheme () == rawdb .PathScheme {
969982 newHead , rootNumber := bc .rewindPathHead (head , root )
970983 return newHead , rootNumber , head .Number .Uint64 () != 0
971984 }
972- return bc .rewindHashHead (head , root , rewindLimit )
985+ return bc .rewindHashHead (head , root , rewindGasLimit )
973986}
974987
975988// setHeadBeyondRoot rewinds the local chain to a new head with the extra condition
976989// that the rewind must pass the specified state root. The extra condition is
977- // ignored if it causes rolling back more than rewindLimit Gas (0 meaning infinte).
990+ // ignored if it causes rolling back more than rewindGasLimit Gas (0 meaning infinte).
978991// If the limit was hit, rewind to last block with state. This method is meant to be
979992// used when rewinding with snapshots enabled to ensure that we go back further than
980993// persistent disk layer. Depending on whether the node was snap synced or full, and
@@ -986,7 +999,7 @@ func (bc *BlockChain) rewindHead(head *types.Header, root common.Hash, rewindLim
986999// requested time. If both `head` and `time` is 0, the chain is rewound to genesis.
9871000//
9881001// The method returns the block number where the requested root cap was found.
989- func (bc * BlockChain ) setHeadBeyondRoot (head uint64 , time uint64 , root common.Hash , repair bool , rewindLimit uint64 ) (uint64 , bool , error ) {
1002+ func (bc * BlockChain ) setHeadBeyondRoot (head uint64 , time uint64 , root common.Hash , repair bool , rewindGasLimit uint64 ) (uint64 , bool , error ) {
9901003 if ! bc .chainmu .TryLock () {
9911004 return 0 , false , errChainStopped
9921005 }
@@ -1006,7 +1019,7 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64, time uint64, root common.Ha
10061019 // chain reparation mechanism without deleting any data!
10071020 if currentBlock := bc .CurrentBlock (); currentBlock != nil && header .Number .Uint64 () <= currentBlock .Number .Uint64 () {
10081021 var newHeadBlock * types.Header
1009- newHeadBlock , blockNumber , rootFound = bc .rewindHead (header , root , rewindLimit )
1022+ newHeadBlock , blockNumber , rootFound = bc .rewindHead (header , root , rewindGasLimit )
10101023 rawdb .WriteHeadBlockHash (db , newHeadBlock .Hash ())
10111024
10121025 // Degrade the chain markers if they are explicitly reverted.
0 commit comments