@@ -163,7 +163,9 @@ type CacheConfig struct {
163
163
StateHistory uint64 // Number of blocks from head whose state histories are reserved.
164
164
StateScheme string // Scheme used to store ethereum states and merkle tree nodes on top
165
165
166
+ // Arbitrum: configure head rewinding limits
166
167
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
167
169
168
170
// Arbitrum: configure GC window
169
171
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 {
212
214
var defaultCacheConfig = & CacheConfig {
213
215
214
216
// Arbitrum Config Options
217
+ // note: some of the defaults are overwritten by nitro side config defaults
218
+
219
+ SnapshotRestoreMaxGas : 0 ,
220
+ HeadRewindBlocksLimit : 0 ,
221
+
215
222
TriesInMemory : state .DefaultTriesInMemory ,
216
223
TrieRetention : 30 * time .Minute ,
217
224
TrieTimeLimitRandomOffset : 0 ,
@@ -782,7 +789,7 @@ func (bc *BlockChain) SetSafe(header *types.Header) {
782
789
}
783
790
784
791
// 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 ) {
786
793
var (
787
794
limit uint64 // The oldest block that will be searched for this rewinding
788
795
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
809
816
} else if head .Number .Uint64 () > params .FullImmutabilityThreshold {
810
817
limit = head .Number .Uint64 () - params .FullImmutabilityThreshold
811
818
}
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
+
812
825
lastFullBlock := uint64 (0 )
813
826
lastFullBlockHash := common.Hash {}
814
827
gasRolledBack := uint64 (0 )
@@ -820,7 +833,7 @@ func (bc *BlockChain) rewindHashHead(head *types.Header, root common.Hash, rewin
820
833
}
821
834
logger ("Block state missing, rewinding further" , "number" , head .Number , "hash" , head .Hash (), "elapsed" , common .PrettyDuration (time .Since (start )))
822
835
823
- if rewindLimit > 0 && lastFullBlock != 0 {
836
+ if rewindGasLimit > 0 && lastFullBlock != 0 {
824
837
// Arbitrum: track the amount of gas rolled back and stop the rollback early if necessary
825
838
gasUsedInBlock := head .GasUsed
826
839
if bc .chainConfig .IsArbitrum () {
@@ -830,7 +843,7 @@ func (bc *BlockChain) rewindHashHead(head *types.Header, root common.Hash, rewin
830
843
}
831
844
}
832
845
gasRolledBack += gasUsedInBlock
833
- if gasRolledBack >= rewindLimit {
846
+ if gasRolledBack >= rewindGasLimit {
834
847
rootNumber = lastFullBlock
835
848
head = bc .GetHeader (lastFullBlockHash , lastFullBlock )
836
849
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
964
977
// representing the state corresponding to snapshot disk layer, is deemed impassable,
965
978
// then block number zero is returned, indicating that snapshot recovery is disabled
966
979
// 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 ) {
968
981
if bc .triedb .Scheme () == rawdb .PathScheme {
969
982
newHead , rootNumber := bc .rewindPathHead (head , root )
970
983
return newHead , rootNumber , head .Number .Uint64 () != 0
971
984
}
972
- return bc .rewindHashHead (head , root , rewindLimit )
985
+ return bc .rewindHashHead (head , root , rewindGasLimit )
973
986
}
974
987
975
988
// setHeadBeyondRoot rewinds the local chain to a new head with the extra condition
976
989
// 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).
978
991
// If the limit was hit, rewind to last block with state. This method is meant to be
979
992
// used when rewinding with snapshots enabled to ensure that we go back further than
980
993
// 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
986
999
// requested time. If both `head` and `time` is 0, the chain is rewound to genesis.
987
1000
//
988
1001
// 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 ) {
990
1003
if ! bc .chainmu .TryLock () {
991
1004
return 0 , false , errChainStopped
992
1005
}
@@ -1006,7 +1019,7 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64, time uint64, root common.Ha
1006
1019
// chain reparation mechanism without deleting any data!
1007
1020
if currentBlock := bc .CurrentBlock (); currentBlock != nil && header .Number .Uint64 () <= currentBlock .Number .Uint64 () {
1008
1021
var newHeadBlock * types.Header
1009
- newHeadBlock , blockNumber , rootFound = bc .rewindHead (header , root , rewindLimit )
1022
+ newHeadBlock , blockNumber , rootFound = bc .rewindHead (header , root , rewindGasLimit )
1010
1023
rawdb .WriteHeadBlockHash (db , newHeadBlock .Hash ())
1011
1024
1012
1025
// Degrade the chain markers if they are explicitly reverted.
0 commit comments