feat: add Spec generic for EvmEnv (#13975)

This commit is contained in:
Arsenii Kulikov
2025-01-24 19:59:55 +04:00
committed by GitHub
parent 621b30f037
commit 203fed0f64
19 changed files with 223 additions and 293 deletions

View File

@ -28,7 +28,7 @@ use reth_primitives_traits::transaction::execute::FillTxEnv;
use reth_revm::{inspector_handle_register, Database, EvmBuilder}; use reth_revm::{inspector_handle_register, Database, EvmBuilder};
use revm_primitives::{ use revm_primitives::{
AnalysisKind, BlobExcessGasAndPrice, BlockEnv, Bytes, CfgEnv, CfgEnvWithHandlerCfg, EVMError, AnalysisKind, BlobExcessGasAndPrice, BlockEnv, Bytes, CfgEnv, CfgEnvWithHandlerCfg, EVMError,
Env, HandlerCfg, ResultAndState, SpecId, TxEnv, TxKind, HandlerCfg, ResultAndState, SpecId, TxEnv, TxKind,
}; };
mod config; mod config;
@ -58,17 +58,6 @@ impl<EXT, DB: Database> Evm for EthEvm<'_, EXT, DB> {
self.0.block() self.0.block()
} }
fn into_env(self) -> EvmEnv {
let Env { cfg, block, tx: _ } = *self.0.context.evm.inner.env;
EvmEnv {
cfg_env_with_handler_cfg: CfgEnvWithHandlerCfg {
cfg_env: cfg,
handler_cfg: self.0.handler.cfg,
},
block_env: block,
}
}
fn transact(&mut self, tx: Self::Tx) -> Result<ResultAndState, Self::Error> { fn transact(&mut self, tx: Self::Tx) -> Result<ResultAndState, Self::Error> {
*self.tx_mut() = tx; *self.tx_mut() = tx;
self.0.transact() self.0.transact()
@ -151,6 +140,7 @@ impl ConfigureEvmEnv for EthEvmConfig {
type Transaction = TransactionSigned; type Transaction = TransactionSigned;
type Error = Infallible; type Error = Infallible;
type TxEnv = TxEnv; type TxEnv = TxEnv;
type Spec = revm_primitives::SpecId;
fn tx_env(&self, transaction: &TransactionSigned, sender: Address) -> Self::TxEnv { fn tx_env(&self, transaction: &TransactionSigned, sender: Address) -> Self::TxEnv {
let mut tx_env = TxEnv::default(); let mut tx_env = TxEnv::default();
@ -159,33 +149,27 @@ impl ConfigureEvmEnv for EthEvmConfig {
} }
fn evm_env(&self, header: &Self::Header) -> EvmEnv { fn evm_env(&self, header: &Self::Header) -> EvmEnv {
let spec_id = config::revm_spec(self.chain_spec(), header); let spec = config::revm_spec(self.chain_spec(), header);
let mut cfg_env = CfgEnv::default(); let mut cfg_env = CfgEnv::default();
cfg_env.chain_id = self.chain_spec.chain().id(); cfg_env.chain_id = self.chain_spec.chain().id();
cfg_env.perf_analyse_created_bytecodes = AnalysisKind::default(); cfg_env.perf_analyse_created_bytecodes = AnalysisKind::default();
let cfg_env_with_handler_cfg = CfgEnvWithHandlerCfg {
cfg_env,
#[allow(clippy::needless_update)] // side-effect of optimism fields
handler_cfg: HandlerCfg { spec_id, ..Default::default() },
};
let block_env = BlockEnv { let block_env = BlockEnv {
number: U256::from(header.number()), number: U256::from(header.number()),
coinbase: header.beneficiary(), coinbase: header.beneficiary(),
timestamp: U256::from(header.timestamp()), timestamp: U256::from(header.timestamp()),
difficulty: if spec_id >= SpecId::MERGE { U256::ZERO } else { header.difficulty() }, difficulty: if spec >= SpecId::MERGE { U256::ZERO } else { header.difficulty() },
prevrandao: if spec_id >= SpecId::MERGE { header.mix_hash() } else { None }, prevrandao: if spec >= SpecId::MERGE { header.mix_hash() } else { None },
gas_limit: U256::from(header.gas_limit()), gas_limit: U256::from(header.gas_limit()),
basefee: U256::from(header.base_fee_per_gas().unwrap_or_default()), basefee: U256::from(header.base_fee_per_gas().unwrap_or_default()),
// EIP-4844 excess blob gas of this block, introduced in Cancun // EIP-4844 excess blob gas of this block, introduced in Cancun
blob_excess_gas_and_price: header.excess_blob_gas.map(|excess_blob_gas| { blob_excess_gas_and_price: header.excess_blob_gas.map(|excess_blob_gas| {
BlobExcessGasAndPrice::new(excess_blob_gas, spec_id >= SpecId::PRAGUE) BlobExcessGasAndPrice::new(excess_blob_gas, spec >= SpecId::PRAGUE)
}), }),
}; };
EvmEnv { cfg_env_with_handler_cfg, block_env } EvmEnv { cfg_env, spec, block_env }
} }
fn next_evm_env( fn next_evm_env(
@ -255,10 +239,14 @@ impl ConfigureEvm for EthEvmConfig {
type Evm<'a, DB: Database + 'a, I: 'a> = EthEvm<'a, I, DB>; type Evm<'a, DB: Database + 'a, I: 'a> = EthEvm<'a, I, DB>;
fn evm_with_env<DB: Database>(&self, db: DB, evm_env: EvmEnv) -> Self::Evm<'_, DB, ()> { fn evm_with_env<DB: Database>(&self, db: DB, evm_env: EvmEnv) -> Self::Evm<'_, DB, ()> {
let cfg_env_with_handler_cfg = CfgEnvWithHandlerCfg {
cfg_env: evm_env.cfg_env,
handler_cfg: HandlerCfg::new(evm_env.spec),
};
EthEvm( EthEvm(
EvmBuilder::default() EvmBuilder::default()
.with_db(db) .with_db(db)
.with_cfg_env_with_handler_cfg(evm_env.cfg_env_with_handler_cfg) .with_cfg_env_with_handler_cfg(cfg_env_with_handler_cfg)
.with_block_env(evm_env.block_env) .with_block_env(evm_env.block_env)
.build(), .build(),
) )
@ -274,11 +262,15 @@ impl ConfigureEvm for EthEvmConfig {
DB: Database, DB: Database,
I: reth_revm::GetInspector<DB>, I: reth_revm::GetInspector<DB>,
{ {
let cfg_env_with_handler_cfg = CfgEnvWithHandlerCfg {
cfg_env: evm_env.cfg_env,
handler_cfg: HandlerCfg::new(evm_env.spec),
};
EthEvm( EthEvm(
EvmBuilder::default() EvmBuilder::default()
.with_db(db) .with_db(db)
.with_external_context(inspector) .with_external_context(inspector)
.with_cfg_env_with_handler_cfg(evm_env.cfg_env_with_handler_cfg) .with_cfg_env_with_handler_cfg(cfg_env_with_handler_cfg)
.with_block_env(evm_env.block_env) .with_block_env(evm_env.block_env)
.append_handler_register(inspector_handle_register) .append_handler_register(inspector_handle_register)
.build(), .build(),
@ -318,12 +310,12 @@ mod tests {
// Use the `EthEvmConfig` to fill the `cfg_env` and `block_env` based on the ChainSpec, // Use the `EthEvmConfig` to fill the `cfg_env` and `block_env` based on the ChainSpec,
// Header, and total difficulty // Header, and total difficulty
let EvmEnv { cfg_env_with_handler_cfg, .. } = let EvmEnv { cfg_env, .. } =
EthEvmConfig::new(Arc::new(chain_spec.clone())).evm_env(&header); EthEvmConfig::new(Arc::new(chain_spec.clone())).evm_env(&header);
// Assert that the chain ID in the `cfg_env` is correctly set to the chain ID of the // Assert that the chain ID in the `cfg_env` is correctly set to the chain ID of the
// ChainSpec // ChainSpec
assert_eq!(cfg_env_with_handler_cfg.chain_id, chain_spec.chain().id()); assert_eq!(cfg_env.chain_id, chain_spec.chain().id());
} }
#[test] #[test]
@ -339,7 +331,7 @@ mod tests {
// Check that the EVM environment // Check that the EVM environment
assert_eq!(evm.context.evm.env.block, evm_env.block_env); assert_eq!(evm.context.evm.env.block, evm_env.block_env);
assert_eq!(evm.context.evm.env.cfg, evm_env.cfg_env_with_handler_cfg.cfg_env); assert_eq!(evm.context.evm.env.cfg, evm_env.cfg_env);
// Default spec ID // Default spec ID
assert_eq!(evm.handler.spec_id(), SpecId::LATEST); assert_eq!(evm.handler.spec_id(), SpecId::LATEST);
@ -358,13 +350,7 @@ mod tests {
// Create a custom configuration environment with a chain ID of 111 // Create a custom configuration environment with a chain ID of 111
let cfg = CfgEnv::default().with_chain_id(111); let cfg = CfgEnv::default().with_chain_id(111);
let evm_env = EvmEnv { let evm_env = EvmEnv { cfg_env: cfg.clone(), ..Default::default() };
cfg_env_with_handler_cfg: CfgEnvWithHandlerCfg {
cfg_env: cfg.clone(),
handler_cfg: Default::default(),
},
..Default::default()
};
let evm = evm_config.evm_with_env(db, evm_env); let evm = evm_config.evm_with_env(db, evm_env);
@ -393,13 +379,7 @@ mod tests {
..Default::default() ..Default::default()
}; };
let evm_env = EvmEnv { let evm_env = EvmEnv { block_env: block, ..Default::default() };
cfg_env_with_handler_cfg: CfgEnvWithHandlerCfg {
cfg_env: CfgEnv::default(),
handler_cfg: Default::default(),
},
block_env: block,
};
let evm = evm_config.evm_with_env(db, evm_env.clone()); let evm = evm_config.evm_with_env(db, evm_env.clone());
@ -420,15 +400,7 @@ mod tests {
let db = CacheDB::<EmptyDBTyped<ProviderError>>::default(); let db = CacheDB::<EmptyDBTyped<ProviderError>>::default();
let handler_cfg = HandlerCfg { spec_id: SpecId::CONSTANTINOPLE, ..Default::default() }; let evm_env = EvmEnv { spec: SpecId::CONSTANTINOPLE, ..Default::default() };
let evm_env = EvmEnv {
cfg_env_with_handler_cfg: CfgEnvWithHandlerCfg {
cfg_env: Default::default(),
handler_cfg,
},
..Default::default()
};
let evm = evm_config.evm_with_env(db, evm_env); let evm = evm_config.evm_with_env(db, evm_env);
@ -454,7 +426,7 @@ mod tests {
// Check that the EVM environment is set to default values // Check that the EVM environment is set to default values
assert_eq!(evm.context.evm.env.block, evm_env.block_env); assert_eq!(evm.context.evm.env.block, evm_env.block_env);
assert_eq!(evm.context.evm.env.cfg, evm_env.cfg_env_with_handler_cfg.cfg_env); assert_eq!(evm.context.evm.env.cfg, evm_env.cfg_env);
assert_eq!(evm.context.external, NoOpInspector); assert_eq!(evm.context.external, NoOpInspector);
assert_eq!(evm.handler.spec_id(), SpecId::LATEST); assert_eq!(evm.handler.spec_id(), SpecId::LATEST);
@ -470,13 +442,8 @@ mod tests {
let cfg_env = CfgEnv::default().with_chain_id(111); let cfg_env = CfgEnv::default().with_chain_id(111);
let block = BlockEnv::default(); let block = BlockEnv::default();
let evm_env = EvmEnv { let evm_env =
cfg_env_with_handler_cfg: CfgEnvWithHandlerCfg { EvmEnv { cfg_env: cfg_env.clone(), block_env: block, spec: Default::default() };
cfg_env: cfg_env.clone(),
handler_cfg: Default::default(),
},
block_env: block,
};
let evm = evm_config.evm_with_env_and_inspector(db, evm_env, NoOpInspector); let evm = evm_config.evm_with_env_and_inspector(db, evm_env, NoOpInspector);
@ -521,21 +488,14 @@ mod tests {
let evm_config = EthEvmConfig::new(MAINNET.clone()); let evm_config = EthEvmConfig::new(MAINNET.clone());
let db = CacheDB::<EmptyDBTyped<ProviderError>>::default(); let db = CacheDB::<EmptyDBTyped<ProviderError>>::default();
let handler_cfg = HandlerCfg { spec_id: SpecId::CONSTANTINOPLE, ..Default::default() }; let evm_env = EvmEnv { spec: SpecId::CONSTANTINOPLE, ..Default::default() };
let evm_env = EvmEnv {
cfg_env_with_handler_cfg: CfgEnvWithHandlerCfg {
handler_cfg,
cfg_env: Default::default(),
},
..Default::default()
};
let evm = evm_config.evm_with_env_and_inspector(db, evm_env.clone(), NoOpInspector); let evm = evm_config.evm_with_env_and_inspector(db, evm_env.clone(), NoOpInspector);
// Check that the spec ID is set properly // Check that the spec ID is set properly
assert_eq!(evm.handler.spec_id(), SpecId::PETERSBURG); assert_eq!(evm.handler.spec_id(), SpecId::PETERSBURG);
assert_eq!(evm.context.evm.env.block, evm_env.block_env); assert_eq!(evm.context.evm.env.block, evm_env.block_env);
assert_eq!(evm.context.evm.env.cfg, evm_env.cfg_env_with_handler_cfg.cfg_env); assert_eq!(evm.context.evm.env.cfg, evm_env.cfg_env);
assert_eq!(evm.context.evm.env.tx, Default::default()); assert_eq!(evm.context.evm.env.tx, Default::default());
assert_eq!(evm.context.external, NoOpInspector); assert_eq!(evm.context.external, NoOpInspector);

View File

@ -81,11 +81,11 @@ where
{ {
/// Returns the configured [`EvmEnv`] for the targeted payload /// Returns the configured [`EvmEnv`] for the targeted payload
/// (that has the `parent` as its parent). /// (that has the `parent` as its parent).
fn cfg_and_block_env( fn evm_env(
&self, &self,
config: &PayloadConfig<EthPayloadBuilderAttributes>, config: &PayloadConfig<EthPayloadBuilderAttributes>,
parent: &Header, parent: &Header,
) -> Result<EvmEnv, EvmConfig::Error> { ) -> Result<EvmEnv<EvmConfig::Spec>, EvmConfig::Error> {
let next_attributes = NextBlockEnvAttributes { let next_attributes = NextBlockEnvAttributes {
timestamp: config.attributes.timestamp(), timestamp: config.attributes.timestamp(),
suggested_fee_recipient: config.attributes.suggested_fee_recipient(), suggested_fee_recipient: config.attributes.suggested_fee_recipient(),
@ -111,7 +111,7 @@ where
args: BuildArguments<Pool, Client, EthPayloadBuilderAttributes, EthBuiltPayload>, args: BuildArguments<Pool, Client, EthPayloadBuilderAttributes, EthBuiltPayload>,
) -> Result<BuildOutcome<EthBuiltPayload>, PayloadBuilderError> { ) -> Result<BuildOutcome<EthBuiltPayload>, PayloadBuilderError> {
let evm_env = self let evm_env = self
.cfg_and_block_env(&args.config, &args.config.parent_header) .evm_env(&args.config, &args.config.parent_header)
.map_err(PayloadBuilderError::other)?; .map_err(PayloadBuilderError::other)?;
let pool = args.pool.clone(); let pool = args.pool.clone();
@ -140,7 +140,7 @@ where
); );
let evm_env = self let evm_env = self
.cfg_and_block_env(&args.config, &args.config.parent_header) .evm_env(&args.config, &args.config.parent_header)
.map_err(PayloadBuilderError::other)?; .map_err(PayloadBuilderError::other)?;
let pool = args.pool.clone(); let pool = args.pool.clone();
@ -167,7 +167,7 @@ pub fn default_ethereum_payload<EvmConfig, Pool, Client, F>(
evm_config: EvmConfig, evm_config: EvmConfig,
builder_config: EthereumBuilderConfig, builder_config: EthereumBuilderConfig,
args: BuildArguments<Pool, Client, EthPayloadBuilderAttributes, EthBuiltPayload>, args: BuildArguments<Pool, Client, EthPayloadBuilderAttributes, EthBuiltPayload>,
evm_env: EvmEnv, evm_env: EvmEnv<EvmConfig::Spec>,
best_txs: F, best_txs: F,
) -> Result<BuildOutcome<EthBuiltPayload>, PayloadBuilderError> ) -> Result<BuildOutcome<EthBuiltPayload>, PayloadBuilderError>
where where

View File

@ -1,36 +1,27 @@
use revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg}; use revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg};
use revm_primitives::{CfgEnv, SpecId};
/// Container type that holds both the configuration and block environment for EVM execution. /// Container type that holds both the configuration and block environment for EVM execution.
#[derive(Debug, Clone)] #[derive(Debug, Clone, Default)]
pub struct EvmEnv { pub struct EvmEnv<Spec = SpecId> {
/// The configuration environment with handler settings /// The configuration environment with handler settings
pub cfg_env_with_handler_cfg: CfgEnvWithHandlerCfg, pub cfg_env: CfgEnv,
/// The block environment containing block-specific data /// The block environment containing block-specific data
pub block_env: BlockEnv, pub block_env: BlockEnv,
/// The spec id of the chain. Specifies which hardfork is currently active, `Spec` type will
/// most likely be an enum over hardforks.
pub spec: Spec,
} }
impl Default for EvmEnv { impl<Spec> EvmEnv<Spec> {
fn default() -> Self {
Self {
cfg_env_with_handler_cfg: CfgEnvWithHandlerCfg {
cfg_env: Default::default(),
// Will set `is_optimism` if `revm/optimism-default-handler` is enabled.
handler_cfg: Default::default(),
},
block_env: BlockEnv::default(),
}
}
}
impl EvmEnv {
/// Create a new `EvmEnv` from its components. /// Create a new `EvmEnv` from its components.
/// ///
/// # Arguments /// # Arguments
/// ///
/// * `cfg_env_with_handler_cfg` - The configuration environment with handler settings /// * `cfg_env_with_handler_cfg` - The configuration environment with handler settings
/// * `block` - The block environment containing block-specific data /// * `block` - The block environment containing block-specific data
pub const fn new(cfg_env_with_handler_cfg: CfgEnvWithHandlerCfg, block_env: BlockEnv) -> Self { pub const fn new(cfg_env: CfgEnv, block_env: BlockEnv, spec: Spec) -> Self {
Self { cfg_env_with_handler_cfg, block_env } Self { cfg_env, spec, block_env }
} }
/// Returns a reference to the block environment. /// Returns a reference to the block environment.
@ -39,19 +30,19 @@ impl EvmEnv {
} }
/// Returns a reference to the configuration environment. /// Returns a reference to the configuration environment.
pub const fn cfg_env_with_handler_cfg(&self) -> &CfgEnvWithHandlerCfg { pub const fn cfg_env(&self) -> &CfgEnv {
&self.cfg_env_with_handler_cfg &self.cfg_env
}
/// Returns the spec id of the chain
pub const fn spec_id(&self) -> &Spec {
&self.spec
} }
} }
impl From<(CfgEnvWithHandlerCfg, BlockEnv)> for EvmEnv { impl From<(CfgEnvWithHandlerCfg, BlockEnv)> for EvmEnv {
fn from((cfg_env_with_handler_cfg, block_env): (CfgEnvWithHandlerCfg, BlockEnv)) -> Self { fn from((cfg_env_with_handler_cfg, block_env): (CfgEnvWithHandlerCfg, BlockEnv)) -> Self {
Self { cfg_env_with_handler_cfg, block_env } let CfgEnvWithHandlerCfg { cfg_env, handler_cfg } = cfg_env_with_handler_cfg;
} Self { cfg_env, spec: handler_cfg.spec_id, block_env }
}
impl From<EvmEnv> for (CfgEnvWithHandlerCfg, BlockEnv) {
fn from(env: EvmEnv) -> Self {
(env.cfg_env_with_handler_cfg, env.block_env)
} }
} }

View File

@ -57,9 +57,6 @@ pub trait Evm {
/// Reference to [`BlockEnv`]. /// Reference to [`BlockEnv`].
fn block(&self) -> &BlockEnv; fn block(&self) -> &BlockEnv;
/// Consumes the type and returns the underlying [`EvmEnv`].
fn into_env(self) -> EvmEnv;
/// Executes the given transaction. /// Executes the given transaction.
fn transact(&mut self, tx: Self::Tx) -> Result<ResultAndState, Self::Error>; fn transact(&mut self, tx: Self::Tx) -> Result<ResultAndState, Self::Error>;
@ -99,7 +96,11 @@ pub trait ConfigureEvm: ConfigureEvmEnv {
/// including the spec id and transaction environment. /// including the spec id and transaction environment.
/// ///
/// This will preserve any handler modifications /// This will preserve any handler modifications
fn evm_with_env<DB: Database>(&self, db: DB, evm_env: EvmEnv) -> Self::Evm<'_, DB, ()>; fn evm_with_env<DB: Database>(
&self,
db: DB,
evm_env: EvmEnv<Self::Spec>,
) -> Self::Evm<'_, DB, ()>;
/// Returns a new EVM with the given database configured with `cfg` and `block_env` /// Returns a new EVM with the given database configured with `cfg` and `block_env`
/// configuration derived from the given header. Relies on /// configuration derived from the given header. Relies on
@ -122,7 +123,7 @@ pub trait ConfigureEvm: ConfigureEvmEnv {
fn evm_with_env_and_inspector<DB, I>( fn evm_with_env_and_inspector<DB, I>(
&self, &self,
db: DB, db: DB,
evm_env: EvmEnv, evm_env: EvmEnv<Self::Spec>,
inspector: I, inspector: I,
) -> Self::Evm<'_, DB, I> ) -> Self::Evm<'_, DB, I>
where where
@ -133,7 +134,7 @@ pub trait ConfigureEvm: ConfigureEvmEnv {
impl<'b, T> ConfigureEvm for &'b T impl<'b, T> ConfigureEvm for &'b T
where where
T: ConfigureEvm, T: ConfigureEvm,
&'b T: ConfigureEvmEnv<Header = T::Header, TxEnv = T::TxEnv>, &'b T: ConfigureEvmEnv<Header = T::Header, TxEnv = T::TxEnv, Spec = T::Spec>,
{ {
type Evm<'a, DB: Database + 'a, I: 'a> = T::Evm<'a, DB, I>; type Evm<'a, DB: Database + 'a, I: 'a> = T::Evm<'a, DB, I>;
@ -141,14 +142,18 @@ where
(*self).evm_for_block(db, header) (*self).evm_for_block(db, header)
} }
fn evm_with_env<DB: Database>(&self, db: DB, evm_env: EvmEnv) -> Self::Evm<'_, DB, ()> { fn evm_with_env<DB: Database>(
&self,
db: DB,
evm_env: EvmEnv<Self::Spec>,
) -> Self::Evm<'_, DB, ()> {
(*self).evm_with_env(db, evm_env) (*self).evm_with_env(db, evm_env)
} }
fn evm_with_env_and_inspector<DB, I>( fn evm_with_env_and_inspector<DB, I>(
&self, &self,
db: DB, db: DB,
evm_env: EvmEnv, evm_env: EvmEnv<Self::Spec>,
inspector: I, inspector: I,
) -> Self::Evm<'_, DB, I> ) -> Self::Evm<'_, DB, I>
where where
@ -177,11 +182,14 @@ pub trait ConfigureEvmEnv: Send + Sync + Unpin + Clone + 'static {
/// The error type that is returned by [`Self::next_evm_env`]. /// The error type that is returned by [`Self::next_evm_env`].
type Error: core::error::Error + Send + Sync; type Error: core::error::Error + Send + Sync;
/// Identifier of the EVM specification.
type Spec: Into<revm_primitives::SpecId> + Debug + Copy + Send + Sync;
/// Returns a [`TxEnv`] from a transaction and [`Address`]. /// Returns a [`TxEnv`] from a transaction and [`Address`].
fn tx_env(&self, transaction: &Self::Transaction, signer: Address) -> Self::TxEnv; fn tx_env(&self, transaction: &Self::Transaction, signer: Address) -> Self::TxEnv;
/// Creates a new [`EvmEnv`] for the given header. /// Creates a new [`EvmEnv`] for the given header.
fn evm_env(&self, header: &Self::Header) -> EvmEnv; fn evm_env(&self, header: &Self::Header) -> EvmEnv<Self::Spec>;
/// Returns the configured [`EvmEnv`] for `parent + 1` block. /// Returns the configured [`EvmEnv`] for `parent + 1` block.
/// ///
@ -192,7 +200,7 @@ pub trait ConfigureEvmEnv: Send + Sync + Unpin + Clone + 'static {
&self, &self,
parent: &Self::Header, parent: &Self::Header,
attributes: NextBlockEnvAttributes, attributes: NextBlockEnvAttributes,
) -> Result<EvmEnv, Self::Error>; ) -> Result<EvmEnv<Self::Spec>, Self::Error>;
} }
/// Represents additional attributes required to configure the next block. /// Represents additional attributes required to configure the next block.

View File

@ -123,7 +123,7 @@ where
pub fn pre_block_blockhashes_contract_call<DB>( pub fn pre_block_blockhashes_contract_call<DB>(
&mut self, &mut self,
db: &mut DB, db: &mut DB,
evm_env: &EvmEnv, evm_env: &EvmEnv<EvmConfig::Spec>,
parent_block_hash: B256, parent_block_hash: B256,
) -> Result<(), BlockExecutionError> ) -> Result<(), BlockExecutionError>
where where
@ -173,7 +173,7 @@ where
pub fn pre_block_beacon_root_contract_call<DB>( pub fn pre_block_beacon_root_contract_call<DB>(
&mut self, &mut self,
db: &mut DB, db: &mut DB,
evm_env: &EvmEnv, evm_env: &EvmEnv<EvmConfig::Spec>,
parent_beacon_block_root: Option<B256>, parent_beacon_block_root: Option<B256>,
) -> Result<(), BlockExecutionError> ) -> Result<(), BlockExecutionError>
where where
@ -223,7 +223,7 @@ where
pub fn post_block_withdrawal_requests_contract_call<DB>( pub fn post_block_withdrawal_requests_contract_call<DB>(
&mut self, &mut self,
db: &mut DB, db: &mut DB,
evm_env: &EvmEnv, evm_env: &EvmEnv<EvmConfig::Spec>,
) -> Result<Bytes, BlockExecutionError> ) -> Result<Bytes, BlockExecutionError>
where where
DB: Database + DatabaseCommit, DB: Database + DatabaseCommit,
@ -256,7 +256,7 @@ where
pub fn post_block_consolidation_requests_contract_call<DB>( pub fn post_block_consolidation_requests_contract_call<DB>(
&mut self, &mut self,
db: &mut DB, db: &mut DB,
evm_env: &EvmEnv, evm_env: &EvmEnv<EvmConfig::Spec>,
) -> Result<Bytes, BlockExecutionError> ) -> Result<Bytes, BlockExecutionError>
where where
DB: Database + DatabaseCommit, DB: Database + DatabaseCommit,

View File

@ -40,7 +40,7 @@ pub use receipts::*;
mod error; mod error;
pub use error::OpBlockExecutionError; pub use error::OpBlockExecutionError;
use revm_primitives::{ use revm_primitives::{
BlobExcessGasAndPrice, BlockEnv, Bytes, CfgEnv, EVMError, Env, HandlerCfg, OptimismFields, BlobExcessGasAndPrice, BlockEnv, Bytes, CfgEnv, EVMError, HandlerCfg, OptimismFields,
ResultAndState, SpecId, TxKind, ResultAndState, SpecId, TxKind,
}; };
@ -58,17 +58,6 @@ impl<EXT, DB: Database> Evm for OpEvm<'_, EXT, DB> {
self.0.block() self.0.block()
} }
fn into_env(self) -> EvmEnv {
let Env { cfg, block, tx: _ } = *self.0.context.evm.inner.env;
EvmEnv {
cfg_env_with_handler_cfg: CfgEnvWithHandlerCfg {
cfg_env: cfg,
handler_cfg: self.0.handler.cfg,
},
block_env: block,
}
}
fn transact(&mut self, tx: Self::Tx) -> Result<ResultAndState, Self::Error> { fn transact(&mut self, tx: Self::Tx) -> Result<ResultAndState, Self::Error> {
*self.tx_mut() = tx; *self.tx_mut() = tx;
self.0.transact() self.0.transact()
@ -158,6 +147,7 @@ impl ConfigureEvmEnv for OpEvmConfig {
type Transaction = OpTransactionSigned; type Transaction = OpTransactionSigned;
type Error = EIP1559ParamError; type Error = EIP1559ParamError;
type TxEnv = TxEnv; type TxEnv = TxEnv;
type Spec = SpecId;
fn tx_env(&self, transaction: &Self::Transaction, signer: Address) -> Self::TxEnv { fn tx_env(&self, transaction: &Self::Transaction, signer: Address) -> Self::TxEnv {
let mut tx_env = TxEnv::default(); let mut tx_env = TxEnv::default();
@ -166,32 +156,27 @@ impl ConfigureEvmEnv for OpEvmConfig {
} }
fn evm_env(&self, header: &Self::Header) -> EvmEnv { fn evm_env(&self, header: &Self::Header) -> EvmEnv {
let spec_id = config::revm_spec(self.chain_spec(), header); let spec = config::revm_spec(self.chain_spec(), header);
let mut cfg_env = CfgEnv::default(); let mut cfg_env = CfgEnv::default();
cfg_env.chain_id = self.chain_spec.chain().id(); cfg_env.chain_id = self.chain_spec.chain().id();
cfg_env.perf_analyse_created_bytecodes = AnalysisKind::default(); cfg_env.perf_analyse_created_bytecodes = AnalysisKind::default();
let cfg_env_with_handler_cfg = CfgEnvWithHandlerCfg {
cfg_env,
handler_cfg: HandlerCfg { spec_id, is_optimism: true },
};
let block_env = BlockEnv { let block_env = BlockEnv {
number: U256::from(header.number()), number: U256::from(header.number()),
coinbase: header.beneficiary(), coinbase: header.beneficiary(),
timestamp: U256::from(header.timestamp()), timestamp: U256::from(header.timestamp()),
difficulty: if spec_id >= SpecId::MERGE { U256::ZERO } else { header.difficulty() }, difficulty: if spec >= SpecId::MERGE { U256::ZERO } else { header.difficulty() },
prevrandao: if spec_id >= SpecId::MERGE { header.mix_hash() } else { None }, prevrandao: if spec >= SpecId::MERGE { header.mix_hash() } else { None },
gas_limit: U256::from(header.gas_limit()), gas_limit: U256::from(header.gas_limit()),
basefee: U256::from(header.base_fee_per_gas().unwrap_or_default()), basefee: U256::from(header.base_fee_per_gas().unwrap_or_default()),
// EIP-4844 excess blob gas of this block, introduced in Cancun // EIP-4844 excess blob gas of this block, introduced in Cancun
blob_excess_gas_and_price: header.excess_blob_gas().map(|excess_blob_gas| { blob_excess_gas_and_price: header.excess_blob_gas().map(|excess_blob_gas| {
BlobExcessGasAndPrice::new(excess_blob_gas, spec_id >= SpecId::PRAGUE) BlobExcessGasAndPrice::new(excess_blob_gas, spec >= SpecId::PRAGUE)
}), }),
}; };
EvmEnv { cfg_env_with_handler_cfg, block_env } EvmEnv { cfg_env, block_env, spec }
} }
fn next_evm_env( fn next_evm_env(
@ -240,12 +225,15 @@ impl ConfigureEvmEnv for OpEvmConfig {
impl ConfigureEvm for OpEvmConfig { impl ConfigureEvm for OpEvmConfig {
type Evm<'a, DB: Database + 'a, I: 'a> = OpEvm<'a, I, DB>; type Evm<'a, DB: Database + 'a, I: 'a> = OpEvm<'a, I, DB>;
fn evm_with_env<DB: Database>(&self, db: DB, mut evm_env: EvmEnv) -> Self::Evm<'_, DB, ()> { fn evm_with_env<DB: Database>(&self, db: DB, evm_env: EvmEnv) -> Self::Evm<'_, DB, ()> {
evm_env.cfg_env_with_handler_cfg.handler_cfg.is_optimism = true; let cfg_env_with_handler_cfg = CfgEnvWithHandlerCfg {
cfg_env: evm_env.cfg_env,
handler_cfg: HandlerCfg { spec_id: evm_env.spec, is_optimism: true },
};
EvmBuilder::default() EvmBuilder::default()
.with_db(db) .with_db(db)
.with_cfg_env_with_handler_cfg(evm_env.cfg_env_with_handler_cfg) .with_cfg_env_with_handler_cfg(cfg_env_with_handler_cfg)
.with_block_env(evm_env.block_env) .with_block_env(evm_env.block_env)
.build() .build()
.into() .into()
@ -254,19 +242,22 @@ impl ConfigureEvm for OpEvmConfig {
fn evm_with_env_and_inspector<DB, I>( fn evm_with_env_and_inspector<DB, I>(
&self, &self,
db: DB, db: DB,
mut evm_env: EvmEnv, evm_env: EvmEnv,
inspector: I, inspector: I,
) -> Self::Evm<'_, DB, I> ) -> Self::Evm<'_, DB, I>
where where
DB: Database, DB: Database,
I: GetInspector<DB>, I: GetInspector<DB>,
{ {
evm_env.cfg_env_with_handler_cfg.handler_cfg.is_optimism = true; let cfg_env_with_handler_cfg = CfgEnvWithHandlerCfg {
cfg_env: evm_env.cfg_env,
handler_cfg: HandlerCfg { spec_id: evm_env.spec, is_optimism: true },
};
EvmBuilder::default() EvmBuilder::default()
.with_db(db) .with_db(db)
.with_external_context(inspector) .with_external_context(inspector)
.with_cfg_env_with_handler_cfg(evm_env.cfg_env_with_handler_cfg) .with_cfg_env_with_handler_cfg(cfg_env_with_handler_cfg)
.with_block_env(evm_env.block_env) .with_block_env(evm_env.block_env)
.append_handler_register(inspector_handle_register) .append_handler_register(inspector_handle_register)
.build() .build()
@ -318,12 +309,12 @@ mod tests {
// Use the `OpEvmConfig` to create the `cfg_env` and `block_env` based on the ChainSpec, // Use the `OpEvmConfig` to create the `cfg_env` and `block_env` based on the ChainSpec,
// Header, and total difficulty // Header, and total difficulty
let EvmEnv { cfg_env_with_handler_cfg, .. } = let EvmEnv { cfg_env, .. } =
OpEvmConfig::new(Arc::new(OpChainSpec { inner: chain_spec.clone() })).evm_env(&header); OpEvmConfig::new(Arc::new(OpChainSpec { inner: chain_spec.clone() })).evm_env(&header);
// Assert that the chain ID in the `cfg_env` is correctly set to the chain ID of the // Assert that the chain ID in the `cfg_env` is correctly set to the chain ID of the
// ChainSpec // ChainSpec
assert_eq!(cfg_env_with_handler_cfg.chain_id, chain_spec.chain().id()); assert_eq!(cfg_env.chain_id, chain_spec.chain().id());
} }
#[test] #[test]
@ -337,7 +328,7 @@ mod tests {
let evm = evm_config.evm_with_env(db, evm_env.clone()); let evm = evm_config.evm_with_env(db, evm_env.clone());
// Check that the EVM environment // Check that the EVM environment
assert_eq!(evm.context.evm.env.cfg, evm_env.cfg_env_with_handler_cfg.cfg_env); assert_eq!(evm.context.evm.env.cfg, evm_env.cfg_env);
// Default spec ID // Default spec ID
assert_eq!(evm.handler.spec_id(), SpecId::LATEST); assert_eq!(evm.handler.spec_id(), SpecId::LATEST);
@ -355,13 +346,7 @@ mod tests {
// Create a custom configuration environment with a chain ID of 111 // Create a custom configuration environment with a chain ID of 111
let cfg = CfgEnv::default().with_chain_id(111); let cfg = CfgEnv::default().with_chain_id(111);
let evm_env = EvmEnv { let evm_env = EvmEnv { cfg_env: cfg.clone(), ..Default::default() };
cfg_env_with_handler_cfg: CfgEnvWithHandlerCfg {
cfg_env: cfg.clone(),
handler_cfg: Default::default(),
},
..Default::default()
};
let evm = evm_config.evm_with_env(db, evm_env); let evm = evm_config.evm_with_env(db, evm_env);
@ -409,15 +394,7 @@ mod tests {
let db = CacheDB::<EmptyDBTyped<ProviderError>>::default(); let db = CacheDB::<EmptyDBTyped<ProviderError>>::default();
let handler_cfg = HandlerCfg { spec_id: SpecId::ECOTONE, ..Default::default() }; let evm_env = EvmEnv { spec: SpecId::ECOTONE, ..Default::default() };
let evm_env = EvmEnv {
cfg_env_with_handler_cfg: CfgEnvWithHandlerCfg {
handler_cfg,
cfg_env: Default::default(),
},
..Default::default()
};
let evm = evm_config.evm_with_env(db, evm_env); let evm = evm_config.evm_with_env(db, evm_env);
@ -433,19 +410,13 @@ mod tests {
let evm_config = test_evm_config(); let evm_config = test_evm_config();
let db = CacheDB::<EmptyDBTyped<ProviderError>>::default(); let db = CacheDB::<EmptyDBTyped<ProviderError>>::default();
let evm_env = EvmEnv { let evm_env = EvmEnv { cfg_env: Default::default(), ..Default::default() };
cfg_env_with_handler_cfg: CfgEnvWithHandlerCfg {
cfg_env: Default::default(),
handler_cfg: HandlerCfg { is_optimism: true, ..Default::default() },
},
..Default::default()
};
let evm = evm_config.evm_with_env_and_inspector(db, evm_env.clone(), NoOpInspector); let evm = evm_config.evm_with_env_and_inspector(db, evm_env.clone(), NoOpInspector);
// Check that the EVM environment is set to default values // Check that the EVM environment is set to default values
assert_eq!(evm.context.evm.env.block, evm_env.block_env); assert_eq!(evm.context.evm.env.block, evm_env.block_env);
assert_eq!(evm.context.evm.env.cfg, evm_env.cfg_env_with_handler_cfg.cfg_env); assert_eq!(evm.context.evm.env.cfg, evm_env.cfg_env);
assert_eq!(evm.context.evm.env.tx, Default::default()); assert_eq!(evm.context.evm.env.tx, Default::default());
assert_eq!(evm.context.external, NoOpInspector); assert_eq!(evm.context.external, NoOpInspector);
assert_eq!(evm.handler.spec_id(), SpecId::LATEST); assert_eq!(evm.handler.spec_id(), SpecId::LATEST);
@ -461,13 +432,7 @@ mod tests {
let cfg = CfgEnv::default().with_chain_id(111); let cfg = CfgEnv::default().with_chain_id(111);
let block = BlockEnv::default(); let block = BlockEnv::default();
let evm_env = EvmEnv { let evm_env = EvmEnv { block_env: block, cfg_env: cfg.clone(), ..Default::default() };
block_env: block,
cfg_env_with_handler_cfg: CfgEnvWithHandlerCfg {
cfg_env: cfg.clone(),
handler_cfg: Default::default(),
},
};
let evm = evm_config.evm_with_env_and_inspector(db, evm_env.clone(), NoOpInspector); let evm = evm_config.evm_with_env_and_inspector(db, evm_env.clone(), NoOpInspector);
@ -511,20 +476,13 @@ mod tests {
let evm_config = test_evm_config(); let evm_config = test_evm_config();
let db = CacheDB::<EmptyDBTyped<ProviderError>>::default(); let db = CacheDB::<EmptyDBTyped<ProviderError>>::default();
let handler_cfg = HandlerCfg { spec_id: SpecId::ECOTONE, ..Default::default() }; let evm_env = EvmEnv { spec: SpecId::ECOTONE, ..Default::default() };
let evm_env = EvmEnv {
cfg_env_with_handler_cfg: CfgEnvWithHandlerCfg {
cfg_env: Default::default(),
handler_cfg,
},
..Default::default()
};
let evm = evm_config.evm_with_env_and_inspector(db, evm_env.clone(), NoOpInspector); let evm = evm_config.evm_with_env_and_inspector(db, evm_env.clone(), NoOpInspector);
// Check that the spec ID is set properly // Check that the spec ID is set properly
assert_eq!(evm.handler.spec_id(), SpecId::ECOTONE); assert_eq!(evm.handler.spec_id(), SpecId::ECOTONE);
assert_eq!(evm.context.evm.env.cfg, evm_env.cfg_env_with_handler_cfg.cfg_env); assert_eq!(evm.context.evm.env.cfg, evm_env.cfg_env);
assert_eq!(evm.context.evm.env.block, evm_env.block_env); assert_eq!(evm.context.evm.env.block, evm_env.block_env);
assert_eq!(evm.context.external, NoOpInspector); assert_eq!(evm.context.external, NoOpInspector);

View File

@ -17,7 +17,8 @@ use reth_basic_payload_builder::*;
use reth_chain_state::ExecutedBlock; use reth_chain_state::ExecutedBlock;
use reth_chainspec::{ChainSpecProvider, EthereumHardforks}; use reth_chainspec::{ChainSpecProvider, EthereumHardforks};
use reth_evm::{ use reth_evm::{
env::EvmEnv, system_calls::SystemCaller, ConfigureEvm, Evm, NextBlockEnvAttributes, env::EvmEnv, system_calls::SystemCaller, ConfigureEvm, ConfigureEvmEnv, Evm,
NextBlockEnvAttributes,
}; };
use reth_execution_types::ExecutionOutcome; use reth_execution_types::ExecutionOutcome;
use reth_optimism_chainspec::OpChainSpec; use reth_optimism_chainspec::OpChainSpec;
@ -125,7 +126,7 @@ where
Txs: PayloadTransactions<Transaction = OpTransactionSigned>, Txs: PayloadTransactions<Transaction = OpTransactionSigned>,
{ {
let evm_env = self let evm_env = self
.cfg_and_block_env(&args.config.attributes, &args.config.parent_header) .evm_env(&args.config.attributes, &args.config.parent_header)
.map_err(PayloadBuilderError::other)?; .map_err(PayloadBuilderError::other)?;
let BuildArguments { client, pool: _, mut cached_reads, config, cancel, best_payload } = let BuildArguments { client, pool: _, mut cached_reads, config, cancel, best_payload } =
@ -162,11 +163,11 @@ where
/// Returns the configured [`EvmEnv`] for the targeted payload /// Returns the configured [`EvmEnv`] for the targeted payload
/// (that has the `parent` as its parent). /// (that has the `parent` as its parent).
pub fn cfg_and_block_env( pub fn evm_env(
&self, &self,
attributes: &OpPayloadBuilderAttributes, attributes: &OpPayloadBuilderAttributes,
parent: &Header, parent: &Header,
) -> Result<EvmEnv, EvmConfig::Error> { ) -> Result<EvmEnv<EvmConfig::Spec>, EvmConfig::Error> {
let next_attributes = NextBlockEnvAttributes { let next_attributes = NextBlockEnvAttributes {
timestamp: attributes.timestamp(), timestamp: attributes.timestamp(),
suggested_fee_recipient: attributes.suggested_fee_recipient(), suggested_fee_recipient: attributes.suggested_fee_recipient(),
@ -189,8 +190,7 @@ where
let attributes = OpPayloadBuilderAttributes::try_new(parent.hash(), attributes, 3) let attributes = OpPayloadBuilderAttributes::try_new(parent.hash(), attributes, 3)
.map_err(PayloadBuilderError::other)?; .map_err(PayloadBuilderError::other)?;
let evm_env = let evm_env = self.evm_env(&attributes, &parent).map_err(PayloadBuilderError::other)?;
self.cfg_and_block_env(&attributes, &parent).map_err(PayloadBuilderError::other)?;
let config = PayloadConfig { parent_header: Arc::new(parent), attributes }; let config = PayloadConfig { parent_header: Arc::new(parent), attributes };
let ctx = OpPayloadBuilderCtx { let ctx = OpPayloadBuilderCtx {
@ -578,7 +578,7 @@ impl ExecutionInfo {
/// Container type that holds all necessities to build a new payload. /// Container type that holds all necessities to build a new payload.
#[derive(Debug)] #[derive(Debug)]
pub struct OpPayloadBuilderCtx<EvmConfig> { pub struct OpPayloadBuilderCtx<EvmConfig: ConfigureEvmEnv> {
/// The type that knows how to perform system calls and configure the evm. /// The type that knows how to perform system calls and configure the evm.
pub evm_config: EvmConfig, pub evm_config: EvmConfig,
/// The DA config for the payload builder /// The DA config for the payload builder
@ -588,14 +588,14 @@ pub struct OpPayloadBuilderCtx<EvmConfig> {
/// How to build the payload. /// How to build the payload.
pub config: PayloadConfig<OpPayloadBuilderAttributes>, pub config: PayloadConfig<OpPayloadBuilderAttributes>,
/// Evm Settings /// Evm Settings
pub evm_env: EvmEnv, pub evm_env: EvmEnv<EvmConfig::Spec>,
/// Marker to check whether the job has been cancelled. /// Marker to check whether the job has been cancelled.
pub cancel: Cancelled, pub cancel: Cancelled,
/// The currently best payload. /// The currently best payload.
pub best_payload: Option<OpBuiltPayload>, pub best_payload: Option<OpBuiltPayload>,
} }
impl<EvmConfig> OpPayloadBuilderCtx<EvmConfig> { impl<EvmConfig: ConfigureEvmEnv> OpPayloadBuilderCtx<EvmConfig> {
/// Returns the parent block the payload will be build on. /// Returns the parent block the payload will be build on.
pub fn parent(&self) -> &SealedHeader { pub fn parent(&self) -> &SealedHeader {
&self.config.parent_header &self.config.parent_header

View File

@ -93,9 +93,9 @@ pub trait EthCall: EstimateCall + Call + LoadPendingBlock + LoadBlock + FullEthA
let mut parent_hash = base_block.hash(); let mut parent_hash = base_block.hash();
// Only enforce base fee if validation is enabled // Only enforce base fee if validation is enabled
evm_env.cfg_env_with_handler_cfg.disable_base_fee = !validation; evm_env.cfg_env.disable_base_fee = !validation;
// Always disable EIP-3607 // Always disable EIP-3607
evm_env.cfg_env_with_handler_cfg.disable_eip3607 = true; evm_env.cfg_env.disable_eip3607 = true;
let this = self.clone(); let this = self.clone();
self.spawn_with_state_at_block(block, move |state| { self.spawn_with_state_at_block(block, move |state| {
@ -178,7 +178,7 @@ pub trait EthCall: EstimateCall + Call + LoadPendingBlock + LoadBlock + FullEthA
call, call,
validation, validation,
default_gas_limit, default_gas_limit,
evm_env.cfg_env_with_handler_cfg.chain_id, evm_env.cfg_env.chain_id,
&mut db, &mut db,
this.tx_resp_builder(), this.tx_resp_builder(),
)?; )?;
@ -387,7 +387,7 @@ pub trait EthCall: EstimateCall + Call + LoadPendingBlock + LoadBlock + FullEthA
/// [`BlockId`]. /// [`BlockId`].
fn create_access_list_with( fn create_access_list_with(
&self, &self,
mut evm_env: EvmEnv, mut evm_env: EvmEnv<<Self::Evm as ConfigureEvmEnv>::Spec>,
at: BlockId, at: BlockId,
mut request: TransactionRequest, mut request: TransactionRequest,
) -> Result<AccessListResult, Self::Error> ) -> Result<AccessListResult, Self::Error>
@ -400,12 +400,12 @@ pub trait EthCall: EstimateCall + Call + LoadPendingBlock + LoadBlock + FullEthA
// we want to disable this in eth_createAccessList, since this is common practice used by // we want to disable this in eth_createAccessList, since this is common practice used by
// other node impls and providers <https://github.com/foundry-rs/foundry/issues/4388> // other node impls and providers <https://github.com/foundry-rs/foundry/issues/4388>
evm_env.cfg_env_with_handler_cfg.disable_block_gas_limit = true; evm_env.cfg_env.disable_block_gas_limit = true;
// The basefee should be ignored for eth_createAccessList // The basefee should be ignored for eth_createAccessList
// See: // See:
// <https://github.com/ethereum/go-ethereum/blob/8990c92aea01ca07801597b00c0d83d4e2d9b811/internal/ethapi/api.go#L1476-L1476> // <https://github.com/ethereum/go-ethereum/blob/8990c92aea01ca07801597b00c0d83d4e2d9b811/internal/ethapi/api.go#L1476-L1476>
evm_env.cfg_env_with_handler_cfg.disable_base_fee = true; evm_env.cfg_env.disable_base_fee = true;
let mut db = CacheDB::new(StateProviderDatabase::new(state)); let mut db = CacheDB::new(StateProviderDatabase::new(state));
@ -427,7 +427,7 @@ pub trait EthCall: EstimateCall + Call + LoadPendingBlock + LoadBlock + FullEthA
// can consume the list since we're not using the request anymore // can consume the list since we're not using the request anymore
let initial = request.access_list.take().unwrap_or_default(); let initial = request.access_list.take().unwrap_or_default();
let precompiles = get_precompiles(evm_env.cfg_env_with_handler_cfg.handler_cfg.spec_id); let precompiles = get_precompiles(evm_env.spec.into());
let mut inspector = AccessListInspector::new(initial, from, to, precompiles); let mut inspector = AccessListInspector::new(initial, from, to, precompiles);
let (result, (evm_env, mut tx_env)) = let (result, (evm_env, mut tx_env)) =
@ -495,16 +495,21 @@ pub trait Call:
fn transact<DB>( fn transact<DB>(
&self, &self,
db: DB, db: DB,
evm_env: EvmEnv, evm_env: EvmEnv<<Self::Evm as ConfigureEvmEnv>::Spec>,
tx_env: <Self::Evm as ConfigureEvmEnv>::TxEnv, tx_env: <Self::Evm as ConfigureEvmEnv>::TxEnv,
) -> Result<(ResultAndState, (EvmEnv, <Self::Evm as ConfigureEvmEnv>::TxEnv)), Self::Error> ) -> Result<
(
ResultAndState,
(EvmEnv<<Self::Evm as ConfigureEvmEnv>::Spec>, <Self::Evm as ConfigureEvmEnv>::TxEnv),
),
Self::Error,
>
where where
DB: Database, DB: Database,
EthApiError: From<DB::Error>, EthApiError: From<DB::Error>,
{ {
let mut evm = self.evm_config().evm_with_env(db, evm_env); let mut evm = self.evm_config().evm_with_env(db, evm_env.clone());
let res = evm.transact(tx_env.clone()).map_err(Self::Error::from_evm_err)?; let res = evm.transact(tx_env.clone()).map_err(Self::Error::from_evm_err)?;
let evm_env = evm.into_env();
Ok((res, (evm_env, tx_env))) Ok((res, (evm_env, tx_env)))
} }
@ -515,17 +520,22 @@ pub trait Call:
fn transact_with_inspector<DB>( fn transact_with_inspector<DB>(
&self, &self,
db: DB, db: DB,
evm_env: EvmEnv, evm_env: EvmEnv<<Self::Evm as ConfigureEvmEnv>::Spec>,
tx_env: <Self::Evm as ConfigureEvmEnv>::TxEnv, tx_env: <Self::Evm as ConfigureEvmEnv>::TxEnv,
inspector: impl GetInspector<DB>, inspector: impl GetInspector<DB>,
) -> Result<(ResultAndState, (EvmEnv, <Self::Evm as ConfigureEvmEnv>::TxEnv)), Self::Error> ) -> Result<
(
ResultAndState,
(EvmEnv<<Self::Evm as ConfigureEvmEnv>::Spec>, <Self::Evm as ConfigureEvmEnv>::TxEnv),
),
Self::Error,
>
where where
DB: Database, DB: Database,
EthApiError: From<DB::Error>, EthApiError: From<DB::Error>,
{ {
let mut evm = self.evm_config().evm_with_env_and_inspector(db, evm_env, inspector); let mut evm = self.evm_config().evm_with_env_and_inspector(db, evm_env.clone(), inspector);
let res = evm.transact(tx_env.clone()).map_err(Self::Error::from_evm_err)?; let res = evm.transact(tx_env.clone()).map_err(Self::Error::from_evm_err)?;
let evm_env = evm.into_env();
Ok((res, (evm_env, tx_env))) Ok((res, (evm_env, tx_env)))
} }
@ -539,7 +549,13 @@ pub trait Call:
overrides: EvmOverrides, overrides: EvmOverrides,
) -> impl Future< ) -> impl Future<
Output = Result< Output = Result<
(ResultAndState, (EvmEnv, <Self::Evm as ConfigureEvmEnv>::TxEnv)), (
ResultAndState,
(
EvmEnv<<Self::Evm as ConfigureEvmEnv>::Spec>,
<Self::Evm as ConfigureEvmEnv>::TxEnv,
),
),
Self::Error, Self::Error,
>, >,
> + Send > + Send
@ -594,7 +610,7 @@ pub trait Call:
Self: LoadPendingBlock, Self: LoadPendingBlock,
F: FnOnce( F: FnOnce(
StateCacheDbRefMutWrapper<'_, '_>, StateCacheDbRefMutWrapper<'_, '_>,
EvmEnv, EvmEnv<<Self::Evm as ConfigureEvmEnv>::Spec>,
<Self::Evm as ConfigureEvmEnv>::TxEnv, <Self::Evm as ConfigureEvmEnv>::TxEnv,
) -> Result<R, Self::Error> ) -> Result<R, Self::Error>
+ Send + Send
@ -680,7 +696,7 @@ pub trait Call:
fn replay_transactions_until<'a, DB, I>( fn replay_transactions_until<'a, DB, I>(
&self, &self,
db: &mut DB, db: &mut DB,
evm_env: EvmEnv, evm_env: EvmEnv<<Self::Evm as ConfigureEvmEnv>::Spec>,
transactions: I, transactions: I,
target_tx_hash: B256, target_tx_hash: B256,
) -> Result<usize, Self::Error> ) -> Result<usize, Self::Error>
@ -728,13 +744,17 @@ pub trait Call:
/// - `nonce` is set to `None` /// - `nonce` is set to `None`
/// ///
/// In addition, this changes the block's gas limit to the configured [`Self::call_gas_limit`]. /// In addition, this changes the block's gas limit to the configured [`Self::call_gas_limit`].
#[expect(clippy::type_complexity)]
fn prepare_call_env<DB>( fn prepare_call_env<DB>(
&self, &self,
mut evm_env: EvmEnv, mut evm_env: EvmEnv<<Self::Evm as ConfigureEvmEnv>::Spec>,
mut request: TransactionRequest, mut request: TransactionRequest,
db: &mut CacheDB<DB>, db: &mut CacheDB<DB>,
overrides: EvmOverrides, overrides: EvmOverrides,
) -> Result<(EvmEnv, <Self::Evm as ConfigureEvmEnv>::TxEnv), Self::Error> ) -> Result<
(EvmEnv<<Self::Evm as ConfigureEvmEnv>::Spec>, <Self::Evm as ConfigureEvmEnv>::TxEnv),
Self::Error,
>
where where
DB: DatabaseRef, DB: DatabaseRef,
EthApiError: From<<DB as DatabaseRef>::Error>, EthApiError: From<<DB as DatabaseRef>::Error>,
@ -751,12 +771,12 @@ pub trait Call:
// Disabled because eth_call is sometimes used with eoa senders // Disabled because eth_call is sometimes used with eoa senders
// See <https://github.com/paradigmxyz/reth/issues/1959> // See <https://github.com/paradigmxyz/reth/issues/1959>
evm_env.cfg_env_with_handler_cfg.disable_eip3607 = true; evm_env.cfg_env.disable_eip3607 = true;
// The basefee should be ignored for eth_call // The basefee should be ignored for eth_call
// See: // See:
// <https://github.com/ethereum/go-ethereum/blob/ee8e83fa5f6cb261dad2ed0a7bbcde4930c41e6c/internal/ethapi/api.go#L985> // <https://github.com/ethereum/go-ethereum/blob/ee8e83fa5f6cb261dad2ed0a7bbcde4930c41e6c/internal/ethapi/api.go#L985>
evm_env.cfg_env_with_handler_cfg.disable_base_fee = true; evm_env.cfg_env.disable_base_fee = true;
// set nonce to None so that the correct nonce is chosen by the EVM // set nonce to None so that the correct nonce is chosen by the EVM
request.nonce = None; request.nonce = None;

View File

@ -36,7 +36,7 @@ pub trait EstimateCall: Call {
/// - `nonce` is set to `None` /// - `nonce` is set to `None`
fn estimate_gas_with<S>( fn estimate_gas_with<S>(
&self, &self,
mut evm_env: EvmEnv, mut evm_env: EvmEnv<<Self::Evm as ConfigureEvmEnv>::Spec>,
mut request: TransactionRequest, mut request: TransactionRequest,
state: S, state: S,
state_override: Option<StateOverride>, state_override: Option<StateOverride>,
@ -46,12 +46,12 @@ pub trait EstimateCall: Call {
{ {
// Disabled because eth_estimateGas is sometimes used with eoa senders // Disabled because eth_estimateGas is sometimes used with eoa senders
// See <https://github.com/paradigmxyz/reth/issues/1959> // See <https://github.com/paradigmxyz/reth/issues/1959>
evm_env.cfg_env_with_handler_cfg.disable_eip3607 = true; evm_env.cfg_env.disable_eip3607 = true;
// The basefee should be ignored for eth_estimateGas and similar // The basefee should be ignored for eth_estimateGas and similar
// See: // See:
// <https://github.com/ethereum/go-ethereum/blob/ee8e83fa5f6cb261dad2ed0a7bbcde4930c41e6c/internal/ethapi/api.go#L985> // <https://github.com/ethereum/go-ethereum/blob/ee8e83fa5f6cb261dad2ed0a7bbcde4930c41e6c/internal/ethapi/api.go#L985>
evm_env.cfg_env_with_handler_cfg.disable_base_fee = true; evm_env.cfg_env.disable_base_fee = true;
// set nonce to None so that the correct nonce is chosen by the EVM // set nonce to None so that the correct nonce is chosen by the EVM
request.nonce = None; request.nonce = None;
@ -281,7 +281,7 @@ pub trait EstimateCall: Call {
fn map_out_of_gas_err<DB>( fn map_out_of_gas_err<DB>(
&self, &self,
env_gas_limit: U256, env_gas_limit: U256,
evm_env: EvmEnv, evm_env: EvmEnv<<Self::Evm as ConfigureEvmEnv>::Spec>,
mut tx_env: <Self::Evm as ConfigureEvmEnv>::TxEnv, mut tx_env: <Self::Evm as ConfigureEvmEnv>::TxEnv,
db: &mut DB, db: &mut DB,
) -> Self::Error ) -> Self::Error

View File

@ -69,7 +69,11 @@ pub trait LoadPendingBlock:
fn pending_block_env_and_cfg( fn pending_block_env_and_cfg(
&self, &self,
) -> Result< ) -> Result<
PendingBlockEnv<ProviderBlock<Self::Provider>, ProviderReceipt<Self::Provider>>, PendingBlockEnv<
ProviderBlock<Self::Provider>,
ProviderReceipt<Self::Provider>,
<Self::Evm as ConfigureEvmEnv>::Spec,
>,
Self::Error, Self::Error,
> { > {
if let Some(block) = if let Some(block) =
@ -234,7 +238,7 @@ pub trait LoadPendingBlock:
#[expect(clippy::type_complexity)] #[expect(clippy::type_complexity)]
fn build_block( fn build_block(
&self, &self,
evm_env: EvmEnv, evm_env: EvmEnv<<Self::Evm as ConfigureEvmEnv>::Spec>,
parent_hash: B256, parent_hash: B256,
) -> Result< ) -> Result<
(RecoveredBlock<ProviderBlock<Self::Provider>>, Vec<ProviderReceipt<Self::Provider>>), (RecoveredBlock<ProviderBlock<Self::Provider>>, Vec<ProviderReceipt<Self::Provider>>),

View File

@ -210,10 +210,13 @@ pub trait LoadState:
/// for. /// for.
/// If the [`BlockId`] is pending, this will return the "Pending" tag, otherwise this returns /// If the [`BlockId`] is pending, this will return the "Pending" tag, otherwise this returns
/// the hash of the exact block. /// the hash of the exact block.
#[expect(clippy::type_complexity)]
fn evm_env_at( fn evm_env_at(
&self, &self,
at: BlockId, at: BlockId,
) -> impl Future<Output = Result<(EvmEnv, BlockId), Self::Error>> + Send ) -> impl Future<
Output = Result<(EvmEnv<<Self::Evm as ConfigureEvmEnv>::Spec>, BlockId), Self::Error>,
> + Send
where where
Self: LoadPendingBlock + SpawnBlocking, Self: LoadPendingBlock + SpawnBlocking,
{ {

View File

@ -37,18 +37,23 @@ pub trait Trace:
fn inspect<DB, I>( fn inspect<DB, I>(
&self, &self,
db: DB, db: DB,
evm_env: EvmEnv, evm_env: EvmEnv<<Self::Evm as ConfigureEvmEnv>::Spec>,
tx_env: <Self::Evm as ConfigureEvmEnv>::TxEnv, tx_env: <Self::Evm as ConfigureEvmEnv>::TxEnv,
inspector: I, inspector: I,
) -> Result<(ResultAndState, (EvmEnv, <Self::Evm as ConfigureEvmEnv>::TxEnv)), Self::Error> ) -> Result<
(
ResultAndState,
(EvmEnv<<Self::Evm as ConfigureEvmEnv>::Spec>, <Self::Evm as ConfigureEvmEnv>::TxEnv),
),
Self::Error,
>
where where
DB: Database, DB: Database,
EthApiError: From<DB::Error>, EthApiError: From<DB::Error>,
I: GetInspector<DB>, I: GetInspector<DB>,
{ {
let mut evm = self.evm_config().evm_with_env_and_inspector(db, evm_env, inspector); let mut evm = self.evm_config().evm_with_env_and_inspector(db, evm_env.clone(), inspector);
let res = evm.transact(tx_env.clone()).map_err(Self::Error::from_evm_err)?; let res = evm.transact(tx_env.clone()).map_err(Self::Error::from_evm_err)?;
let evm_env = evm.into_env();
Ok((res, (evm_env, tx_env))) Ok((res, (evm_env, tx_env)))
} }
@ -61,7 +66,7 @@ pub trait Trace:
/// Caution: this is blocking /// Caution: this is blocking
fn trace_at<F, R>( fn trace_at<F, R>(
&self, &self,
evm_env: EvmEnv, evm_env: EvmEnv<<Self::Evm as ConfigureEvmEnv>::Spec>,
tx_env: <Self::Evm as ConfigureEvmEnv>::TxEnv, tx_env: <Self::Evm as ConfigureEvmEnv>::TxEnv,
config: TracingInspectorConfig, config: TracingInspectorConfig,
at: BlockId, at: BlockId,
@ -88,7 +93,7 @@ pub trait Trace:
/// the configured [`EvmEnv`] was inspected. /// the configured [`EvmEnv`] was inspected.
fn spawn_trace_at_with_state<F, R>( fn spawn_trace_at_with_state<F, R>(
&self, &self,
evm_env: EvmEnv, evm_env: EvmEnv<<Self::Evm as ConfigureEvmEnv>::Spec>,
tx_env: <Self::Evm as ConfigureEvmEnv>::TxEnv, tx_env: <Self::Evm as ConfigureEvmEnv>::TxEnv,
config: TracingInspectorConfig, config: TracingInspectorConfig,
at: BlockId, at: BlockId,
@ -444,7 +449,7 @@ pub trait Trace:
&self, &self,
block: &RecoveredBlock<ProviderBlock<Self::Provider>>, block: &RecoveredBlock<ProviderBlock<Self::Provider>>,
db: &mut DB, db: &mut DB,
evm_env: &EvmEnv, evm_env: &EvmEnv<<Self::Evm as ConfigureEvmEnv>::Spec>,
) -> Result<(), Self::Error> { ) -> Result<(), Self::Error> {
let mut system_caller = let mut system_caller =
SystemCaller::new(self.evm_config().clone(), self.provider().chain_spec()); SystemCaller::new(self.evm_config().clone(), self.provider().chain_spec());

View File

@ -14,9 +14,9 @@ use reth_primitives_traits::Block;
/// Configured [`EvmEnv`] for a pending block. /// Configured [`EvmEnv`] for a pending block.
#[derive(Debug, Clone, Constructor)] #[derive(Debug, Clone, Constructor)]
pub struct PendingBlockEnv<B: Block = reth_primitives::Block, R = Receipt> { pub struct PendingBlockEnv<B: Block, R, Spec> {
/// Configured [`EvmEnv`] for the pending block. /// Configured [`EvmEnv`] for the pending block.
pub evm_env: EvmEnv, pub evm_env: EvmEnv<Spec>,
/// Origin block for the config /// Origin block for the config
pub origin: PendingBlockEnvOrigin<B, R>, pub origin: PendingBlockEnvOrigin<B, R>,
} }

View File

@ -95,7 +95,7 @@ where
async fn trace_block( async fn trace_block(
&self, &self,
block: Arc<RecoveredBlock<ProviderBlock<Eth::Provider>>>, block: Arc<RecoveredBlock<ProviderBlock<Eth::Provider>>>,
evm_env: EvmEnv, evm_env: EvmEnv<<Eth::Evm as ConfigureEvmEnv>::Spec>,
opts: GethDebugTracingOptions, opts: GethDebugTracingOptions,
) -> Result<Vec<TraceResult>, Eth::Error> { ) -> Result<Vec<TraceResult>, Eth::Error> {
// replay all transactions of the block // replay all transactions of the block
@ -446,7 +446,7 @@ where
&mut inspector, &mut inspector,
)?; )?;
let env = revm_primitives::Env::boxed( let env = revm_primitives::Env::boxed(
evm_env.cfg_env_with_handler_cfg.cfg_env, evm_env.cfg_env,
evm_env.block_env, evm_env.block_env,
tx_env.into(), tx_env.into(),
); );
@ -650,7 +650,7 @@ where
fn trace_transaction( fn trace_transaction(
&self, &self,
opts: &GethDebugTracingOptions, opts: &GethDebugTracingOptions,
evm_env: EvmEnv, evm_env: EvmEnv<<Eth::Evm as ConfigureEvmEnv>::Spec>,
tx_env: <Eth::Evm as ConfigureEvmEnv>::TxEnv, tx_env: <Eth::Evm as ConfigureEvmEnv>::TxEnv,
db: &mut StateCacheDb<'_>, db: &mut StateCacheDb<'_>,
transaction_context: Option<TransactionContext>, transaction_context: Option<TransactionContext>,
@ -781,7 +781,7 @@ where
let state = res.state.clone(); let state = res.state.clone();
let env = revm_primitives::Env::boxed( let env = revm_primitives::Env::boxed(
evm_env.cfg_env_with_handler_cfg.cfg_env, evm_env.cfg_env,
evm_env.block_env, evm_env.block_env,
tx_env.into(), tx_env.into(),
); );

View File

@ -1,18 +1,16 @@
//! `Eth` bundle implementation and helpers. //! `Eth` bundle implementation and helpers.
use alloy_consensus::{BlockHeader, EnvKzgSettings, Transaction as _}; use alloy_consensus::{EnvKzgSettings, Transaction as _};
use alloy_eips::eip4844::MAX_DATA_GAS_PER_BLOCK; use alloy_eips::eip4844::MAX_DATA_GAS_PER_BLOCK;
use alloy_primitives::{Keccak256, U256}; use alloy_primitives::{Keccak256, U256};
use alloy_rpc_types_mev::{EthCallBundle, EthCallBundleResponse, EthCallBundleTransactionResult}; use alloy_rpc_types_mev::{EthCallBundle, EthCallBundleResponse, EthCallBundleTransactionResult};
use jsonrpsee::core::RpcResult; use jsonrpsee::core::RpcResult;
use reth_chainspec::EthChainSpec;
use reth_evm::{ConfigureEvm, ConfigureEvmEnv, Evm}; use reth_evm::{ConfigureEvm, ConfigureEvmEnv, Evm};
use reth_primitives_traits::SignedTransaction; use reth_primitives_traits::SignedTransaction;
use reth_provider::{ChainSpecProvider, HeaderProvider};
use reth_revm::database::StateProviderDatabase; use reth_revm::database::StateProviderDatabase;
use reth_rpc_eth_api::{ use reth_rpc_eth_api::{
helpers::{Call, EthTransactions, LoadPendingBlock}, helpers::{Call, EthTransactions, LoadPendingBlock},
EthCallBundleApiServer, FromEthApiError, FromEvmError, RpcNodeCore, EthCallBundleApiServer, FromEthApiError, FromEvmError,
}; };
use reth_rpc_eth_types::{utils::recover_raw_transaction, EthApiError, RpcInvalidTransactionError}; use reth_rpc_eth_types::{utils::recover_raw_transaction, EthApiError, RpcInvalidTransactionError};
use reth_tasks::pool::BlockingTaskGuard; use reth_tasks::pool::BlockingTaskGuard;
@ -23,7 +21,6 @@ use revm::{
db::{CacheDB, DatabaseCommit, DatabaseRef}, db::{CacheDB, DatabaseCommit, DatabaseRef},
primitives::ResultAndState, primitives::ResultAndState,
}; };
use revm_primitives::SpecId;
use std::sync::Arc; use std::sync::Arc;
/// `Eth` bundle implementation. /// `Eth` bundle implementation.
@ -132,21 +129,6 @@ where
if let Some(base_fee) = base_fee { if let Some(base_fee) = base_fee {
evm_env.block_env.basefee = U256::from(base_fee); evm_env.block_env.basefee = U256::from(base_fee);
} else if evm_env.cfg_env_with_handler_cfg.handler_cfg.spec_id.is_enabled_in(SpecId::LONDON)
{
let parent_block = evm_env.block_env.number.saturating_to::<u64>();
// here we need to fetch the _next_ block's basefee based on the parent block <https://github.com/flashbots/mev-geth/blob/fddf97beec5877483f879a77b7dea2e58a58d653/internal/ethapi/api.go#L2130>
let parent = RpcNodeCore::provider(self.eth_api())
.header_by_number(parent_block)
.map_err(Eth::Error::from_eth_err)?
.ok_or(EthApiError::HeaderNotFound(parent_block.into()))?;
if let Some(base_fee) = parent.next_block_base_fee(
RpcNodeCore::provider(self.eth_api())
.chain_spec()
.base_fee_params_at_block(parent_block),
) {
evm_env.block_env.basefee = U256::from(base_fee);
}
} }
let state_block_number = evm_env.block_env.number; let state_block_number = evm_env.block_env.number;

View File

@ -1,6 +1,5 @@
//! `Eth` Sim bundle implementation and helpers. //! `Eth` Sim bundle implementation and helpers.
use alloy_consensus::BlockHeader;
use alloy_eips::BlockNumberOrTag; use alloy_eips::BlockNumberOrTag;
use alloy_primitives::U256; use alloy_primitives::U256;
use alloy_rpc_types_eth::BlockId; use alloy_rpc_types_eth::BlockId;
@ -9,21 +8,20 @@ use alloy_rpc_types_mev::{
SimBundleOverrides, SimBundleResponse, Validity, SimBundleOverrides, SimBundleResponse, Validity,
}; };
use jsonrpsee::core::RpcResult; use jsonrpsee::core::RpcResult;
use reth_chainspec::EthChainSpec;
use reth_evm::{ConfigureEvm, ConfigureEvmEnv, Evm}; use reth_evm::{ConfigureEvm, ConfigureEvmEnv, Evm};
use reth_provider::{ChainSpecProvider, HeaderProvider, ProviderTx}; use reth_provider::ProviderTx;
use reth_revm::database::StateProviderDatabase; use reth_revm::database::StateProviderDatabase;
use reth_rpc_api::MevSimApiServer; use reth_rpc_api::MevSimApiServer;
use reth_rpc_eth_api::{ use reth_rpc_eth_api::{
helpers::{Call, EthTransactions, LoadPendingBlock}, helpers::{Call, EthTransactions, LoadPendingBlock},
FromEthApiError, RpcNodeCore, FromEthApiError,
}; };
use reth_rpc_eth_types::{utils::recover_raw_transaction, EthApiError}; use reth_rpc_eth_types::{utils::recover_raw_transaction, EthApiError};
use reth_tasks::pool::BlockingTaskGuard; use reth_tasks::pool::BlockingTaskGuard;
use reth_transaction_pool::{PoolConsensusTx, PoolPooledTx, PoolTransaction, TransactionPool}; use reth_transaction_pool::{PoolConsensusTx, PoolPooledTx, PoolTransaction, TransactionPool};
use revm::{ use revm::{
db::CacheDB, db::CacheDB,
primitives::{Address, ResultAndState, SpecId}, primitives::{Address, ResultAndState},
DatabaseCommit, DatabaseRef, DatabaseCommit, DatabaseRef,
}; };
use std::{sync::Arc, time::Duration}; use std::{sync::Arc, time::Duration};
@ -246,15 +244,6 @@ where
let block_id = parent_block.unwrap_or(BlockId::Number(BlockNumberOrTag::Pending)); let block_id = parent_block.unwrap_or(BlockId::Number(BlockNumberOrTag::Pending));
let (mut evm_env, current_block) = self.eth_api().evm_env_at(block_id).await?; let (mut evm_env, current_block) = self.eth_api().evm_env_at(block_id).await?;
let parent_header = RpcNodeCore::provider(&self.inner.eth_api)
.header_by_number(evm_env.block_env.number.saturating_to::<u64>())
.map_err(EthApiError::from_eth_err)? // Explicitly map the error
.ok_or_else(|| {
EthApiError::HeaderNotFound(
(evm_env.block_env.number.saturating_to::<u64>()).into(),
)
})?;
// apply overrides // apply overrides
if let Some(block_number) = block_number { if let Some(block_number) = block_number {
evm_env.block_env.number = U256::from(block_number); evm_env.block_env.number = U256::from(block_number);
@ -274,15 +263,6 @@ where
if let Some(base_fee) = base_fee { if let Some(base_fee) = base_fee {
evm_env.block_env.basefee = U256::from(base_fee); evm_env.block_env.basefee = U256::from(base_fee);
} else if evm_env.cfg_env_with_handler_cfg.handler_cfg.spec_id.is_enabled_in(SpecId::LONDON)
{
if let Some(base_fee) = parent_header.next_block_base_fee(
RpcNodeCore::provider(&self.inner.eth_api)
.chain_spec()
.base_fee_params_at_block(evm_env.block_env.number.saturating_to::<u64>()),
) {
evm_env.block_env.basefee = U256::from(base_fee);
}
} }
let eth_api = self.inner.eth_api.clone(); let eth_api = self.inner.eth_api.clone();

View File

@ -15,7 +15,7 @@ use reth::{
handler::register::EvmHandler, handler::register::EvmHandler,
inspector_handle_register, inspector_handle_register,
precompile::{Precompile, PrecompileOutput, PrecompileSpecId}, precompile::{Precompile, PrecompileOutput, PrecompileSpecId},
primitives::{Env, PrecompileResult, TxEnv}, primitives::{CfgEnvWithHandlerCfg, Env, HandlerCfg, PrecompileResult, SpecId, TxEnv},
ContextPrecompiles, Database, EvmBuilder, GetInspector, ContextPrecompiles, Database, EvmBuilder, GetInspector,
}, },
rpc::types::engine::PayloadAttributes, rpc::types::engine::PayloadAttributes,
@ -88,6 +88,7 @@ impl ConfigureEvmEnv for MyEvmConfig {
type Transaction = TransactionSigned; type Transaction = TransactionSigned;
type Error = Infallible; type Error = Infallible;
type TxEnv = TxEnv; type TxEnv = TxEnv;
type Spec = SpecId;
fn tx_env(&self, transaction: &Self::Transaction, signer: Address) -> Self::TxEnv { fn tx_env(&self, transaction: &Self::Transaction, signer: Address) -> Self::TxEnv {
self.inner.tx_env(transaction, signer) self.inner.tx_env(transaction, signer)
@ -110,9 +111,13 @@ impl ConfigureEvm for MyEvmConfig {
type Evm<'a, DB: Database + 'a, I: 'a> = EthEvm<'a, I, DB>; type Evm<'a, DB: Database + 'a, I: 'a> = EthEvm<'a, I, DB>;
fn evm_with_env<DB: Database>(&self, db: DB, evm_env: EvmEnv) -> Self::Evm<'_, DB, ()> { fn evm_with_env<DB: Database>(&self, db: DB, evm_env: EvmEnv) -> Self::Evm<'_, DB, ()> {
let cfg_env_with_handler_cfg = CfgEnvWithHandlerCfg {
cfg_env: evm_env.cfg_env,
handler_cfg: HandlerCfg::new(evm_env.spec),
};
EvmBuilder::default() EvmBuilder::default()
.with_db(db) .with_db(db)
.with_cfg_env_with_handler_cfg(evm_env.cfg_env_with_handler_cfg) .with_cfg_env_with_handler_cfg(cfg_env_with_handler_cfg)
.with_block_env(evm_env.block_env) .with_block_env(evm_env.block_env)
// add additional precompiles // add additional precompiles
.append_handler_register(MyEvmConfig::set_precompiles) .append_handler_register(MyEvmConfig::set_precompiles)
@ -130,10 +135,15 @@ impl ConfigureEvm for MyEvmConfig {
DB: Database, DB: Database,
I: GetInspector<DB>, I: GetInspector<DB>,
{ {
let cfg_env_with_handler_cfg = CfgEnvWithHandlerCfg {
cfg_env: evm_env.cfg_env,
handler_cfg: HandlerCfg::new(evm_env.spec),
};
EvmBuilder::default() EvmBuilder::default()
.with_db(db) .with_db(db)
.with_external_context(inspector) .with_external_context(inspector)
.with_cfg_env_with_handler_cfg(evm_env.cfg_env_with_handler_cfg) .with_cfg_env_with_handler_cfg(cfg_env_with_handler_cfg)
.with_block_env(evm_env.block_env) .with_block_env(evm_env.block_env)
// add additional precompiles // add additional precompiles
.append_handler_register(MyEvmConfig::set_precompiles) .append_handler_register(MyEvmConfig::set_precompiles)

View File

@ -30,7 +30,7 @@ use reth::{
}; };
use reth_evm::EvmEnv; use reth_evm::EvmEnv;
use reth_node_ethereum::node::EthereumNode; use reth_node_ethereum::node::EthereumNode;
use revm_primitives::CfgEnvWithHandlerCfg; use revm_primitives::HandlerCfg;
fn main() { fn main() {
Cli::<EthereumChainSpecParser, RethCliTxpoolExt>::parse() Cli::<EthereumChainSpecParser, RethCliTxpoolExt>::parse()
@ -65,13 +65,9 @@ fn main() {
BlockNumberOrTag::Latest.into(), BlockNumberOrTag::Latest.into(),
EvmOverrides::default(), EvmOverrides::default(),
move |db, evm_env, tx_env| { move |db, evm_env, tx_env| {
let EvmEnv { let EvmEnv { cfg_env, block_env, spec } = evm_env;
cfg_env_with_handler_cfg:
CfgEnvWithHandlerCfg { handler_cfg, cfg_env },
block_env,
} = evm_env;
let env = EnvWithHandlerCfg { let env = EnvWithHandlerCfg {
handler_cfg, handler_cfg: HandlerCfg::new(spec),
env: Env::boxed(cfg_env, block_env, tx_env), env: Env::boxed(cfg_env, block_env, tx_env),
}; };
let mut dummy_inspector = DummyInspector::default(); let mut dummy_inspector = DummyInspector::default();

View File

@ -13,7 +13,10 @@ use reth::{
handler::register::EvmHandler, handler::register::EvmHandler,
inspector_handle_register, inspector_handle_register,
precompile::{Precompile, PrecompileSpecId}, precompile::{Precompile, PrecompileSpecId},
primitives::{Env, PrecompileResult, SpecId, StatefulPrecompileMut, TxEnv}, primitives::{
CfgEnvWithHandlerCfg, Env, HandlerCfg, PrecompileResult, SpecId, StatefulPrecompileMut,
TxEnv,
},
ContextPrecompile, ContextPrecompiles, Database, EvmBuilder, GetInspector, ContextPrecompile, ContextPrecompiles, Database, EvmBuilder, GetInspector,
}, },
tasks::TaskManager, tasks::TaskManager,
@ -149,6 +152,7 @@ impl ConfigureEvmEnv for MyEvmConfig {
type Transaction = TransactionSigned; type Transaction = TransactionSigned;
type Error = Infallible; type Error = Infallible;
type TxEnv = TxEnv; type TxEnv = TxEnv;
type Spec = SpecId;
fn tx_env(&self, transaction: &Self::Transaction, signer: Address) -> Self::TxEnv { fn tx_env(&self, transaction: &Self::Transaction, signer: Address) -> Self::TxEnv {
self.inner.tx_env(transaction, signer) self.inner.tx_env(transaction, signer)
@ -171,10 +175,15 @@ impl ConfigureEvm for MyEvmConfig {
type Evm<'a, DB: Database + 'a, I: 'a> = EthEvm<'a, I, DB>; type Evm<'a, DB: Database + 'a, I: 'a> = EthEvm<'a, I, DB>;
fn evm_with_env<DB: Database>(&self, db: DB, evm_env: EvmEnv) -> Self::Evm<'_, DB, ()> { fn evm_with_env<DB: Database>(&self, db: DB, evm_env: EvmEnv) -> Self::Evm<'_, DB, ()> {
let cfg_env_with_handler_cfg = CfgEnvWithHandlerCfg {
cfg_env: evm_env.cfg_env,
handler_cfg: HandlerCfg::new(evm_env.spec),
};
let new_cache = self.precompile_cache.clone(); let new_cache = self.precompile_cache.clone();
EvmBuilder::default() EvmBuilder::default()
.with_db(db) .with_db(db)
.with_cfg_env_with_handler_cfg(evm_env.cfg_env_with_handler_cfg) .with_cfg_env_with_handler_cfg(cfg_env_with_handler_cfg)
.with_block_env(evm_env.block_env) .with_block_env(evm_env.block_env)
// add additional precompiles // add additional precompiles
.append_handler_register_box(Box::new(move |handler| { .append_handler_register_box(Box::new(move |handler| {
@ -194,11 +203,15 @@ impl ConfigureEvm for MyEvmConfig {
DB: Database, DB: Database,
I: GetInspector<DB>, I: GetInspector<DB>,
{ {
let cfg_env_with_handler_cfg = CfgEnvWithHandlerCfg {
cfg_env: evm_env.cfg_env,
handler_cfg: HandlerCfg::new(evm_env.spec),
};
let new_cache = self.precompile_cache.clone(); let new_cache = self.precompile_cache.clone();
EvmBuilder::default() EvmBuilder::default()
.with_db(db) .with_db(db)
.with_external_context(inspector) .with_external_context(inspector)
.with_cfg_env_with_handler_cfg(evm_env.cfg_env_with_handler_cfg) .with_cfg_env_with_handler_cfg(cfg_env_with_handler_cfg)
.with_block_env(evm_env.block_env) .with_block_env(evm_env.block_env)
// add additional precompiles // add additional precompiles
.append_handler_register_box(Box::new(move |handler| { .append_handler_register_box(Box::new(move |handler| {