Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
klkvr committed Jan 29, 2025
1 parent f02aba4 commit b1dfab9
Show file tree
Hide file tree
Showing 39 changed files with 301 additions and 247 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 3 additions & 4 deletions crates/engine/util/src/reorg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use reth_errors::{BlockExecutionError, BlockValidationError, RethError, RethResu
use reth_ethereum_forks::EthereumHardforks;
use reth_evm::{
state_change::post_block_withdrawals_balance_increments, system_calls::SystemCaller,
ConfigureEvm, Evm,
ConfigureEvm, Evm, EvmError,
};
use reth_payload_primitives::EngineApiMessageVersion;
use reth_payload_validator::ExecutionPayloadValidator;
Expand All @@ -29,7 +29,6 @@ use reth_revm::{
DatabaseCommit,
};
use reth_rpc_types_compat::engine::payload::block_to_payload;
use revm_primitives::EVMError;
use std::{
collections::VecDeque,
future::Future,
Expand Down Expand Up @@ -328,8 +327,8 @@ where
let tx_env = evm_config.tx_env(&tx_recovered, tx_recovered.signer());
let exec_result = match evm.transact(tx_env) {
Ok(result) => result,
error @ Err(EVMError::Transaction(_) | EVMError::Header(_)) => {
trace!(target: "engine::stream::reorg", hash = %tx.tx_hash(), ?error, "Error executing transaction from next block");
Err(err) if err.as_invalid_tx_err().is_some() => {
trace!(target: "engine::stream::reorg", hash = %tx.tx_hash(), ?err, "Error executing transaction from next block");
continue
}
// Treat error as fatal
Expand Down
23 changes: 8 additions & 15 deletions crates/ethereum/evm/src/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,22 @@ use crate::{
use alloc::{boxed::Box, sync::Arc, vec::Vec};
use alloy_consensus::{BlockHeader, Transaction};
use alloy_eips::{eip6110, eip7685::Requests};
use core::fmt::Display;
use reth_chainspec::{ChainSpec, EthereumHardfork, EthereumHardforks, MAINNET};
use reth_consensus::ConsensusError;
use reth_ethereum_consensus::validate_block_post_execution;
use reth_evm::{
execute::{
balance_increment_state, BasicBlockExecutorProvider, BlockExecutionError,
BlockExecutionStrategy, BlockExecutionStrategyFactory, BlockValidationError, ExecuteOutput,
ProviderError,
},
state_change::post_block_balance_increments,
system_calls::{OnStateHook, SystemCaller},
ConfigureEvm, Evm,
ConfigureEvm, Database, Evm,
};
use reth_primitives::{EthPrimitives, Receipt, RecoveredBlock};
use reth_primitives_traits::{BlockBody, SignedTransaction};
use reth_revm::db::State;
use revm_primitives::{
db::{Database, DatabaseCommit},
ResultAndState,
};
use revm_primitives::{db::DatabaseCommit, ResultAndState};

/// Factory for [`EthExecutionStrategy`].
#[derive(Debug, Clone)]
Expand Down Expand Up @@ -71,12 +66,11 @@ where
{
type Primitives = EthPrimitives;

type Strategy<DB: Database<Error: Into<ProviderError> + Display>> =
EthExecutionStrategy<DB, EvmConfig>;
type Strategy<DB: Database> = EthExecutionStrategy<DB, 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();
Expand Down Expand Up @@ -113,7 +107,7 @@ where

impl<DB, EvmConfig> BlockExecutionStrategy for EthExecutionStrategy<DB, EvmConfig>
where
DB: Database<Error: Into<ProviderError> + Display>,
DB: Database,
EvmConfig: ConfigureEvm<
Header = alloy_consensus::Header,
Transaction = reth_primitives::TransactionSigned,
Expand Down Expand Up @@ -163,11 +157,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),
}
})?;
self.system_caller.on_state(&result_and_state.state);
Expand Down Expand Up @@ -307,7 +300,7 @@ mod tests {
use reth_primitives::{Account, Block, BlockBody, Transaction};
use reth_primitives_traits::{crypto::secp256k1::public_key_to_address, Block as _};
use reth_revm::{
database::StateProviderDatabase, test_utils::StateProviderTest, TransitionState,
database::StateProviderDatabase, test_utils::StateProviderTest, Database, TransitionState,
};
use reth_testing_utils::generators::{self, sign_tx_with_key_pair};
use revm_primitives::{address, EvmState, BLOCKHASH_SERVE_WINDOW};
Expand Down Expand Up @@ -393,7 +386,7 @@ mod tests {
);

assert!(matches!(
err.as_validation().unwrap().clone(),
err.as_validation().unwrap(),
BlockValidationError::MissingParentBeaconBlockRoot
));

Expand Down
5 changes: 3 additions & 2 deletions crates/ethereum/evm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ use alloy_consensus::{BlockHeader, Header};
use alloy_primitives::{Address, U256};
use core::{convert::Infallible, fmt::Debug};
use reth_chainspec::ChainSpec;
use reth_evm::{env::EvmEnv, ConfigureEvm, ConfigureEvmEnv, Evm, NextBlockEnvAttributes};
use reth_evm::{env::EvmEnv, ConfigureEvm, ConfigureEvmEnv, Database, Evm, NextBlockEnvAttributes};
use reth_primitives::TransactionSigned;
use reth_primitives_traits::transaction::execute::FillTxEnv;
use reth_revm::{inspector_handle_register, Database, EvmBuilder};
use reth_revm::{inspector_handle_register, EvmBuilder};
use revm_primitives::{
AnalysisKind, BlobExcessGasAndPrice, BlockEnv, Bytes, CfgEnv, CfgEnvWithHandlerCfg, EVMError,
HandlerCfg, ResultAndState, SpecId, TxEnv, TxKind,
Expand Down Expand Up @@ -237,6 +237,7 @@ impl ConfigureEvmEnv for EthEvmConfig {

impl ConfigureEvm for EthEvmConfig {
type Evm<'a, DB: Database + 'a, I: 'a> = EthEvm<'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 {
Expand Down
44 changes: 20 additions & 24 deletions crates/ethereum/payload/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ use reth_basic_payload_builder::{
use reth_chainspec::{ChainSpec, ChainSpecProvider};
use reth_errors::RethError;
use reth_evm::{
env::EvmEnv, system_calls::SystemCaller, ConfigureEvm, Evm, NextBlockEnvAttributes,
env::EvmEnv, system_calls::SystemCaller, ConfigureEvm, Evm, EvmError, InvalidTxError,
NextBlockEnvAttributes,
};
use reth_evm_ethereum::{eip6110::parse_deposits_from_receipts, EthEvmConfig};
use reth_execution_types::ExecutionOutcome;
Expand All @@ -44,7 +45,7 @@ use reth_transaction_pool::{
};
use revm::{
db::{states::bundle_state::BundleRetention, State},
primitives::{EVMError, InvalidTransaction, ResultAndState},
primitives::ResultAndState,
DatabaseCommit,
};
use std::sync::Arc;
Expand Down Expand Up @@ -276,30 +277,25 @@ 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(
&pool_tx,
InvalidPoolTransactionError::Consensus(
InvalidTransactionError::TxTypeNotSupported,
),
);
}

continue
}
err => {
// this is an error that we should treat as fatal for this attempt
return Err(PayloadBuilderError::EvmExecutionError(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
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(
&pool_tx,
InvalidPoolTransactionError::Consensus(
InvalidTransactionError::TxTypeNotSupported,
),
);
}
continue
}
// this is an error that we should treat as fatal for this attempt
return Err(PayloadBuilderError::evm(err))
}
};

Expand Down
15 changes: 7 additions & 8 deletions crates/evm/execution-errors/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,18 @@ reth-prune-types.workspace = true
alloy-primitives.workspace = true
alloy-rlp.workspace = true
alloy-eips.workspace = true
revm-primitives.workspace = true
nybbles.workspace = true

thiserror.workspace = true
derive_more.workspace = true

[features]
default = ["std"]
std = [
"reth-consensus/std",
"alloy-eips/std",
"alloy-primitives/std",
"revm-primitives/std",
"alloy-rlp/std",
"thiserror/std",
"nybbles/std",
"reth-consensus/std",
"alloy-eips/std",
"alloy-primitives/std",
"alloy-rlp/std",
"thiserror/std",
"nybbles/std"
]
8 changes: 5 additions & 3 deletions crates/evm/execution-errors/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

extern crate alloc;

use core::fmt::Display;

use alloc::{
boxed::Box,
string::{String, ToString},
Expand All @@ -20,22 +22,22 @@ use alloy_primitives::B256;
use reth_consensus::ConsensusError;
use reth_prune_types::PruneSegmentError;
use reth_storage_errors::provider::ProviderError;
use revm_primitives::EVMError;
use thiserror::Error;

pub mod trie;
pub use trie::*;

/// Transaction validation errors
#[derive(Error, Clone, Debug)]
#[derive(Error, derive_more::Debug)]
pub enum BlockValidationError {
/// EVM error with transaction hash and message
#[error("EVM reported invalid transaction ({hash}): {error}")]
#[debug("{error}")]
EVM {
/// The hash of the transaction
hash: B256,
/// The EVM error.
error: Box<EVMError<ProviderError>>,
error: Box<dyn Display + Send + Sync>,
},
/// Error when recovering the sender for a transaction
#[error("failed to recover sender for transaction")]
Expand Down
19 changes: 7 additions & 12 deletions crates/evm/src/either.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
//! Helper type that represents one of two possible executor types
use core::fmt::Display;

use crate::{
execute::{BatchExecutor, BlockExecutorProvider, Executor},
system_calls::OnStateHook,
Database,
};
use reth_storage_errors::provider::ProviderError;
use revm_primitives::db::Database;

// re-export Either
pub use futures_util::future::Either;
Expand All @@ -20,15 +17,13 @@ where
{
type Primitives = A::Primitives;

type Executor<DB: Database<Error: Into<ProviderError> + Display>> =
Either<A::Executor<DB>, B::Executor<DB>>;
type Executor<DB: Database> = Either<A::Executor<DB>, B::Executor<DB>>;

type BatchExecutor<DB: Database<Error: Into<ProviderError> + Display>> =
Either<A::BatchExecutor<DB>, B::BatchExecutor<DB>>;
type BatchExecutor<DB: Database> = Either<A::BatchExecutor<DB>, B::BatchExecutor<DB>>;

fn executor<DB>(&self, db: DB) -> Self::Executor<DB>
where
DB: Database<Error: Into<ProviderError> + Display>,
DB: Database,
{
match self {
Self::Left(a) => Either::Left(a.executor(db)),
Expand All @@ -38,7 +33,7 @@ where

fn batch_executor<DB>(&self, db: DB) -> Self::BatchExecutor<DB>
where
DB: Database<Error: Into<ProviderError> + Display>,
DB: Database,
{
match self {
Self::Left(a) => Either::Left(a.batch_executor(db)),
Expand All @@ -51,7 +46,7 @@ impl<A, B, DB> Executor<DB> for Either<A, B>
where
A: Executor<DB>,
B: for<'a> Executor<DB, Input<'a> = A::Input<'a>, Output = A::Output, Error = A::Error>,
DB: Database<Error: Into<ProviderError> + Display>,
DB: Database,
{
type Input<'a> = A::Input<'a>;
type Output = A::Output;
Expand Down Expand Up @@ -97,7 +92,7 @@ impl<A, B, DB> BatchExecutor<DB> for Either<A, B>
where
A: BatchExecutor<DB>,
B: for<'a> BatchExecutor<DB, Input<'a> = A::Input<'a>, Output = A::Output, Error = A::Error>,
DB: Database<Error: Into<ProviderError> + Display>,
DB: Database,
{
type Input<'a> = A::Input<'a>;
type Output = A::Output;
Expand Down
Loading

0 comments on commit b1dfab9

Please sign in to comment.