@@ -157,7 +157,9 @@ type CacheConfig struct {
157
157
StateHistory uint64 // Number of blocks from head whose state histories are reserved.
158
158
StateScheme string // Scheme used to store ethereum states and merkle tree nodes on top
159
159
160
+ // Arbitrum: configure head rewinding limits
160
161
SnapshotRestoreMaxGas uint64 // Rollback up to this much gas to restore snapshot (otherwise snapshot recalculated from nothing)
162
+ HeadRewindBlocksLimit uint64 // Rollback up to this many blocks to restore chain head (0 = preserve default upstream behaviour), only for HashScheme
161
163
162
164
// Arbitrum: configure GC window
163
165
TriesInMemory uint64 // Height difference before which a trie may not be garbage-collected
@@ -202,6 +204,11 @@ func (c *CacheConfig) triedbConfig(isVerkle bool) *triedb.Config {
202
204
var defaultCacheConfig = & CacheConfig {
203
205
204
206
// Arbitrum Config Options
207
+ // note: some of the defaults are overwritten by nitro side config defaults
208
+
209
+ SnapshotRestoreMaxGas : 0 ,
210
+ HeadRewindBlocksLimit : 0 ,
211
+
205
212
TriesInMemory : state .DefaultTriesInMemory ,
206
213
TrieRetention : 30 * time .Minute ,
207
214
TrieTimeLimitRandomOffset : 0 ,
@@ -691,7 +698,7 @@ func (bc *BlockChain) SetSafe(header *types.Header) {
691
698
}
692
699
693
700
// rewindHashHead implements the logic of rewindHead in the context of hash scheme.
694
- func (bc * BlockChain ) rewindHashHead (head * types.Header , root common.Hash , rewindLimit uint64 ) (* types.Header , uint64 , bool ) {
701
+ func (bc * BlockChain ) rewindHashHead (head * types.Header , root common.Hash , rewindGasLimit uint64 ) (* types.Header , uint64 , bool ) {
695
702
var (
696
703
limit uint64 // The oldest block that will be searched for this rewinding
697
704
rootFound = root == common.Hash {} // Flag whether we're beyond the requested root (no root, always true)
@@ -718,6 +725,12 @@ func (bc *BlockChain) rewindHashHead(head *types.Header, root common.Hash, rewin
718
725
} else if head .Number .Uint64 () > params .FullImmutabilityThreshold {
719
726
limit = head .Number .Uint64 () - params .FullImmutabilityThreshold
720
727
}
728
+
729
+ // arbitrum: overwrite the oldest block limit if pivot block is not available and HeadRewindBlocksLimit is configured
730
+ if pivot == nil && bc .cacheConfig .HeadRewindBlocksLimit > 0 && head .Number .Uint64 () > bc .cacheConfig .HeadRewindBlocksLimit {
731
+ limit = head .Number .Uint64 () - bc .cacheConfig .HeadRewindBlocksLimit
732
+ }
733
+
721
734
lastFullBlock := uint64 (0 )
722
735
lastFullBlockHash := common.Hash {}
723
736
gasRolledBack := uint64 (0 )
@@ -729,7 +742,7 @@ func (bc *BlockChain) rewindHashHead(head *types.Header, root common.Hash, rewin
729
742
}
730
743
logger ("Block state missing, rewinding further" , "number" , head .Number , "hash" , head .Hash (), "elapsed" , common .PrettyDuration (time .Since (start )))
731
744
732
- if rewindLimit > 0 && lastFullBlock != 0 {
745
+ if rewindGasLimit > 0 && lastFullBlock != 0 {
733
746
// Arbitrum: track the amount of gas rolled back and stop the rollback early if necessary
734
747
gasUsedInBlock := head .GasUsed
735
748
if bc .chainConfig .IsArbitrum () {
@@ -739,7 +752,7 @@ func (bc *BlockChain) rewindHashHead(head *types.Header, root common.Hash, rewin
739
752
}
740
753
}
741
754
gasRolledBack += gasUsedInBlock
742
- if gasRolledBack >= rewindLimit {
755
+ if gasRolledBack >= rewindGasLimit {
743
756
rootNumber = lastFullBlock
744
757
head = bc .GetHeader (lastFullBlockHash , lastFullBlock )
745
758
log .Debug ("Rewound to block with state but not snapshot" , "number" , head .Number .Uint64 (), "hash" , head .Hash ())
@@ -873,17 +886,17 @@ func (bc *BlockChain) rewindPathHead(head *types.Header, root common.Hash) (*typ
873
886
// representing the state corresponding to snapshot disk layer, is deemed impassable,
874
887
// then block number zero is returned, indicating that snapshot recovery is disabled
875
888
// and the whole snapshot should be auto-generated in case of head mismatch.
876
- func (bc * BlockChain ) rewindHead (head * types.Header , root common.Hash , rewindLimit uint64 ) (* types.Header , uint64 , bool ) {
889
+ func (bc * BlockChain ) rewindHead (head * types.Header , root common.Hash , rewindGasLimit uint64 ) (* types.Header , uint64 , bool ) {
877
890
if bc .triedb .Scheme () == rawdb .PathScheme {
878
891
newHead , rootNumber := bc .rewindPathHead (head , root )
879
892
return newHead , rootNumber , head .Number .Uint64 () != 0
880
893
}
881
- return bc .rewindHashHead (head , root , rewindLimit )
894
+ return bc .rewindHashHead (head , root , rewindGasLimit )
882
895
}
883
896
884
897
// setHeadBeyondRoot rewinds the local chain to a new head with the extra condition
885
898
// that the rewind must pass the specified state root. The extra condition is
886
- // ignored if it causes rolling back more than rewindLimit Gas (0 meaning infinte).
899
+ // ignored if it causes rolling back more than rewindGasLimit Gas (0 meaning infinte).
887
900
// If the limit was hit, rewind to last block with state. This method is meant to be
888
901
// used when rewinding with snapshots enabled to ensure that we go back further than
889
902
// persistent disk layer. Depending on whether the node was snap synced or full, and
@@ -895,7 +908,7 @@ func (bc *BlockChain) rewindHead(head *types.Header, root common.Hash, rewindLim
895
908
// requested time. If both `head` and `time` is 0, the chain is rewound to genesis.
896
909
//
897
910
// The method returns the block number where the requested root cap was found.
898
- func (bc * BlockChain ) setHeadBeyondRoot (head uint64 , time uint64 , root common.Hash , repair bool , rewindLimit uint64 ) (uint64 , bool , error ) {
911
+ func (bc * BlockChain ) setHeadBeyondRoot (head uint64 , time uint64 , root common.Hash , repair bool , rewindGasLimit uint64 ) (uint64 , bool , error ) {
899
912
if ! bc .chainmu .TryLock () {
900
913
return 0 , false , errChainStopped
901
914
}
@@ -915,7 +928,7 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64, time uint64, root common.Ha
915
928
// chain reparation mechanism without deleting any data!
916
929
if currentBlock := bc .CurrentBlock (); currentBlock != nil && header .Number .Uint64 () <= currentBlock .Number .Uint64 () {
917
930
var newHeadBlock * types.Header
918
- newHeadBlock , blockNumber , rootFound = bc .rewindHead (header , root , rewindLimit )
931
+ newHeadBlock , blockNumber , rootFound = bc .rewindHead (header , root , rewindGasLimit )
919
932
rawdb .WriteHeadBlockHash (db , newHeadBlock .Hash ())
920
933
921
934
// Degrade the chain markers if they are explicitly reverted.
0 commit comments