mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat: add Evm trait (#13823)
This commit is contained in:
@ -19,7 +19,7 @@ use reth_evm::{
|
||||
},
|
||||
state_change::post_block_balance_increments,
|
||||
system_calls::{OnStateHook, SystemCaller},
|
||||
ConfigureEvm, TxEnvOverrides,
|
||||
ConfigureEvm, Evm, TxEnvOverrides,
|
||||
};
|
||||
use reth_optimism_chainspec::OpChainSpec;
|
||||
use reth_optimism_consensus::validate_block_post_execution;
|
||||
@ -226,14 +226,14 @@ where
|
||||
.transpose()
|
||||
.map_err(|_| OpBlockExecutionError::AccountLoadFailed(*sender))?;
|
||||
|
||||
self.evm_config.fill_tx_env(evm.tx_mut(), transaction, *sender);
|
||||
let mut tx_env = self.evm_config.tx_env(transaction, *sender);
|
||||
|
||||
if let Some(tx_env_overrides) = &mut self.tx_env_overrides {
|
||||
tx_env_overrides.apply(evm.tx_mut());
|
||||
tx_env_overrides.apply(&mut tx_env);
|
||||
}
|
||||
|
||||
// Execute transaction.
|
||||
let result_and_state = evm.transact().map_err(move |err| {
|
||||
let result_and_state = evm.transact(tx_env).map_err(move |err| {
|
||||
let new_err = err.map_db_err(|e| e.into());
|
||||
// Ensure hash is calculated for error log, if not already done
|
||||
BlockValidationError::EVM {
|
||||
|
||||
@ -12,19 +12,20 @@
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
use alloc::{sync::Arc, vec::Vec};
|
||||
use alloc::sync::Arc;
|
||||
use alloy_consensus::Header;
|
||||
use alloy_eips::eip7840::BlobParams;
|
||||
use alloy_primitives::{Address, U256};
|
||||
use core::fmt::Debug;
|
||||
use op_alloy_consensus::EIP1559ParamError;
|
||||
use reth_evm::{env::EvmEnv, ConfigureEvm, ConfigureEvmEnv, NextBlockEnvAttributes};
|
||||
use reth_evm::{env::EvmEnv, ConfigureEvm, ConfigureEvmEnv, Evm, NextBlockEnvAttributes};
|
||||
use reth_optimism_chainspec::OpChainSpec;
|
||||
use reth_optimism_primitives::OpTransactionSigned;
|
||||
use reth_primitives_traits::FillTxEnv;
|
||||
use reth_revm::{
|
||||
inspector_handle_register,
|
||||
primitives::{AnalysisKind, CfgEnvWithHandlerCfg, TxEnv},
|
||||
Database, Evm, EvmBuilder, GetInspector,
|
||||
Database, EvmBuilder, GetInspector,
|
||||
};
|
||||
|
||||
mod config;
|
||||
@ -39,44 +40,48 @@ pub use receipts::*;
|
||||
mod error;
|
||||
pub use error::OpBlockExecutionError;
|
||||
use revm_primitives::{
|
||||
BlobExcessGasAndPrice, BlockEnv, Bytes, CfgEnv, Env, HandlerCfg, OptimismFields, SpecId, TxKind,
|
||||
BlobExcessGasAndPrice, BlockEnv, Bytes, CfgEnv, EVMError, Env, HandlerCfg, OptimismFields,
|
||||
ResultAndState, SpecId, TxKind,
|
||||
};
|
||||
|
||||
/// Optimism-related EVM configuration.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct OpEvmConfig {
|
||||
chain_spec: Arc<OpChainSpec>,
|
||||
}
|
||||
/// OP EVM implementation.
|
||||
#[derive(derive_more::Debug, derive_more::Deref, derive_more::DerefMut, derive_more::From)]
|
||||
#[debug(bound(DB::Error: Debug))]
|
||||
pub struct OpEvm<'a, EXT, DB: Database>(reth_revm::Evm<'a, EXT, DB>);
|
||||
|
||||
impl OpEvmConfig {
|
||||
/// Creates a new [`OpEvmConfig`] with the given chain spec.
|
||||
pub const fn new(chain_spec: Arc<OpChainSpec>) -> Self {
|
||||
Self { chain_spec }
|
||||
impl<EXT, DB: Database> Evm for OpEvm<'_, EXT, DB> {
|
||||
type DB = DB;
|
||||
type Tx = TxEnv;
|
||||
type Error = EVMError<DB::Error>;
|
||||
|
||||
fn block(&self) -> &BlockEnv {
|
||||
self.0.block()
|
||||
}
|
||||
|
||||
/// Returns the chain spec associated with this configuration.
|
||||
pub const fn chain_spec(&self) -> &Arc<OpChainSpec> {
|
||||
&self.chain_spec
|
||||
}
|
||||
}
|
||||
|
||||
impl ConfigureEvmEnv for OpEvmConfig {
|
||||
type Header = Header;
|
||||
type Transaction = OpTransactionSigned;
|
||||
type Error = EIP1559ParamError;
|
||||
|
||||
fn fill_tx_env(&self, tx_env: &mut TxEnv, transaction: &OpTransactionSigned, sender: Address) {
|
||||
transaction.fill_tx_env(tx_env, sender);
|
||||
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 fill_tx_env_system_contract_call(
|
||||
&self,
|
||||
env: &mut Env,
|
||||
fn transact(&mut self, tx: Self::Tx) -> Result<ResultAndState, Self::Error> {
|
||||
*self.tx_mut() = tx;
|
||||
self.0.transact()
|
||||
}
|
||||
|
||||
fn transact_system_call(
|
||||
&mut self,
|
||||
caller: Address,
|
||||
contract: Address,
|
||||
data: Bytes,
|
||||
) {
|
||||
env.tx = TxEnv {
|
||||
) -> Result<ResultAndState, Self::Error> {
|
||||
#[allow(clippy::needless_update)] // side-effect of optimism fields
|
||||
let tx_env = TxEnv {
|
||||
caller,
|
||||
transact_to: TxKind::Call(contract),
|
||||
// Explicitly set nonce to None so revm does not do any nonce checks
|
||||
@ -107,11 +112,54 @@ impl ConfigureEvmEnv for OpEvmConfig {
|
||||
},
|
||||
};
|
||||
|
||||
*self.tx_mut() = tx_env;
|
||||
|
||||
let prev_block_env = self.block().clone();
|
||||
|
||||
// ensure the block gas limit is >= the tx
|
||||
env.block.gas_limit = U256::from(env.tx.gas_limit);
|
||||
self.block_mut().gas_limit = U256::from(self.tx().gas_limit);
|
||||
|
||||
// disable the base fee check for this call by setting the base fee to zero
|
||||
env.block.basefee = U256::ZERO;
|
||||
self.block_mut().basefee = U256::ZERO;
|
||||
|
||||
let res = self.0.transact();
|
||||
|
||||
// re-set the block env
|
||||
*self.block_mut() = prev_block_env;
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
fn db_mut(&mut self) -> &mut Self::DB {
|
||||
&mut self.context.evm.db
|
||||
}
|
||||
}
|
||||
|
||||
/// Optimism-related EVM configuration.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct OpEvmConfig {
|
||||
chain_spec: Arc<OpChainSpec>,
|
||||
}
|
||||
|
||||
impl OpEvmConfig {
|
||||
/// Creates a new [`OpEvmConfig`] with the given chain spec.
|
||||
pub const fn new(chain_spec: Arc<OpChainSpec>) -> Self {
|
||||
Self { chain_spec }
|
||||
}
|
||||
|
||||
/// Returns the chain spec associated with this configuration.
|
||||
pub const fn chain_spec(&self) -> &Arc<OpChainSpec> {
|
||||
&self.chain_spec
|
||||
}
|
||||
}
|
||||
|
||||
impl ConfigureEvmEnv for OpEvmConfig {
|
||||
type Header = Header;
|
||||
type Transaction = OpTransactionSigned;
|
||||
type Error = EIP1559ParamError;
|
||||
|
||||
fn fill_tx_env(&self, tx_env: &mut TxEnv, transaction: &OpTransactionSigned, sender: Address) {
|
||||
transaction.fill_tx_env(tx_env, sender);
|
||||
}
|
||||
|
||||
fn fill_cfg_env(&self, cfg_env: &mut CfgEnvWithHandlerCfg, header: &Self::Header) {
|
||||
@ -168,12 +216,14 @@ 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,
|
||||
tx: TxEnv,
|
||||
) -> Evm<'_, (), DB> {
|
||||
) -> Self::Evm<'_, DB, ()> {
|
||||
evm_env.cfg_env_with_handler_cfg.handler_cfg.is_optimism = true;
|
||||
|
||||
EvmBuilder::default()
|
||||
@ -182,6 +232,7 @@ impl ConfigureEvm for OpEvmConfig {
|
||||
.with_block_env(evm_env.block_env)
|
||||
.with_tx_env(tx)
|
||||
.build()
|
||||
.into()
|
||||
}
|
||||
|
||||
fn evm_with_env_and_inspector<DB, I>(
|
||||
@ -190,7 +241,7 @@ impl ConfigureEvm for OpEvmConfig {
|
||||
mut evm_env: EvmEnv,
|
||||
tx: TxEnv,
|
||||
inspector: I,
|
||||
) -> Evm<'_, I, DB>
|
||||
) -> Self::Evm<'_, DB, I>
|
||||
where
|
||||
DB: Database,
|
||||
I: GetInspector<DB>,
|
||||
@ -205,6 +256,7 @@ impl ConfigureEvm for OpEvmConfig {
|
||||
.with_tx_env(tx)
|
||||
.append_handler_register(inspector_handle_register)
|
||||
.build()
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -15,7 +15,9 @@ use op_alloy_rpc_types_engine::OpPayloadAttributes;
|
||||
use reth_basic_payload_builder::*;
|
||||
use reth_chain_state::ExecutedBlock;
|
||||
use reth_chainspec::{ChainSpecProvider, EthereumHardforks};
|
||||
use reth_evm::{env::EvmEnv, system_calls::SystemCaller, ConfigureEvm, NextBlockEnvAttributes};
|
||||
use reth_evm::{
|
||||
env::EvmEnv, system_calls::SystemCaller, ConfigureEvm, Evm, NextBlockEnvAttributes,
|
||||
};
|
||||
use reth_execution_types::ExecutionOutcome;
|
||||
use reth_optimism_chainspec::OpChainSpec;
|
||||
use reth_optimism_consensus::calculate_receipt_root_no_memo_optimism;
|
||||
@ -777,9 +779,9 @@ where
|
||||
))
|
||||
})?;
|
||||
|
||||
*evm.tx_mut() = self.evm_config.tx_env(sequencer_tx.tx(), sequencer_tx.signer());
|
||||
let tx_env = self.evm_config.tx_env(sequencer_tx.tx(), sequencer_tx.signer());
|
||||
|
||||
let ResultAndState { result, state } = match evm.transact() {
|
||||
let ResultAndState { result, state } = match evm.transact(tx_env) {
|
||||
Ok(res) => res,
|
||||
Err(err) => {
|
||||
match err {
|
||||
@ -874,9 +876,9 @@ where
|
||||
}
|
||||
|
||||
// Configure the environment for the tx.
|
||||
*evm.tx_mut() = self.evm_config.tx_env(tx.tx(), tx.signer());
|
||||
let tx_env = self.evm_config.tx_env(tx.tx(), tx.signer());
|
||||
|
||||
let ResultAndState { result, state } = match evm.transact() {
|
||||
let ResultAndState { result, state } = match evm.transact(tx_env) {
|
||||
Ok(res) => res,
|
||||
Err(err) => {
|
||||
match err {
|
||||
|
||||
Reference in New Issue
Block a user