mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat: generic TxEnv (#13957)
This commit is contained in:
@ -6,7 +6,6 @@ use crate::{
|
||||
execute::{BatchExecutor, BlockExecutorProvider, Executor},
|
||||
system_calls::OnStateHook,
|
||||
};
|
||||
use alloc::boxed::Box;
|
||||
use alloy_primitives::BlockNumber;
|
||||
use reth_prune_types::PruneModes;
|
||||
use reth_storage_errors::provider::ProviderError;
|
||||
@ -60,13 +59,6 @@ where
|
||||
type Output = A::Output;
|
||||
type Error = A::Error;
|
||||
|
||||
fn init(&mut self, tx_env_overrides: Box<dyn crate::TxEnvOverrides>) {
|
||||
match self {
|
||||
Self::Left(a) => a.init(tx_env_overrides),
|
||||
Self::Right(b) => b.init(tx_env_overrides),
|
||||
}
|
||||
}
|
||||
|
||||
fn execute(self, input: Self::Input<'_>) -> Result<Self::Output, Self::Error> {
|
||||
match self {
|
||||
Self::Left(a) => a.execute(input),
|
||||
|
||||
@ -8,7 +8,7 @@ pub use reth_execution_errors::{
|
||||
pub use reth_execution_types::{BlockExecutionOutput, ExecutionOutcome};
|
||||
pub use reth_storage_errors::provider::ProviderError;
|
||||
|
||||
use crate::{system_calls::OnStateHook, TxEnvOverrides};
|
||||
use crate::system_calls::OnStateHook;
|
||||
use alloc::{boxed::Box, vec::Vec};
|
||||
use alloy_eips::eip7685::Requests;
|
||||
use alloy_primitives::{
|
||||
@ -38,9 +38,6 @@ pub trait Executor<DB> {
|
||||
/// The error type returned by the executor.
|
||||
type Error;
|
||||
|
||||
/// Initialize the executor with the given transaction environment overrides.
|
||||
fn init(&mut self, _tx_env_overrides: Box<dyn TxEnvOverrides>) {}
|
||||
|
||||
/// Consumes the type and executes the block.
|
||||
///
|
||||
/// # Note
|
||||
@ -199,9 +196,6 @@ pub trait BlockExecutionStrategy {
|
||||
/// The error type returned by this strategy's methods.
|
||||
type Error: From<ProviderError> + core::error::Error;
|
||||
|
||||
/// Initialize the strategy with the given transaction environment overrides.
|
||||
fn init(&mut self, _tx_env_overrides: Box<dyn TxEnvOverrides>) {}
|
||||
|
||||
/// Applies any necessary changes before executing the block's transactions.
|
||||
fn apply_pre_execution_changes(
|
||||
&mut self,
|
||||
@ -341,10 +335,6 @@ where
|
||||
type Output = BlockExecutionOutput<<S::Primitives as NodePrimitives>::Receipt>;
|
||||
type Error = S::Error;
|
||||
|
||||
fn init(&mut self, env_overrides: Box<dyn TxEnvOverrides>) {
|
||||
self.strategy.init(env_overrides);
|
||||
}
|
||||
|
||||
fn execute(mut self, block: Self::Input<'_>) -> Result<Self::Output, Self::Error> {
|
||||
self.strategy.apply_pre_execution_changes(block)?;
|
||||
let ExecuteOutput { receipts, gas_used } = self.strategy.execute_transactions(block)?;
|
||||
@ -518,7 +508,7 @@ mod tests {
|
||||
use reth_chainspec::{ChainSpec, MAINNET};
|
||||
use reth_primitives::EthPrimitives;
|
||||
use revm::db::{CacheDB, EmptyDBTyped};
|
||||
use revm_primitives::{address, bytes, AccountInfo, TxEnv, KECCAK_EMPTY};
|
||||
use revm_primitives::{address, bytes, AccountInfo, KECCAK_EMPTY};
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
@ -734,29 +724,6 @@ mod tests {
|
||||
assert_eq!(block_execution_output.state, expected_finish_result);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tx_env_overrider() {
|
||||
let strategy_factory = TestExecutorStrategyFactory {
|
||||
execute_transactions_result: ExecuteOutput {
|
||||
receipts: vec![Receipt::default()],
|
||||
gas_used: 10,
|
||||
},
|
||||
apply_post_execution_changes_result: Requests::new(vec![bytes!("deadbeef")]),
|
||||
finish_result: BundleState::default(),
|
||||
};
|
||||
let provider = BasicBlockExecutorProvider::new(strategy_factory);
|
||||
let db = CacheDB::<EmptyDBTyped<ProviderError>>::default();
|
||||
|
||||
// if we want to apply tx env overrides the executor must be mut.
|
||||
let mut executor = provider.executor(db);
|
||||
// execute consumes the executor, so we can only call it once.
|
||||
executor.init(Box::new(|tx_env: &mut TxEnv| {
|
||||
tx_env.nonce.take();
|
||||
}));
|
||||
let result = executor.execute(&Default::default());
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
|
||||
fn setup_state_with_account(
|
||||
addr: Address,
|
||||
balance: u128,
|
||||
|
||||
@ -17,11 +17,16 @@
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
use core::fmt::Debug;
|
||||
|
||||
use alloy_consensus::BlockHeader as _;
|
||||
use alloy_eips::eip2930::AccessList;
|
||||
use alloy_primitives::{Address, Bytes, B256, U256};
|
||||
use reth_primitives_traits::{BlockHeader, SignedTransaction};
|
||||
use revm::{Database, DatabaseCommit, GetInspector};
|
||||
use revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg, EVMError, ResultAndState, SpecId, TxEnv};
|
||||
use revm_primitives::{
|
||||
BlockEnv, CfgEnvWithHandlerCfg, EVMError, ResultAndState, SpecId, TxEnv, TxKind,
|
||||
};
|
||||
|
||||
pub mod either;
|
||||
/// EVM environment configuration.
|
||||
@ -87,7 +92,11 @@ pub trait Evm {
|
||||
/// Trait for configuring the EVM for executing full blocks.
|
||||
pub trait ConfigureEvm: ConfigureEvmEnv {
|
||||
/// The EVM implementation.
|
||||
type Evm<'a, DB: Database + 'a, I: 'a>: Evm<Tx = TxEnv, DB = DB, Error = EVMError<DB::Error>>;
|
||||
type Evm<'a, DB: Database + 'a, I: 'a>: Evm<
|
||||
Tx = Self::TxEnv,
|
||||
DB = DB,
|
||||
Error = EVMError<DB::Error>,
|
||||
>;
|
||||
|
||||
/// Returns a new EVM with the given database configured with the given environment settings,
|
||||
/// including the spec id and transaction environment.
|
||||
@ -127,7 +136,7 @@ pub trait ConfigureEvm: ConfigureEvmEnv {
|
||||
impl<'b, T> ConfigureEvm for &'b T
|
||||
where
|
||||
T: ConfigureEvm,
|
||||
&'b T: ConfigureEvmEnv<Header = T::Header>,
|
||||
&'b T: ConfigureEvmEnv<Header = T::Header, TxEnv = T::TxEnv>,
|
||||
{
|
||||
type Evm<'a, DB: Database + 'a, I: 'a> = T::Evm<'a, DB, I>;
|
||||
|
||||
@ -165,18 +174,26 @@ pub trait ConfigureEvmEnv: Send + Sync + Unpin + Clone + 'static {
|
||||
/// The transaction type.
|
||||
type Transaction: SignedTransaction;
|
||||
|
||||
/// Transaction environment used by EVM.
|
||||
type TxEnv: TransactionEnv;
|
||||
|
||||
/// The error type that is returned by [`Self::next_cfg_and_block_env`].
|
||||
type Error: core::error::Error + Send + Sync;
|
||||
|
||||
/// Returns a [`TxEnv`] from a transaction and [`Address`].
|
||||
fn tx_env(&self, transaction: &Self::Transaction, signer: Address) -> TxEnv {
|
||||
let mut tx_env = TxEnv::default();
|
||||
fn tx_env(&self, transaction: &Self::Transaction, signer: Address) -> Self::TxEnv {
|
||||
let mut tx_env = Default::default();
|
||||
self.fill_tx_env(&mut tx_env, transaction, signer);
|
||||
tx_env
|
||||
}
|
||||
|
||||
/// Fill transaction environment from a transaction and the given sender address.
|
||||
fn fill_tx_env(&self, tx_env: &mut TxEnv, transaction: &Self::Transaction, sender: Address);
|
||||
fn fill_tx_env(
|
||||
&self,
|
||||
tx_env: &mut Self::TxEnv,
|
||||
transaction: &Self::Transaction,
|
||||
sender: Address,
|
||||
);
|
||||
|
||||
/// Returns a [`CfgEnvWithHandlerCfg`] for the given header.
|
||||
fn cfg_env(&self, header: &Self::Header) -> CfgEnvWithHandlerCfg {
|
||||
@ -262,17 +279,77 @@ pub struct NextBlockEnvAttributes {
|
||||
pub gas_limit: u64,
|
||||
}
|
||||
|
||||
/// Function hook that allows to modify a transaction environment.
|
||||
pub trait TxEnvOverrides {
|
||||
/// Apply the overrides by modifying the given `TxEnv`.
|
||||
fn apply(&mut self, env: &mut TxEnv);
|
||||
/// Abstraction over transaction environment.
|
||||
pub trait TransactionEnv:
|
||||
Into<revm_primitives::TxEnv> + Debug + Default + Clone + Send + Sync + 'static
|
||||
{
|
||||
/// Returns configured gas limit.
|
||||
fn gas_limit(&self) -> u64;
|
||||
|
||||
/// Set the gas limit.
|
||||
fn set_gas_limit(&mut self, gas_limit: u64);
|
||||
|
||||
/// Set the gas limit.
|
||||
fn with_gas_limit(mut self, gas_limit: u64) -> Self {
|
||||
self.set_gas_limit(gas_limit);
|
||||
self
|
||||
}
|
||||
|
||||
/// Returns configured gas price.
|
||||
fn gas_price(&self) -> U256;
|
||||
|
||||
/// Returns configured value.
|
||||
fn value(&self) -> U256;
|
||||
|
||||
/// Caller of the transaction.
|
||||
fn caller(&self) -> Address;
|
||||
|
||||
/// Set access list.
|
||||
fn set_access_list(&mut self, access_list: AccessList);
|
||||
|
||||
/// Set access list.
|
||||
fn with_access_list(mut self, access_list: AccessList) -> Self {
|
||||
self.set_access_list(access_list);
|
||||
self
|
||||
}
|
||||
|
||||
/// Returns calldata for the transaction.
|
||||
fn input(&self) -> &Bytes;
|
||||
|
||||
/// Returns [`TxKind`] of the transaction.
|
||||
fn kind(&self) -> TxKind;
|
||||
}
|
||||
|
||||
impl<F> TxEnvOverrides for F
|
||||
where
|
||||
F: FnMut(&mut TxEnv),
|
||||
{
|
||||
fn apply(&mut self, env: &mut TxEnv) {
|
||||
self(env)
|
||||
impl TransactionEnv for TxEnv {
|
||||
fn gas_limit(&self) -> u64 {
|
||||
self.gas_limit
|
||||
}
|
||||
|
||||
fn set_gas_limit(&mut self, gas_limit: u64) {
|
||||
self.gas_limit = gas_limit;
|
||||
}
|
||||
|
||||
fn gas_price(&self) -> U256 {
|
||||
self.gas_price.to()
|
||||
}
|
||||
|
||||
fn value(&self) -> U256 {
|
||||
self.value
|
||||
}
|
||||
|
||||
fn caller(&self) -> Address {
|
||||
self.caller
|
||||
}
|
||||
|
||||
fn set_access_list(&mut self, access_list: AccessList) {
|
||||
self.access_list = access_list.to_vec();
|
||||
}
|
||||
|
||||
fn input(&self) -> &Bytes {
|
||||
&self.data
|
||||
}
|
||||
|
||||
fn kind(&self) -> TxKind {
|
||||
self.transact_to
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user