mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat: abstract over Evm::Error (#14085)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
@ -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,
|
||||
{
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
//! Helper traits to wrap generic l1 errors, in network specific error type configured in
|
||||
//! `reth_rpc_eth_api::EthApiTypes`.
|
||||
|
||||
use revm_primitives::EVMError;
|
||||
use reth_errors::ProviderError;
|
||||
use reth_evm::ConfigureEvm;
|
||||
|
||||
use crate::EthApiError;
|
||||
|
||||
@ -79,21 +80,16 @@ impl AsEthApiError for EthApiError {
|
||||
}
|
||||
|
||||
/// Helper trait to convert from revm errors.
|
||||
pub trait FromEvmError: From<EthApiError> {
|
||||
/// Converts from a revm error.
|
||||
fn from_evm_err<E>(err: EVMError<E>) -> Self
|
||||
where
|
||||
EthApiError: From<E>;
|
||||
}
|
||||
|
||||
impl<T> FromEvmError for T
|
||||
where
|
||||
T: From<EthApiError>,
|
||||
{
|
||||
fn from_evm_err<E>(err: EVMError<E>) -> Self
|
||||
where
|
||||
EthApiError: From<E>,
|
||||
{
|
||||
err.into_eth_err()
|
||||
pub trait FromEvmError<Evm: ConfigureEvm>: From<Evm::EvmError<ProviderError>> {
|
||||
/// Converts from EVM error to this type.
|
||||
fn from_evm_err(err: Evm::EvmError<ProviderError>) -> Self {
|
||||
err.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, Evm> FromEvmError<Evm> for T
|
||||
where
|
||||
T: From<Evm::EvmError<ProviderError>>,
|
||||
Evm: ConfigureEvm,
|
||||
{
|
||||
}
|
||||
|
||||
@ -651,8 +651,9 @@ where
|
||||
|
||||
let ExecutionWitnessRecord { hashed_state, codes, keys } = witness_record;
|
||||
|
||||
let state =
|
||||
state_provider.witness(Default::default(), hashed_state).map_err(Into::into)?;
|
||||
let state = state_provider
|
||||
.witness(Default::default(), hashed_state)
|
||||
.map_err(EthApiError::from)?;
|
||||
Ok(ExecutionWitness { state: state.into_iter().collect(), codes, keys })
|
||||
})
|
||||
.await
|
||||
|
||||
@ -7,7 +7,7 @@ use reth_evm::ConfigureEvm;
|
||||
use reth_provider::{BlockReader, ProviderHeader};
|
||||
use reth_rpc_eth_api::{
|
||||
helpers::{estimate::EstimateCall, Call, EthCall, LoadPendingBlock, LoadState, SpawnBlocking},
|
||||
FromEthApiError, FullEthApiTypes, IntoEthApiError,
|
||||
FromEthApiError, FromEvmError, FullEthApiTypes, IntoEthApiError,
|
||||
};
|
||||
use reth_rpc_eth_types::{revm_utils::CallFees, RpcInvalidTransactionError};
|
||||
use revm_primitives::{BlockEnv, TxEnv, TxKind, U256};
|
||||
@ -21,8 +21,10 @@ where
|
||||
|
||||
impl<Provider, Pool, Network, EvmConfig> Call for EthApi<Provider, Pool, Network, EvmConfig>
|
||||
where
|
||||
Self: LoadState<Evm: ConfigureEvm<TxEnv = TxEnv, Header = ProviderHeader<Self::Provider>>>
|
||||
+ SpawnBlocking,
|
||||
Self: LoadState<
|
||||
Evm: ConfigureEvm<TxEnv = TxEnv, Header = ProviderHeader<Self::Provider>>,
|
||||
Error: FromEvmError<Self::Evm>,
|
||||
> + SpawnBlocking,
|
||||
EvmConfig: ConfigureEvm<Header = Header>,
|
||||
Provider: BlockReader,
|
||||
{
|
||||
|
||||
@ -13,7 +13,7 @@ use reth_provider::{
|
||||
};
|
||||
use reth_rpc_eth_api::{
|
||||
helpers::{LoadPendingBlock, SpawnBlocking},
|
||||
RpcNodeCore,
|
||||
FromEvmError, RpcNodeCore,
|
||||
};
|
||||
use reth_rpc_eth_types::PendingBlock;
|
||||
use reth_transaction_pool::{PoolTransaction, TransactionPool};
|
||||
@ -26,6 +26,7 @@ impl<Provider, Pool, Network, EvmConfig> LoadPendingBlock
|
||||
where
|
||||
Self: SpawnBlocking<
|
||||
NetworkTypes: alloy_network::Network<HeaderResponse = alloy_rpc_types_eth::Header>,
|
||||
Error: FromEvmError<Self::Evm>,
|
||||
> + RpcNodeCore<
|
||||
Provider: BlockReaderIdExt<
|
||||
Transaction = reth_primitives::TransactionSigned,
|
||||
|
||||
@ -2,7 +2,10 @@
|
||||
|
||||
use reth_evm::ConfigureEvm;
|
||||
use reth_provider::{BlockReader, ProviderHeader, ProviderTx};
|
||||
use reth_rpc_eth_api::helpers::{LoadState, Trace};
|
||||
use reth_rpc_eth_api::{
|
||||
helpers::{LoadState, Trace},
|
||||
FromEvmError,
|
||||
};
|
||||
|
||||
use crate::EthApi;
|
||||
|
||||
@ -14,6 +17,7 @@ where
|
||||
Header = ProviderHeader<Self::Provider>,
|
||||
Transaction = ProviderTx<Self::Provider>,
|
||||
>,
|
||||
Error: FromEvmError<Self::Evm>,
|
||||
>,
|
||||
Provider: BlockReader,
|
||||
{
|
||||
|
||||
@ -14,7 +14,7 @@ use reth_revm::database::StateProviderDatabase;
|
||||
use reth_rpc_api::MevSimApiServer;
|
||||
use reth_rpc_eth_api::{
|
||||
helpers::{Call, EthTransactions, LoadPendingBlock},
|
||||
FromEthApiError,
|
||||
FromEthApiError, FromEvmError,
|
||||
};
|
||||
use reth_rpc_eth_types::{utils::recover_raw_transaction, EthApiError};
|
||||
use reth_tasks::pool::BlockingTaskGuard;
|
||||
@ -307,7 +307,7 @@ where
|
||||
|
||||
let ResultAndState { result, state } = evm
|
||||
.transact(eth_api.evm_config().tx_env(&item.tx, item.signer))
|
||||
.map_err(EthApiError::from_eth_err)?;
|
||||
.map_err(Eth::Error::from_evm_err)?;
|
||||
|
||||
if !result.is_success() && !item.can_revert {
|
||||
return Err(EthApiError::InvalidParams(
|
||||
|
||||
Reference in New Issue
Block a user