feat: abstract over Evm::Error (#14085)

Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
Arsenii Kulikov
2025-01-30 17:02:20 +04:00
committed by GitHub
parent 6b13409812
commit 98a021ee7d
40 changed files with 298 additions and 247 deletions

View File

@ -17,7 +17,8 @@ use alloy_rpc_types_eth::{
};
use futures::Future;
use reth_chainspec::EthChainSpec;
use reth_evm::{env::EvmEnv, ConfigureEvm, ConfigureEvmEnv, Evm, TransactionEnv};
use reth_errors::ProviderError;
use reth_evm::{env::EvmEnv, ConfigureEvm, ConfigureEvmEnv, Database, Evm, TransactionEnv};
use reth_node_api::BlockBody;
use reth_primitives_traits::SignedTransaction;
use reth_provider::{BlockIdReader, ChainSpecProvider, ProviderHeader};
@ -36,7 +37,7 @@ use reth_rpc_eth_types::{
simulate::{self, EthSimulateError},
EthApiError, RevertError, RpcInvalidTransactionError, StateCacheDb,
};
use revm::{Database, DatabaseCommit, GetInspector};
use revm::{DatabaseCommit, GetInspector};
use revm_inspectors::{access_list::AccessListInspector, transfer::TransferInspector};
use tracing::trace;
@ -473,7 +474,10 @@ pub trait EthCall: EstimateCall + Call + LoadPendingBlock + LoadBlock + FullEthA
/// Executes code on state.
pub trait Call:
LoadState<Evm: ConfigureEvm<Header = ProviderHeader<Self::Provider>>> + SpawnBlocking
LoadState<
Evm: ConfigureEvm<Header = ProviderHeader<Self::Provider>>,
Error: FromEvmError<Self::Evm>,
> + SpawnBlocking
{
/// Returns default gas limit to use for `eth_call` and tracing RPC methods.
///
@ -508,8 +512,7 @@ pub trait Call:
Self::Error,
>
where
DB: Database,
EthApiError: From<DB::Error>,
DB: Database<Error = ProviderError>,
{
let mut evm = self.evm_config().evm_with_env(db, evm_env.clone());
let res = evm.transact(tx_env.clone()).map_err(Self::Error::from_evm_err)?;
@ -534,8 +537,7 @@ pub trait Call:
Self::Error,
>
where
DB: Database,
EthApiError: From<DB::Error>,
DB: Database<Error = ProviderError>,
{
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)?;
@ -704,8 +706,7 @@ pub trait Call:
target_tx_hash: B256,
) -> Result<usize, Self::Error>
where
DB: Database + DatabaseCommit,
EthApiError: From<DB::Error>,
DB: Database<Error = ProviderError> + DatabaseCommit,
I: IntoIterator<Item = (&'a Address, &'a <Self::Evm as ConfigureEvmEnv>::Transaction)>,
<Self::Evm as ConfigureEvmEnv>::Transaction: SignedTransaction,
{

View File

@ -6,7 +6,8 @@ use alloy_primitives::U256;
use alloy_rpc_types_eth::{state::StateOverride, transaction::TransactionRequest, BlockId};
use futures::Future;
use reth_chainspec::MIN_TRANSACTION_GAS;
use reth_evm::{env::EvmEnv, ConfigureEvmEnv, TransactionEnv};
use reth_errors::ProviderError;
use reth_evm::{env::EvmEnv, ConfigureEvmEnv, Database, TransactionEnv};
use reth_provider::StateProvider;
use reth_revm::{
database::StateProviderDatabase,
@ -18,7 +19,7 @@ use reth_rpc_eth_types::{
EthApiError, RevertError, RpcInvalidTransactionError,
};
use reth_rpc_server_types::constants::gas_oracle::{CALL_STIPEND_GAS, ESTIMATE_GAS_ERROR_RATIO};
use revm_primitives::{db::Database, TxKind};
use revm_primitives::TxKind;
use tracing::trace;
/// Gas execution estimates
@ -286,7 +287,7 @@ pub trait EstimateCall: Call {
db: &mut DB,
) -> Self::Error
where
DB: Database,
DB: Database<Error = ProviderError>,
EthApiError: From<DB::Error>,
{
let req_gas_limit = tx_env.gas_limit();

View File

@ -13,7 +13,8 @@ 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, NextBlockEnvAttributes,
system_calls::SystemCaller, ConfigureEvm, ConfigureEvmEnv, Evm, EvmError, InvalidTxError,
NextBlockEnvAttributes,
};
use reth_primitives::{InvalidTransactionError, RecoveredBlock};
use reth_primitives_traits::Receipt;
@ -23,7 +24,7 @@ use reth_provider::{
};
use reth_revm::{
database::StateProviderDatabase,
primitives::{BlockEnv, EVMError, ExecutionResult, InvalidTransaction, ResultAndState},
primitives::{BlockEnv, ExecutionResult, ResultAndState},
};
use reth_rpc_eth_types::{EthApiError, PendingBlock, PendingBlockEnv, PendingBlockEnvOrigin};
use reth_transaction_pool::{
@ -43,6 +44,7 @@ pub trait LoadPendingBlock:
NetworkTypes: Network<
HeaderResponse = alloy_rpc_types_eth::Header<ProviderHeader<Self::Provider>>,
>,
Error: FromEvmError<Self::Evm>,
> + RpcNodeCore<
Provider: BlockReaderIdExt<Receipt: Receipt>
+ ChainSpecProvider<ChainSpec: EthChainSpec + EthereumHardforks>
@ -334,27 +336,23 @@ pub trait LoadPendingBlock:
let ResultAndState { result, state } = match evm.transact(tx_env) {
Ok(res) => res,
Err(err) => {
match err {
EVMError::Transaction(err) => {
if matches!(err, InvalidTransaction::NonceTooLow { .. }) {
// if the nonce is too low, we can skip this transaction
} else {
// if the transaction is invalid, we can skip it and all of its
// descendants
best_txs.mark_invalid(
&pool_tx,
InvalidPoolTransactionError::Consensus(
InvalidTransactionError::TxTypeNotSupported,
),
);
}
continue
}
err => {
// this is an error that we should treat as fatal for this attempt
return Err(Self::Error::from_evm_err(err))
if let Some(err) = err.as_invalid_tx_err() {
if err.is_nonce_too_low() {
// if the nonce is too low, we can skip this transaction
} else {
// if the transaction is invalid, we can skip it and all of its
// descendants
best_txs.mark_invalid(
&pool_tx,
InvalidPoolTransactionError::Consensus(
InvalidTransactionError::TxTypeNotSupported,
),
);
}
continue
}
// this is an error that we should treat as fatal for this attempt
return Err(Self::Error::from_evm_err(err));
}
};
// drop evm to release db reference.

View File

@ -7,7 +7,10 @@ use alloy_primitives::B256;
use alloy_rpc_types_eth::{BlockId, TransactionInfo};
use futures::Future;
use reth_chainspec::ChainSpecProvider;
use reth_evm::{env::EvmEnv, system_calls::SystemCaller, ConfigureEvm, ConfigureEvmEnv, Evm};
use reth_errors::ProviderError;
use reth_evm::{
env::EvmEnv, system_calls::SystemCaller, ConfigureEvm, ConfigureEvmEnv, Database, Evm,
};
use reth_primitives::RecoveredBlock;
use reth_primitives_traits::{BlockBody, SignedTransaction};
use reth_provider::{BlockReader, ProviderBlock, ProviderHeader, ProviderTx};
@ -16,7 +19,7 @@ use reth_rpc_eth_types::{
cache::db::{StateCacheDb, StateCacheDbRefMutWrapper, StateProviderTraitObjWrapper},
EthApiError,
};
use revm::{db::CacheDB, Database, DatabaseCommit, GetInspector, Inspector};
use revm::{db::CacheDB, DatabaseCommit, GetInspector, Inspector};
use revm_inspectors::tracing::{TracingInspector, TracingInspectorConfig};
use revm_primitives::{EvmState, ExecutionResult, ResultAndState};
use std::{fmt::Display, sync::Arc};
@ -29,6 +32,7 @@ pub trait Trace:
Header = ProviderHeader<Self::Provider>,
Transaction = ProviderTx<Self::Provider>,
>,
Error: FromEvmError<Self::Evm>,
>
{
/// Executes the [`EvmEnv`] against the given [Database] without committing state
@ -48,8 +52,7 @@ pub trait Trace:
Self::Error,
>
where
DB: Database,
EthApiError: From<DB::Error>,
DB: Database<Error = ProviderError>,
I: GetInspector<DB>,
{
let mut evm = self.evm_config().evm_with_env_and_inspector(db, evm_env.clone(), inspector);

View File

@ -11,7 +11,7 @@ use reth_provider::{ProviderTx, ReceiptProvider, TransactionsProvider};
use reth_rpc_types_compat::TransactionCompat;
use reth_transaction_pool::{PoolTransaction, TransactionPool};
use crate::{AsEthApiError, FromEthApiError, FromEvmError, RpcNodeCore};
use crate::{AsEthApiError, FromEthApiError, RpcNodeCore};
/// Network specific `eth` API types.
pub trait EthApiTypes: Send + Sync + Clone {
@ -19,7 +19,6 @@ pub trait EthApiTypes: Send + Sync + Clone {
type Error: Into<jsonrpsee_types::error::ErrorObject<'static>>
+ FromEthApiError
+ AsEthApiError
+ FromEvmError
+ Error
+ Send
+ Sync;