@@ -42,11 +42,12 @@ const EstimateGasErrorRatio = 0.015
42
42
// these together, it would be excessively hard to test. Splitting the parts out
43
43
// allows testing without needing a proper live chain.
44
44
type Options struct {
45
- Config * params.ChainConfig // Chain configuration for hard fork selection
46
- Chain core.ChainContext // Chain context to access past block hashes
47
- Header * types.Header // Header defining the block context to execute in
48
- State * state.StateDB // Pre-state on top of which to estimate the gas
49
- Backend core.NodeInterfaceBackendAPI
45
+ Config * params.ChainConfig // Chain configuration for hard fork selection
46
+ Chain core.ChainContext // Chain context to access past block hashes
47
+ Header * types.Header // Header defining the block context to execute in
48
+ State * state.StateDB // Pre-state on top of which to estimate the gas
49
+ Backend core.NodeInterfaceBackendAPI
50
+ RunScheduledTxes func (context.Context , core.NodeInterfaceBackendAPI , * state.StateDB , * types.Header , vm.BlockContext , core.MessageRunMode , * core.ExecutionResult ) (* core.ExecutionResult , error )
50
51
51
52
ErrorRatio float64 // Allowed overestimation ratio for faster estimation termination
52
53
}
@@ -235,8 +236,7 @@ func run(ctx context.Context, call *core.Message, opts *Options) (*core.Executio
235
236
evm .Cancel ()
236
237
}()
237
238
// Execute the call, returning a wrapped error or the result
238
- gp := new (core.GasPool ).AddGas (math .MaxUint64 )
239
- result , err := core .ApplyMessage (evm , call , gp )
239
+ result , err := core .ApplyMessage (evm , call , new (core.GasPool ).AddGas (math .MaxUint64 ))
240
240
if vmerr := dirtyState .Error (); vmerr != nil {
241
241
return nil , vmerr
242
242
}
@@ -245,42 +245,9 @@ func run(ctx context.Context, call *core.Message, opts *Options) (*core.Executio
245
245
}
246
246
247
247
// Arbitrum: a tx can schedule another (see retryables)
248
- scheduled := result .ScheduledTxes
249
- for len (scheduled ) > 0 {
250
- // This will panic if the scheduled tx is signed, but we only schedule unsigned ones
251
- msg , err := core .TransactionToMessage (scheduled [0 ], types .NewArbitrumSigner (nil ), opts .Header .BaseFee )
252
- if err != nil {
253
- return nil , err
254
- }
255
- // The scheduling transaction will "use" all of the gas available to it,
256
- // but it's really just passing it on to the scheduled tx, so we subtract it out here.
257
- if result .UsedGas >= msg .GasLimit {
258
- result .UsedGas -= msg .GasLimit
259
- } else {
260
- log .Warn ("Scheduling tx used less gas than scheduled tx has available" , "usedGas" , result .UsedGas , "scheduledGas" , msg .GasLimit )
261
- result .UsedGas = 0
262
- }
263
- msg .TxRunMode = core .MessageGasEstimationMode
264
- // make a new EVM for the scheduled Tx (an EVM must never be reused)
265
- evm := opts .Backend .GetEVM (ctx , msg , dirtyState , opts .Header , & vm.Config {NoBaseFee : true }, & evmContext )
266
- go func () {
267
- <- ctx .Done ()
268
- evm .Cancel ()
269
- }()
270
-
271
- scheduledTxResult , err := core .ApplyMessage (evm , msg , gp )
272
- if err != nil {
273
- return nil , err // Bail out
274
- }
275
- if err := dirtyState .Error (); err != nil {
276
- return nil , err
277
- }
278
- if scheduledTxResult .Failed () {
279
- return scheduledTxResult , nil
280
- }
281
- // Add back in any gas used by the scheduled transaction.
282
- result .UsedGas += scheduledTxResult .UsedGas
283
- scheduled = append (scheduled [1 :], scheduledTxResult .ScheduledTxes ... )
248
+ result , err = opts .RunScheduledTxes (ctx , opts .Backend , dirtyState , opts .Header , evmContext , core .MessageGasEstimationMode , result )
249
+ if err != nil {
250
+ return nil , err
284
251
}
285
252
286
253
return result , nil
0 commit comments