@@ -246,6 +246,8 @@ pub struct Backend {
246
246
// === wallet === //
247
247
capabilities : Arc < RwLock < WalletCapabilities > > ,
248
248
executor_wallet : Arc < RwLock < Option < EthereumWallet > > > ,
249
+ /// Disable pool balance checks
250
+ disable_pool_balance_checks : bool ,
249
251
}
250
252
251
253
impl Backend {
@@ -309,9 +311,9 @@ impl Backend {
309
311
states = states. disk_path ( cache_path) ;
310
312
}
311
313
312
- let ( slots_in_an_epoch, precompile_factory) = {
314
+ let ( slots_in_an_epoch, precompile_factory, disable_pool_balance_checks ) = {
313
315
let cfg = node_config. read ( ) . await ;
314
- ( cfg. slots_in_an_epoch , cfg. precompile_factory . clone ( ) )
316
+ ( cfg. slots_in_an_epoch , cfg. precompile_factory . clone ( ) , cfg . disable_pool_balance_checks )
315
317
} ;
316
318
317
319
let ( capabilities, executor_wallet) = if odyssey {
@@ -376,6 +378,7 @@ impl Backend {
376
378
mining : Arc :: new ( tokio:: sync:: Mutex :: new ( ( ) ) ) ,
377
379
capabilities : Arc :: new ( RwLock :: new ( capabilities) ) ,
378
380
executor_wallet : Arc :: new ( RwLock :: new ( executor_wallet) ) ,
381
+ disable_pool_balance_checks,
379
382
} ;
380
383
381
384
if let Some ( interval_block_time) = automine_block_time {
@@ -3341,22 +3344,7 @@ impl TransactionValidator for Backend {
3341
3344
}
3342
3345
}
3343
3346
3344
- if tx. gas_limit ( ) < MIN_TRANSACTION_GAS as u64 {
3345
- warn ! ( target: "backend" , "[{:?}] gas too low" , tx. hash( ) ) ;
3346
- return Err ( InvalidTransactionError :: GasTooLow ) ;
3347
- }
3348
-
3349
- // Check gas limit, iff block gas limit is set.
3350
- if !env. evm_env . cfg_env . disable_block_gas_limit
3351
- && tx. gas_limit ( ) > env. evm_env . block_env . gas_limit
3352
- {
3353
- warn ! ( target: "backend" , "[{:?}] gas too high" , tx. hash( ) ) ;
3354
- return Err ( InvalidTransactionError :: GasTooHigh ( ErrDetail {
3355
- detail : String :: from ( "tx.gas_limit > env.block.gas_limit" ) ,
3356
- } ) ) ;
3357
- }
3358
-
3359
- // check nonce
3347
+ // Nonce validation
3360
3348
let is_deposit_tx =
3361
3349
matches ! ( & pending. transaction. transaction, TypedTransaction :: Deposit ( _) ) ;
3362
3350
let nonce = tx. nonce ( ) ;
@@ -3365,39 +3353,15 @@ impl TransactionValidator for Backend {
3365
3353
return Err ( InvalidTransactionError :: NonceTooLow ) ;
3366
3354
}
3367
3355
3368
- if env. evm_env . cfg_env . spec >= SpecId :: LONDON {
3369
- if tx. gas_price ( ) < env. evm_env . block_env . basefee . into ( ) && !is_deposit_tx {
3370
- warn ! ( target: "backend" , "max fee per gas={}, too low, block basefee={}" , tx. gas_price( ) , env. evm_env. block_env. basefee) ;
3371
- return Err ( InvalidTransactionError :: FeeCapTooLow ) ;
3372
- }
3373
-
3374
- if let ( Some ( max_priority_fee_per_gas) , Some ( max_fee_per_gas) ) =
3375
- ( tx. essentials ( ) . max_priority_fee_per_gas , tx. essentials ( ) . max_fee_per_gas )
3376
- && max_priority_fee_per_gas > max_fee_per_gas
3377
- {
3378
- warn ! ( target: "backend" , "max priority fee per gas={}, too high, max fee per gas={}" , max_priority_fee_per_gas, max_fee_per_gas) ;
3379
- return Err ( InvalidTransactionError :: TipAboveFeeCap ) ;
3380
- }
3381
- }
3382
-
3383
- // EIP-4844 Cancun hard fork validation steps
3356
+ // EIP-4844 structural validation
3384
3357
if env. evm_env . cfg_env . spec >= SpecId :: CANCUN && tx. transaction . is_eip4844 ( ) {
3385
- // Light checks first: see if the blob fee cap is too low.
3386
- if let Some ( max_fee_per_blob_gas) = tx. essentials ( ) . max_fee_per_blob_gas
3387
- && let Some ( blob_gas_and_price) = & env. evm_env . block_env . blob_excess_gas_and_price
3388
- && max_fee_per_blob_gas < blob_gas_and_price. blob_gasprice
3389
- {
3390
- warn ! ( target: "backend" , "max fee per blob gas={}, too low, block blob gas price={}" , max_fee_per_blob_gas, blob_gas_and_price. blob_gasprice) ;
3391
- return Err ( InvalidTransactionError :: BlobFeeCapTooLow ) ;
3392
- }
3393
-
3394
3358
// Heavy (blob validation) checks
3395
- let tx = match & tx. transaction {
3359
+ let blob_tx = match & tx. transaction {
3396
3360
TypedTransaction :: EIP4844 ( tx) => tx. tx ( ) ,
3397
3361
_ => unreachable ! ( ) ,
3398
3362
} ;
3399
3363
3400
- let blob_count = tx . tx ( ) . blob_versioned_hashes . len ( ) ;
3364
+ let blob_count = blob_tx . tx ( ) . blob_versioned_hashes . len ( ) ;
3401
3365
3402
3366
// Ensure there are blob hashes.
3403
3367
if blob_count == 0 {
@@ -3412,40 +3376,85 @@ impl TransactionValidator for Backend {
3412
3376
3413
3377
// Check for any blob validation errors if not impersonating.
3414
3378
if !self . skip_blob_validation ( Some ( * pending. sender ( ) ) )
3415
- && let Err ( err) = tx . validate ( EnvKzgSettings :: default ( ) . get ( ) )
3379
+ && let Err ( err) = blob_tx . validate ( EnvKzgSettings :: default ( ) . get ( ) )
3416
3380
{
3417
3381
return Err ( InvalidTransactionError :: BlobTransactionValidationError ( err) ) ;
3418
3382
}
3419
3383
}
3420
3384
3421
- let max_cost = tx. max_cost ( ) ;
3422
- let value = tx. value ( ) ;
3385
+ // Balance and fee related checks
3386
+ if !self . disable_pool_balance_checks {
3387
+ // Gas limit validation
3388
+ if tx. gas_limit ( ) < MIN_TRANSACTION_GAS as u64 {
3389
+ warn ! ( target: "backend" , "[{:?}] gas too low" , tx. hash( ) ) ;
3390
+ return Err ( InvalidTransactionError :: GasTooLow ) ;
3391
+ }
3423
3392
3424
- match & tx. transaction {
3425
- TypedTransaction :: Deposit ( deposit_tx) => {
3426
- // Deposit transactions
3427
- // https://specs.optimism.io/protocol/deposits.html#execution
3428
- // 1. no gas cost check required since already have prepaid gas from L1
3429
- // 2. increment account balance by deposited amount before checking for sufficient
3430
- // funds `tx.value <= existing account value + deposited value`
3431
- if value > account. balance + U256 :: from ( deposit_tx. mint ) {
3432
- warn ! ( target: "backend" , "[{:?}] insufficient balance={}, required={} account={:?}" , tx. hash( ) , account. balance + U256 :: from( deposit_tx. mint) , value, * pending. sender( ) ) ;
3433
- return Err ( InvalidTransactionError :: InsufficientFunds ) ;
3393
+ // Check gas limit against block gas limit, if block gas limit is set.
3394
+ if !env. evm_env . cfg_env . disable_block_gas_limit
3395
+ && tx. gas_limit ( ) > env. evm_env . block_env . gas_limit
3396
+ {
3397
+ warn ! ( target: "backend" , "[{:?}] gas too high" , tx. hash( ) ) ;
3398
+ return Err ( InvalidTransactionError :: GasTooHigh ( ErrDetail {
3399
+ detail : String :: from ( "tx.gas_limit > env.block.gas_limit" ) ,
3400
+ } ) ) ;
3401
+ }
3402
+
3403
+ // EIP-1559 fee validation (London hard fork and later)
3404
+ if env. evm_env . cfg_env . spec >= SpecId :: LONDON {
3405
+ if tx. gas_price ( ) < env. evm_env . block_env . basefee . into ( ) && !is_deposit_tx {
3406
+ warn ! ( target: "backend" , "max fee per gas={}, too low, block basefee={}" , tx. gas_price( ) , env. evm_env. block_env. basefee) ;
3407
+ return Err ( InvalidTransactionError :: FeeCapTooLow ) ;
3434
3408
}
3409
+
3410
+ if let ( Some ( max_priority_fee_per_gas) , Some ( max_fee_per_gas) ) =
3411
+ ( tx. essentials ( ) . max_priority_fee_per_gas , tx. essentials ( ) . max_fee_per_gas )
3412
+ && max_priority_fee_per_gas > max_fee_per_gas
3413
+ {
3414
+ warn ! ( target: "backend" , "max priority fee per gas={}, too high, max fee per gas={}" , max_priority_fee_per_gas, max_fee_per_gas) ;
3415
+ return Err ( InvalidTransactionError :: TipAboveFeeCap ) ;
3416
+ }
3417
+ }
3418
+
3419
+ // EIP-4844 blob fee validation
3420
+ if env. evm_env . cfg_env . spec >= SpecId :: CANCUN
3421
+ && tx. transaction . is_eip4844 ( )
3422
+ && let Some ( max_fee_per_blob_gas) = tx. essentials ( ) . max_fee_per_blob_gas
3423
+ && let Some ( blob_gas_and_price) = & env. evm_env . block_env . blob_excess_gas_and_price
3424
+ && max_fee_per_blob_gas < blob_gas_and_price. blob_gasprice
3425
+ {
3426
+ warn ! ( target: "backend" , "max fee per blob gas={}, too low, block blob gas price={}" , max_fee_per_blob_gas, blob_gas_and_price. blob_gasprice) ;
3427
+ return Err ( InvalidTransactionError :: BlobFeeCapTooLow ) ;
3435
3428
}
3436
- _ => {
3437
- // check sufficient funds: `gas * price + value`
3438
- let req_funds = max_cost. checked_add ( value. saturating_to ( ) ) . ok_or_else ( || {
3439
- warn ! ( target: "backend" , "[{:?}] cost too high" , tx. hash( ) ) ;
3440
- InvalidTransactionError :: InsufficientFunds
3441
- } ) ?;
3442
- if account. balance < U256 :: from ( req_funds) {
3443
- warn ! ( target: "backend" , "[{:?}] insufficient allowance={}, required={} account={:?}" , tx. hash( ) , account. balance, req_funds, * pending. sender( ) ) ;
3444
- return Err ( InvalidTransactionError :: InsufficientFunds ) ;
3429
+
3430
+ let max_cost = tx. max_cost ( ) ;
3431
+ let value = tx. value ( ) ;
3432
+ match & tx. transaction {
3433
+ TypedTransaction :: Deposit ( deposit_tx) => {
3434
+ // Deposit transactions
3435
+ // https://specs.optimism.io/protocol/deposits.html#execution
3436
+ // 1. no gas cost check required since already have prepaid gas from L1
3437
+ // 2. increment account balance by deposited amount before checking for
3438
+ // sufficient funds `tx.value <= existing account value + deposited value`
3439
+ if value > account. balance + U256 :: from ( deposit_tx. mint ) {
3440
+ warn ! ( target: "backend" , "[{:?}] insufficient balance={}, required={} account={:?}" , tx. hash( ) , account. balance + U256 :: from( deposit_tx. mint) , value, * pending. sender( ) ) ;
3441
+ return Err ( InvalidTransactionError :: InsufficientFunds ) ;
3442
+ }
3443
+ }
3444
+ _ => {
3445
+ // check sufficient funds: `gas * price + value`
3446
+ let req_funds =
3447
+ max_cost. checked_add ( value. saturating_to ( ) ) . ok_or_else ( || {
3448
+ warn ! ( target: "backend" , "[{:?}] cost too high" , tx. hash( ) ) ;
3449
+ InvalidTransactionError :: InsufficientFunds
3450
+ } ) ?;
3451
+ if account. balance < U256 :: from ( req_funds) {
3452
+ warn ! ( target: "backend" , "[{:?}] insufficient allowance={}, required={} account={:?}" , tx. hash( ) , account. balance, req_funds, * pending. sender( ) ) ;
3453
+ return Err ( InvalidTransactionError :: InsufficientFunds ) ;
3454
+ }
3445
3455
}
3446
3456
}
3447
3457
}
3448
-
3449
3458
Ok ( ( ) )
3450
3459
}
3451
3460
0 commit comments