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:
@ -7,23 +7,23 @@ use alloy_consensus::BlockHeader;
|
||||
use alloy_eips::{eip4895::Withdrawal, eip7685::Requests};
|
||||
use alloy_sol_macro::sol;
|
||||
use alloy_sol_types::SolCall;
|
||||
#[cfg(feature = "optimism")]
|
||||
use reth::revm::primitives::OptimismFields;
|
||||
use reth::{
|
||||
api::{ConfigureEvm, NodeTypesWithEngine},
|
||||
builder::{components::ExecutorBuilder, BuilderContext, FullNodeTypes},
|
||||
cli::Cli,
|
||||
providers::ProviderError,
|
||||
revm::{
|
||||
interpreter::Host,
|
||||
primitives::{address, Address, Bytes, Env, TransactTo, TxEnv, U256},
|
||||
Database, DatabaseCommit, Evm, State,
|
||||
primitives::{address, Address},
|
||||
Database, DatabaseCommit, State,
|
||||
},
|
||||
};
|
||||
use reth_chainspec::{ChainSpec, EthereumHardforks};
|
||||
use reth_evm::execute::{
|
||||
BlockExecutionError, BlockExecutionStrategy, BlockExecutionStrategyFactory, ExecuteOutput,
|
||||
InternalBlockExecutionError,
|
||||
use reth_evm::{
|
||||
execute::{
|
||||
BlockExecutionError, BlockExecutionStrategy, BlockExecutionStrategyFactory, ExecuteOutput,
|
||||
InternalBlockExecutionError,
|
||||
},
|
||||
Evm,
|
||||
};
|
||||
use reth_evm_ethereum::EthEvmConfig;
|
||||
use reth_node_ethereum::{node::EthereumAddOns, BasicBlockExecutorProvider, EthereumNode};
|
||||
@ -177,19 +177,11 @@ sol!(
|
||||
|
||||
/// Applies the post-block call to the withdrawal / deposit contract, using the given block,
|
||||
/// [`ChainSpec`], EVM.
|
||||
pub fn apply_withdrawals_contract_call<EXT, DB: Database + DatabaseCommit>(
|
||||
pub fn apply_withdrawals_contract_call(
|
||||
withdrawals: &[Withdrawal],
|
||||
evm: &mut Evm<'_, EXT, DB>,
|
||||
) -> Result<(), BlockExecutionError>
|
||||
where
|
||||
DB::Error: std::fmt::Display,
|
||||
{
|
||||
// get previous env
|
||||
let previous_env = Box::new(evm.context.env().clone());
|
||||
|
||||
// modify env for pre block call
|
||||
fill_tx_env_with_system_contract_call(
|
||||
&mut evm.context.evm.env,
|
||||
evm: &mut impl Evm<Error: Display, DB: DatabaseCommit>,
|
||||
) -> Result<(), BlockExecutionError> {
|
||||
let mut state = match evm.transact_system_call(
|
||||
SYSTEM_ADDRESS,
|
||||
WITHDRAWALS_ADDRESS,
|
||||
withdrawalsCall {
|
||||
@ -198,12 +190,9 @@ where
|
||||
}
|
||||
.abi_encode()
|
||||
.into(),
|
||||
);
|
||||
|
||||
let mut state = match evm.transact() {
|
||||
) {
|
||||
Ok(res) => res.state,
|
||||
Err(e) => {
|
||||
evm.context.evm.env = previous_env;
|
||||
return Err(BlockExecutionError::Internal(InternalBlockExecutionError::Other(
|
||||
format!("withdrawal contract system call revert: {}", e).into(),
|
||||
)))
|
||||
@ -213,47 +202,8 @@ where
|
||||
// Clean-up post system tx context
|
||||
state.remove(&SYSTEM_ADDRESS);
|
||||
state.remove(&evm.block().coinbase);
|
||||
evm.context.evm.db.commit(state);
|
||||
// re-set the previous env
|
||||
evm.context.evm.env = previous_env;
|
||||
|
||||
evm.db_mut().commit(state);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn fill_tx_env_with_system_contract_call(
|
||||
env: &mut Env,
|
||||
caller: Address,
|
||||
contract: Address,
|
||||
data: Bytes,
|
||||
) {
|
||||
env.tx = TxEnv {
|
||||
caller,
|
||||
transact_to: TransactTo::Call(contract),
|
||||
// Explicitly set nonce to None so revm does not do any nonce checks
|
||||
nonce: None,
|
||||
gas_limit: 30_000_000,
|
||||
value: U256::ZERO,
|
||||
data,
|
||||
// Setting the gas price to zero enforces that no value is transferred as part of the call,
|
||||
// and that the call will not count against the block's gas limit
|
||||
gas_price: U256::ZERO,
|
||||
// The chain ID check is not relevant here and is disabled if set to None
|
||||
chain_id: None,
|
||||
// Setting the gas priority fee to None ensures the effective gas price is derived from the
|
||||
// `gas_price` field, which we need to be zero
|
||||
gas_priority_fee: None,
|
||||
access_list: Vec::new(),
|
||||
// blob fields can be None for this tx
|
||||
blob_hashes: Vec::new(),
|
||||
max_fee_per_blob_gas: None,
|
||||
authorization_list: None,
|
||||
#[cfg(feature = "optimism")]
|
||||
optimism: OptimismFields::default(),
|
||||
};
|
||||
|
||||
// ensure the block gas limit is >= the tx
|
||||
env.block.gas_limit = U256::from(env.tx.gas_limit);
|
||||
|
||||
// disable the base fee check for this call by setting the base fee to zero
|
||||
env.block.basefee = U256::ZERO;
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@ use reth::{
|
||||
inspector_handle_register,
|
||||
precompile::{Precompile, PrecompileOutput, PrecompileSpecId},
|
||||
primitives::{CfgEnvWithHandlerCfg, Env, PrecompileResult, TxEnv},
|
||||
ContextPrecompiles, Database, Evm, EvmBuilder, GetInspector,
|
||||
ContextPrecompiles, Database, EvmBuilder, GetInspector,
|
||||
},
|
||||
rpc::types::engine::PayloadAttributes,
|
||||
tasks::TaskManager,
|
||||
@ -24,7 +24,7 @@ use reth::{
|
||||
};
|
||||
use reth_chainspec::{Chain, ChainSpec};
|
||||
use reth_evm::env::EvmEnv;
|
||||
use reth_evm_ethereum::EthEvmConfig;
|
||||
use reth_evm_ethereum::{EthEvm, EthEvmConfig};
|
||||
use reth_node_api::{
|
||||
ConfigureEvm, ConfigureEvmEnv, FullNodeTypes, NextBlockEnvAttributes, NodeTypes,
|
||||
NodeTypesWithEngine, PayloadTypes,
|
||||
@ -93,16 +93,6 @@ impl ConfigureEvmEnv for MyEvmConfig {
|
||||
self.inner.fill_tx_env(tx_env, transaction, sender);
|
||||
}
|
||||
|
||||
fn fill_tx_env_system_contract_call(
|
||||
&self,
|
||||
env: &mut Env,
|
||||
caller: Address,
|
||||
contract: Address,
|
||||
data: Bytes,
|
||||
) {
|
||||
self.inner.fill_tx_env_system_contract_call(env, caller, contract, data);
|
||||
}
|
||||
|
||||
fn fill_cfg_env(&self, cfg_env: &mut CfgEnvWithHandlerCfg, header: &Self::Header) {
|
||||
self.inner.fill_cfg_env(cfg_env, header);
|
||||
}
|
||||
@ -117,7 +107,14 @@ impl ConfigureEvmEnv for MyEvmConfig {
|
||||
}
|
||||
|
||||
impl ConfigureEvm for MyEvmConfig {
|
||||
fn evm_with_env<DB: Database>(&self, db: DB, evm_env: EvmEnv, tx: TxEnv) -> Evm<'_, (), 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,
|
||||
tx: TxEnv,
|
||||
) -> Self::Evm<'_, DB, ()> {
|
||||
EvmBuilder::default()
|
||||
.with_db(db)
|
||||
.with_cfg_env_with_handler_cfg(evm_env.cfg_env_with_handler_cfg)
|
||||
@ -126,6 +123,7 @@ impl ConfigureEvm for MyEvmConfig {
|
||||
// add additional precompiles
|
||||
.append_handler_register(MyEvmConfig::set_precompiles)
|
||||
.build()
|
||||
.into()
|
||||
}
|
||||
|
||||
fn evm_with_env_and_inspector<DB, I>(
|
||||
@ -134,7 +132,7 @@ impl ConfigureEvm for MyEvmConfig {
|
||||
evm_env: EvmEnv,
|
||||
tx: TxEnv,
|
||||
inspector: I,
|
||||
) -> Evm<'_, I, DB>
|
||||
) -> Self::Evm<'_, DB, I>
|
||||
where
|
||||
DB: Database,
|
||||
I: GetInspector<DB>,
|
||||
@ -149,6 +147,7 @@ impl ConfigureEvm for MyEvmConfig {
|
||||
.append_handler_register(MyEvmConfig::set_precompiles)
|
||||
.append_handler_register(inspector_handle_register)
|
||||
.build()
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@ use reth::{
|
||||
primitives::{
|
||||
CfgEnvWithHandlerCfg, Env, PrecompileResult, SpecId, StatefulPrecompileMut, TxEnv,
|
||||
},
|
||||
ContextPrecompile, ContextPrecompiles, Database, Evm, EvmBuilder, GetInspector,
|
||||
ContextPrecompile, ContextPrecompiles, Database, EvmBuilder, GetInspector,
|
||||
},
|
||||
tasks::TaskManager,
|
||||
};
|
||||
@ -25,8 +25,8 @@ use reth_evm::env::EvmEnv;
|
||||
use reth_node_api::{ConfigureEvm, ConfigureEvmEnv, FullNodeTypes, NodeTypes};
|
||||
use reth_node_core::{args::RpcServerArgs, node_config::NodeConfig};
|
||||
use reth_node_ethereum::{
|
||||
node::EthereumAddOns, BasicBlockExecutorProvider, EthEvmConfig, EthExecutionStrategyFactory,
|
||||
EthereumNode,
|
||||
evm::EthEvm, node::EthereumAddOns, BasicBlockExecutorProvider, EthEvmConfig,
|
||||
EthExecutionStrategyFactory, EthereumNode,
|
||||
};
|
||||
use reth_primitives::{EthPrimitives, TransactionSigned};
|
||||
use reth_tracing::{RethTracer, Tracer};
|
||||
@ -155,16 +155,6 @@ impl ConfigureEvmEnv for MyEvmConfig {
|
||||
self.inner.fill_tx_env(tx_env, transaction, sender)
|
||||
}
|
||||
|
||||
fn fill_tx_env_system_contract_call(
|
||||
&self,
|
||||
env: &mut Env,
|
||||
caller: Address,
|
||||
contract: Address,
|
||||
data: Bytes,
|
||||
) {
|
||||
self.inner.fill_tx_env_system_contract_call(env, caller, contract, data)
|
||||
}
|
||||
|
||||
fn fill_cfg_env(&self, cfg_env: &mut CfgEnvWithHandlerCfg, header: &Self::Header) {
|
||||
self.inner.fill_cfg_env(cfg_env, header)
|
||||
}
|
||||
@ -179,7 +169,14 @@ impl ConfigureEvmEnv for MyEvmConfig {
|
||||
}
|
||||
|
||||
impl ConfigureEvm for MyEvmConfig {
|
||||
fn evm_with_env<DB: Database>(&self, db: DB, evm_env: EvmEnv, tx: TxEnv) -> Evm<'_, (), 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,
|
||||
tx: TxEnv,
|
||||
) -> Self::Evm<'_, DB, ()> {
|
||||
let new_cache = self.precompile_cache.clone();
|
||||
EvmBuilder::default()
|
||||
.with_db(db)
|
||||
@ -191,6 +188,7 @@ impl ConfigureEvm for MyEvmConfig {
|
||||
MyEvmConfig::set_precompiles(handler, new_cache.clone())
|
||||
}))
|
||||
.build()
|
||||
.into()
|
||||
}
|
||||
|
||||
fn evm_with_env_and_inspector<DB, I>(
|
||||
@ -199,7 +197,7 @@ impl ConfigureEvm for MyEvmConfig {
|
||||
evm_env: EvmEnv,
|
||||
tx: TxEnv,
|
||||
inspector: I,
|
||||
) -> Evm<'_, I, DB>
|
||||
) -> Self::Evm<'_, DB, I>
|
||||
where
|
||||
DB: Database,
|
||||
I: GetInspector<DB>,
|
||||
@ -217,6 +215,7 @@ impl ConfigureEvm for MyEvmConfig {
|
||||
}))
|
||||
.append_handler_register(inspector_handle_register)
|
||||
.build()
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user