mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat: add Spec generic for EvmEnv (#13975)
This commit is contained in:
@ -40,7 +40,7 @@ pub use receipts::*;
|
||||
mod error;
|
||||
pub use error::OpBlockExecutionError;
|
||||
use revm_primitives::{
|
||||
BlobExcessGasAndPrice, BlockEnv, Bytes, CfgEnv, EVMError, Env, HandlerCfg, OptimismFields,
|
||||
BlobExcessGasAndPrice, BlockEnv, Bytes, CfgEnv, EVMError, HandlerCfg, OptimismFields,
|
||||
ResultAndState, SpecId, TxKind,
|
||||
};
|
||||
|
||||
@ -58,17 +58,6 @@ impl<EXT, DB: Database> Evm for OpEvm<'_, EXT, DB> {
|
||||
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> {
|
||||
*self.tx_mut() = tx;
|
||||
self.0.transact()
|
||||
@ -158,6 +147,7 @@ impl ConfigureEvmEnv for OpEvmConfig {
|
||||
type Transaction = OpTransactionSigned;
|
||||
type Error = EIP1559ParamError;
|
||||
type TxEnv = TxEnv;
|
||||
type Spec = SpecId;
|
||||
|
||||
fn tx_env(&self, transaction: &Self::Transaction, signer: Address) -> Self::TxEnv {
|
||||
let mut tx_env = TxEnv::default();
|
||||
@ -166,32 +156,27 @@ impl ConfigureEvmEnv for OpEvmConfig {
|
||||
}
|
||||
|
||||
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();
|
||||
cfg_env.chain_id = self.chain_spec.chain().id();
|
||||
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 {
|
||||
number: U256::from(header.number()),
|
||||
coinbase: header.beneficiary(),
|
||||
timestamp: U256::from(header.timestamp()),
|
||||
difficulty: if spec_id >= SpecId::MERGE { U256::ZERO } else { header.difficulty() },
|
||||
prevrandao: if spec_id >= SpecId::MERGE { header.mix_hash() } else { None },
|
||||
difficulty: if spec >= SpecId::MERGE { U256::ZERO } else { header.difficulty() },
|
||||
prevrandao: if spec >= SpecId::MERGE { header.mix_hash() } else { None },
|
||||
gas_limit: U256::from(header.gas_limit()),
|
||||
basefee: U256::from(header.base_fee_per_gas().unwrap_or_default()),
|
||||
// EIP-4844 excess blob gas of this block, introduced in Cancun
|
||||
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(
|
||||
@ -240,12 +225,15 @@ impl ConfigureEvmEnv for OpEvmConfig {
|
||||
impl ConfigureEvm for OpEvmConfig {
|
||||
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, ()> {
|
||||
evm_env.cfg_env_with_handler_cfg.handler_cfg.is_optimism = true;
|
||||
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 { spec_id: evm_env.spec, is_optimism: true },
|
||||
};
|
||||
|
||||
EvmBuilder::default()
|
||||
.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)
|
||||
.build()
|
||||
.into()
|
||||
@ -254,19 +242,22 @@ impl ConfigureEvm for OpEvmConfig {
|
||||
fn evm_with_env_and_inspector<DB, I>(
|
||||
&self,
|
||||
db: DB,
|
||||
mut evm_env: EvmEnv,
|
||||
evm_env: EvmEnv,
|
||||
inspector: I,
|
||||
) -> Self::Evm<'_, DB, I>
|
||||
where
|
||||
DB: Database,
|
||||
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()
|
||||
.with_db(db)
|
||||
.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)
|
||||
.append_handler_register(inspector_handle_register)
|
||||
.build()
|
||||
@ -318,12 +309,12 @@ mod tests {
|
||||
|
||||
// Use the `OpEvmConfig` to create the `cfg_env` and `block_env` based on the ChainSpec,
|
||||
// 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);
|
||||
|
||||
// Assert that the chain ID in the `cfg_env` is correctly set to the chain ID of the
|
||||
// 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]
|
||||
@ -337,7 +328,7 @@ mod tests {
|
||||
let evm = evm_config.evm_with_env(db, evm_env.clone());
|
||||
|
||||
// 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
|
||||
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
|
||||
let cfg = CfgEnv::default().with_chain_id(111);
|
||||
|
||||
let evm_env = EvmEnv {
|
||||
cfg_env_with_handler_cfg: CfgEnvWithHandlerCfg {
|
||||
cfg_env: cfg.clone(),
|
||||
handler_cfg: Default::default(),
|
||||
},
|
||||
..Default::default()
|
||||
};
|
||||
let evm_env = EvmEnv { cfg_env: cfg.clone(), ..Default::default() };
|
||||
|
||||
let evm = evm_config.evm_with_env(db, evm_env);
|
||||
|
||||
@ -409,15 +394,7 @@ mod tests {
|
||||
|
||||
let db = CacheDB::<EmptyDBTyped<ProviderError>>::default();
|
||||
|
||||
let handler_cfg = HandlerCfg { spec_id: SpecId::ECOTONE, ..Default::default() };
|
||||
|
||||
let evm_env = EvmEnv {
|
||||
cfg_env_with_handler_cfg: CfgEnvWithHandlerCfg {
|
||||
handler_cfg,
|
||||
cfg_env: Default::default(),
|
||||
},
|
||||
..Default::default()
|
||||
};
|
||||
let evm_env = EvmEnv { spec: SpecId::ECOTONE, ..Default::default() };
|
||||
|
||||
let evm = evm_config.evm_with_env(db, evm_env);
|
||||
|
||||
@ -433,19 +410,13 @@ mod tests {
|
||||
let evm_config = test_evm_config();
|
||||
let db = CacheDB::<EmptyDBTyped<ProviderError>>::default();
|
||||
|
||||
let evm_env = EvmEnv {
|
||||
cfg_env_with_handler_cfg: CfgEnvWithHandlerCfg {
|
||||
cfg_env: Default::default(),
|
||||
handler_cfg: HandlerCfg { is_optimism: true, ..Default::default() },
|
||||
},
|
||||
..Default::default()
|
||||
};
|
||||
let evm_env = EvmEnv { cfg_env: Default::default(), ..Default::default() };
|
||||
|
||||
let evm = evm_config.evm_with_env_and_inspector(db, evm_env.clone(), NoOpInspector);
|
||||
|
||||
// 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.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.external, NoOpInspector);
|
||||
assert_eq!(evm.handler.spec_id(), SpecId::LATEST);
|
||||
@ -461,13 +432,7 @@ mod tests {
|
||||
|
||||
let cfg = CfgEnv::default().with_chain_id(111);
|
||||
let block = BlockEnv::default();
|
||||
let evm_env = EvmEnv {
|
||||
block_env: block,
|
||||
cfg_env_with_handler_cfg: CfgEnvWithHandlerCfg {
|
||||
cfg_env: cfg.clone(),
|
||||
handler_cfg: Default::default(),
|
||||
},
|
||||
};
|
||||
let evm_env = EvmEnv { block_env: block, cfg_env: cfg.clone(), ..Default::default() };
|
||||
|
||||
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 db = CacheDB::<EmptyDBTyped<ProviderError>>::default();
|
||||
|
||||
let handler_cfg = HandlerCfg { spec_id: SpecId::ECOTONE, ..Default::default() };
|
||||
let evm_env = EvmEnv {
|
||||
cfg_env_with_handler_cfg: CfgEnvWithHandlerCfg {
|
||||
cfg_env: Default::default(),
|
||||
handler_cfg,
|
||||
},
|
||||
..Default::default()
|
||||
};
|
||||
let evm_env = EvmEnv { spec: SpecId::ECOTONE, ..Default::default() };
|
||||
|
||||
let evm = evm_config.evm_with_env_and_inspector(db, evm_env.clone(), NoOpInspector);
|
||||
|
||||
// Check that the spec ID is set properly
|
||||
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.external, NoOpInspector);
|
||||
|
||||
|
||||
@ -17,7 +17,8 @@ use reth_basic_payload_builder::*;
|
||||
use reth_chain_state::ExecutedBlock;
|
||||
use reth_chainspec::{ChainSpecProvider, EthereumHardforks};
|
||||
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_optimism_chainspec::OpChainSpec;
|
||||
@ -125,7 +126,7 @@ where
|
||||
Txs: PayloadTransactions<Transaction = OpTransactionSigned>,
|
||||
{
|
||||
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)?;
|
||||
|
||||
let BuildArguments { client, pool: _, mut cached_reads, config, cancel, best_payload } =
|
||||
@ -162,11 +163,11 @@ where
|
||||
|
||||
/// Returns the configured [`EvmEnv`] for the targeted payload
|
||||
/// (that has the `parent` as its parent).
|
||||
pub fn cfg_and_block_env(
|
||||
pub fn evm_env(
|
||||
&self,
|
||||
attributes: &OpPayloadBuilderAttributes,
|
||||
parent: &Header,
|
||||
) -> Result<EvmEnv, EvmConfig::Error> {
|
||||
) -> Result<EvmEnv<EvmConfig::Spec>, EvmConfig::Error> {
|
||||
let next_attributes = NextBlockEnvAttributes {
|
||||
timestamp: attributes.timestamp(),
|
||||
suggested_fee_recipient: attributes.suggested_fee_recipient(),
|
||||
@ -189,8 +190,7 @@ where
|
||||
let attributes = OpPayloadBuilderAttributes::try_new(parent.hash(), attributes, 3)
|
||||
.map_err(PayloadBuilderError::other)?;
|
||||
|
||||
let evm_env =
|
||||
self.cfg_and_block_env(&attributes, &parent).map_err(PayloadBuilderError::other)?;
|
||||
let evm_env = self.evm_env(&attributes, &parent).map_err(PayloadBuilderError::other)?;
|
||||
|
||||
let config = PayloadConfig { parent_header: Arc::new(parent), attributes };
|
||||
let ctx = OpPayloadBuilderCtx {
|
||||
@ -578,7 +578,7 @@ impl ExecutionInfo {
|
||||
|
||||
/// Container type that holds all necessities to build a new payload.
|
||||
#[derive(Debug)]
|
||||
pub struct OpPayloadBuilderCtx<EvmConfig> {
|
||||
pub struct OpPayloadBuilderCtx<EvmConfig: ConfigureEvmEnv> {
|
||||
/// The type that knows how to perform system calls and configure the evm.
|
||||
pub evm_config: EvmConfig,
|
||||
/// The DA config for the payload builder
|
||||
@ -588,14 +588,14 @@ pub struct OpPayloadBuilderCtx<EvmConfig> {
|
||||
/// How to build the payload.
|
||||
pub config: PayloadConfig<OpPayloadBuilderAttributes>,
|
||||
/// Evm Settings
|
||||
pub evm_env: EvmEnv,
|
||||
pub evm_env: EvmEnv<EvmConfig::Spec>,
|
||||
/// Marker to check whether the job has been cancelled.
|
||||
pub cancel: Cancelled,
|
||||
/// The currently best payload.
|
||||
pub best_payload: Option<OpBuiltPayload>,
|
||||
}
|
||||
|
||||
impl<EvmConfig> OpPayloadBuilderCtx<EvmConfig> {
|
||||
impl<EvmConfig: ConfigureEvmEnv> OpPayloadBuilderCtx<EvmConfig> {
|
||||
/// Returns the parent block the payload will be build on.
|
||||
pub fn parent(&self) -> &SealedHeader {
|
||||
&self.config.parent_header
|
||||
|
||||
Reference in New Issue
Block a user