mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
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:
@ -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
|
||||
|
||||
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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,
|
||||
&[],
|
||||
);
|
||||
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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>
|
||||
|
||||
Reference in New Issue
Block a user