feat: alloy-evm and new revm integration (#14021)

Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
Co-authored-by: rakita <rakita@users.noreply.github.com>
This commit is contained in:
Arsenii Kulikov
2025-02-17 23:59:23 +04:00
committed by GitHub
parent bb6dec7ceb
commit 336c3d1fac
142 changed files with 1841 additions and 1929 deletions

View File

@ -13,9 +13,9 @@ workspace = true
[dependencies]
# reth
revm.workspace = true
revm = { workspace = true, features = ["optional_block_gas_limit", "optional_eip3607", "optional_no_base_fee"] }
revm-inspectors.workspace = true
revm-primitives = { workspace = true, features = ["dev"] }
revm-primitives = { workspace = true }
reth-primitives-traits.workspace = true
reth-errors.workspace = true
reth-evm.workspace = true

View File

@ -3,8 +3,7 @@
use super::{LoadBlock, LoadPendingBlock, LoadState, LoadTransaction, SpawnBlocking, Trace};
use crate::{
helpers::estimate::EstimateCall, FromEthApiError, FromEvmError, FullEthApiTypes, RpcBlock,
RpcNodeCore,
helpers::estimate::EstimateCall, FromEvmError, FullEthApiTypes, RpcBlock, RpcNodeCore,
};
use alloy_consensus::BlockHeader;
use alloy_eips::{eip1559::calc_next_block_base_fee, eip2930::AccessListResult};
@ -18,16 +17,14 @@ use alloy_rpc_types_eth::{
use futures::Future;
use reth_chainspec::EthChainSpec;
use reth_errors::ProviderError;
use reth_evm::{env::EvmEnv, ConfigureEvm, ConfigureEvmEnv, Database, Evm, TransactionEnv};
use reth_evm::{
ConfigureEvm, ConfigureEvmEnv, Evm, EvmEnv, HaltReasonFor, InspectorFor, SpecFor,
TransactionEnv,
};
use reth_node_api::BlockBody;
use reth_primitives_traits::SignedTransaction;
use reth_provider::{BlockIdReader, ChainSpecProvider, ProviderHeader};
use reth_revm::{
database::StateProviderDatabase,
db::CacheDB,
primitives::{BlockEnv, ExecutionResult, ResultAndState},
DatabaseRef,
};
use reth_revm::{database::StateProviderDatabase, db::CacheDB, DatabaseRef};
use reth_rpc_eth_types::{
cache::db::{StateCacheDbRefMutWrapper, StateProviderTraitObjWrapper},
error::{api::FromEvmHalt, ensure_success},
@ -35,7 +32,13 @@ use reth_rpc_eth_types::{
simulate::{self, EthSimulateError},
EthApiError, RevertError, RpcInvalidTransactionError, StateCacheDb,
};
use revm::{DatabaseCommit, GetInspector};
use revm::{
context_interface::{
result::{ExecutionResult, ResultAndState},
Transaction,
},
Database, DatabaseCommit,
};
use revm_inspectors::{access_list::AccessListInspector, transfer::TransferInspector};
use tracing::trace;
@ -106,12 +109,12 @@ pub trait EthCall: EstimateCall + Call + LoadPendingBlock + LoadBlock + FullEthA
let chain_spec = RpcNodeCore::provider(&this).chain_spec();
while let Some(block) = block_state_calls.next() {
// Increase number and timestamp for every new block
evm_env.block_env.number += U256::from(1);
evm_env.block_env.timestamp += U256::from(1);
evm_env.block_env.number += 1;
evm_env.block_env.timestamp += 1;
if validation {
let base_fee_params = chain_spec
.base_fee_params_at_timestamp(evm_env.block_env.timestamp.to());
let base_fee_params =
chain_spec.base_fee_params_at_timestamp(evm_env.block_env.timestamp);
let base_fee = if let Some(latest) = blocks.last() {
let header = &latest.inner.header;
calc_next_block_base_fee(
@ -123,9 +126,9 @@ pub trait EthCall: EstimateCall + Call + LoadPendingBlock + LoadBlock + FullEthA
} else {
base_block.next_block_base_fee(base_fee_params).unwrap_or_default()
};
evm_env.block_env.basefee = U256::from(base_fee);
evm_env.block_env.basefee = base_fee;
} else {
evm_env.block_env.basefee = U256::ZERO;
evm_env.block_env.basefee = 0;
}
let SimBlock { block_overrides, state_overrides, calls } = block;
@ -137,7 +140,7 @@ pub trait EthCall: EstimateCall + Call + LoadPendingBlock + LoadBlock + FullEthA
apply_state_overrides(state_overrides, &mut db)?;
}
if (total_gas_limit - gas_used) < evm_env.block_env.gas_limit.to() {
if (total_gas_limit - gas_used) < evm_env.block_env.gas_limit {
return Err(
EthApiError::Other(Box::new(EthSimulateError::GasLimitReached)).into()
)
@ -148,7 +151,7 @@ pub trait EthCall: EstimateCall + Call + LoadPendingBlock + LoadBlock + FullEthA
let txs_without_gas_limit =
calls.iter().filter(|tx| tx.gas.is_none()).count();
if total_specified_gas > evm_env.block_env.gas_limit.to() {
if total_specified_gas > evm_env.block_env.gas_limit {
return Err(EthApiError::Other(Box::new(
EthSimulateError::BlockGasLimitExceeded,
))
@ -156,7 +159,7 @@ pub trait EthCall: EstimateCall + Call + LoadPendingBlock + LoadBlock + FullEthA
}
if txs_without_gas_limit > 0 {
(evm_env.block_env.gas_limit.to::<u64>() - total_specified_gas) /
(evm_env.block_env.gas_limit - total_specified_gas) /
txs_without_gas_limit as u64
} else {
0
@ -252,7 +255,7 @@ pub trait EthCall: EstimateCall + Call + LoadPendingBlock + LoadBlock + FullEthA
let (res, _env) =
self.transact_call_at(request, block_number.unwrap_or_default(), overrides).await?;
ensure_success(res.result).map_err(Self::Error::from_eth_err)
ensure_success(res.result)
}
}
@ -341,7 +344,7 @@ pub trait EthCall: EstimateCall + Call + LoadPendingBlock + LoadBlock + FullEthA
this.prepare_call_env(evm_env.clone(), tx, &mut db, overrides)?;
let (res, _) = this.transact(&mut db, evm_env, tx)?;
match ensure_success(res.result) {
match ensure_success::<_, Self::Error>(res.result) {
Ok(output) => {
results.push(EthCallResponse { value: Some(output), error: None });
}
@ -397,8 +400,9 @@ pub trait EthCall: EstimateCall + Call + LoadPendingBlock + LoadBlock + FullEthA
Self: Trace,
{
let state = self.state_at_block_id(at)?;
let mut db = CacheDB::new(StateProviderDatabase::new(state));
let mut tx_env = self.create_txn_env(&evm_env.block_env, request.clone())?;
let mut tx_env = self.create_txn_env(&evm_env, request.clone(), &mut db)?;
// 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>
@ -409,12 +413,10 @@ pub trait EthCall: EstimateCall + Call + LoadPendingBlock + LoadBlock + FullEthA
// <https://github.com/ethereum/go-ethereum/blob/8990c92aea01ca07801597b00c0d83d4e2d9b811/internal/ethapi/api.go#L1476-L1476>
evm_env.cfg_env.disable_base_fee = true;
let mut db = CacheDB::new(StateProviderDatabase::new(state));
if request.gas.is_none() && tx_env.gas_price() > U256::ZERO {
if request.gas.is_none() && tx_env.gas_price() > 0 {
let cap = caller_gas_allowance(&mut db, &tx_env)?;
// no gas limit was provided in the request, so we need to cap the request's gas limit
tx_env.set_gas_limit(cap.min(evm_env.block_env.gas_limit).saturating_to());
tx_env.set_gas_limit(cap.min(evm_env.block_env.gas_limit));
}
// can consume the list since we're not using the request anymore
@ -494,7 +496,7 @@ pub trait Call:
tx_env: <Self::Evm as ConfigureEvmEnv>::TxEnv,
) -> Result<
(
ResultAndState,
ResultAndState<HaltReasonFor<Self::Evm>>,
(EvmEnv<<Self::Evm as ConfigureEvmEnv>::Spec>, <Self::Evm as ConfigureEvmEnv>::TxEnv),
),
Self::Error,
@ -511,21 +513,22 @@ pub trait Call:
/// Executes the [`EvmEnv`] against the given [Database] without committing state
/// changes.
#[expect(clippy::type_complexity)]
fn transact_with_inspector<DB>(
fn transact_with_inspector<DB, I>(
&self,
db: DB,
evm_env: EvmEnv<<Self::Evm as ConfigureEvmEnv>::Spec>,
tx_env: <Self::Evm as ConfigureEvmEnv>::TxEnv,
inspector: impl GetInspector<DB>,
inspector: I,
) -> Result<
(
ResultAndState,
ResultAndState<HaltReasonFor<Self::Evm>>,
(EvmEnv<<Self::Evm as ConfigureEvmEnv>::Spec>, <Self::Evm as ConfigureEvmEnv>::TxEnv),
),
Self::Error,
>
where
DB: Database<Error = ProviderError>,
I: InspectorFor<DB, Self::Evm>,
{
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)?;
@ -543,7 +546,7 @@ pub trait Call:
) -> impl Future<
Output = Result<
(
ResultAndState,
ResultAndState<HaltReasonFor<Self::Evm>>,
(
EvmEnv<<Self::Evm as ConfigureEvmEnv>::Spec>,
<Self::Evm as ConfigureEvmEnv>::TxEnv,
@ -643,7 +646,11 @@ pub trait Call:
) -> impl Future<Output = Result<Option<R>, Self::Error>> + Send
where
Self: LoadBlock + LoadTransaction,
F: FnOnce(TransactionInfo, ResultAndState, StateCacheDb<'_>) -> Result<R, Self::Error>
F: FnOnce(
TransactionInfo,
ResultAndState<HaltReasonFor<Self::Evm>>,
StateCacheDb<'_>,
) -> Result<R, Self::Error>
+ Send
+ 'static,
R: Send + 'static,
@ -716,11 +723,12 @@ pub trait Call:
/// Configures a new `TxEnv` for the [`TransactionRequest`]
///
/// All `TxEnv` fields are derived from the given [`TransactionRequest`], if fields are
/// `None`, they fall back to the [`BlockEnv`]'s settings.
/// `None`, they fall back to the [`EvmEnv`]'s settings.
fn create_txn_env(
&self,
block_env: &BlockEnv,
evm_env: &EvmEnv<SpecFor<Self::Evm>>,
request: TransactionRequest,
db: impl Database<Error: Into<EthApiError>>,
) -> Result<<Self::Evm as ConfigureEvmEnv>::TxEnv, Self::Error>;
/// Prepares the [`EvmEnv`] for execution of calls.
@ -759,7 +767,7 @@ pub trait Call:
}
// apply configured gas cap
evm_env.block_env.gas_limit = U256::from(self.call_gas_limit());
evm_env.block_env.gas_limit = self.call_gas_limit();
// Disabled because eth_call is sometimes used with eoa senders
// See <https://github.com/paradigmxyz/reth/issues/1959>
@ -781,16 +789,16 @@ pub trait Call:
}
let request_gas = request.gas;
let mut tx_env = self.create_txn_env(&evm_env.block_env, request)?;
let mut tx_env = self.create_txn_env(&evm_env, request, &mut *db)?;
if request_gas.is_none() {
// No gas limit was provided in the request, so we need to cap the transaction gas limit
if tx_env.gas_price() > U256::ZERO {
if tx_env.gas_price() > 0 {
// If gas price is specified, cap transaction gas limit with caller allowance
trace!(target: "rpc::eth::call", ?tx_env, "Applying gas limit cap with caller allowance");
let cap = caller_gas_allowance(db, &tx_env)?;
// ensure we cap gas_limit to the block's
tx_env.set_gas_limit(cap.min(evm_env.block_env.gas_limit).saturating_to());
tx_env.set_gas_limit(cap.min(evm_env.block_env.gas_limit));
}
}

View File

@ -7,15 +7,16 @@ use alloy_rpc_types_eth::{state::StateOverride, transaction::TransactionRequest,
use futures::Future;
use reth_chainspec::MIN_TRANSACTION_GAS;
use reth_errors::ProviderError;
use reth_evm::{env::EvmEnv, ConfigureEvmEnv, Database, TransactionEnv};
use reth_evm::{ConfigureEvmEnv, Database, EvmEnv, TransactionEnv};
use reth_provider::StateProvider;
use reth_revm::{database::StateProviderDatabase, db::CacheDB, primitives::ExecutionResult};
use reth_revm::{database::StateProviderDatabase, db::CacheDB};
use reth_rpc_eth_types::{
error::api::FromEvmHalt,
revm_utils::{apply_state_overrides, caller_gas_allowance},
EthApiError, RevertError, RpcInvalidTransactionError,
};
use reth_rpc_server_types::constants::gas_oracle::{CALL_STIPEND_GAS, ESTIMATE_GAS_ERROR_RATIO};
use revm::context_interface::{result::ExecutionResult, Transaction};
use revm_primitives::TxKind;
use tracing::trace;
@ -55,7 +56,7 @@ pub trait EstimateCall: Call {
request.nonce = None;
// Keep a copy of gas related request values
let tx_request_gas_limit = request.gas.map(U256::from);
let tx_request_gas_limit = request.gas;
let tx_request_gas_price = request.gas_price;
// the gas limit of the corresponding block
let block_env_gas_limit = evm_env.block_env.gas_limit;
@ -73,8 +74,8 @@ pub trait EstimateCall: Call {
.unwrap_or(block_env_gas_limit);
// Configure the evm env
let mut tx_env = self.create_txn_env(&evm_env.block_env, request)?;
let mut db = CacheDB::new(StateProviderDatabase::new(state));
let mut tx_env = self.create_txn_env(&evm_env, request, &mut db)?;
// Apply any state overrides if specified.
if let Some(state_override) = state_override {
@ -107,15 +108,12 @@ pub trait EstimateCall: Call {
// Check funds of the sender (only useful to check if transaction gas price is more than 0).
//
// The caller allowance is check by doing `(account.balance - tx.value) / tx.gas_price`
if tx_env.gas_price() > U256::ZERO {
if tx_env.gas_price() > 0 {
// cap the highest gas limit by max gas caller can afford with given gas price
highest_gas_limit = highest_gas_limit
.min(caller_gas_allowance(&mut db, &tx_env).map_err(Self::Error::from_eth_err)?);
}
// We can now normalize the highest gas limit to a u64
let mut highest_gas_limit = highest_gas_limit.saturating_to::<u64>();
// If the provided gas limit is less than computed cap, use that
tx_env.set_gas_limit(tx_env.gas_limit().min(highest_gas_limit));
@ -288,7 +286,7 @@ pub trait EstimateCall: Call {
#[inline]
fn map_out_of_gas_err<DB>(
&self,
env_gas_limit: U256,
env_gas_limit: u64,
evm_env: EvmEnv<<Self::Evm as ConfigureEvmEnv>::Spec>,
mut tx_env: <Self::Evm as ConfigureEvmEnv>::TxEnv,
db: &mut DB,
@ -298,7 +296,7 @@ pub trait EstimateCall: Call {
EthApiError: From<DB::Error>,
{
let req_gas_limit = tx_env.gas_limit();
tx_env.set_gas_limit(env_gas_limit.try_into().unwrap_or(u64::MAX));
tx_env.set_gas_limit(env_gas_limit);
let (res, _) = match self.transact(db, evm_env, tx_env) {
Ok(res) => res,
Err(err) => return err,
@ -314,7 +312,7 @@ pub trait EstimateCall: Call {
RpcInvalidTransactionError::Revert(RevertError::new(output)).into_eth_err()
}
ExecutionResult::Halt { reason, .. } => {
RpcInvalidTransactionError::EvmHalt(reason).into_eth_err()
Self::Error::from_evm_halt(reason, req_gas_limit)
}
}
}
@ -326,8 +324,8 @@ pub trait EstimateCall: Call {
/// gas limit for a transaction. It adjusts the highest or lowest gas limits depending on
/// whether the execution succeeded, reverted, or halted due to specific reasons.
#[inline]
pub fn update_estimated_gas_range(
result: ExecutionResult,
pub fn update_estimated_gas_range<Halt>(
result: ExecutionResult<Halt>,
tx_gas_limit: u64,
highest_gas_limit: &mut u64,
lowest_gas_limit: &mut u64,

View File

@ -11,8 +11,8 @@ use futures::Future;
use reth_chainspec::{EthChainSpec, EthereumHardforks};
use reth_errors::RethError;
use reth_evm::{
env::EvmEnv, state_change::post_block_withdrawals_balance_increments,
system_calls::SystemCaller, ConfigureEvm, ConfigureEvmEnv, Evm, EvmError, InvalidTxError,
state_change::post_block_withdrawals_balance_increments, system_calls::SystemCaller,
ConfigureEvm, ConfigureEvmEnv, Evm, EvmEnv, EvmError, HaltReasonFor, InvalidTxError,
NextBlockEnvAttributes,
};
use reth_primitives::{InvalidTransactionError, RecoveredBlock};
@ -23,14 +23,21 @@ use reth_provider::{
};
use reth_revm::{
database::StateProviderDatabase,
primitives::{BlockEnv, ExecutionResult, ResultAndState},
db::{states::bundle_state::BundleRetention, State},
};
use reth_rpc_eth_types::{EthApiError, PendingBlock, PendingBlockEnv, PendingBlockEnvOrigin};
use reth_transaction_pool::{
error::InvalidPoolTransactionError, BestTransactionsAttributes, PoolTransaction,
TransactionPool,
};
use revm::{db::states::bundle_state::BundleRetention, DatabaseCommit, State};
use revm::{
context::BlockEnv,
context_interface::{
result::{ExecutionResult, ResultAndState},
Block,
},
DatabaseCommit,
};
use std::time::{Duration, Instant};
use tokio::sync::Mutex;
use tracing::debug;
@ -155,7 +162,7 @@ pub trait LoadPendingBlock:
// check if the block is still good
if let Some(pending_block) = lock.as_ref() {
// this is guaranteed to be the `latest` header
if pending.evm_env.block_env.number.to::<u64>() == pending_block.block.number() &&
if pending.evm_env.block_env.number == pending_block.block.number() &&
parent_hash == pending_block.block.parent_hash() &&
now <= pending_block.expires_at
{
@ -193,7 +200,7 @@ pub trait LoadPendingBlock:
fn assemble_receipt(
&self,
tx: &ProviderTx<Self::Provider>,
result: ExecutionResult,
result: ExecutionResult<HaltReasonFor<Self::Evm>>,
cumulative_gas_used: u64,
) -> ProviderReceipt<Self::Provider>;
@ -214,7 +221,7 @@ pub trait LoadPendingBlock:
parent_hash: B256,
state_root: B256,
transactions: Vec<ProviderTx<Self::Provider>>,
results: Vec<ExecutionResult>,
results: Vec<ExecutionResult<HaltReasonFor<Self::Evm>>>,
) -> (ProviderBlock<Self::Provider>, Vec<ProviderReceipt<Self::Provider>>) {
let mut cumulative_gas_used = 0;
let mut receipts = Vec::with_capacity(results.len());
@ -257,15 +264,15 @@ pub trait LoadPendingBlock:
let mut cumulative_gas_used = 0;
let mut sum_blob_gas_used = 0;
let block_gas_limit: u64 = evm_env.block_env.gas_limit.to::<u64>();
let base_fee = evm_env.block_env.basefee.to::<u64>();
let block_gas_limit: u64 = evm_env.block_env.gas_limit;
let base_fee = evm_env.block_env.basefee;
let mut executed_txs = Vec::new();
let mut senders = Vec::new();
let mut best_txs =
self.pool().best_transactions_with_attributes(BestTransactionsAttributes::new(
base_fee,
evm_env.block_env.get_blob_gasprice().map(|gasprice| gasprice as u64),
evm_env.block_env.blob_gasprice().map(|gasprice| gasprice as u64),
));
let chain_spec = self.provider().chain_spec();
@ -384,7 +391,7 @@ pub trait LoadPendingBlock:
// executes the withdrawals and commits them to the Database and BundleState.
let balance_increments = post_block_withdrawals_balance_increments(
chain_spec.as_ref(),
evm_env.block_env.timestamp.try_into().unwrap_or(u64::MAX),
evm_env.block_env.timestamp,
&[],
);

View File

@ -10,7 +10,7 @@ use alloy_serde::JsonStorageKey;
use futures::Future;
use reth_chainspec::{EthChainSpec, EthereumHardforks};
use reth_errors::RethError;
use reth_evm::{env::EvmEnv, ConfigureEvmEnv};
use reth_evm::{ConfigureEvmEnv, EvmEnv};
use reth_provider::{
BlockIdReader, BlockNumReader, ChainSpecProvider, StateProvider, StateProviderBox,
StateProviderFactory,

View File

@ -9,20 +9,24 @@ use futures::Future;
use reth_chainspec::ChainSpecProvider;
use reth_errors::ProviderError;
use reth_evm::{
env::EvmEnv, system_calls::SystemCaller, ConfigureEvm, ConfigureEvmEnv, Database, Evm,
system_calls::SystemCaller, ConfigureEvm, ConfigureEvmEnv, Database, Evm, EvmEnv,
HaltReasonFor, InspectorFor,
};
use reth_primitives::RecoveredBlock;
use reth_primitives_traits::{BlockBody, SignedTransaction};
use reth_provider::{BlockReader, ProviderBlock, ProviderHeader, ProviderTx};
use reth_revm::database::StateProviderDatabase;
use reth_revm::{database::StateProviderDatabase, db::CacheDB};
use reth_rpc_eth_types::{
cache::db::{StateCacheDb, StateCacheDbRefMutWrapper, StateProviderTraitObjWrapper},
EthApiError,
};
use revm::{db::CacheDB, DatabaseCommit, GetInspector, Inspector};
use revm::{
context_interface::result::{ExecutionResult, ResultAndState},
state::EvmState,
DatabaseCommit,
};
use revm_inspectors::tracing::{TracingInspector, TracingInspectorConfig};
use revm_primitives::{EvmState, ExecutionResult, ResultAndState};
use std::{fmt::Display, sync::Arc};
use std::sync::Arc;
/// Executes CPU heavy tasks.
pub trait Trace:
@ -46,14 +50,14 @@ pub trait Trace:
inspector: I,
) -> Result<
(
ResultAndState,
ResultAndState<HaltReasonFor<Self::Evm>>,
(EvmEnv<<Self::Evm as ConfigureEvmEnv>::Spec>, <Self::Evm as ConfigureEvmEnv>::TxEnv),
),
Self::Error,
>
where
DB: Database<Error = ProviderError>,
I: GetInspector<DB>,
I: InspectorFor<DB, Self::Evm>,
{
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)?;
@ -77,7 +81,10 @@ pub trait Trace:
) -> Result<R, Self::Error>
where
Self: Call,
F: FnOnce(TracingInspector, ResultAndState) -> Result<R, Self::Error>,
F: FnOnce(
TracingInspector,
ResultAndState<HaltReasonFor<Self::Evm>>,
) -> Result<R, Self::Error>,
{
self.with_state_at_block(at, |state| {
let mut db = CacheDB::new(StateProviderDatabase::new(state));
@ -104,7 +111,11 @@ pub trait Trace:
) -> impl Future<Output = Result<R, Self::Error>> + Send
where
Self: LoadPendingBlock + Call,
F: FnOnce(TracingInspector, ResultAndState, StateCacheDb<'_>) -> Result<R, Self::Error>
F: FnOnce(
TracingInspector,
ResultAndState<HaltReasonFor<Self::Evm>>,
StateCacheDb<'_>,
) -> Result<R, Self::Error>
+ Send
+ 'static,
R: Send + 'static,
@ -138,7 +149,7 @@ pub trait Trace:
F: FnOnce(
TransactionInfo,
TracingInspector,
ResultAndState,
ResultAndState<HaltReasonFor<Self::Evm>>,
StateCacheDb<'_>,
) -> Result<R, Self::Error>
+ Send
@ -168,12 +179,13 @@ pub trait Trace:
F: FnOnce(
TransactionInfo,
Insp,
ResultAndState,
ResultAndState<HaltReasonFor<Self::Evm>>,
StateCacheDb<'_>,
) -> Result<R, Self::Error>
+ Send
+ 'static,
Insp: for<'a, 'b> Inspector<StateCacheDbRefMutWrapper<'a, 'b>> + Send + 'static,
Insp:
for<'a, 'b> InspectorFor<StateCacheDbRefMutWrapper<'a, 'b>, Self::Evm> + Send + 'static,
R: Send + 'static,
{
async move {
@ -232,7 +244,7 @@ pub trait Trace:
F: Fn(
TransactionInfo,
TracingInspector,
ExecutionResult,
ExecutionResult<HaltReasonFor<Self::Evm>>,
&EvmState,
&StateCacheDb<'_>,
) -> Result<R, Self::Error>
@ -272,14 +284,15 @@ pub trait Trace:
F: Fn(
TransactionInfo,
Insp,
ExecutionResult,
ExecutionResult<HaltReasonFor<Self::Evm>>,
&EvmState,
&StateCacheDb<'_>,
) -> Result<R, Self::Error>
+ Send
+ 'static,
Setup: FnMut() -> Insp + Send + 'static,
Insp: for<'a, 'b> Inspector<StateCacheDbRefMutWrapper<'a, 'b>> + Send + 'static,
Insp:
for<'a, 'b> InspectorFor<StateCacheDbRefMutWrapper<'a, 'b>, Self::Evm> + Send + 'static,
R: Send + 'static,
{
async move {
@ -306,8 +319,8 @@ pub trait Trace:
let state_at = block.parent_hash();
let block_hash = block.hash();
let block_number = evm_env.block_env.number.saturating_to::<u64>();
let base_fee = evm_env.block_env.basefee.saturating_to::<u64>();
let block_number = evm_env.block_env.number;
let base_fee = evm_env.block_env.basefee;
// now get the state
let state = this.state_at_block_id(state_at.into())?;
@ -391,7 +404,7 @@ pub trait Trace:
F: Fn(
TransactionInfo,
TracingInspector,
ExecutionResult,
ExecutionResult<HaltReasonFor<Self::Evm>>,
&EvmState,
&StateCacheDb<'_>,
) -> Result<R, Self::Error>
@ -430,14 +443,15 @@ pub trait Trace:
F: Fn(
TransactionInfo,
Insp,
ExecutionResult,
ExecutionResult<HaltReasonFor<Self::Evm>>,
&EvmState,
&StateCacheDb<'_>,
) -> Result<R, Self::Error>
+ Send
+ 'static,
Setup: FnMut() -> Insp + Send + 'static,
Insp: for<'a, 'b> Inspector<StateCacheDbRefMutWrapper<'a, 'b>> + Send + 'static,
Insp:
for<'a, 'b> InspectorFor<StateCacheDbRefMutWrapper<'a, 'b>, Self::Evm> + Send + 'static,
R: Send + 'static,
{
self.trace_block_until_with_inspector(block_id, block, None, insp_setup, f)
@ -448,7 +462,7 @@ pub trait Trace:
/// Note: This should only be called when tracing an entire block vs individual transactions.
/// When tracing transaction on top of an already committed block state, those transitions are
/// already applied.
fn apply_pre_execution_changes<DB: Send + Database<Error: Display> + DatabaseCommit>(
fn apply_pre_execution_changes<DB: Send + Database + DatabaseCommit>(
&self,
block: &RecoveredBlock<ProviderBlock<Self::Provider>>,
db: &mut DB,

View File

@ -38,8 +38,7 @@ use std::sync::Arc;
/// There are subtle differences between when transacting [`TransactionRequest`]:
///
/// The endpoints `eth_call` and `eth_estimateGas` and `eth_createAccessList` should always
/// __disable__ the base fee check in the
/// [`EnvWithHandlerCfg`](revm_primitives::CfgEnvWithHandlerCfg).
/// __disable__ the base fee check in the [`CfgEnv`](revm::context::CfgEnv).
///
/// The behaviour for tracing endpoints is not consistent across clients.
/// Geth also disables the basefee check for tracing: <https://github.com/ethereum/go-ethereum/blob/bc0b87ca196f92e5af49bd33cc190ef0ec32b197/eth/tracers/api.go#L955-L955>