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:
@ -7,7 +7,6 @@ use crate::{
|
||||
use alloc::{boxed::Box, sync::Arc, vec::Vec};
|
||||
use alloy_consensus::{BlockHeader, Eip658Value, Receipt, Transaction as _};
|
||||
use alloy_eips::eip7685::Requests;
|
||||
use core::fmt::Display;
|
||||
use op_alloy_consensus::OpDepositReceipt;
|
||||
use reth_chainspec::EthereumHardforks;
|
||||
use reth_consensus::ConsensusError;
|
||||
@ -15,11 +14,10 @@ use reth_evm::{
|
||||
execute::{
|
||||
balance_increment_state, BasicBlockExecutorProvider, BlockExecutionError,
|
||||
BlockExecutionStrategy, BlockExecutionStrategyFactory, BlockValidationError, ExecuteOutput,
|
||||
ProviderError,
|
||||
},
|
||||
state_change::post_block_balance_increments,
|
||||
system_calls::{OnStateHook, SystemCaller},
|
||||
ConfigureEvmFor, Evm,
|
||||
ConfigureEvmFor, Database, Evm,
|
||||
};
|
||||
use reth_optimism_chainspec::OpChainSpec;
|
||||
use reth_optimism_consensus::validate_block_post_execution;
|
||||
@ -29,7 +27,7 @@ use reth_optimism_primitives::{
|
||||
};
|
||||
use reth_primitives::{NodePrimitives, RecoveredBlock};
|
||||
use reth_primitives_traits::{BlockBody, SignedTransaction};
|
||||
use reth_revm::{Database, State};
|
||||
use reth_revm::State;
|
||||
use revm_primitives::{db::DatabaseCommit, ResultAndState};
|
||||
use tracing::trace;
|
||||
|
||||
@ -76,12 +74,11 @@ where
|
||||
EvmConfig: ConfigureEvmFor<N> + Clone + Unpin + Sync + Send + 'static,
|
||||
{
|
||||
type Primitives = N;
|
||||
type Strategy<DB: Database<Error: Into<ProviderError> + Display>> =
|
||||
OpExecutionStrategy<DB, N, EvmConfig>;
|
||||
type Strategy<DB: Database> = OpExecutionStrategy<DB, N, EvmConfig>;
|
||||
|
||||
fn create_strategy<DB>(&self, db: DB) -> Self::Strategy<DB>
|
||||
where
|
||||
DB: Database<Error: Into<ProviderError> + Display>,
|
||||
DB: Database,
|
||||
{
|
||||
let state =
|
||||
State::builder().with_database(db).with_bundle_update().without_state_clear().build();
|
||||
@ -131,7 +128,7 @@ where
|
||||
|
||||
impl<DB, N, EvmConfig> BlockExecutionStrategy for OpExecutionStrategy<DB, N, EvmConfig>
|
||||
where
|
||||
DB: Database<Error: Into<ProviderError> + Display>,
|
||||
DB: Database,
|
||||
N: NodePrimitives<
|
||||
BlockHeader = alloy_consensus::Header,
|
||||
SignedTx: OpTransaction,
|
||||
@ -214,11 +211,10 @@ where
|
||||
|
||||
// Execute transaction.
|
||||
let result_and_state = evm.transact(tx_env).map_err(move |err| {
|
||||
let new_err = err.map_db_err(|e| e.into());
|
||||
// Ensure hash is calculated for error log, if not already done
|
||||
BlockValidationError::EVM {
|
||||
hash: transaction.recalculate_hash(),
|
||||
error: Box::new(new_err),
|
||||
error: Box::new(err),
|
||||
}
|
||||
})?;
|
||||
|
||||
|
||||
@ -18,14 +18,14 @@ use alloy_eips::eip7840::BlobParams;
|
||||
use alloy_primitives::{Address, U256};
|
||||
use core::fmt::Debug;
|
||||
use op_alloy_consensus::EIP1559ParamError;
|
||||
use reth_evm::{env::EvmEnv, ConfigureEvm, ConfigureEvmEnv, Evm, NextBlockEnvAttributes};
|
||||
use reth_evm::{env::EvmEnv, ConfigureEvm, ConfigureEvmEnv, Database, Evm, NextBlockEnvAttributes};
|
||||
use reth_optimism_chainspec::OpChainSpec;
|
||||
use reth_optimism_primitives::OpTransactionSigned;
|
||||
use reth_primitives_traits::FillTxEnv;
|
||||
use reth_revm::{
|
||||
inspector_handle_register,
|
||||
primitives::{AnalysisKind, CfgEnvWithHandlerCfg, TxEnv},
|
||||
Database, EvmBuilder, GetInspector,
|
||||
EvmBuilder, GetInspector,
|
||||
};
|
||||
|
||||
mod config;
|
||||
@ -224,6 +224,7 @@ impl ConfigureEvmEnv for OpEvmConfig {
|
||||
|
||||
impl ConfigureEvm for OpEvmConfig {
|
||||
type Evm<'a, DB: Database + 'a, I: 'a> = OpEvm<'a, I, DB>;
|
||||
type EvmError<DBError: core::error::Error + Send + Sync + 'static> = EVMError<DBError>;
|
||||
|
||||
fn evm_with_env<DB: Database>(&self, db: DB, evm_env: EvmEnv) -> Self::Evm<'_, DB, ()> {
|
||||
let cfg_env_with_handler_cfg = CfgEnvWithHandlerCfg {
|
||||
|
||||
@ -33,6 +33,7 @@ reth-revm = { workspace = true, features = ["std"] }
|
||||
reth-trie-db.workspace = true
|
||||
reth-rpc-server-types.workspace = true
|
||||
reth-rpc-types-compat.workspace = true
|
||||
reth-rpc-eth-types.workspace = true
|
||||
reth-tasks = { workspace = true, optional = true }
|
||||
|
||||
# op-reth
|
||||
|
||||
@ -9,7 +9,9 @@ use crate::{
|
||||
use op_alloy_consensus::OpPooledTransaction;
|
||||
use reth_basic_payload_builder::{BasicPayloadJobGenerator, BasicPayloadJobGeneratorConfig};
|
||||
use reth_chainspec::{EthChainSpec, Hardforks};
|
||||
use reth_evm::{execute::BasicBlockExecutorProvider, ConfigureEvmEnv, ConfigureEvmFor};
|
||||
use reth_evm::{
|
||||
execute::BasicBlockExecutorProvider, ConfigureEvm, ConfigureEvmEnv, ConfigureEvmFor,
|
||||
};
|
||||
use reth_network::{NetworkConfig, NetworkHandle, NetworkManager, NetworkPrimitives, PeersInfo};
|
||||
use reth_node_api::{AddOnsContext, FullNodeComponents, NodeAddOns, PrimitivesTy, TxTy};
|
||||
use reth_node_builder::{
|
||||
@ -32,10 +34,11 @@ use reth_optimism_primitives::{OpPrimitives, OpReceipt, OpTransactionSigned};
|
||||
use reth_optimism_rpc::{
|
||||
miner::{MinerApiExtServer, OpMinerExtApi},
|
||||
witness::{DebugExecutionWitnessApiServer, OpDebugWitnessApi},
|
||||
OpEthApi, SequencerClient,
|
||||
OpEthApi, OpEthApiError, SequencerClient,
|
||||
};
|
||||
use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService};
|
||||
use reth_provider::{CanonStateSubscriptions, EthStorage};
|
||||
use reth_rpc_eth_types::error::FromEvmError;
|
||||
use reth_rpc_server_types::RethRpcModule;
|
||||
use reth_tracing::tracing::{debug, info};
|
||||
use reth_transaction_pool::{
|
||||
@ -193,6 +196,7 @@ where
|
||||
>,
|
||||
Evm: ConfigureEvmEnv<TxEnv = TxEnv>,
|
||||
>,
|
||||
OpEthApiError: FromEvmError<N::Evm>,
|
||||
{
|
||||
type Handle = RpcHandle<N, OpEthApi<N>>;
|
||||
|
||||
@ -241,8 +245,9 @@ where
|
||||
Storage = OpStorage,
|
||||
Engine = OpEngineTypes,
|
||||
>,
|
||||
Evm: ConfigureEvmEnv<TxEnv = TxEnv>,
|
||||
Evm: ConfigureEvm<TxEnv = TxEnv>,
|
||||
>,
|
||||
OpEthApiError: FromEvmError<N::Evm>,
|
||||
{
|
||||
type EthApi = OpEthApi<N>;
|
||||
|
||||
|
||||
@ -17,8 +17,8 @@ use reth_basic_payload_builder::*;
|
||||
use reth_chain_state::{ExecutedBlock, ExecutedBlockWithTrieUpdates};
|
||||
use reth_chainspec::{ChainSpecProvider, EthereumHardforks};
|
||||
use reth_evm::{
|
||||
env::EvmEnv, system_calls::SystemCaller, ConfigureEvm, ConfigureEvmEnv, Evm,
|
||||
NextBlockEnvAttributes,
|
||||
env::EvmEnv, system_calls::SystemCaller, ConfigureEvm, ConfigureEvmEnv, Database, Evm,
|
||||
EvmError, InvalidTxError, NextBlockEnvAttributes,
|
||||
};
|
||||
use reth_execution_types::ExecutionOutcome;
|
||||
use reth_optimism_chainspec::OpChainSpec;
|
||||
@ -42,8 +42,8 @@ use reth_transaction_pool::{
|
||||
};
|
||||
use revm::{
|
||||
db::{states::bundle_state::BundleRetention, State},
|
||||
primitives::{EVMError, InvalidTransaction, ResultAndState},
|
||||
Database, DatabaseCommit,
|
||||
primitives::ResultAndState,
|
||||
DatabaseCommit,
|
||||
};
|
||||
use std::{fmt::Display, sync::Arc};
|
||||
use tracing::{debug, trace, warn};
|
||||
@ -818,16 +818,12 @@ where
|
||||
let ResultAndState { result, state } = match evm.transact(tx_env) {
|
||||
Ok(res) => res,
|
||||
Err(err) => {
|
||||
match err {
|
||||
EVMError::Transaction(err) => {
|
||||
trace!(target: "payload_builder", %err, ?sequencer_tx, "Error in sequencer transaction, skipping.");
|
||||
continue
|
||||
}
|
||||
err => {
|
||||
// this is an error that we should treat as fatal for this attempt
|
||||
return Err(PayloadBuilderError::EvmExecutionError(err))
|
||||
}
|
||||
if err.is_invalid_tx_err() {
|
||||
trace!(target: "payload_builder", %err, ?sequencer_tx, "Error in sequencer transaction, skipping.");
|
||||
continue
|
||||
}
|
||||
// this is an error that we should treat as fatal for this attempt
|
||||
return Err(PayloadBuilderError::EvmExecutionError(Box::new(err)))
|
||||
}
|
||||
};
|
||||
|
||||
@ -915,25 +911,21 @@ where
|
||||
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
|
||||
trace!(target: "payload_builder", %err, ?tx, "skipping nonce too low transaction");
|
||||
} else {
|
||||
// if the transaction is invalid, we can skip it and all of its
|
||||
// descendants
|
||||
trace!(target: "payload_builder", %err, ?tx, "skipping invalid transaction and its descendants");
|
||||
best_txs.mark_invalid(tx.signer(), tx.nonce());
|
||||
}
|
||||
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
|
||||
trace!(target: "payload_builder", %err, ?tx, "skipping nonce too low transaction");
|
||||
} else {
|
||||
// if the transaction is invalid, we can skip it and all of its
|
||||
// descendants
|
||||
trace!(target: "payload_builder", %err, ?tx, "skipping invalid transaction and its descendants");
|
||||
best_txs.mark_invalid(tx.signer(), tx.nonce());
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
err => {
|
||||
// this is an error that we should treat as fatal for this attempt
|
||||
return Err(PayloadBuilderError::EvmExecutionError(err))
|
||||
}
|
||||
continue
|
||||
}
|
||||
// this is an error that we should treat as fatal for this attempt
|
||||
return Err(PayloadBuilderError::EvmExecutionError(Box::new(err)))
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ use reth_optimism_evm::OpBlockExecutionError;
|
||||
use reth_rpc_eth_api::AsEthApiError;
|
||||
use reth_rpc_eth_types::EthApiError;
|
||||
use reth_rpc_server_types::result::{internal_rpc_err, rpc_err};
|
||||
use revm::primitives::{InvalidTransaction, OptimismInvalidTransaction};
|
||||
use revm::primitives::{EVMError, InvalidTransaction, OptimismInvalidTransaction};
|
||||
|
||||
/// Optimism specific errors, that extend [`EthApiError`].
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
@ -119,3 +119,12 @@ impl From<BlockError> for OpEthApiError {
|
||||
Self::Eth(error.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl<DB> From<EVMError<DB>> for OpEthApiError
|
||||
where
|
||||
EthApiError: From<EVMError<DB>>,
|
||||
{
|
||||
fn from(error: EVMError<DB>) -> Self {
|
||||
Self::Eth(error.into())
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,8 +40,7 @@ where
|
||||
let excess_blob_gas = block.excess_blob_gas();
|
||||
let timestamp = block.timestamp();
|
||||
|
||||
let mut l1_block_info =
|
||||
reth_optimism_evm::extract_l1_info(block.body()).map_err(OpEthApiError::from)?;
|
||||
let mut l1_block_info = reth_optimism_evm::extract_l1_info(block.body())?;
|
||||
|
||||
return block
|
||||
.body()
|
||||
|
||||
@ -6,7 +6,7 @@ use reth_evm::ConfigureEvm;
|
||||
use reth_provider::ProviderHeader;
|
||||
use reth_rpc_eth_api::{
|
||||
helpers::{estimate::EstimateCall, Call, EthCall, LoadBlock, LoadState, SpawnBlocking},
|
||||
FromEthApiError, FullEthApiTypes, IntoEthApiError,
|
||||
FromEthApiError, FromEvmError, FullEthApiTypes, IntoEthApiError,
|
||||
};
|
||||
use reth_rpc_eth_types::{revm_utils::CallFees, RpcInvalidTransactionError};
|
||||
use revm::primitives::{BlockEnv, OptimismFields, TxEnv};
|
||||
@ -28,8 +28,10 @@ where
|
||||
|
||||
impl<N> Call for OpEthApi<N>
|
||||
where
|
||||
Self: LoadState<Evm: ConfigureEvm<Header = ProviderHeader<Self::Provider>, TxEnv = TxEnv>>
|
||||
+ SpawnBlocking,
|
||||
Self: LoadState<
|
||||
Evm: ConfigureEvm<Header = ProviderHeader<Self::Provider>, TxEnv = TxEnv>,
|
||||
Error: FromEvmError<Self::Evm>,
|
||||
> + SpawnBlocking,
|
||||
Self::Error: From<OpEthApiError>,
|
||||
N: OpNodeCore,
|
||||
{
|
||||
|
||||
@ -30,7 +30,7 @@ use reth_rpc_eth_api::{
|
||||
AddDevSigners, EthApiSpec, EthFees, EthSigner, EthState, LoadBlock, LoadFee, LoadState,
|
||||
SpawnBlocking, Trace,
|
||||
},
|
||||
EthApiTypes, RpcNodeCore, RpcNodeCoreExt,
|
||||
EthApiTypes, FromEvmError, RpcNodeCore, RpcNodeCoreExt,
|
||||
};
|
||||
use reth_rpc_eth_types::{EthStateCache, FeeHistoryCache, GasPriceOracle};
|
||||
use reth_tasks::{
|
||||
@ -252,6 +252,7 @@ where
|
||||
Header = ProviderHeader<Self::Provider>,
|
||||
Transaction = ProviderTx<Self::Provider>,
|
||||
>,
|
||||
Error: FromEvmError<Self::Evm>,
|
||||
>,
|
||||
N: OpNodeCore,
|
||||
{
|
||||
|
||||
@ -21,7 +21,7 @@ use reth_provider::{
|
||||
};
|
||||
use reth_rpc_eth_api::{
|
||||
helpers::{LoadPendingBlock, SpawnBlocking},
|
||||
EthApiTypes, FromEthApiError, RpcNodeCore,
|
||||
EthApiTypes, FromEthApiError, FromEvmError, RpcNodeCore,
|
||||
};
|
||||
use reth_rpc_eth_types::{EthApiError, PendingBlock};
|
||||
use reth_transaction_pool::{PoolTransaction, TransactionPool};
|
||||
@ -34,6 +34,7 @@ where
|
||||
NetworkTypes: Network<
|
||||
HeaderResponse = alloy_rpc_types_eth::Header<ProviderHeader<Self::Provider>>,
|
||||
>,
|
||||
Error: FromEvmError<Self::Evm>,
|
||||
>,
|
||||
N: RpcNodeCore<
|
||||
Provider: BlockReaderIdExt<
|
||||
|
||||
Reference in New Issue
Block a user