@@ -27,7 +27,7 @@ use crate::{
2727 pool:: transactions:: PoolTransaction ,
2828 sign:: build_typed_transaction,
2929 } ,
30- evm:: celo_precompile,
30+ evm:: celo_precompile:: { self , CELO_TRANSFER_ADDRESS } ,
3131 inject_precompiles,
3232 mem:: {
3333 inspector:: AnvilInspector ,
@@ -41,7 +41,10 @@ use alloy_consensus::{
4141 proofs:: { calculate_receipt_root, calculate_transaction_root} ,
4242 transaction:: Recovered ,
4343} ;
44- use alloy_eips:: { eip1559:: BaseFeeParams , eip4844:: kzg_to_versioned_hash, eip7840:: BlobParams } ;
44+ use alloy_eips:: {
45+ eip1559:: BaseFeeParams , eip4844:: kzg_to_versioned_hash, eip7840:: BlobParams ,
46+ eip7910:: SystemContract ,
47+ } ;
4548use alloy_evm:: {
4649 Database , Evm ,
4750 eth:: EthEvmContext ,
@@ -108,14 +111,18 @@ use op_revm::{
108111use parking_lot:: { Mutex , RwLock } ;
109112use revm:: {
110113 DatabaseCommit , Inspector ,
111- context:: { Block as RevmBlock , BlockEnv , TxEnv } ,
114+ context:: { Block as RevmBlock , BlockEnv , Cfg , TxEnv } ,
112115 context_interface:: {
113116 block:: BlobExcessGasAndPrice ,
114117 result:: { ExecutionResult , Output , ResultAndState } ,
115118 } ,
116119 database:: { CacheDB , WrapDatabaseRef } ,
117120 interpreter:: InstructionResult ,
118- precompile:: secp256r1:: { P256VERIFY , P256VERIFY_BASE_GAS_FEE } ,
121+ precompile:: {
122+ PrecompileId , PrecompileSpecId , Precompiles ,
123+ secp256r1:: { P256VERIFY , P256VERIFY_ADDRESS , P256VERIFY_BASE_GAS_FEE } ,
124+ u64_to_address,
125+ } ,
119126 primitives:: { KECCAK_EMPTY , hardfork:: SpecId } ,
120127 state:: AccountInfo ,
121128} ;
@@ -843,6 +850,56 @@ impl Backend {
843850 self . env . read ( ) . is_celo
844851 }
845852
853+ /// Returns the precompiles for the current spec.
854+ pub fn precompiles ( & self ) -> BTreeMap < String , Address > {
855+ let spec_id = self . env . read ( ) . evm_env . cfg_env . spec ;
856+ let precompiles = Precompiles :: new ( PrecompileSpecId :: from_spec_id ( spec_id) ) ;
857+
858+ let mut precompiles_map = BTreeMap :: < String , Address > :: default ( ) ;
859+ for ( address, precompile) in precompiles. inner ( ) {
860+ precompiles_map. insert ( precompile. id ( ) . name ( ) . to_string ( ) , * address) ;
861+ }
862+
863+ if self . odyssey {
864+ precompiles_map. insert (
865+ PrecompileId :: P256Verify . name ( ) . to_string ( ) ,
866+ u64_to_address ( P256VERIFY_ADDRESS ) ,
867+ ) ;
868+ }
869+
870+ if self . is_celo ( ) {
871+ precompiles_map. insert (
872+ celo_precompile:: PRECOMPILE_ID_CELO_TRANSFER . clone ( ) . name ( ) . to_string ( ) ,
873+ CELO_TRANSFER_ADDRESS ,
874+ ) ;
875+ }
876+
877+ if let Some ( factory) = & self . precompile_factory {
878+ for ( precompile, _) in & factory. precompiles ( ) {
879+ precompiles_map. insert ( precompile. id ( ) . name ( ) . to_string ( ) , * precompile. address ( ) ) ;
880+ }
881+ }
882+
883+ precompiles_map
884+ }
885+
886+ /// Returns the system contracts for the current spec.
887+ pub fn system_contracts ( & self ) -> BTreeMap < SystemContract , Address > {
888+ let mut system_contracts = BTreeMap :: < SystemContract , Address > :: default ( ) ;
889+
890+ let spec_id = self . env . read ( ) . evm_env . cfg_env . spec ;
891+
892+ if spec_id >= SpecId :: CANCUN {
893+ system_contracts. extend ( SystemContract :: cancun ( ) ) ;
894+ }
895+
896+ if spec_id >= SpecId :: PRAGUE {
897+ system_contracts. extend ( SystemContract :: prague ( None ) ) ;
898+ }
899+
900+ system_contracts
901+ }
902+
846903 /// Returns [`BlobParams`] corresponding to the current spec.
847904 pub fn blob_params ( & self ) -> BlobParams {
848905 let spec_id = self . env . read ( ) . evm_env . cfg_env . spec ;
@@ -1534,6 +1591,7 @@ impl Backend {
15341591 ///
15351592 /// - `disable_eip3607` is set to `true`
15361593 /// - `disable_base_fee` is set to `true`
1594+ /// - `tx_gas_limit_cap` is set to `Some(u64::MAX)` indicating no gas limit cap
15371595 /// - `nonce` check is skipped if `request.nonce` is None
15381596 fn build_call_env (
15391597 & self ,
@@ -1576,6 +1634,7 @@ impl Backend {
15761634 // we want to disable this in eth_call, since this is common practice used by other node
15771635 // impls and providers <https://github.com/foundry-rs/foundry/issues/4388>
15781636 env. evm_env . cfg_env . disable_block_gas_limit = true ;
1637+ env. evm_env . cfg_env . tx_gas_limit_cap = Some ( u64:: MAX ) ;
15791638
15801639 // The basefee should be ignored for calls against state for
15811640 // - eth_call
@@ -3422,7 +3481,7 @@ impl TransactionValidator for Backend {
34223481 return Err ( InvalidTransactionError :: GasTooLow ) ;
34233482 }
34243483
3425- // Check gas limit against block gas limit, if block gas limit is set.
3484+ // Check tx gas limit against block gas limit, if block gas limit is set.
34263485 if !env. evm_env . cfg_env . disable_block_gas_limit
34273486 && tx. gas_limit ( ) > env. evm_env . block_env . gas_limit
34283487 {
@@ -3432,7 +3491,17 @@ impl TransactionValidator for Backend {
34323491 } ) ) ;
34333492 }
34343493
3435- // EIP-1559 fee validation (London hard fork and later)
3494+ // Check tx gas limit against tx gas limit cap (Osaka hard fork and later).
3495+ if env. evm_env . cfg_env . tx_gas_limit_cap . is_none ( )
3496+ && tx. gas_limit ( ) > env. evm_env . cfg_env ( ) . tx_gas_limit_cap ( )
3497+ {
3498+ warn ! ( target: "backend" , "[{:?}] gas too high" , tx. hash( ) ) ;
3499+ return Err ( InvalidTransactionError :: GasTooHigh ( ErrDetail {
3500+ detail : String :: from ( "tx.gas_limit > env.cfg.tx_gas_limit_cap" ) ,
3501+ } ) ) ;
3502+ }
3503+
3504+ // EIP-1559 fee validation (London hard fork and later).
34363505 if env. evm_env . cfg_env . spec >= SpecId :: LONDON {
34373506 if tx. gas_price ( ) < env. evm_env . block_env . basefee . into ( ) && !is_deposit_tx {
34383507 warn ! ( target: "backend" , "max fee per gas={}, too low, block basefee={}" , tx. gas_price( ) , env. evm_env. block_env. basefee) ;
0 commit comments