From ed42993e66411615f0a88a80bc6d46917e6fccea Mon Sep 17 00:00:00 2001 From: Wodann Date: Mon, 17 Jun 2024 15:21:47 +0000 Subject: [PATCH 01/13] WIP --- Cargo.lock | 9 ++--- crates/edr_eth/Cargo.toml | 2 +- crates/edr_evm/Cargo.toml | 2 +- crates/edr_evm/src/block/builder.rs | 57 ++++++++++++++++----------- crates/edr_evm/src/chain_spec.rs | 15 ++++++- crates/edr_evm/src/debug.rs | 13 +++++- crates/edr_evm/src/debug_trace.rs | 7 +--- crates/edr_evm/src/lib.rs | 7 +++- crates/edr_evm/src/miner.rs | 6 +-- crates/edr_evm/src/runtime.rs | 18 ++++----- crates/edr_provider/src/data.rs | 14 +++---- crates/edr_provider/src/data/call.rs | 4 +- crates/edr_provider/src/data/gas.rs | 6 +-- crates/edr_provider/src/test_utils.rs | 4 +- 14 files changed, 99 insertions(+), 65 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6a8093aea..e87acd64d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2830,10 +2830,9 @@ dependencies = [ [[package]] name = "revm" version = "8.0.0" -source = "git+https://github.com/NomicFoundation/revm?rev=aceb093#aceb0939b1712faa0e8f45c1f5621c11b81df94e" +source = "git+https://github.com/NomicFoundation/revm?rev=48d55ef#48d55ef74263b0f5512101225439e42872309fae" dependencies = [ "auto_impl", - "cfg-if", "dyn-clone", "revm-interpreter", "revm-precompile", @@ -2843,7 +2842,7 @@ dependencies = [ [[package]] name = "revm-interpreter" version = "4.0.0" -source = "git+https://github.com/NomicFoundation/revm?rev=aceb093#aceb0939b1712faa0e8f45c1f5621c11b81df94e" +source = "git+https://github.com/NomicFoundation/revm?rev=48d55ef#48d55ef74263b0f5512101225439e42872309fae" dependencies = [ "revm-primitives", "serde", @@ -2852,7 +2851,7 @@ dependencies = [ [[package]] name = "revm-precompile" version = "6.0.0" -source = "git+https://github.com/NomicFoundation/revm?rev=aceb093#aceb0939b1712faa0e8f45c1f5621c11b81df94e" +source = "git+https://github.com/NomicFoundation/revm?rev=48d55ef#48d55ef74263b0f5512101225439e42872309fae" dependencies = [ "aurora-engine-modexp", "c-kzg", @@ -2867,7 +2866,7 @@ dependencies = [ [[package]] name = "revm-primitives" version = "3.1.1" -source = "git+https://github.com/NomicFoundation/revm?rev=aceb093#aceb0939b1712faa0e8f45c1f5621c11b81df94e" +source = "git+https://github.com/NomicFoundation/revm?rev=48d55ef#48d55ef74263b0f5512101225439e42872309fae" dependencies = [ "alloy-primitives 0.7.4", "auto_impl", diff --git a/crates/edr_eth/Cargo.toml b/crates/edr_eth/Cargo.toml index 51be60cea..6b1d1fa8d 100644 --- a/crates/edr_eth/Cargo.toml +++ b/crates/edr_eth/Cargo.toml @@ -15,7 +15,7 @@ itertools = { version = "0.10.5", default-features = false, features = ["use_all k256 = { version = "0.13.1", default-features = false, features = ["arithmetic", "ecdsa", "pkcs8", ] } log = { version = "0.4.17", default-features = false } once_cell = { version = "1.18.0", default-features = false, features = ["alloc", "race", "std"] } -revm-primitives = { git = "https://github.com/NomicFoundation/revm", rev = "aceb093", version = "3.1", default-features = false, features = ["c-kzg", "hashbrown"] } +revm-primitives = { git = "https://github.com/NomicFoundation/revm", rev = "48d55ef", version = "3.1", default-features = false, features = ["c-kzg", "hashbrown"] } serde = { version = "1.0.147", default-features = false, features = ["derive"], optional = true } sha2 = { version = "0.10.8", default-features = false } sha3 = { version = "0.10.8", default-features = false } diff --git a/crates/edr_evm/Cargo.toml b/crates/edr_evm/Cargo.toml index 1e8251083..e6568df89 100644 --- a/crates/edr_evm/Cargo.toml +++ b/crates/edr_evm/Cargo.toml @@ -19,7 +19,7 @@ parking_lot = { version = "0.12.1", default-features = false } edr_defaults = { version = "0.3.5", path = "../edr_defaults" } edr_eth = { version = "0.3.5", path = "../edr_eth", features = ["rand", "serde"] } edr_rpc_eth = { version = "0.3.5", path = "../edr_rpc_eth" } -revm = { git = "https://github.com/NomicFoundation/revm", rev = "aceb093", version = "8.0", default-features = false, features = ["c-kzg", "dev", "serde"] } +revm = { git = "https://github.com/NomicFoundation/revm", rev = "48d55ef", version = "8.0", default-features = false, features = ["c-kzg", "dev", "serde"] } rpds = { version = "1.1.0", default-features = false, features = ["std"] } serde = { version = "1.0.158", default-features = false, features = ["std"] } serde_json = { version = "1.0.94", default-features = false, features = ["std"] } diff --git a/crates/edr_evm/src/block/builder.rs b/crates/edr_evm/src/block/builder.rs index 8f87207ad..f2351ed9d 100644 --- a/crates/edr_evm/src/block/builder.rs +++ b/crates/edr_evm/src/block/builder.rs @@ -14,10 +14,10 @@ use edr_eth::{ }; use revm::{ db::{DatabaseComponentError, DatabaseComponents, StateRef}, + handler::{CfgEnvWithChainSpec, EnvWithChainSpec}, primitives::{ - BlobExcessGasAndPrice, BlockEnv, CfgEnvWithHandlerCfg, EVMError, EnvWithHandlerCfg, - ExecutionResult, InvalidHeader, InvalidTransaction, Output, ResultAndState, SpecId, - MAX_BLOB_GAS_PER_BLOCK, + BlobExcessGasAndPrice, BlockEnv, EVMError, ExecutionResult, InvalidHeader, + InvalidTransaction, Output, ResultAndState, SpecId, MAX_BLOB_GAS_PER_BLOCK, }, Context, DatabaseCommit, Evm, InnerEvmContext, }; @@ -75,12 +75,14 @@ pub enum BlockTransactionError { State(SE), } -impl From>> for BlockTransactionError +impl From>> + for BlockTransactionError where + ChainSpecT: revm::primitives::ChainSpec, BE: Debug + Send, SE: Debug + Send, { - fn from(error: EVMError>) -> Self { + fn from(error: EVMError>) -> Self { match error { EVMError::Transaction(e) => match e { InvalidTransaction::LackOfFundForMaxFee { fee, balance } => { @@ -107,13 +109,17 @@ where /// was executed. pub struct ExecutionResultWithContext< 'evm, + ChainSpecT, BlockchainErrorT, StateErrorT, DebugDataT, StateT: StateRef, -> { +> where + ChainSpecT: revm::primitives::ChainSpec, +{ /// The result of executing the transaction. - pub result: Result>, + pub result: + Result, BlockTransactionError>, /// The context in which the transaction was executed. pub evm_context: EvmContext<'evm, L1ChainSpec, BlockchainErrorT, DebugDataT, StateT>, } @@ -128,7 +134,7 @@ pub struct BuildBlockResult { /// A builder for constructing Ethereum blocks. pub struct BlockBuilder { - cfg: CfgEnvWithHandlerCfg, + cfg: CfgEnvWithChainSpec, header: PartialHeader, transactions: Vec, state_diff: StateDiff, @@ -141,15 +147,13 @@ impl BlockBuilder { /// Creates an intance of [`BlockBuilder`]. #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))] pub fn new( - cfg: CfgEnvWithHandlerCfg, + cfg: CfgEnvWithChainSpec, parent: &dyn SyncBlock, mut options: BlockOptions, dao_hardfork_activation_block: Option, ) -> Result { - if cfg.handler_cfg.spec_id < SpecId::BYZANTIUM { - return Err(BlockBuilderCreationError::UnsupportedHardfork( - cfg.handler_cfg.spec_id, - )); + if cfg.spec_id < SpecId::BYZANTIUM { + return Err(BlockBuilderCreationError::UnsupportedHardfork(cfg.spec_id)); } let parent_header = parent.header(); @@ -160,7 +164,7 @@ impl BlockBuilder { }; let withdrawals = std::mem::take(&mut options.withdrawals).or_else(|| { - if cfg.handler_cfg.spec_id >= SpecId::SHANGHAI { + if cfg.spec_id >= SpecId::SHANGHAI { Some(Vec::new()) } else { None @@ -168,13 +172,13 @@ impl BlockBuilder { }); options.parent_hash = Some(*parent.hash()); - let header = PartialHeader::new(cfg.handler_cfg.spec_id, options, Some(parent_header)); + let header = PartialHeader::new(cfg.spec_id, options, Some(parent_header)); if let Some(dao_hardfork_activation_block) = dao_hardfork_activation_block { const DAO_FORCE_EXTRA_DATA_RANGE: u64 = 9; let drift = header.number - dao_hardfork_activation_block; - if cfg.handler_cfg.spec_id >= SpecId::DAO_FORK + if cfg.spec_id >= SpecId::DAO_FORK && drift <= DAO_FORCE_EXTRA_DATA_RANGE && *header.extra_data != DAO_EXTRA_DATA { @@ -194,7 +198,7 @@ impl BlockBuilder { } /// Retrieves the config of the block builder. - pub fn config(&self) -> &CfgEnvWithHandlerCfg { + pub fn config(&self) -> &CfgEnvWithChainSpec { &self.cfg } @@ -223,7 +227,14 @@ impl BlockBuilder { debug_context: Option< DebugContext<'evm, L1ChainSpec, BlockchainErrorT, DebugDataT, StateT>, >, - ) -> ExecutionResultWithContext<'evm, BlockchainErrorT, StateErrorT, DebugDataT, StateT> + ) -> ExecutionResultWithContext< + 'evm, + L1ChainSpec, + BlockchainErrorT, + StateErrorT, + DebugDataT, + StateT, + > where 'blockchain: 'evm, BlockchainErrorT: Debug + Send, @@ -259,7 +270,7 @@ impl BlockBuilder { } } - let spec_id = self.cfg.handler_cfg.spec_id; + let spec_id = self.cfg.spec_id; let block = BlockEnv { number: U256::from(self.header.number), @@ -280,7 +291,7 @@ impl BlockBuilder { .map(|BlobGas { excess_gas, .. }| BlobExcessGasAndPrice::new(*excess_gas)), }; - let env = EnvWithHandlerCfg::new_with_cfg_env( + let env = EnvWithChainSpec::new_with_cfg_env( self.cfg.clone(), block.clone(), transaction.clone().into(), @@ -300,6 +311,7 @@ impl BlockBuilder { ) = { if let Some(debug_context) = debug_context { let mut evm = Evm::builder() + .with_chain_spec::() .with_ref_db(db) .with_external_context(debug_context.data) .with_env_with_handler_cfg(env) @@ -335,6 +347,7 @@ impl BlockBuilder { } } else { let mut evm = Evm::builder() + .with_chain_spec::() .with_ref_db(db) .with_env_with_handler_cfg(env) .build(); @@ -535,7 +548,7 @@ mod tests { let spec_id = SpecId::BYZANTIUM; let parent = LocalBlock::empty(spec_id, partial_header); - let cfg = CfgEnvWithHandlerCfg::new_with_spec_id(CfgEnv::default(), spec_id); + let cfg = CfgEnvWithChainSpec::::new(CfgEnv::default(), spec_id); let block_options = BlockOptions { number: Some(DUMMY_DAO_HARDFORK_BLOCK_NUMBER), extra_data: Some(Bytes::from(DAO_EXTRA_DATA)), @@ -568,7 +581,7 @@ mod tests { let spec_id = SpecId::BYZANTIUM; let parent = LocalBlock::empty(spec_id, partial_header); - let cfg = CfgEnvWithHandlerCfg::new_with_spec_id(CfgEnv::default(), spec_id); + let cfg = CfgEnvWithChainSpec::::new(CfgEnv::default(), spec_id); let block_options = BlockOptions { number: Some(DUMMY_DAO_HARDFORK_BLOCK_NUMBER), diff --git a/crates/edr_evm/src/chain_spec.rs b/crates/edr_evm/src/chain_spec.rs index 543e979b6..7a8a7b79a 100644 --- a/crates/edr_evm/src/chain_spec.rs +++ b/crates/edr_evm/src/chain_spec.rs @@ -14,6 +14,7 @@ use crate::{transaction::remote::EthRpcTransaction, EthRpcBlock, IntoRemoteBlock pub trait ChainSpec: Debug + alloy_rlp::Encodable + + revm::primitives::ChainSpec + RpcSpec< RpcBlock<::RpcTransaction>: EthRpcBlock + IntoRemoteBlock, RpcTransaction: EthRpcTransaction, @@ -38,9 +39,21 @@ impl SyncChainSpec for ChainSpecT where } /// The chain specification for Ethereum Layer 1. -#[derive(Clone, Copy, Debug, PartialEq, Eq, RlpEncodable)] +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, RlpEncodable)] pub struct L1ChainSpec; +impl revm::primitives::ChainSpec for L1ChainSpec { + type Block = revm::primitives::BlockEnv; + + type Hardfork = revm::primitives::SpecId; + + type HaltReason = revm::primitives::HaltReason; + + type Transaction = revm::primitives::TxEnv; + + type TransactionValidationError = revm::primitives::InvalidTransaction; +} + impl ChainSpec for L1ChainSpec { type SignedTransaction = edr_eth::transaction::Signed; } diff --git a/crates/edr_evm/src/debug.rs b/crates/edr_evm/src/debug.rs index 82df0167d..0a1caa26c 100644 --- a/crates/edr_evm/src/debug.rs +++ b/crates/edr_evm/src/debug.rs @@ -6,6 +6,7 @@ use crate::blockchain::SyncBlockchain; /// Type for registering handles, specialised for EDR database component types. pub type HandleRegister<'evm, ChainSpecT, BlockchainErrorT, DebugDataT, StateT> = revm::handler::register::HandleRegister< + ChainSpecT, DebugDataT, WrapDatabaseRef< DatabaseComponents< @@ -17,14 +18,22 @@ pub type HandleRegister<'evm, ChainSpecT, BlockchainErrorT, DebugDataT, StateT> /// Type for encapsulating contextual data and handler registration in an /// `EvmBuilder`. -pub struct DebugContext<'evm, ChainSpecT, BlockchainErrorT, DebugDataT, StateT: StateRef> { +pub struct DebugContext<'evm, ChainSpecT, BlockchainErrorT, DebugDataT, StateT> +where + ChainSpecT: revm::primitives::ChainSpec, + StateT: StateRef, +{ /// The contextual data. pub data: DebugDataT, /// The function to register handles. pub register_handles_fn: HandleRegister<'evm, ChainSpecT, BlockchainErrorT, DebugDataT, StateT>, } -pub struct EvmContext<'evm, ChainSpecT, BlockchainErrorT, DebugDataT, StateT: StateRef> { +pub struct EvmContext<'evm, ChainSpecT, BlockchainErrorT, DebugDataT, StateT> +where + ChainSpecT: revm::primitives::ChainSpec, + StateT: StateRef, +{ pub debug: Option>, pub state: StateT, } diff --git a/crates/edr_evm/src/debug_trace.rs b/crates/edr_evm/src/debug_trace.rs index e4f8c968f..c58de6fcd 100644 --- a/crates/edr_evm/src/debug_trace.rs +++ b/crates/edr_evm/src/debug_trace.rs @@ -12,10 +12,7 @@ use revm::{ opcode::{self, BoxedInstruction, InstructionTables, OpCode}, InstructionResult, Interpreter, InterpreterResult, }, - primitives::{ - hex, Address, BlockEnv, Bytes, CfgEnvWithHandlerCfg, ExecutionResult, ResultAndState, - SpecId, U256, - }, + primitives::{hex, Address, BlockEnv, Bytes, ExecutionResult, ResultAndState, SpecId, U256}, Database, Evm, EvmContext, JournalEntry, }; @@ -75,7 +72,7 @@ pub fn debug_trace_transaction( blockchain: &dyn SyncBlockchain, // Take ownership of the state so that we can apply throw-away modifications on it mut state: Box>, - evm_config: CfgEnvWithHandlerCfg, + evm_config: CfgEnvWithChainSpec, trace_config: DebugTraceConfig, block_env: BlockEnv, transactions: Vec, diff --git a/crates/edr_evm/src/lib.rs b/crates/edr_evm/src/lib.rs index 3290461dc..7306d7a94 100644 --- a/crates/edr_evm/src/lib.rs +++ b/crates/edr_evm/src/lib.rs @@ -5,8 +5,6 @@ //! The EDR EVM exposes APIs for running and interacting with a multi-threaded //! Ethereum Virtual Machine (or EVM). -pub use revm::primitives::*; - pub use crate::{ block::*, debug::{DebugContext, GetContextData}, @@ -65,3 +63,8 @@ pub mod interpreter { pub mod precompile { pub use revm::precompile::{u64_to_address, PrecompileSpecId, Precompiles}; } + +// /// Primitive types of Ethereum +// pub mod primitives { +// pub use revm::primitives::*; +// } diff --git a/crates/edr_evm/src/miner.rs b/crates/edr_evm/src/miner.rs index eef3bf01a..6f4d1e2a5 100644 --- a/crates/edr_evm/src/miner.rs +++ b/crates/edr_evm/src/miner.rs @@ -6,7 +6,7 @@ use edr_eth::{ transaction::{self, SignedTransaction as _, Transaction}, U256, }; -use revm::primitives::{CfgEnvWithHandlerCfg, ExecutionResult, InvalidTransaction}; +use revm::primitives::{CfgEnvWithChainSpec, ExecutionResult, InvalidTransaction}; use serde::{Deserialize, Serialize}; use crate::{ @@ -97,7 +97,7 @@ pub fn mine_block<'blockchain, 'evm, BlockchainErrorT, DebugDataT, StateErrorT>( blockchain: &'blockchain dyn SyncBlockchain, mut state: Box>, mem_pool: &MemPool, - cfg: &CfgEnvWithHandlerCfg, + cfg: &CfgEnvWithChainSpec, options: BlockOptions, min_gas_price: U256, mine_ordering: MineOrdering, @@ -289,7 +289,7 @@ pub fn mine_block_with_single_transaction< blockchain: &'blockchain dyn SyncBlockchain, state: Box>, transaction: transaction::Signed, - cfg: &CfgEnvWithHandlerCfg, + cfg: &CfgEnvWithChainSpec, options: BlockOptions, min_gas_price: U256, reward: U256, diff --git a/crates/edr_evm/src/runtime.rs b/crates/edr_evm/src/runtime.rs index a46db0aaa..34d23c725 100644 --- a/crates/edr_evm/src/runtime.rs +++ b/crates/edr_evm/src/runtime.rs @@ -3,7 +3,7 @@ use std::fmt::Debug; use revm::{ db::{DatabaseComponents, StateRef}, primitives::{ - BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ExecutionResult, ResultAndState, SpecId, + BlockEnv, CfgEnvWithChainSpec, EnvWithChainSpec, ExecutionResult, ResultAndState, SpecId, TxEnv, }, DatabaseCommit, Evm, @@ -32,7 +32,7 @@ pub fn dry_run<'blockchain, 'evm, 'overrides, 'state, DebugDataT, BlockchainErro blockchain: &'blockchain dyn SyncBlockchain, state: &'state dyn SyncState, state_overrides: &'overrides StateOverrides, - cfg: CfgEnvWithHandlerCfg, + cfg: CfgEnvWithChainSpec, transaction: TxEnv, block: BlockEnv, debug_context: Option< @@ -55,7 +55,7 @@ where let state_overrider = StateRefOverrider::new(state_overrides, state); - let env = EnvWithHandlerCfg::new_with_cfg_env(cfg, block, transaction); + let env = EnvWithChainSpec::new_with_cfg_env(cfg, block, transaction); let result = { let evm_builder = Evm::builder().with_ref_db(DatabaseComponents { state: state_overrider, @@ -96,7 +96,7 @@ pub fn guaranteed_dry_run< blockchain: &'blockchain dyn SyncBlockchain, state: &'state dyn SyncState, state_overrides: &'overrides StateOverrides, - mut cfg: CfgEnvWithHandlerCfg, + mut cfg: CfgEnvWithChainSpec, mut transaction: TxEnv, block: BlockEnv, debug_context: Option< @@ -134,7 +134,7 @@ where pub fn run<'blockchain, 'evm, BlockchainErrorT, DebugDataT, StateT>( blockchain: &'blockchain dyn SyncBlockchain, state: StateT, - cfg: CfgEnvWithHandlerCfg, + cfg: CfgEnvWithChainSpec, transaction: TxEnv, block: BlockEnv, debug_context: Option>, @@ -147,7 +147,7 @@ where { validate_configuration(&cfg, &block, &transaction)?; - let env = EnvWithHandlerCfg::new_with_cfg_env(cfg, block, transaction); + let env = EnvWithChainSpec::new_with_cfg_env(cfg, block, transaction); let evm_builder = Evm::builder().with_ref_db(DatabaseComponents { state, block_hash: blockchain, @@ -171,15 +171,15 @@ where } fn validate_configuration( - cfg: &CfgEnvWithHandlerCfg, + cfg: &CfgEnvWithChainSpec, block: &BlockEnv, transaction: &TxEnv, ) -> Result<(), TransactionError> { - if cfg.handler_cfg.spec_id > SpecId::MERGE && block.prevrandao.is_none() { + if cfg.spec_id > SpecId::MERGE && block.prevrandao.is_none() { return Err(TransactionError::MissingPrevrandao); } - if transaction.gas_priority_fee.is_some() && cfg.handler_cfg.spec_id < SpecId::LONDON { + if transaction.gas_priority_fee.is_some() && cfg.spec_id < SpecId::LONDON { return Err(TransactionError::Eip1559Unsupported); } diff --git a/crates/edr_provider/src/data.rs b/crates/edr_provider/src/data.rs index 861145018..591d1a636 100644 --- a/crates/edr_provider/src/data.rs +++ b/crates/edr_provider/src/data.rs @@ -43,7 +43,7 @@ use edr_evm::{ trace::Trace, transaction::{self, SignedTransaction as _}, Account, AccountInfo, BlobExcessGasAndPrice, Block as _, BlockAndTotalDifficulty, BlockEnv, - Bytecode, CfgEnv, CfgEnvWithHandlerCfg, DebugContext, DebugTraceConfig, + Bytecode, CfgEnv, CfgEnvWithChainSpec, DebugContext, DebugTraceConfig, DebugTraceResultWithTraces, Eip3155AndRawTracers, ExecutionResult, HashMap, HashSet, MemPool, MineBlockResultAndState, OrderedTransaction, RandomHashGenerator, StorageSlot, SyncBlock, TxEnv, KECCAK_EMPTY, @@ -1106,7 +1106,7 @@ impl ProviderData, - &CfgEnvWithHandlerCfg, + &CfgEnvWithChainSpec, BlockOptions, &mut Debugger, ) -> Result< @@ -1893,7 +1893,7 @@ impl ProviderData, - ) -> Result> { + ) -> Result, ProviderError> { let block_number = block_spec .map(|block_spec| self.block_number_by_block_spec(block_spec)) .transpose()? @@ -1914,7 +1914,7 @@ impl ProviderData::new_with_spec_id(cfg_env, spec_id)) } fn execute_in_block_context( @@ -1960,7 +1960,7 @@ impl ProviderData, - &CfgEnvWithHandlerCfg, + &CfgEnvWithChainSpec, BlockOptions, &mut Debugger, ) -> Result< @@ -2009,7 +2009,7 @@ impl ProviderData, options: BlockOptions, debugger: &mut Debugger, ) -> Result, ProviderError> { @@ -2035,7 +2035,7 @@ impl ProviderData, options: BlockOptions, transaction: transaction::Signed, debugger: &mut Debugger, diff --git a/crates/edr_provider/src/data/call.rs b/crates/edr_provider/src/data/call.rs index 84641ab41..ba27ad1c8 100644 --- a/crates/edr_provider/src/data/call.rs +++ b/crates/edr_provider/src/data/call.rs @@ -9,7 +9,7 @@ use edr_evm::{ chain_spec::L1ChainSpec, guaranteed_dry_run, state::{StateError, StateOverrides, StateRefOverrider, SyncState}, - BlobExcessGasAndPrice, BlockEnv, CfgEnvWithHandlerCfg, DebugContext, ExecutionResult, TxEnv, + BlobExcessGasAndPrice, BlockEnv, CfgEnvWithChainSpec, DebugContext, ExecutionResult, TxEnv, }; use crate::ProviderError; @@ -22,7 +22,7 @@ where pub header: &'a Header, pub state: &'a dyn SyncState, pub state_overrides: &'a StateOverrides, - pub cfg_env: CfgEnvWithHandlerCfg, + pub cfg_env: CfgEnvWithChainSpec, pub tx_env: TxEnv, // `DebugContext` cannot be simplified further #[allow(clippy::type_complexity)] diff --git a/crates/edr_provider/src/data/gas.rs b/crates/edr_provider/src/data/gas.rs index 056889dbb..0b98c8c4b 100644 --- a/crates/edr_provider/src/data/gas.rs +++ b/crates/edr_provider/src/data/gas.rs @@ -7,7 +7,7 @@ use edr_evm::{ chain_spec::L1ChainSpec, state::{StateError, StateOverrides, SyncState}, trace::{register_trace_collector_handles, TraceCollector}, - CfgEnvWithHandlerCfg, DebugContext, ExecutionResult, SyncBlock, TxEnv, + CfgEnvWithChainSpec, DebugContext, ExecutionResult, SyncBlock, TxEnv, }; use itertools::Itertools; @@ -21,7 +21,7 @@ pub(super) struct CheckGasLimitArgs<'a> { pub header: &'a Header, pub state: &'a dyn SyncState, pub state_overrides: &'a StateOverrides, - pub cfg_env: CfgEnvWithHandlerCfg, + pub cfg_env: CfgEnvWithChainSpec, pub tx_env: TxEnv, pub gas_limit: u64, pub trace_collector: &'a mut TraceCollector, @@ -67,7 +67,7 @@ pub(super) struct BinarySearchEstimationArgs<'a> { pub header: &'a Header, pub state: &'a dyn SyncState, pub state_overrides: &'a StateOverrides, - pub cfg_env: CfgEnvWithHandlerCfg, + pub cfg_env: CfgEnvWithChainSpec, pub tx_env: TxEnv, pub lower_bound: u64, pub upper_bound: u64, diff --git a/crates/edr_provider/src/test_utils.rs b/crates/edr_provider/src/test_utils.rs index 4ac720415..9f4f337aa 100644 --- a/crates/edr_provider/src/test_utils.rs +++ b/crates/edr_provider/src/test_utils.rs @@ -16,7 +16,7 @@ use edr_evm::{ blockchain::{Blockchain as _, ForkedBlockchain}, chain_spec::L1ChainSpec, state::IrregularState, - Block, BlockBuilder, CfgEnv, CfgEnvWithHandlerCfg, DebugContext, ExecutionResultWithContext, + Block, BlockBuilder, CfgEnv, CfgEnvWithChainSpec, DebugContext, ExecutionResultWithContext, IntoRemoteBlock, RandomHashGenerator, }; use edr_rpc_eth::client::EthRpcClient; @@ -181,7 +181,7 @@ pub async fn run_full_block(url: String, block_number: u64, chain_id: u64) -> an cfg.chain_id = chain_id; cfg.disable_eip3607 = true; - let cfg = CfgEnvWithHandlerCfg::new_with_spec_id(cfg, spec_id); + let cfg = CfgEnvWithChainSpec::new_with_spec_id(cfg, spec_id); let parent = blockchain.last_block()?; let replay_header = replay_block.header(); From 994ec5330b8c412fa41a40c390a4697dfc18dbf4 Mon Sep 17 00:00:00 2001 From: Wodann Date: Thu, 20 Jun 2024 04:20:11 +0000 Subject: [PATCH 02/13] feat: adopt multi-chain revm --- Cargo.lock | 109 +++++---- crates/edr_eth/Cargo.toml | 4 +- crates/edr_eth/src/access_list.rs | 53 ----- crates/edr_eth/src/lib.rs | 7 +- crates/edr_eth/src/transaction.rs | 43 +--- .../src/transaction/request/eip1559.rs | 3 +- .../src/transaction/request/eip2930.rs | 3 +- .../src/transaction/request/eip4844.rs | 3 +- crates/edr_eth/src/transaction/signed.rs | 225 +++++++++--------- .../edr_eth/src/transaction/signed/eip155.rs | 6 +- .../edr_eth/src/transaction/signed/eip1559.rs | 11 +- .../edr_eth/src/transaction/signed/eip2930.rs | 11 +- .../edr_eth/src/transaction/signed/eip4844.rs | 6 +- .../edr_eth/src/transaction/signed/legacy.rs | 6 +- crates/edr_evm/Cargo.toml | 2 +- crates/edr_evm/src/block/local.rs | 4 +- .../edr_evm/src/blockchain/storage/sparse.rs | 4 +- crates/edr_evm/src/chain_spec.rs | 9 +- crates/edr_evm/src/debug_trace.rs | 121 ++++++---- crates/edr_evm/src/state/trie.rs | 4 +- crates/edr_evm/src/state/trie/state_trie.rs | 7 +- crates/edr_evm/src/state/trie/storage_trie.rs | 6 +- crates/edr_evm/src/state/trie/trie_query.rs | 3 +- crates/edr_evm/src/trace.rs | 4 +- crates/edr_evm/src/transaction.rs | 56 ++--- crates/edr_provider/Cargo.toml | 2 +- crates/edr_rpc_eth/src/call_request.rs | 2 +- crates/edr_rpc_eth/src/transaction.rs | 3 +- 28 files changed, 330 insertions(+), 387 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e87acd64d..c36aed6a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -46,14 +46,14 @@ checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] name = "alloy-dyn-abi" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8425a283510106b1a6ad25dd4bb648ecde7da3fd2baeb9400a85ad62f51ec90b" +checksum = "cb6e6436a9530f25010d13653e206fab4c9feddacf21a54de8d7311b275bc56b" dependencies = [ "alloy-json-abi", - "alloy-primitives 0.7.4", + "alloy-primitives 0.7.6", "alloy-sol-type-parser", - "alloy-sol-types 0.7.4", + "alloy-sol-types 0.7.6", "const-hex", "derive_more", "itoa", @@ -62,13 +62,28 @@ dependencies = [ "winnow 0.6.8", ] +[[package]] +name = "alloy-eips" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32d6d8118b83b0489cfb7e6435106948add2b35217f4a5004ef895f613f60299" +dependencies = [ + "alloy-primitives 0.7.6", + "alloy-rlp", + "alloy-serde", + "c-kzg", + "once_cell", + "serde", + "sha2", +] + [[package]] name = "alloy-json-abi" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e30946aa6173020259055a44971f5cf40a7d76c931d209caeb51b333263df4f" +checksum = "aaeaccd50238126e3a0ff9387c7c568837726ad4f4e399b528ca88104d6c25ef" dependencies = [ - "alloy-primitives 0.7.4", + "alloy-primitives 0.7.6", "alloy-sol-type-parser", "serde", "serde_json", @@ -97,9 +112,9 @@ dependencies = [ [[package]] name = "alloy-primitives" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db8aa973e647ec336810a9356af8aea787249c9d00b1525359f3db29a68d231b" +checksum = "f783611babedbbe90db3478c120fb5f5daacceffc210b39adc0af4fe0da70bad" dependencies = [ "alloy-rlp", "bytes", @@ -140,6 +155,17 @@ dependencies = [ "syn 2.0.58", ] +[[package]] +name = "alloy-serde" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d94da1c0c4e27cc344b05626fe22a89dc6b8b531b9475f3b7691dbf6913e4109" +dependencies = [ + "alloy-primitives 0.7.6", + "serde", + "serde_json", +] + [[package]] name = "alloy-sol-macro" version = "0.5.4" @@ -160,9 +186,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dbd17d67f3e89478c8a634416358e539e577899666c927bc3d2b1328ee9b6ca" +checksum = "4bad41a7c19498e3f6079f7744656328699f8ea3e783bdd10d85788cd439f572" dependencies = [ "alloy-sol-macro-expander", "alloy-sol-macro-input", @@ -174,27 +200,27 @@ dependencies = [ [[package]] name = "alloy-sol-macro-expander" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6da95adcf4760bb4b108fefa51d50096c5e5fdd29ee72fed3e86ee414f2e34" +checksum = "fd9899da7d011b4fe4c406a524ed3e3f963797dbc93b45479d60341d3a27b252" dependencies = [ "alloy-sol-macro-input", "const-hex", - "heck 0.4.1", + "heck 0.5.0", "indexmap 2.2.6", "proc-macro-error", "proc-macro2", "quote", "syn 2.0.58", - "syn-solidity 0.7.4", + "syn-solidity 0.7.6", "tiny-keccak", ] [[package]] name = "alloy-sol-macro-input" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32c8da04c1343871fb6ce5a489218f9c85323c8340a36e9106b5fc98d4dd59d5" +checksum = "d32d595768fdc61331a132b6f65db41afae41b9b97d36c21eb1b955c422a7e60" dependencies = [ "const-hex", "dunce", @@ -202,14 +228,14 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.58", - "syn-solidity 0.7.4", + "syn-solidity 0.7.6", ] [[package]] name = "alloy-sol-type-parser" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368cae4dc052cad1d8f72eb2ae0c38027116933eeb49213c200a9e9875f208d7" +checksum = "baa2fbd22d353d8685bd9fee11ba2d8b5c3b1d11e56adb3265fcf1f32bfdf404" dependencies = [ "winnow 0.6.8", ] @@ -228,12 +254,12 @@ dependencies = [ [[package]] name = "alloy-sol-types" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40a64d2d2395c1ac636b62419a7b17ec39031d6b2367e66e9acbf566e6055e9c" +checksum = "a49042c6d3b66a9fe6b2b5a8bf0d39fc2ae1ee0310a2a26ffedd79fb097878dd" dependencies = [ - "alloy-primitives 0.7.4", - "alloy-sol-macro 0.7.4", + "alloy-primitives 0.7.6", + "alloy-sol-macro 0.7.6", "const-hex", "serde", ] @@ -618,9 +644,9 @@ dependencies = [ [[package]] name = "c-kzg" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3130f3d8717cc02e668a896af24984d5d5d4e8bf12e278e982e0f1bd88a0f9af" +checksum = "cdf100c4cea8f207e883ff91ca886d621d8a166cb04971dfaa9bb8fd99ed95df" dependencies = [ "blst", "cc", @@ -2829,8 +2855,8 @@ dependencies = [ [[package]] name = "revm" -version = "8.0.0" -source = "git+https://github.com/NomicFoundation/revm?rev=48d55ef#48d55ef74263b0f5512101225439e42872309fae" +version = "9.0.0" +source = "git+https://github.com/NomicFoundation/revm?rev=3c66641#3c6664156fec3af4489e4a85db87c02a75188fba" dependencies = [ "auto_impl", "dyn-clone", @@ -2841,8 +2867,8 @@ dependencies = [ [[package]] name = "revm-interpreter" -version = "4.0.0" -source = "git+https://github.com/NomicFoundation/revm?rev=48d55ef#48d55ef74263b0f5512101225439e42872309fae" +version = "5.0.0" +source = "git+https://github.com/NomicFoundation/revm?rev=3c66641#3c6664156fec3af4489e4a85db87c02a75188fba" dependencies = [ "revm-primitives", "serde", @@ -2850,8 +2876,8 @@ dependencies = [ [[package]] name = "revm-precompile" -version = "6.0.0" -source = "git+https://github.com/NomicFoundation/revm?rev=48d55ef#48d55ef74263b0f5512101225439e42872309fae" +version = "7.0.0" +source = "git+https://github.com/NomicFoundation/revm?rev=3c66641#3c6664156fec3af4489e4a85db87c02a75188fba" dependencies = [ "aurora-engine-modexp", "c-kzg", @@ -2865,10 +2891,11 @@ dependencies = [ [[package]] name = "revm-primitives" -version = "3.1.1" -source = "git+https://github.com/NomicFoundation/revm?rev=48d55ef#48d55ef74263b0f5512101225439e42872309fae" +version = "4.0.0" +source = "git+https://github.com/NomicFoundation/revm?rev=3c66641#3c6664156fec3af4489e4a85db87c02a75188fba" dependencies = [ - "alloy-primitives 0.7.4", + "alloy-eips", + "alloy-primitives 0.7.6", "auto_impl", "bitflags 2.5.0", "bitvec", @@ -2923,9 +2950,9 @@ dependencies = [ [[package]] name = "ruint" -version = "1.12.1" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f308135fef9fc398342da5472ce7c484529df23743fb7c734e0f3d472971e62" +checksum = "2c3cc4c2511671f327125da14133d0c5c5d137f006a1017a16f557bc85b16286" dependencies = [ "alloy-rlp", "ark-ff 0.3.0", @@ -2947,9 +2974,9 @@ dependencies = [ [[package]] name = "ruint-macro" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f86854cf50259291520509879a5c294c3c9a4c334e9ff65071c51e42ef1e2343" +checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" [[package]] name = "rustc-demangle" @@ -3347,9 +3374,9 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8db114c44cf843a8bacd37a146e37987a0b823a0e8bc4fdc610c9c72ab397a5" +checksum = "8d71e19bca02c807c9faa67b5a47673ff231b6e7449b251695188522f1dc44b2" dependencies = [ "paste", "proc-macro2", diff --git a/crates/edr_eth/Cargo.toml b/crates/edr_eth/Cargo.toml index 6b1d1fa8d..6f04ffb43 100644 --- a/crates/edr_eth/Cargo.toml +++ b/crates/edr_eth/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" [dependencies] anyhow = "1.0.75" alloy-rlp = { version = "0.3", default-features = false, features = ["derive"] } -c-kzg = { version = "1.0.0", default-features = false } +c-kzg = { version = "1.0.2", default-features = false } hash-db = { version = "0.15.2", default-features = false } hash256-std-hasher = { version = "0.15.2", default-features = false } hashbrown = { version = "0.14.3", default-features = false, features = ["ahash", "allocator-api2", "inline-more"] } @@ -15,7 +15,7 @@ itertools = { version = "0.10.5", default-features = false, features = ["use_all k256 = { version = "0.13.1", default-features = false, features = ["arithmetic", "ecdsa", "pkcs8", ] } log = { version = "0.4.17", default-features = false } once_cell = { version = "1.18.0", default-features = false, features = ["alloc", "race", "std"] } -revm-primitives = { git = "https://github.com/NomicFoundation/revm", rev = "48d55ef", version = "3.1", default-features = false, features = ["c-kzg", "hashbrown"] } +revm-primitives = { git = "https://github.com/NomicFoundation/revm", rev = "3c66641", version = "4.0", default-features = false, features = ["c-kzg", "hashbrown"] } serde = { version = "1.0.147", default-features = false, features = ["derive"], optional = true } sha2 = { version = "0.10.8", default-features = false } sha3 = { version = "0.10.8", default-features = false } diff --git a/crates/edr_eth/src/access_list.rs b/crates/edr_eth/src/access_list.rs index 9790b3ea6..5744aa4c7 100644 --- a/crates/edr_eth/src/access_list.rs +++ b/crates/edr_eth/src/access_list.rs @@ -26,56 +26,3 @@ impl From for Vec { src.0 } } - -/// Access list item -#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, RlpDecodable, RlpEncodable)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] -pub struct AccessListItem { - /// Accessed address - pub address: Address, - /// Accessed storage keys - // In JSON, we have to accept null as well for storage key, but we don't want to change the - // type to Option> as that's invalid in RLP. - #[cfg_attr( - feature = "serde", - serde(deserialize_with = "crate::serde::optional_to_default") - )] - pub storage_keys: Vec, -} - -impl From for (Address, Vec) { - fn from(value: AccessListItem) -> Self { - ( - value.address, - value - .storage_keys - .into_iter() - .map(|key| U256::from_be_bytes(key.0)) - .collect(), - ) - } -} - -impl From for Vec<(Address, Vec)> { - fn from(value: AccessList) -> Self { - value.0.into_iter().map(AccessListItem::into).collect() - } -} - -#[cfg(all(test, feature = "serde"))] -mod tests { - use serde_json::json; - - use super::*; - - #[test] - fn access_list_item() { - let item_json = json!( { - "address": "0x1234567890123456789012345678901234567890", - "storageKeys": null, - }); - - let _item: AccessListItem = serde_json::from_value(item_json).unwrap(); - } -} diff --git a/crates/edr_eth/src/lib.rs b/crates/edr_eth/src/lib.rs index e9bfb3cf5..87f48ef91 100644 --- a/crates/edr_eth/src/lib.rs +++ b/crates/edr_eth/src/lib.rs @@ -5,8 +5,8 @@ //! Ethereum types as needed by EDR. In particular, they are based on the same //! primitive types as `revm`. -/// Ethereum access list types -pub mod access_list; +// /// Ethereum access list types +// pub mod access_list; /// Ethereum account types pub mod account; /// Parent beacon types and constants @@ -46,7 +46,8 @@ pub mod withdrawal; pub use c_kzg::{Blob, Bytes48, BYTES_PER_BLOB, BYTES_PER_COMMITMENT, BYTES_PER_PROOF}; pub use revm_primitives::{ alloy_primitives::{Bloom, BloomInput, B512, B64, U64}, - hex_literal, AccountInfo, Address, Bytecode, Bytes, HashMap, HashSet, SpecId, B256, U256, + hex_literal, AccessList, AccessListItem, AccountInfo, Address, Bytecode, Bytes, HashMap, + HashSet, SpecId, B256, U256, }; pub use self::block_spec::{BlockSpec, BlockTag, Eip1898BlockSpec, PreEip1898BlockSpec}; diff --git a/crates/edr_eth/src/transaction.rs b/crates/edr_eth/src/transaction.rs index 193706ded..42bc3380c 100644 --- a/crates/edr_eth/src/transaction.rs +++ b/crates/edr_eth/src/transaction.rs @@ -17,10 +17,7 @@ pub use revm_primitives::alloy_primitives::TxKind; use revm_primitives::B256; pub use self::r#type::TransactionType; -use crate::{ - access_list::{AccessList, AccessListItem}, - Address, Bytes, U256, -}; +use crate::{AccessListItem, Address, Bytes, U256}; pub const INVALID_TX_TYPE_ERROR_MESSAGE: &str = "invalid tx type"; @@ -55,44 +52,15 @@ pub enum Signed { Eip4844(signed::Eip4844), } -/// Trait for signed transactions. -pub trait SignedTransaction: Transaction { - /// Returns the caller/signer of the transaction. - fn caller(&self) -> &Address; -} - -pub trait Transaction { - /// Returns the access list of the transaction, if any. - fn access_list(&self) -> Option<&AccessList>; - - /// Returns the input data of the transaction. - fn data(&self) -> &Bytes; - +pub trait Transaction: revm_primitives::Transaction { /// The effective gas price of the transaction, calculated using the /// provided block base fee. fn effective_gas_price(&self, block_base_fee: U256) -> U256; - /// The maximum amount of gas the transaction can use. - fn gas_limit(&self) -> u64; - - /// The gas price the sender is willing to pay. - fn gas_price(&self) -> U256; - - /// Returns what kind of transaction this is. - fn kind(&self) -> TxKind; - /// The maximum fee per gas the sender is willing to pay. Only applicable /// for post-EIP-1559 transactions. fn max_fee_per_gas(&self) -> Option; - /// The maximum fee per blob gas the sender is willing to pay. Only - /// applicable for EIP-4844 transactions. - fn max_fee_per_blob_gas(&self) -> Option; - - /// The maximum priority fee per gas the sender is willing to pay. Only - /// applicable for post-EIP-1559 transactions. - fn max_priority_fee_per_gas(&self) -> Option; - /// The transaction's nonce. fn nonce(&self) -> u64; @@ -105,17 +73,14 @@ pub trait Transaction { /// The type of the transaction. fn transaction_type(&self) -> TransactionType; - - /// The value of the transaction. - fn value(&self) -> U256; } pub fn max_cost(transaction: &impl Transaction) -> U256 { - U256::from(transaction.gas_limit()).saturating_mul(transaction.gas_price()) + U256::from(transaction.gas_limit()).saturating_mul(*transaction.gas_price()) } pub fn upfront_cost(transaction: &impl Transaction) -> U256 { - max_cost(transaction).saturating_add(transaction.value()) + max_cost(transaction).saturating_add(*transaction.value()) } /// Represents _all_ transaction requests received from RPC diff --git a/crates/edr_eth/src/transaction/request/eip1559.rs b/crates/edr_eth/src/transaction/request/eip1559.rs index a72fad60a..670cbdfb3 100644 --- a/crates/edr_eth/src/transaction/request/eip1559.rs +++ b/crates/edr_eth/src/transaction/request/eip1559.rs @@ -5,11 +5,10 @@ use k256::SecretKey; use revm_primitives::keccak256; use crate::{ - access_list::AccessListItem, signature::{self, public_key_to_address, Fakeable, SignatureError}, transaction::{self, TxKind}, utils::envelop_bytes, - Address, Bytes, B256, U256, + AccessListItem, Address, Bytes, B256, U256, }; #[derive(Clone, Debug, PartialEq, Eq, RlpDecodable, RlpEncodable)] diff --git a/crates/edr_eth/src/transaction/request/eip2930.rs b/crates/edr_eth/src/transaction/request/eip2930.rs index a200f36a7..26b2c53d9 100644 --- a/crates/edr_eth/src/transaction/request/eip2930.rs +++ b/crates/edr_eth/src/transaction/request/eip2930.rs @@ -5,11 +5,10 @@ use k256::SecretKey; use revm_primitives::keccak256; use crate::{ - access_list::AccessListItem, signature::{self, public_key_to_address, Fakeable, SignatureError}, transaction::{self, TxKind}, utils::envelop_bytes, - Address, Bytes, B256, U256, + AccessListItem, Address, Bytes, B256, U256, }; #[derive(Clone, Debug, PartialEq, Eq, RlpEncodable)] diff --git a/crates/edr_eth/src/transaction/request/eip4844.rs b/crates/edr_eth/src/transaction/request/eip4844.rs index 46340e81a..da02ea17d 100644 --- a/crates/edr_eth/src/transaction/request/eip4844.rs +++ b/crates/edr_eth/src/transaction/request/eip4844.rs @@ -5,11 +5,10 @@ use k256::SecretKey; use revm_primitives::keccak256; use crate::{ - access_list::AccessListItem, signature::{self, public_key_to_address, Fakeable, SignatureError}, transaction, utils::envelop_bytes, - Address, Bytes, B256, U256, + AccessListItem, Address, Bytes, B256, U256, }; #[derive(Clone, Debug, PartialEq, Eq, RlpEncodable)] diff --git a/crates/edr_eth/src/transaction/signed.rs b/crates/edr_eth/src/transaction/signed.rs index 5a9bd2385..15b94a812 100644 --- a/crates/edr_eth/src/transaction/signed.rs +++ b/crates/edr_eth/src/transaction/signed.rs @@ -5,7 +5,7 @@ mod eip4844; mod legacy; use alloy_rlp::{Buf, BufMut}; -use revm_primitives::{TransactTo, TxEnv}; +use revm_primitives::TxEnv; pub use self::{ eip155::Eip155, @@ -14,20 +14,8 @@ pub use self::{ eip4844::Eip4844, legacy::{Legacy, PreOrPostEip155}, }; -use super::{ - Signed, SignedTransaction, Transaction, TransactionType, TxKind, INVALID_TX_TYPE_ERROR_MESSAGE, -}; -use crate::{ - access_list::AccessList, signature::Signature, utils::enveloped, Address, Bytes, B256, U256, -}; - -/// Converts a `TxKind` to a `TransactTo`. -fn kind_to_transact_to(kind: TxKind) -> TransactTo { - match kind { - TxKind::Create => TransactTo::Create, - TxKind::Call(to) => TransactTo::Call(to), - } -} +use super::{Signed, Transaction, TransactionType, TxKind, INVALID_TX_TYPE_ERROR_MESSAGE}; +use crate::{signature::Signature, utils::enveloped, AccessListItem, Address, Bytes, B256, U256}; impl Signed { /// Whether this is a legacy (pre-EIP-155) transaction. @@ -55,28 +43,6 @@ impl Signed { matches!(self, Signed::Eip4844(_)) } - /// Retrieves the blob hashes of the transaction, if any. - pub fn blob_hashes(&self) -> Option> { - match self { - Signed::PreEip155Legacy(_) - | Signed::PostEip155Legacy(_) - | Signed::Eip2930(_) - | Signed::Eip1559(_) => None, - Signed::Eip4844(tx) => Some(tx.blob_hashes.clone()), - } - } - - /// Returns the chain id of the transaction. - pub fn chain_id(&self) -> Option { - match self { - Signed::PreEip155Legacy(_) => None, - Signed::PostEip155Legacy(t) => Some(t.chain_id()), - Signed::Eip2930(t) => Some(t.chain_id), - Signed::Eip1559(t) => Some(t.chain_id), - Signed::Eip4844(t) => Some(t.chain_id), - } - } - pub fn as_legacy(&self) -> Option<&self::legacy::Legacy> { match self { Signed::PreEip155Legacy(tx) => Some(tx), @@ -206,49 +172,74 @@ impl From for TxEnv { } } -impl SignedTransaction for Signed { - fn caller(&self) -> &Address { +impl Transaction for Signed { + fn effective_gas_price(&self, block_base_fee: U256) -> U256 { match self { - Signed::PreEip155Legacy(tx) => tx.caller(), - Signed::PostEip155Legacy(tx) => tx.caller(), - Signed::Eip2930(tx) => tx.caller(), - Signed::Eip1559(tx) => tx.caller(), - Signed::Eip4844(tx) => tx.caller(), + Signed::PreEip155Legacy(tx) => tx.gas_price, + Signed::PostEip155Legacy(tx) => tx.gas_price, + Signed::Eip2930(tx) => tx.gas_price, + Signed::Eip1559(tx) => tx + .max_fee_per_gas + .min(block_base_fee + tx.max_priority_fee_per_gas), + Signed::Eip4844(tx) => tx + .max_fee_per_gas + .min(block_base_fee + tx.max_priority_fee_per_gas), } } -} -impl Transaction for Signed { - fn access_list(&self) -> Option<&AccessList> { + fn max_fee_per_gas(&self) -> Option { match self { - Signed::PreEip155Legacy(_) | Signed::PostEip155Legacy(_) => None, - Signed::Eip2930(tx) => Some(&tx.access_list), - Signed::Eip1559(tx) => Some(&tx.access_list), - Signed::Eip4844(tx) => Some(&tx.access_list), + Signed::PreEip155Legacy(_) | Signed::PostEip155Legacy(_) | Signed::Eip2930(_) => None, + Signed::Eip1559(tx) => Some(tx.max_fee_per_gas), + Signed::Eip4844(tx) => Some(tx.max_fee_per_gas), } } - fn data(&self) -> &Bytes { + fn nonce(&self) -> u64 { match self { - Signed::PreEip155Legacy(tx) => &tx.input, - Signed::PostEip155Legacy(tx) => &tx.input, - Signed::Eip2930(tx) => &tx.input, - Signed::Eip1559(tx) => &tx.input, - Signed::Eip4844(tx) => &tx.input, + Signed::PreEip155Legacy(t) => t.nonce, + Signed::PostEip155Legacy(t) => t.nonce, + Signed::Eip2930(t) => t.nonce, + Signed::Eip1559(t) => t.nonce, + Signed::Eip4844(t) => t.nonce, } } - fn effective_gas_price(&self, block_base_fee: U256) -> U256 { + fn total_blob_gas(&self) -> Option { match self { - Signed::PreEip155Legacy(tx) => tx.gas_price, - Signed::PostEip155Legacy(tx) => tx.gas_price, - Signed::Eip2930(tx) => tx.gas_price, - Signed::Eip1559(tx) => tx - .max_fee_per_gas - .min(block_base_fee + tx.max_priority_fee_per_gas), - Signed::Eip4844(tx) => tx - .max_fee_per_gas - .min(block_base_fee + tx.max_priority_fee_per_gas), + Signed::Eip4844(tx) => Some(tx.total_blob_gas()), + _ => None, + } + } + + fn transaction_hash(&self) -> &B256 { + match self { + Signed::PreEip155Legacy(t) => t.hash(), + Signed::PostEip155Legacy(t) => t.hash(), + Signed::Eip2930(t) => t.hash(), + Signed::Eip1559(t) => t.hash(), + Signed::Eip4844(t) => t.hash(), + } + } + + fn transaction_type(&self) -> TransactionType { + match self { + Signed::PreEip155Legacy(_) | Signed::PostEip155Legacy(_) => TransactionType::Legacy, + Signed::Eip2930(_) => TransactionType::Eip2930, + Signed::Eip1559(_) => TransactionType::Eip1559, + Signed::Eip4844(_) => TransactionType::Eip4844, + } + } +} + +impl revm_primitives::Transaction for Signed { + fn caller(&self) -> &Address { + match self { + Signed::PreEip155Legacy(tx) => tx.caller(), + Signed::PostEip155Legacy(tx) => tx.caller(), + Signed::Eip2930(tx) => tx.caller(), + Signed::Eip1559(tx) => tx.caller(), + Signed::Eip4844(tx) => tx.caller(), } } @@ -262,13 +253,13 @@ impl Transaction for Signed { } } - fn gas_price(&self) -> U256 { + fn gas_price(&self) -> &U256 { match self { - Signed::PreEip155Legacy(tx) => tx.gas_price, - Signed::PostEip155Legacy(tx) => tx.gas_price, - Signed::Eip2930(tx) => tx.gas_price, - Signed::Eip1559(tx) => tx.max_fee_per_gas, - Signed::Eip4844(tx) => tx.max_fee_per_gas, + Signed::PreEip155Legacy(tx) => &tx.gas_price, + Signed::PostEip155Legacy(tx) => &tx.gas_price, + Signed::Eip2930(tx) => &tx.gas_price, + Signed::Eip1559(tx) => &tx.max_fee_per_gas, + Signed::Eip4844(tx) => &tx.max_fee_per_gas, } } @@ -282,84 +273,88 @@ impl Transaction for Signed { } } - fn max_fee_per_gas(&self) -> Option { + fn value(&self) -> &U256 { match self { - Signed::PreEip155Legacy(_) | Signed::PostEip155Legacy(_) | Signed::Eip2930(_) => None, - Signed::Eip1559(tx) => Some(tx.max_fee_per_gas), - Signed::Eip4844(tx) => Some(tx.max_fee_per_gas), + Signed::PreEip155Legacy(tx) => &tx.value, + Signed::PostEip155Legacy(tx) => &tx.value, + Signed::Eip2930(tx) => &tx.value, + Signed::Eip1559(tx) => &tx.value, + Signed::Eip4844(tx) => &tx.value, } } - fn max_fee_per_blob_gas(&self) -> Option { + fn data(&self) -> &Bytes { match self { - Signed::PreEip155Legacy(_) - | Signed::PostEip155Legacy(_) - | Signed::Eip2930(_) - | Signed::Eip1559(_) => None, - Signed::Eip4844(tx) => Some(tx.max_fee_per_blob_gas), + Signed::PreEip155Legacy(tx) => &tx.input, + Signed::PostEip155Legacy(tx) => &tx.input, + Signed::Eip2930(tx) => &tx.input, + Signed::Eip1559(tx) => &tx.input, + Signed::Eip4844(tx) => &tx.input, } } - fn max_priority_fee_per_gas(&self) -> Option { - match self { - Signed::PreEip155Legacy(_) | Signed::PostEip155Legacy(_) | Signed::Eip2930(_) => None, - Signed::Eip1559(tx) => Some(tx.max_priority_fee_per_gas), - Signed::Eip4844(tx) => Some(tx.max_priority_fee_per_gas), - } + fn nonce_opt(&self) -> Option { + Some(self.nonce()) } - fn nonce(&self) -> u64 { + fn chain_id(&self) -> Option { match self { - Signed::PreEip155Legacy(t) => t.nonce, - Signed::PostEip155Legacy(t) => t.nonce, - Signed::Eip2930(t) => t.nonce, - Signed::Eip1559(t) => t.nonce, - Signed::Eip4844(t) => t.nonce, + Signed::PreEip155Legacy(_) => None, + Signed::PostEip155Legacy(t) => Some(t.chain_id()), + Signed::Eip2930(t) => Some(t.chain_id), + Signed::Eip1559(t) => Some(t.chain_id), + Signed::Eip4844(t) => Some(t.chain_id), } } - fn total_blob_gas(&self) -> Option { + fn access_list(&self) -> &[AccessListItem] { match self { - Signed::Eip4844(tx) => Some(tx.total_blob_gas()), - _ => None, + Signed::PreEip155Legacy(_) | Signed::PostEip155Legacy(_) => &[], + Signed::Eip2930(tx) => &tx.access_list.0, + Signed::Eip1559(tx) => &tx.access_list.0, + Signed::Eip4844(tx) => &tx.access_list.0, } } - fn transaction_hash(&self) -> &B256 { + fn max_priority_fee_per_gas(&self) -> Option<&U256> { match self { - Signed::PreEip155Legacy(t) => t.hash(), - Signed::PostEip155Legacy(t) => t.hash(), - Signed::Eip2930(t) => t.hash(), - Signed::Eip1559(t) => t.hash(), - Signed::Eip4844(t) => t.hash(), + Signed::PreEip155Legacy(_) | Signed::PostEip155Legacy(_) | Signed::Eip2930(_) => None, + Signed::Eip1559(tx) => Some(&tx.max_priority_fee_per_gas), + Signed::Eip4844(tx) => Some(&tx.max_priority_fee_per_gas), } } - fn transaction_type(&self) -> TransactionType { + fn blob_hashes(&self) -> &[B256] { match self { - Signed::PreEip155Legacy(_) | Signed::PostEip155Legacy(_) => TransactionType::Legacy, - Signed::Eip2930(_) => TransactionType::Eip2930, - Signed::Eip1559(_) => TransactionType::Eip1559, - Signed::Eip4844(_) => TransactionType::Eip4844, + Signed::PreEip155Legacy(_) + | Signed::PostEip155Legacy(_) + | Signed::Eip2930(_) + | Signed::Eip1559(_) => &[], + Signed::Eip4844(tx) => &tx.blob_hashes, } } - fn value(&self) -> U256 { + fn max_fee_per_blob_gas(&self) -> Option<&U256> { match self { - Signed::PreEip155Legacy(tx) => tx.value, - Signed::PostEip155Legacy(tx) => tx.value, - Signed::Eip2930(tx) => tx.value, - Signed::Eip1559(tx) => tx.value, - Signed::Eip4844(tx) => tx.value, + Signed::PreEip155Legacy(_) + | Signed::PostEip155Legacy(_) + | Signed::Eip2930(_) + | Signed::Eip1559(_) => None, + Signed::Eip4844(tx) => Some(&tx.max_fee_per_blob_gas), } } } +impl revm_primitives::TransactionValidation for Signed { + type ValidationError = revm_primitives::InvalidTransaction; +} + #[cfg(test)] mod tests { use std::sync::OnceLock; use alloy_rlp::Decodable as _; + use revm_primitives::{AccessList, Transaction as _}; use super::*; use crate::{signature, transaction, Bytes}; diff --git a/crates/edr_eth/src/transaction/signed/eip155.rs b/crates/edr_eth/src/transaction/signed/eip155.rs index 6f6c50f9d..d29342d4b 100644 --- a/crates/edr_eth/src/transaction/signed/eip155.rs +++ b/crates/edr_eth/src/transaction/signed/eip155.rs @@ -1,10 +1,8 @@ use std::sync::OnceLock; use alloy_rlp::RlpEncodable; -use hashbrown::HashMap; use revm_primitives::{keccak256, TxEnv}; -use super::kind_to_transact_to; use crate::{ signature::{self, Signature}, transaction::{self, TxKind}, @@ -70,7 +68,7 @@ impl From for TxEnv { caller: *value.caller(), gas_limit: value.gas_limit, gas_price: value.gas_price, - transact_to: kind_to_transact_to(value.kind), + transact_to: value.kind, value: value.value, data: value.input, nonce: Some(value.nonce), @@ -79,8 +77,6 @@ impl From for TxEnv { gas_priority_fee: None, blob_hashes: Vec::new(), max_fee_per_blob_gas: None, - eof_initcodes: Vec::new(), - eof_initcodes_hashed: HashMap::new(), } } } diff --git a/crates/edr_eth/src/transaction/signed/eip1559.rs b/crates/edr_eth/src/transaction/signed/eip1559.rs index 50627f4c1..2d9172b5f 100644 --- a/crates/edr_eth/src/transaction/signed/eip1559.rs +++ b/crates/edr_eth/src/transaction/signed/eip1559.rs @@ -1,16 +1,13 @@ use std::sync::OnceLock; use alloy_rlp::{RlpDecodable, RlpEncodable}; -use hashbrown::HashMap; use revm_primitives::{keccak256, TxEnv}; -use super::kind_to_transact_to; use crate::{ - access_list::AccessList, signature::{self, Fakeable}, transaction::{self, TxKind}, utils::envelop_bytes, - Address, Bytes, B256, U256, + AccessList, Address, Bytes, B256, U256, }; #[derive(Clone, Debug, Eq, RlpEncodable)] @@ -60,7 +57,7 @@ impl From for TxEnv { caller: *value.caller(), gas_limit: value.gas_limit, gas_price: value.max_fee_per_gas, - transact_to: kind_to_transact_to(value.kind), + transact_to: value.kind, value: value.value, data: value.input, nonce: Some(value.nonce), @@ -69,8 +66,6 @@ impl From for TxEnv { gas_priority_fee: Some(value.max_priority_fee_per_gas), blob_hashes: Vec::new(), max_fee_per_blob_gas: None, - eof_initcodes: Vec::new(), - eof_initcodes_hashed: HashMap::new(), } } } @@ -154,8 +149,8 @@ mod tests { use super::*; use crate::{ - access_list::AccessListItem, signature::{secret_key_from_str, secret_key_to_address}, + AccessListItem, }; const DUMMY_SECRET_KEY: &str = diff --git a/crates/edr_eth/src/transaction/signed/eip2930.rs b/crates/edr_eth/src/transaction/signed/eip2930.rs index d90ad7be3..3a9a02430 100644 --- a/crates/edr_eth/src/transaction/signed/eip2930.rs +++ b/crates/edr_eth/src/transaction/signed/eip2930.rs @@ -1,16 +1,13 @@ use std::sync::OnceLock; use alloy_rlp::{RlpDecodable, RlpEncodable}; -use hashbrown::HashMap; use revm_primitives::{keccak256, TxEnv}; -use super::kind_to_transact_to; use crate::{ - access_list::AccessList, signature::{self, Fakeable}, transaction::{self, TxKind}, utils::envelop_bytes, - Address, Bytes, B256, U256, + AccessList, Address, Bytes, B256, U256, }; #[derive(Clone, Debug, Eq, RlpEncodable)] @@ -59,7 +56,7 @@ impl From for TxEnv { caller: *value.caller(), gas_limit: value.gas_limit, gas_price: value.gas_price, - transact_to: kind_to_transact_to(value.kind), + transact_to: value.kind, value: value.value, data: value.input, nonce: Some(value.nonce), @@ -68,8 +65,6 @@ impl From for TxEnv { gas_priority_fee: None, blob_hashes: Vec::new(), max_fee_per_blob_gas: None, - eof_initcodes: Vec::new(), - eof_initcodes_hashed: HashMap::new(), } } } @@ -148,7 +143,7 @@ mod tests { use k256::SecretKey; use super::*; - use crate::{access_list::AccessListItem, signature::secret_key_from_str}; + use crate::{signature::secret_key_from_str, AccessListItem}; fn dummy_request() -> transaction::request::Eip2930 { let to = Address::from_str("0xc014ba5ec014ba5ec014ba5ec014ba5ec014ba5e").unwrap(); diff --git a/crates/edr_eth/src/transaction/signed/eip4844.rs b/crates/edr_eth/src/transaction/signed/eip4844.rs index dd74df5d9..cec271e89 100644 --- a/crates/edr_eth/src/transaction/signed/eip4844.rs +++ b/crates/edr_eth/src/transaction/signed/eip4844.rs @@ -1,15 +1,13 @@ use std::sync::OnceLock; use alloy_rlp::{RlpDecodable, RlpEncodable}; -use hashbrown::HashMap; use revm_primitives::{keccak256, TransactTo, TxEnv, GAS_PER_BLOB}; use crate::{ - access_list::AccessList, signature::{self, Fakeable}, transaction, utils::envelop_bytes, - Address, Bytes, B256, U256, + AccessList, Address, Bytes, B256, U256, }; #[derive(Clone, Debug, Eq, RlpEncodable)] @@ -79,8 +77,6 @@ impl From for TxEnv { gas_priority_fee: Some(value.max_priority_fee_per_gas), blob_hashes: value.blob_hashes, max_fee_per_blob_gas: Some(value.max_fee_per_blob_gas), - eof_initcodes: Vec::new(), - eof_initcodes_hashed: HashMap::new(), } } } diff --git a/crates/edr_eth/src/transaction/signed/legacy.rs b/crates/edr_eth/src/transaction/signed/legacy.rs index 9a1597840..18720fc16 100644 --- a/crates/edr_eth/src/transaction/signed/legacy.rs +++ b/crates/edr_eth/src/transaction/signed/legacy.rs @@ -1,10 +1,8 @@ use std::sync::OnceLock; use alloy_rlp::{RlpDecodable, RlpEncodable}; -use hashbrown::HashMap; use revm_primitives::{keccak256, TxEnv}; -use super::kind_to_transact_to; use crate::{ signature::{self, Fakeable}, transaction::{self, TxKind}, @@ -49,7 +47,7 @@ impl From for TxEnv { caller: *value.caller(), gas_limit: value.gas_limit, gas_price: value.gas_price, - transact_to: kind_to_transact_to(value.kind), + transact_to: value.kind, value: value.value, data: value.input, nonce: Some(value.nonce), @@ -58,8 +56,6 @@ impl From for TxEnv { gas_priority_fee: None, blob_hashes: Vec::new(), max_fee_per_blob_gas: None, - eof_initcodes: Vec::new(), - eof_initcodes_hashed: HashMap::new(), } } } diff --git a/crates/edr_evm/Cargo.toml b/crates/edr_evm/Cargo.toml index e6568df89..54527adfa 100644 --- a/crates/edr_evm/Cargo.toml +++ b/crates/edr_evm/Cargo.toml @@ -19,7 +19,7 @@ parking_lot = { version = "0.12.1", default-features = false } edr_defaults = { version = "0.3.5", path = "../edr_defaults" } edr_eth = { version = "0.3.5", path = "../edr_eth", features = ["rand", "serde"] } edr_rpc_eth = { version = "0.3.5", path = "../edr_rpc_eth" } -revm = { git = "https://github.com/NomicFoundation/revm", rev = "48d55ef", version = "8.0", default-features = false, features = ["c-kzg", "dev", "serde"] } +revm = { git = "https://github.com/NomicFoundation/revm", rev = "3c66641", version = "9.0", default-features = false, features = ["c-kzg", "dev", "serde"] } rpds = { version = "1.1.0", default-features = false, features = ["std"] } serde = { version = "1.0.158", default-features = false, features = ["std"] } serde_json = { version = "1.0.94", default-features = false, features = ["std"] } diff --git a/crates/edr_evm/src/block/local.rs b/crates/edr_evm/src/block/local.rs index a90d1bfec..84bf6b9f9 100644 --- a/crates/edr_evm/src/block/local.rs +++ b/crates/edr_evm/src/block/local.rs @@ -7,7 +7,7 @@ use edr_eth::{ receipt::{BlockReceipt, TransactionReceipt, TypedReceipt}, trie, withdrawal::Withdrawal, - B256, + SpecId, B256, }; use itertools::izip; use revm::primitives::keccak256; @@ -16,7 +16,7 @@ use crate::{ blockchain::BlockchainError, chain_spec::{ChainSpec, SyncChainSpec}, transaction::DetailedTransaction, - Block, SpecId, SyncBlock, + Block, SyncBlock, }; /// A locally mined block, which contains complete information. diff --git a/crates/edr_evm/src/blockchain/storage/sparse.rs b/crates/edr_evm/src/blockchain/storage/sparse.rs index 5e3b624ac..1377e9f89 100644 --- a/crates/edr_evm/src/blockchain/storage/sparse.rs +++ b/crates/edr_evm/src/blockchain/storage/sparse.rs @@ -6,10 +6,10 @@ use edr_eth::{ transaction::Transaction, Address, B256, U256, }; -use revm::primitives::{HashMap, HashSet}; +use revm::primitives::{hash_map::OccupiedError, HashMap, HashSet}; use super::InsertError; -use crate::{chain_spec::ChainSpec, hash_map::OccupiedError, Block}; +use crate::{chain_spec::ChainSpec, Block}; /// A storage solution for storing a subset of a Blockchain's blocks in-memory. #[derive(Debug)] diff --git a/crates/edr_evm/src/chain_spec.rs b/crates/edr_evm/src/chain_spec.rs index 7a8a7b79a..89401122a 100644 --- a/crates/edr_evm/src/chain_spec.rs +++ b/crates/edr_evm/src/chain_spec.rs @@ -1,7 +1,10 @@ use std::fmt::Debug; use alloy_rlp::RlpEncodable; -use edr_eth::{transaction::SignedTransaction, B256}; +use edr_eth::{ + transaction::{self, SignedTransaction}, + B256, +}; use edr_rpc_eth::spec::{EthRpcSpec, RpcSpec}; use revm::primitives::TxEnv; use serde::{de::DeserializeOwned, Serialize}; @@ -49,9 +52,7 @@ impl revm::primitives::ChainSpec for L1ChainSpec { type HaltReason = revm::primitives::HaltReason; - type Transaction = revm::primitives::TxEnv; - - type TransactionValidationError = revm::primitives::InvalidTransaction; + type Transaction = transaction::Signed; } impl ChainSpec for L1ChainSpec { diff --git a/crates/edr_evm/src/debug_trace.rs b/crates/edr_evm/src/debug_trace.rs index c58de6fcd..1ff1cc42c 100644 --- a/crates/edr_evm/src/debug_trace.rs +++ b/crates/edr_evm/src/debug_trace.rs @@ -1,4 +1,4 @@ -use std::{collections::HashMap, fmt::Debug, sync::Arc}; +use std::{collections::HashMap, fmt::Debug, marker::PhantomData, sync::Arc}; use edr_eth::{ transaction::{self, Transaction}, @@ -7,12 +7,15 @@ use edr_eth::{ }; use revm::{ db::DatabaseComponents, - handler::register::EvmHandler, + handler::{register::EvmHandler, CfgEnvWithChainSpec}, interpreter::{ opcode::{self, BoxedInstruction, InstructionTables, OpCode}, InstructionResult, Interpreter, InterpreterResult, }, - primitives::{hex, Address, BlockEnv, Bytes, ExecutionResult, ResultAndState, SpecId, U256}, + primitives::{ + hex, Address, Block as _, Bytes, EVMError, ExecutionResult, InvalidTransaction, + ResultAndState, SpecId, Transaction as _, U256, + }, Database, Evm, EvmContext, JournalEntry, }; @@ -25,12 +28,18 @@ use crate::{ }; /// EIP-3155 and raw tracers. -pub struct Eip3155AndRawTracers { - eip3155: TracerEip3155, +pub struct Eip3155AndRawTracers +where + ChainSpecT: revm::primitives::ChainSpec, +{ + eip3155: TracerEip3155, raw: TraceCollector, } -impl Eip3155AndRawTracers { +impl Eip3155AndRawTracers +where + ChainSpecT: revm::primitives::ChainSpec, +{ /// Creates a new instance. pub fn new(config: DebugTraceConfig, verbose_tracing: bool) -> Self { Self { @@ -40,24 +49,31 @@ impl Eip3155AndRawTracers { } } -impl GetContextData for Eip3155AndRawTracers { +impl GetContextData for Eip3155AndRawTracers +where + ChainSpecT: revm::primitives::ChainSpec, +{ fn get_context_data(&mut self) -> &mut TraceCollector { &mut self.raw } } -impl GetContextData for Eip3155AndRawTracers { - fn get_context_data(&mut self) -> &mut TracerEip3155 { +impl GetContextData> for Eip3155AndRawTracers +where + ChainSpecT: revm::primitives::ChainSpec, +{ + fn get_context_data(&mut self) -> &mut TracerEip3155 { &mut self.eip3155 } } /// Register EIP-3155 and trace collector handles. pub fn register_eip_3155_and_raw_tracers_handles< + ChainSpecT: revm::primitives::ChainSpec, DatabaseT: Database, - ContextT: GetContextData + GetContextData, + ContextT: GetContextData + GetContextData>, >( - handler: &mut EvmHandler<'_, ContextT, DatabaseT>, + handler: &mut EvmHandler<'_, ChainSpecT, ContextT, DatabaseT>, ) where DatabaseT::Error: Debug, { @@ -74,32 +90,33 @@ pub fn debug_trace_transaction( mut state: Box>, evm_config: CfgEnvWithChainSpec, trace_config: DebugTraceConfig, - block_env: BlockEnv, - transactions: Vec, + block: ChainSpecT::Block, + transactions: Vec, transaction_hash: &B256, verbose_tracing: bool, -) -> Result> +) -> Result> where + ChainSpecT: revm::primitives::ChainSpec< + TransactionValidationError: std::error::Error + From, + >, BlockchainErrorT: Debug + Send, StateErrorT: Debug + Send, { - if evm_config.handler_cfg.spec_id < SpecId::SPURIOUS_DRAGON { + let l1_spec_id = evm_config.spec_id.into(); + if l1_spec_id < SpecId::SPURIOUS_DRAGON { // Matching Hardhat Network behaviour: https://github.com/NomicFoundation/hardhat/blob/af7e4ce6a18601ec9cd6d4aa335fa7e24450e638/packages/hardhat-core/src/internal/hardhat-network/provider/vm/ethereumjs.ts#L427 return Err(DebugTraceError::InvalidSpecId { - spec_id: evm_config.handler_cfg.spec_id, + spec_id: l1_spec_id, }); } - if evm_config.handler_cfg.spec_id > SpecId::MERGE && block_env.prevrandao.is_none() { - return Err(TransactionError::MissingPrevrandao.into()); - } - for transaction in transactions { if transaction.transaction_hash() == transaction_hash { let mut tracer = Eip3155AndRawTracers::new(trace_config, verbose_tracing); let ResultAndState { result, .. } = { let mut evm = Evm::builder() + .with_chain_spec::() .with_ref_db(DatabaseComponents { state: state.as_ref(), block_hash: blockchain, @@ -107,8 +124,8 @@ where .with_external_context(&mut tracer) .with_cfg_env_with_handler_cfg(evm_config) .append_handler_register(register_eip_3155_and_raw_tracers_handles) - .with_block_env(block_env) - .with_tx_env(transaction.into()) + .with_block_env(block) + .with_tx_env(transaction) .build(); evm.transact().map_err(TransactionError::from)? @@ -118,12 +135,13 @@ where } else { let ResultAndState { state: changes, .. } = { let mut evm = Evm::builder() + .with_chain_spec::() .with_ref_db(DatabaseComponents { state: state.as_ref(), block_hash: blockchain, }) .with_cfg_env_with_handler_cfg(evm_config.clone()) - .with_block_env(block_env.clone()) + .with_block_env(block.clone()) .with_tx_env(transaction.into()) .build(); @@ -136,15 +154,18 @@ where Err(DebugTraceError::InvalidTransactionHash { transaction_hash: *transaction_hash, - block_number: block_env.number, + block_number: block.number(), }) } /// Convert an `ExecutionResult` to a `DebugTraceResult`. -pub fn execution_result_to_debug_result( - execution_result: ExecutionResult, - tracer: Eip3155AndRawTracers, -) -> DebugTraceResultWithTraces { +pub fn execution_result_to_debug_result( + execution_result: ExecutionResult, + tracer: Eip3155AndRawTracers, +) -> DebugTraceResultWithTraces +where + ChainSpecT: revm::primitives::ChainSpec, +{ let Eip3155AndRawTracers { eip3155, raw } = tracer; let traces = raw.into_traces(); @@ -187,7 +208,10 @@ pub struct DebugTraceConfig { /// Debug trace error. #[derive(Debug, thiserror::Error)] -pub enum DebugTraceError { +pub enum DebugTraceError +where + ChainSpecT: revm::primitives::ChainSpec, +{ /// Invalid hardfork spec argument. #[error("Invalid spec id: {spec_id:?}. `debug_traceTransaction` is not supported prior to Spurious Dragon")] InvalidSpecId { @@ -204,7 +228,7 @@ pub enum DebugTraceError { }, /// Transaction error. #[error(transparent)] - TransactionError(#[from] TransactionError), + TransactionError(#[from] TransactionError), } /// Result of a `debug_traceTransaction` call. @@ -268,10 +292,11 @@ pub struct DebugTraceLogItem { /// Register EIP-3155 tracer handles. pub fn register_eip_3155_tracer_handles< + ChainSpecT: revm::primitives::ChainSpec, DatabaseT: Database, - ContextT: GetContextData, + ContextT: GetContextData>, >( - handler: &mut EvmHandler<'_, ContextT, DatabaseT>, + handler: &mut EvmHandler<'_, ChainSpecT, ContextT, DatabaseT>, ) { // Every instruction inside flat table that is going to be wrapped by tracer // calls. @@ -289,6 +314,7 @@ pub fn register_eip_3155_tracer_handles< .into_iter() .map(|i| instruction_handler(i)) .collect::>(), + InstructionTables::_Unused(_) => unreachable!(), }; // cast vector to array. @@ -318,14 +344,16 @@ pub fn register_eip_3155_tracer_handles< /// Outer closure that calls tracer for every instruction. fn instruction_handler< 'a, - ContextT: GetContextData, + ChainSpecT: revm::primitives::ChainSpec, + ContextT: GetContextData>, DatabaseT: Database, - Instruction: Fn(&mut Interpreter, &mut Evm<'a, ContextT, DatabaseT>) + 'a, + Instruction: Fn(&mut Interpreter, &mut Evm<'a, ChainSpecT, ContextT, DatabaseT>) + 'a, >( instruction: Instruction, -) -> BoxedInstruction<'a, Evm<'a, ContextT, DatabaseT>> { +) -> BoxedInstruction<'a, Evm<'a, ChainSpecT, ContextT, DatabaseT>> { Box::new( - move |interpreter: &mut Interpreter, host: &mut Evm<'a, ContextT, DatabaseT>| { + move |interpreter: &mut Interpreter, + host: &mut Evm<'a, ChainSpecT, ContextT, DatabaseT>| { // SAFETY: as the PC was already incremented we need to subtract 1 to preserve // the old Inspector behavior. interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.sub(1) }; @@ -351,7 +379,10 @@ fn instruction_handler< /// An EIP-3155 compatible EVM tracer. #[derive(Debug)] -pub struct TracerEip3155 { +pub struct TracerEip3155 +where + ChainSpecT: revm::primitives::ChainSpec, +{ config: DebugTraceConfig, logs: Vec, contract_address: Address, @@ -363,9 +394,13 @@ pub struct TracerEip3155 { stack: Vec, // Contract-specific storage storage: HashMap>, + phantom: PhantomData, } -impl TracerEip3155 { +impl TracerEip3155 +where + ChainSpecT: revm::primitives::ChainSpec, +{ /// Create a new tracer. pub fn new(config: DebugTraceConfig) -> Self { Self { @@ -379,6 +414,7 @@ impl TracerEip3155 { memory: Vec::default(), mem_size: 0, storage: HashMap::default(), + phantom: PhantomData, } } @@ -404,7 +440,7 @@ impl TracerEip3155 { fn step_end( &mut self, interp: &mut Interpreter, - context: &mut EvmContext, + context: &mut EvmContext, ) { let depth = context.journaled_state.depth(); @@ -486,8 +522,11 @@ impl TracerEip3155 { } } -impl GetContextData for TracerEip3155 { - fn get_context_data(&mut self) -> &mut TracerEip3155 { +impl GetContextData> for TracerEip3155 +where + ChainSpecT: revm::primitives::ChainSpec, +{ + fn get_context_data(&mut self) -> &mut TracerEip3155 { self } } diff --git a/crates/edr_evm/src/state/trie.rs b/crates/edr_evm/src/state/trie.rs index f1908eb57..1399a2e3a 100644 --- a/crates/edr_evm/src/state/trie.rs +++ b/crates/edr_evm/src/state/trie.rs @@ -251,8 +251,10 @@ impl StateDebug for TrieState { #[cfg(test)] mod tests { + use edr_eth::Bytes; + use super::*; - use crate::{state::AccountModifierFn, Bytes}; + use crate::state::AccountModifierFn; #[test] fn test_trie_state_clone() -> anyhow::Result<()> { diff --git a/crates/edr_evm/src/state/trie/state_trie.rs b/crates/edr_evm/src/state/trie/state_trie.rs index e0210e5eb..cc4cb65e4 100644 --- a/crates/edr_evm/src/state/trie/state_trie.rs +++ b/crates/edr_evm/src/state/trie/state_trie.rs @@ -1,12 +1,9 @@ use std::sync::Arc; use alloy_rlp::Decodable; -use edr_eth::account::BasicAccount; +use edr_eth::{account::BasicAccount, AccountInfo, Address, B256}; -use crate::{ - state::trie::{persistent_memory_db::PersistentMemoryDB, trie_query::TrieQuery}, - AccountInfo, Address, B256, -}; +use crate::state::trie::{persistent_memory_db::PersistentMemoryDB, trie_query::TrieQuery}; #[derive(Debug)] pub(super) struct StateTrie { diff --git a/crates/edr_evm/src/state/trie/storage_trie.rs b/crates/edr_evm/src/state/trie/storage_trie.rs index 189b6827b..7679c52ec 100644 --- a/crates/edr_evm/src/state/trie/storage_trie.rs +++ b/crates/edr_evm/src/state/trie/storage_trie.rs @@ -1,12 +1,10 @@ use std::{collections::BTreeMap, sync::Arc}; use alloy_rlp::Decodable; +use edr_eth::{B256, U256}; use hasher::{Hasher, HasherKeccak}; -use crate::{ - state::trie::{persistent_memory_db::PersistentMemoryDB, trie_query::TrieQuery}, - B256, U256, -}; +use crate::state::trie::{persistent_memory_db::PersistentMemoryDB, trie_query::TrieQuery}; #[derive(Debug)] pub(super) struct StorageTrie { diff --git a/crates/edr_evm/src/state/trie/trie_query.rs b/crates/edr_evm/src/state/trie/trie_query.rs index 2e2870d12..6d05f3b4c 100644 --- a/crates/edr_evm/src/state/trie/trie_query.rs +++ b/crates/edr_evm/src/state/trie/trie_query.rs @@ -1,9 +1,10 @@ use std::sync::Arc; use cita_trie::{PatriciaTrie, Trie}; +use edr_eth::B256; use hasher::{Hasher, HasherKeccak}; -use crate::{state::trie::persistent_memory_db::PersistentMemoryDB, B256}; +use crate::state::trie::persistent_memory_db::PersistentMemoryDB; /// A light wrapper over the DB of the Merkle-Patricia trie that allows us to /// read, add and remove elements. diff --git a/crates/edr_evm/src/trace.rs b/crates/edr_evm/src/trace.rs index ae0db95aa..857675ab5 100644 --- a/crates/edr_evm/src/trace.rs +++ b/crates/edr_evm/src/trace.rs @@ -16,10 +16,11 @@ use crate::debug::GetContextData; /// Registers trace collector handles to the EVM handler. pub fn register_trace_collector_handles< + ChainSpecT: revm::primitives::ChainSpec, DatabaseT: Database, ContextT: GetContextData, >( - handler: &mut EvmHandler<'_, ContextT, DatabaseT>, + handler: &mut EvmHandler<'_, ChainSpecT, ContextT, DatabaseT>, ) where DatabaseT::Error: Debug, { @@ -39,6 +40,7 @@ pub fn register_trace_collector_handles< .into_iter() .map(|i| instruction_handler(i)) .collect::>(), + InstructionTables::_Unused(_) => unreachable!(), }; // cast vector to array. diff --git a/crates/edr_evm/src/transaction.rs b/crates/edr_evm/src/transaction.rs index 99d1c796a..5c64ccf65 100644 --- a/crates/edr_evm/src/transaction.rs +++ b/crates/edr_evm/src/transaction.rs @@ -8,48 +8,51 @@ use std::fmt::Debug; pub use edr_eth::transaction::*; use edr_eth::{Address, SpecId, U256}; use revm::{ - db::DatabaseComponentError, - interpreter::gas::validate_initial_tx_gas, - primitives::{EVMError, InvalidHeader, InvalidTransaction}, + db::DatabaseComponentError, interpreter::gas::validate_initial_tx_gas, primitives::EVMError, }; pub use self::detailed::*; /// Invalid transaction error #[derive(Debug, thiserror::Error)] -pub enum TransactionError { +pub enum TransactionError +where + ChainErrorT: revm::primitives::ChainSpec, +{ /// Blockchain errors #[error(transparent)] - Blockchain(#[from] BE), - #[error("{0}")] + Blockchain(BlockchainErrorT), /// Custom errors + #[error("{0}")] Custom(String), /// EIP-1559 is not supported #[error("Cannot run transaction: EIP 1559 is not activated.")] Eip1559Unsupported, + /// Invalid block header + #[error(transparent)] + InvalidHeader(revm::primitives::InvalidHeader), /// Corrupt transaction data - #[error("Invalid transaction: {0:?}")] - InvalidTransaction(InvalidTransaction), - /// The transaction is expected to have a prevrandao, as the executor's - /// config is on a post-merge hardfork. - #[error("Post-merge transaction is missing prevrandao")] - MissingPrevrandao, + #[error(transparent)] + InvalidTransaction(ChainErrorT::TransactionValidationError), /// State errors #[error(transparent)] - State(SE), + State(StateErrorT), } -impl From>> for TransactionError +impl + From>> + for TransactionError where - BE: Debug + Send, - SE: Debug + Send, + ChainSpecT: revm::primitives::ChainSpec, + BlockchainErrorT: Debug + Send, + StateErrorT: Debug + Send, { - fn from(error: EVMError>) -> Self { + fn from( + error: EVMError>, + ) -> Self { match error { - EVMError::Transaction(e) => Self::InvalidTransaction(e), - EVMError::Header( - InvalidHeader::ExcessBlobGasNotSet | InvalidHeader::PrevrandaoNotSet, - ) => unreachable!("error: {error:?}"), + EVMError::Transaction(error) => Self::InvalidTransaction(error), + EVMError::Header(error) => Self::InvalidHeader(error), EVMError::Database(DatabaseComponentError::State(e)) => Self::State(e), EVMError::Database(DatabaseComponentError::BlockHash(e)) => Self::Blockchain(e), EVMError::Custom(error) => Self::Custom(error), @@ -95,20 +98,11 @@ pub fn validate( /// Calculates the initial cost of a transaction. pub fn initial_cost(transaction: &impl Transaction, spec_id: SpecId) -> u64 { - let access_list = transaction - .access_list() - .cloned() - .map(Vec::<(Address, Vec)>::from); - validate_initial_tx_gas( spec_id, transaction.data().as_ref(), transaction.kind() == TxKind::Create, - access_list - .as_ref() - .map_or(&[], |access_list| access_list.as_slice()), - // TODO: https://github.com/NomicFoundation/edr/issues/427 - &[], + transaction.access_list(), ) } diff --git a/crates/edr_provider/Cargo.toml b/crates/edr_provider/Cargo.toml index 4f6d28f6b..25fd11889 100644 --- a/crates/edr_provider/Cargo.toml +++ b/crates/edr_provider/Cargo.toml @@ -4,7 +4,7 @@ version = "0.3.5" edition = "2021" [dependencies] -alloy-dyn-abi = { version = "0.7.4", features = ["eip712"] } +alloy-dyn-abi = { version = "0.7.6", features = ["eip712"] } alloy-sol-types = { version = "0.5.1", default-features = false, features = ["std"] } anyhow = { version = "1.0.75", optional = true } auto_impl = { version = "1.2", default-features = false } diff --git a/crates/edr_rpc_eth/src/call_request.rs b/crates/edr_rpc_eth/src/call_request.rs index 2965a5b1c..5e722d3aa 100644 --- a/crates/edr_rpc_eth/src/call_request.rs +++ b/crates/edr_rpc_eth/src/call_request.rs @@ -1,4 +1,4 @@ -use edr_eth::{access_list::AccessListItem, Address, Bytes, B256, U256}; +use edr_eth::{AccessListItem, Address, Bytes, B256, U256}; /// For specifying input to methods requiring a transaction object, like /// `eth_call` and `eth_estimateGas` diff --git a/crates/edr_rpc_eth/src/transaction.rs b/crates/edr_rpc_eth/src/transaction.rs index 73759d7c3..facf132fe 100644 --- a/crates/edr_rpc_eth/src/transaction.rs +++ b/crates/edr_rpc_eth/src/transaction.rs @@ -1,10 +1,9 @@ use std::sync::OnceLock; use edr_eth::{ - access_list::AccessListItem, signature, transaction::{self, TxKind}, - Address, Bytes, B256, U256, + AccessListItem, Address, Bytes, B256, U256, }; /// RPC transaction From 705cbc9c59bcf623379ab73c2fdf8ff93678f987 Mon Sep 17 00:00:00 2001 From: Wodann Date: Fri, 21 Jun 2024 03:25:57 +0000 Subject: [PATCH 03/13] WIP --- Cargo.lock | 4 - crates/edr_eth/Cargo.toml | 3 +- crates/edr_eth/src/lib.rs | 4 +- crates/edr_eth/src/transaction.rs | 11 +- crates/edr_eth/src/transaction/signed.rs | 61 +++--- .../edr_eth/src/transaction/signed/eip155.rs | 23 +- .../edr_eth/src/transaction/signed/eip1559.rs | 21 +- .../edr_eth/src/transaction/signed/eip2930.rs | 21 +- .../edr_eth/src/transaction/signed/eip4844.rs | 21 +- .../edr_eth/src/transaction/signed/legacy.rs | 21 +- crates/edr_evm/Cargo.toml | 3 +- crates/edr_evm/src/block.rs | 5 +- crates/edr_evm/src/block/builder.rs | 77 ++----- crates/edr_evm/src/block/local.rs | 6 +- crates/edr_evm/src/block/remote.rs | 8 +- .../edr_evm/src/blockchain/storage/sparse.rs | 2 +- crates/edr_evm/src/chain_spec.rs | 22 +- crates/edr_evm/src/debug_trace.rs | 131 +++++------ crates/edr_evm/src/mempool.rs | 12 +- crates/edr_evm/src/miner.rs | 74 ++++--- crates/edr_evm/src/runtime.rs | 69 +++--- crates/edr_evm/src/state/diff.rs | 4 +- crates/edr_evm/src/state/trie/storage_trie.rs | 2 +- crates/edr_evm/src/trace.rs | 206 ++++++++++-------- crates/edr_evm/src/transaction.rs | 53 ++++- crates/edr_evm/src/transaction/detailed.rs | 2 +- crates/edr_evm/tests/blockchain.rs | 14 +- crates/edr_evm/tests/mem_pool.rs | 2 +- crates/edr_evm/tests/transaction.rs | 2 +- crates/edr_napi/src/logger.rs | 2 +- crates/edr_provider/src/data.rs | 12 +- crates/edr_provider/src/data/account.rs | 6 +- crates/edr_provider/src/data/call.rs | 9 +- crates/edr_provider/src/data/gas.rs | 26 +-- crates/edr_provider/src/debug_mine.rs | 2 +- crates/edr_provider/src/filter/criteria.rs | 3 +- crates/edr_provider/src/pending.rs | 2 +- crates/edr_provider/src/requests/debug.rs | 9 +- .../edr_provider/src/requests/eth/blocks.rs | 2 +- crates/edr_provider/src/requests/eth/call.rs | 6 +- crates/edr_provider/src/requests/eth/evm.rs | 4 +- .../edr_provider/src/requests/eth/filter.rs | 3 +- crates/edr_provider/src/requests/eth/gas.rs | 6 +- .../src/requests/eth/transactions.rs | 8 +- .../src/requests/hardhat/miner.rs | 4 +- .../edr_provider/src/requests/validation.rs | 4 +- crates/edr_provider/tests/eip4844.rs | 4 +- 47 files changed, 455 insertions(+), 541 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c36aed6a9..3f33389f2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2856,7 +2856,6 @@ dependencies = [ [[package]] name = "revm" version = "9.0.0" -source = "git+https://github.com/NomicFoundation/revm?rev=3c66641#3c6664156fec3af4489e4a85db87c02a75188fba" dependencies = [ "auto_impl", "dyn-clone", @@ -2868,7 +2867,6 @@ dependencies = [ [[package]] name = "revm-interpreter" version = "5.0.0" -source = "git+https://github.com/NomicFoundation/revm?rev=3c66641#3c6664156fec3af4489e4a85db87c02a75188fba" dependencies = [ "revm-primitives", "serde", @@ -2877,7 +2875,6 @@ dependencies = [ [[package]] name = "revm-precompile" version = "7.0.0" -source = "git+https://github.com/NomicFoundation/revm?rev=3c66641#3c6664156fec3af4489e4a85db87c02a75188fba" dependencies = [ "aurora-engine-modexp", "c-kzg", @@ -2892,7 +2889,6 @@ dependencies = [ [[package]] name = "revm-primitives" version = "4.0.0" -source = "git+https://github.com/NomicFoundation/revm?rev=3c66641#3c6664156fec3af4489e4a85db87c02a75188fba" dependencies = [ "alloy-eips", "alloy-primitives 0.7.6", diff --git a/crates/edr_eth/Cargo.toml b/crates/edr_eth/Cargo.toml index 6f04ffb43..046189272 100644 --- a/crates/edr_eth/Cargo.toml +++ b/crates/edr_eth/Cargo.toml @@ -15,7 +15,8 @@ itertools = { version = "0.10.5", default-features = false, features = ["use_all k256 = { version = "0.13.1", default-features = false, features = ["arithmetic", "ecdsa", "pkcs8", ] } log = { version = "0.4.17", default-features = false } once_cell = { version = "1.18.0", default-features = false, features = ["alloc", "race", "std"] } -revm-primitives = { git = "https://github.com/NomicFoundation/revm", rev = "3c66641", version = "4.0", default-features = false, features = ["c-kzg", "hashbrown"] } +# revm-primitives = { git = "https://github.com/NomicFoundation/revm", rev = "cb53dc8", version = "4.0", default-features = false, features = ["c-kzg", "hashbrown"] } +revm-primitives = { path = "../../../revm/crates/primitives", version = "4.0", default-features = false, features = ["c-kzg", "hashbrown"] } serde = { version = "1.0.147", default-features = false, features = ["derive"], optional = true } sha2 = { version = "0.10.8", default-features = false } sha3 = { version = "0.10.8", default-features = false } diff --git a/crates/edr_eth/src/lib.rs b/crates/edr_eth/src/lib.rs index 87f48ef91..352afd605 100644 --- a/crates/edr_eth/src/lib.rs +++ b/crates/edr_eth/src/lib.rs @@ -46,8 +46,8 @@ pub mod withdrawal; pub use c_kzg::{Blob, Bytes48, BYTES_PER_BLOB, BYTES_PER_COMMITMENT, BYTES_PER_PROOF}; pub use revm_primitives::{ alloy_primitives::{Bloom, BloomInput, B512, B64, U64}, - hex_literal, AccessList, AccessListItem, AccountInfo, Address, Bytecode, Bytes, HashMap, - HashSet, SpecId, B256, U256, + hex_literal, AccessList, AccessListItem, Account, AccountInfo, AccountStatus, Address, + Bytecode, Bytes, HashMap, HashSet, SpecId, B256, KECCAK_EMPTY, MAX_INITCODE_SIZE, U256, }; pub use self::block_spec::{BlockSpec, BlockTag, Eip1898BlockSpec, PreEip1898BlockSpec}; diff --git a/crates/edr_eth/src/transaction.rs b/crates/edr_eth/src/transaction.rs index 42bc3380c..32c41a7e5 100644 --- a/crates/edr_eth/src/transaction.rs +++ b/crates/edr_eth/src/transaction.rs @@ -13,8 +13,8 @@ pub mod request; pub mod signed; mod r#type; -pub use revm_primitives::alloy_primitives::TxKind; use revm_primitives::B256; +pub use revm_primitives::{alloy_primitives::TxKind, Transaction}; pub use self::r#type::TransactionType; use crate::{AccessListItem, Address, Bytes, U256}; @@ -52,7 +52,7 @@ pub enum Signed { Eip4844(signed::Eip4844), } -pub trait Transaction: revm_primitives::Transaction { +pub trait SignedTransaction: Transaction { /// The effective gas price of the transaction, calculated using the /// provided block base fee. fn effective_gas_price(&self, block_base_fee: U256) -> U256; @@ -61,9 +61,6 @@ pub trait Transaction: revm_primitives::Transaction { /// for post-EIP-1559 transactions. fn max_fee_per_gas(&self) -> Option; - /// The transaction's nonce. - fn nonce(&self) -> u64; - /// The total amount of blob gas used by the transaction. Only applicable /// for EIP-4844 transactions. fn total_blob_gas(&self) -> Option; @@ -75,11 +72,11 @@ pub trait Transaction: revm_primitives::Transaction { fn transaction_type(&self) -> TransactionType; } -pub fn max_cost(transaction: &impl Transaction) -> U256 { +pub fn max_cost(transaction: &impl SignedTransaction) -> U256 { U256::from(transaction.gas_limit()).saturating_mul(*transaction.gas_price()) } -pub fn upfront_cost(transaction: &impl Transaction) -> U256 { +pub fn upfront_cost(transaction: &impl SignedTransaction) -> U256 { max_cost(transaction).saturating_add(*transaction.value()) } diff --git a/crates/edr_eth/src/transaction/signed.rs b/crates/edr_eth/src/transaction/signed.rs index 15b94a812..0575c1974 100644 --- a/crates/edr_eth/src/transaction/signed.rs +++ b/crates/edr_eth/src/transaction/signed.rs @@ -4,8 +4,9 @@ mod eip2930; mod eip4844; mod legacy; +use std::sync::OnceLock; + use alloy_rlp::{Buf, BufMut}; -use revm_primitives::TxEnv; pub use self::{ eip155::Eip155, @@ -14,8 +15,12 @@ pub use self::{ eip4844::Eip4844, legacy::{Legacy, PreOrPostEip155}, }; -use super::{Signed, Transaction, TransactionType, TxKind, INVALID_TX_TYPE_ERROR_MESSAGE}; -use crate::{signature::Signature, utils::enveloped, AccessListItem, Address, Bytes, B256, U256}; +use super::{Signed, SignedTransaction, TransactionType, TxKind, INVALID_TX_TYPE_ERROR_MESSAGE}; +use crate::{ + signature::{Fakeable, Signature}, + utils::enveloped, + AccessListItem, Address, Bytes, B256, U256, +}; impl Signed { /// Whether this is a legacy (pre-EIP-155) transaction. @@ -121,6 +126,22 @@ impl alloy_rlp::Encodable for Signed { } } +impl Default for Signed { + fn default() -> Self { + // This implementation is necessary to be able to use `revm`'s builder pattern. + Self::PreEip155Legacy(Legacy { + nonce: 0, + gas_price: U256::ZERO, + gas_limit: u64::MAX, + kind: TxKind::Call(Address::ZERO), // will do nothing + value: U256::ZERO, + input: Bytes::new(), + signature: Fakeable::fake(Address::ZERO, Some(0)), + hash: OnceLock::new(), + }) + } +} + impl From for Signed { fn from(transaction: self::legacy::Legacy) -> Self { Self::PreEip155Legacy(transaction) @@ -160,19 +181,7 @@ impl From for Signed { } } -impl From for TxEnv { - fn from(value: Signed) -> Self { - match value { - Signed::PreEip155Legacy(tx) => tx.into(), - Signed::PostEip155Legacy(tx) => tx.into(), - Signed::Eip2930(tx) => tx.into(), - Signed::Eip1559(tx) => tx.into(), - Signed::Eip4844(tx) => tx.into(), - } - } -} - -impl Transaction for Signed { +impl SignedTransaction for Signed { fn effective_gas_price(&self, block_base_fee: U256) -> U256 { match self { Signed::PreEip155Legacy(tx) => tx.gas_price, @@ -195,16 +204,6 @@ impl Transaction for Signed { } } - fn nonce(&self) -> u64 { - match self { - Signed::PreEip155Legacy(t) => t.nonce, - Signed::PostEip155Legacy(t) => t.nonce, - Signed::Eip2930(t) => t.nonce, - Signed::Eip1559(t) => t.nonce, - Signed::Eip4844(t) => t.nonce, - } - } - fn total_blob_gas(&self) -> Option { match self { Signed::Eip4844(tx) => Some(tx.total_blob_gas()), @@ -293,8 +292,14 @@ impl revm_primitives::Transaction for Signed { } } - fn nonce_opt(&self) -> Option { - Some(self.nonce()) + fn nonce(&self) -> u64 { + match self { + Signed::PreEip155Legacy(t) => t.nonce, + Signed::PostEip155Legacy(t) => t.nonce, + Signed::Eip2930(t) => t.nonce, + Signed::Eip1559(t) => t.nonce, + Signed::Eip4844(t) => t.nonce, + } } fn chain_id(&self) -> Option { diff --git a/crates/edr_eth/src/transaction/signed/eip155.rs b/crates/edr_eth/src/transaction/signed/eip155.rs index d29342d4b..a58e64c68 100644 --- a/crates/edr_eth/src/transaction/signed/eip155.rs +++ b/crates/edr_eth/src/transaction/signed/eip155.rs @@ -1,7 +1,7 @@ use std::sync::OnceLock; use alloy_rlp::RlpEncodable; -use revm_primitives::{keccak256, TxEnv}; +use revm_primitives::keccak256; use crate::{ signature::{self, Signature}, @@ -60,27 +60,6 @@ impl From for Eip155 { } } -impl From for TxEnv { - fn from(value: Eip155) -> Self { - let chain_id = value.chain_id(); - - TxEnv { - caller: *value.caller(), - gas_limit: value.gas_limit, - gas_price: value.gas_price, - transact_to: value.kind, - value: value.value, - data: value.input, - nonce: Some(value.nonce), - chain_id: Some(chain_id), - access_list: Vec::new(), - gas_priority_fee: None, - blob_hashes: Vec::new(), - max_fee_per_blob_gas: None, - } - } -} - impl PartialEq for Eip155 { fn eq(&self, other: &Self) -> bool { self.nonce == other.nonce diff --git a/crates/edr_eth/src/transaction/signed/eip1559.rs b/crates/edr_eth/src/transaction/signed/eip1559.rs index 2d9172b5f..7395d9867 100644 --- a/crates/edr_eth/src/transaction/signed/eip1559.rs +++ b/crates/edr_eth/src/transaction/signed/eip1559.rs @@ -1,7 +1,7 @@ use std::sync::OnceLock; use alloy_rlp::{RlpDecodable, RlpEncodable}; -use revm_primitives::{keccak256, TxEnv}; +use revm_primitives::keccak256; use crate::{ signature::{self, Fakeable}, @@ -51,25 +51,6 @@ impl Eip1559 { } } -impl From for TxEnv { - fn from(value: Eip1559) -> Self { - TxEnv { - caller: *value.caller(), - gas_limit: value.gas_limit, - gas_price: value.max_fee_per_gas, - transact_to: value.kind, - value: value.value, - data: value.input, - nonce: Some(value.nonce), - chain_id: Some(value.chain_id), - access_list: value.access_list.into(), - gas_priority_fee: Some(value.max_priority_fee_per_gas), - blob_hashes: Vec::new(), - max_fee_per_blob_gas: None, - } - } -} - impl PartialEq for Eip1559 { fn eq(&self, other: &Self) -> bool { self.chain_id == other.chain_id diff --git a/crates/edr_eth/src/transaction/signed/eip2930.rs b/crates/edr_eth/src/transaction/signed/eip2930.rs index 3a9a02430..18467f519 100644 --- a/crates/edr_eth/src/transaction/signed/eip2930.rs +++ b/crates/edr_eth/src/transaction/signed/eip2930.rs @@ -1,7 +1,7 @@ use std::sync::OnceLock; use alloy_rlp::{RlpDecodable, RlpEncodable}; -use revm_primitives::{keccak256, TxEnv}; +use revm_primitives::keccak256; use crate::{ signature::{self, Fakeable}, @@ -50,25 +50,6 @@ impl Eip2930 { } } -impl From for TxEnv { - fn from(value: Eip2930) -> Self { - TxEnv { - caller: *value.caller(), - gas_limit: value.gas_limit, - gas_price: value.gas_price, - transact_to: value.kind, - value: value.value, - data: value.input, - nonce: Some(value.nonce), - chain_id: Some(value.chain_id), - access_list: value.access_list.into(), - gas_priority_fee: None, - blob_hashes: Vec::new(), - max_fee_per_blob_gas: None, - } - } -} - impl PartialEq for Eip2930 { fn eq(&self, other: &Self) -> bool { self.chain_id == other.chain_id diff --git a/crates/edr_eth/src/transaction/signed/eip4844.rs b/crates/edr_eth/src/transaction/signed/eip4844.rs index cec271e89..68736a330 100644 --- a/crates/edr_eth/src/transaction/signed/eip4844.rs +++ b/crates/edr_eth/src/transaction/signed/eip4844.rs @@ -1,7 +1,7 @@ use std::sync::OnceLock; use alloy_rlp::{RlpDecodable, RlpEncodable}; -use revm_primitives::{keccak256, TransactTo, TxEnv, GAS_PER_BLOB}; +use revm_primitives::{keccak256, GAS_PER_BLOB}; use crate::{ signature::{self, Fakeable}, @@ -62,25 +62,6 @@ impl Eip4844 { } } -impl From for TxEnv { - fn from(value: Eip4844) -> Self { - Self { - caller: *value.caller(), - gas_limit: value.gas_limit, - gas_price: value.max_fee_per_gas, - transact_to: TransactTo::Call(value.to), - value: value.value, - data: value.input, - nonce: Some(value.nonce), - chain_id: Some(value.chain_id), - access_list: value.access_list.into(), - gas_priority_fee: Some(value.max_priority_fee_per_gas), - blob_hashes: value.blob_hashes, - max_fee_per_blob_gas: Some(value.max_fee_per_blob_gas), - } - } -} - impl PartialEq for Eip4844 { fn eq(&self, other: &Self) -> bool { self.chain_id == other.chain_id diff --git a/crates/edr_eth/src/transaction/signed/legacy.rs b/crates/edr_eth/src/transaction/signed/legacy.rs index 18720fc16..651d74410 100644 --- a/crates/edr_eth/src/transaction/signed/legacy.rs +++ b/crates/edr_eth/src/transaction/signed/legacy.rs @@ -1,7 +1,7 @@ use std::sync::OnceLock; use alloy_rlp::{RlpDecodable, RlpEncodable}; -use revm_primitives::{keccak256, TxEnv}; +use revm_primitives::keccak256; use crate::{ signature::{self, Fakeable}, @@ -41,25 +41,6 @@ impl Legacy { } } -impl From for TxEnv { - fn from(value: Legacy) -> Self { - TxEnv { - caller: *value.caller(), - gas_limit: value.gas_limit, - gas_price: value.gas_price, - transact_to: value.kind, - value: value.value, - data: value.input, - nonce: Some(value.nonce), - chain_id: None, - access_list: Vec::new(), - gas_priority_fee: None, - blob_hashes: Vec::new(), - max_fee_per_blob_gas: None, - } - } -} - impl PartialEq for Legacy { fn eq(&self, other: &Self) -> bool { self.nonce == other.nonce diff --git a/crates/edr_evm/Cargo.toml b/crates/edr_evm/Cargo.toml index 54527adfa..85a73db56 100644 --- a/crates/edr_evm/Cargo.toml +++ b/crates/edr_evm/Cargo.toml @@ -19,7 +19,8 @@ parking_lot = { version = "0.12.1", default-features = false } edr_defaults = { version = "0.3.5", path = "../edr_defaults" } edr_eth = { version = "0.3.5", path = "../edr_eth", features = ["rand", "serde"] } edr_rpc_eth = { version = "0.3.5", path = "../edr_rpc_eth" } -revm = { git = "https://github.com/NomicFoundation/revm", rev = "3c66641", version = "9.0", default-features = false, features = ["c-kzg", "dev", "serde"] } +# revm = { git = "https://github.com/NomicFoundation/revm", rev = "cb53dc8", version = "9.0", default-features = false, features = ["c-kzg", "dev", "serde"] } +revm = { path = "../../../revm/crates/revm", version = "9.0", default-features = false, features = ["c-kzg", "dev", "serde"] } rpds = { version = "1.1.0", default-features = false, features = ["std"] } serde = { version = "1.0.158", default-features = false, features = ["std"] } serde_json = { version = "1.0.94", default-features = false, features = ["std"] } diff --git a/crates/edr_evm/src/block.rs b/crates/edr_evm/src/block.rs index 9e9a44184..21c3b0baf 100644 --- a/crates/edr_evm/src/block.rs +++ b/crates/edr_evm/src/block.rs @@ -6,7 +6,8 @@ use std::{fmt::Debug, sync::Arc}; use auto_impl::auto_impl; use edr_eth::{ - block, receipt::BlockReceipt, transaction::Transaction, withdrawal::Withdrawal, B256, U256, + block, receipt::BlockReceipt, transaction::SignedTransaction, withdrawal::Withdrawal, B256, + U256, }; pub use self::{ @@ -40,7 +41,7 @@ pub trait Block: Debug { fn rlp_size(&self) -> u64; /// Returns the block's transactions. - fn transactions(&self) -> &[ChainSpecT::SignedTransaction]; + fn transactions(&self) -> &[ChainSpecT::Transaction]; /// Returns the receipts of the block's transactions. fn transaction_receipts(&self) -> Result>, Self::Error>; diff --git a/crates/edr_evm/src/block/builder.rs b/crates/edr_evm/src/block/builder.rs index f2351ed9d..266fb196f 100644 --- a/crates/edr_evm/src/block/builder.rs +++ b/crates/edr_evm/src/block/builder.rs @@ -7,17 +7,17 @@ use edr_eth::{ block::{BlobGas, BlockOptions, PartialHeader}, log::{add_log_to_bloom, Log}, receipt::{TransactionReceipt, TypedReceipt, TypedReceiptData}, - transaction::{self, SignedTransaction as _, Transaction as _, TransactionType}, + transaction::{self, SignedTransaction as _, TransactionType}, trie::{ordered_trie_root, KECCAK_NULL_RLP}, withdrawal::Withdrawal, Address, Bloom, U256, }; use revm::{ - db::{DatabaseComponentError, DatabaseComponents, StateRef}, + db::{DatabaseComponents, StateRef}, handler::{CfgEnvWithChainSpec, EnvWithChainSpec}, primitives::{ - BlobExcessGasAndPrice, BlockEnv, EVMError, ExecutionResult, InvalidHeader, - InvalidTransaction, Output, ResultAndState, SpecId, MAX_BLOB_GAS_PER_BLOCK, + BlobExcessGasAndPrice, BlockEnv, ExecutionResult, Output, ResultAndState, SpecId, + Transaction as _, MAX_BLOB_GAS_PER_BLOCK, }, Context, DatabaseCommit, Evm, InnerEvmContext, }; @@ -28,6 +28,7 @@ use crate::{ chain_spec::{ChainSpec, L1ChainSpec}, debug::{DebugContext, EvmContext}, state::{AccountModifierFn, StateDebug, StateDiff, SyncState}, + transaction::TransactionError, SyncBlock, }; @@ -46,63 +47,19 @@ pub enum BlockBuilderCreationError { /// An error caused during execution of a transaction while building a block. #[derive(Debug, thiserror::Error)] -pub enum BlockTransactionError { - /// Blockchain errors - #[error(transparent)] - BlockHash(BE), - /// Custom error - #[error("{0}")] - Custom(String), +pub enum BlockTransactionError +where + ChainSpecT: revm::primitives::ChainSpec, +{ /// Transaction has higher gas limit than is remaining in block #[error("Transaction has a higher gas limit than the remaining gas in the block")] ExceedsBlockGasLimit, /// Transaction has higher blob gas usage than is remaining in block #[error("Transaction has higher blob gas usage than is remaining in block")] ExceedsBlockBlobGasLimit, - /// Sender does not have enough funds to send transaction. - #[error("Sender doesn't have enough funds to send tx. The max upfront cost is: {max_upfront_cost} and the sender's balance is: {sender_balance}.")] - InsufficientFunds { - /// The maximum upfront cost of the transaction - max_upfront_cost: U256, - /// The sender's balance - sender_balance: U256, - }, - /// Corrupt transaction data - #[error("Invalid transaction: {0:?}")] - InvalidTransaction(InvalidTransaction), - /// State errors + /// Transaction error #[error(transparent)] - State(SE), -} - -impl From>> - for BlockTransactionError -where - ChainSpecT: revm::primitives::ChainSpec, - BE: Debug + Send, - SE: Debug + Send, -{ - fn from(error: EVMError>) -> Self { - match error { - EVMError::Transaction(e) => match e { - InvalidTransaction::LackOfFundForMaxFee { fee, balance } => { - Self::InsufficientFunds { - max_upfront_cost: *fee, - sender_balance: *balance, - } - } - _ => Self::InvalidTransaction(e), - }, - EVMError::Database(DatabaseComponentError::State(e)) => Self::State(e), - EVMError::Database(DatabaseComponentError::BlockHash(e)) => Self::BlockHash(e), - // This case is a bug in our codebase for local blockchains, but it can happen that the - // remote returns incorrect block data in which case we should return a custom error. - EVMError::Header( - error @ (InvalidHeader::ExcessBlobGasNotSet | InvalidHeader::PrevrandaoNotSet), - ) => Self::Custom(error.to_string()), - EVMError::Custom(error) => Self::Custom(error), - } - } + Transaction(#[from] TransactionError), } /// The result of executing a transaction, along with the context in which it @@ -118,8 +75,10 @@ pub struct ExecutionResultWithContext< ChainSpecT: revm::primitives::ChainSpec, { /// The result of executing the transaction. - pub result: - Result, BlockTransactionError>, + pub result: Result< + ExecutionResult, + BlockTransactionError, + >, /// The context in which the transaction was executed. pub evm_context: EvmContext<'evm, L1ChainSpec, BlockchainErrorT, DebugDataT, StateT>, } @@ -294,7 +253,7 @@ impl BlockBuilder { let env = EnvWithChainSpec::new_with_cfg_env( self.cfg.clone(), block.clone(), - transaction.clone().into(), + transaction.clone(), ); let db = DatabaseComponents { @@ -340,7 +299,7 @@ impl BlockBuilder { Ok(result) => (evm_context, result), Err(error) => { return ExecutionResultWithContext { - result: Err(error.into()), + result: Err(TransactionError::from(error).into()), evm_context, }; } @@ -371,7 +330,7 @@ impl BlockBuilder { Ok(result) => (evm_context, result), Err(error) => { return ExecutionResultWithContext { - result: Err(error.into()), + result: Err(TransactionError::from(error).into()), evm_context, }; } diff --git a/crates/edr_evm/src/block/local.rs b/crates/edr_evm/src/block/local.rs index 84bf6b9f9..763605a52 100644 --- a/crates/edr_evm/src/block/local.rs +++ b/crates/edr_evm/src/block/local.rs @@ -24,7 +24,7 @@ use crate::{ #[rlp(trailing)] pub struct LocalBlock { header: block::Header, - transactions: Vec, + transactions: Vec, #[rlp(skip)] transaction_receipts: Vec>, ommers: Vec, @@ -56,7 +56,7 @@ impl LocalBlock { /// Constructs a new instance with the provided data. pub fn new( partial_header: PartialHeader, - transactions: Vec, + transactions: Vec, transaction_receipts: Vec>, ommers: Vec
, withdrawals: Option>, @@ -127,7 +127,7 @@ impl Block for LocalBlock { .expect("usize fits into u64") } - fn transactions(&self) -> &[ChainSpecT::SignedTransaction] { + fn transactions(&self) -> &[ChainSpecT::Transaction] { &self.transactions } diff --git a/crates/edr_evm/src/block/remote.rs b/crates/edr_evm/src/block/remote.rs index 31922eaf5..31c08d66f 100644 --- a/crates/edr_evm/src/block/remote.rs +++ b/crates/edr_evm/src/block/remote.rs @@ -3,7 +3,7 @@ use std::sync::{Arc, OnceLock}; use edr_eth::{ block::{BlobGas, Header}, receipt::BlockReceipt, - transaction::{self, Transaction}, + transaction::{self, SignedTransaction}, withdrawal::Withdrawal, B256, U256, }; @@ -43,7 +43,7 @@ pub enum CreationError { #[derive(Clone, Debug)] pub struct RemoteBlock { header: Header, - transactions: Vec, + transactions: Vec, /// The receipts of the block's transactions receipts: OnceLock>>, /// The hashes of the block's ommers @@ -78,7 +78,7 @@ impl Block for RemoteBlock { self.size } - fn transactions(&self) -> &[ChainSpecT::SignedTransaction] { + fn transactions(&self) -> &[ChainSpecT::Transaction] { &self.transactions } @@ -92,7 +92,7 @@ impl Block for RemoteBlock { self.rpc_client.get_transaction_receipts( self.transactions .iter() - .map(ChainSpecT::SignedTransaction::transaction_hash), + .map(ChainSpecT::Transaction::transaction_hash), ), ) }) diff --git a/crates/edr_evm/src/blockchain/storage/sparse.rs b/crates/edr_evm/src/blockchain/storage/sparse.rs index 1377e9f89..83928acbd 100644 --- a/crates/edr_evm/src/blockchain/storage/sparse.rs +++ b/crates/edr_evm/src/blockchain/storage/sparse.rs @@ -3,7 +3,7 @@ use std::{marker::PhantomData, sync::Arc}; use edr_eth::{ log::{matches_address_filter, matches_topics_filter}, receipt::BlockReceipt, - transaction::Transaction, + transaction::SignedTransaction, Address, B256, U256, }; use revm::primitives::{hash_map::OccupiedError, HashMap, HashSet}; diff --git a/crates/edr_evm/src/chain_spec.rs b/crates/edr_evm/src/chain_spec.rs index 89401122a..75a19d5cb 100644 --- a/crates/edr_evm/src/chain_spec.rs +++ b/crates/edr_evm/src/chain_spec.rs @@ -6,7 +6,6 @@ use edr_eth::{ B256, }; use edr_rpc_eth::spec::{EthRpcSpec, RpcSpec}; -use revm::primitives::TxEnv; use serde::{de::DeserializeOwned, Serialize}; use crate::{transaction::remote::EthRpcTransaction, EthRpcBlock, IntoRemoteBlock}; @@ -17,27 +16,20 @@ use crate::{transaction::remote::EthRpcTransaction, EthRpcBlock, IntoRemoteBlock pub trait ChainSpec: Debug + alloy_rlp::Encodable - + revm::primitives::ChainSpec - + RpcSpec< + + revm::primitives::ChainSpec< + Transaction: alloy_rlp::Encodable + Clone + Debug + PartialEq + Eq + SignedTransaction, + > + RpcSpec< RpcBlock<::RpcTransaction>: EthRpcBlock + IntoRemoteBlock, RpcTransaction: EthRpcTransaction, > + RpcSpec: EthRpcBlock> { - /// The type of signed transactions used by this chain. - type SignedTransaction: alloy_rlp::Encodable - + Clone - + Debug - + TryInto - + PartialEq - + Eq - + SignedTransaction; } /// A supertrait for [`ChainSpec`] that is safe to send between threads. -pub trait SyncChainSpec: ChainSpec + Send + Sync + 'static {} +pub trait SyncChainSpec: ChainSpec + Send + Sync + 'static {} impl SyncChainSpec for ChainSpecT where - ChainSpecT: ChainSpec + Send + Sync + 'static + ChainSpecT: ChainSpec + Send + Sync + 'static { } @@ -55,9 +47,7 @@ impl revm::primitives::ChainSpec for L1ChainSpec { type Transaction = transaction::Signed; } -impl ChainSpec for L1ChainSpec { - type SignedTransaction = edr_eth::transaction::Signed; -} +impl ChainSpec for L1ChainSpec {} impl RpcSpec for L1ChainSpec { type RpcBlock = ::RpcBlock where Data: Default + DeserializeOwned + Serialize; diff --git a/crates/edr_evm/src/debug_trace.rs b/crates/edr_evm/src/debug_trace.rs index 1ff1cc42c..a8c97eae6 100644 --- a/crates/edr_evm/src/debug_trace.rs +++ b/crates/edr_evm/src/debug_trace.rs @@ -1,26 +1,23 @@ use std::{collections::HashMap, fmt::Debug, marker::PhantomData, sync::Arc}; -use edr_eth::{ - transaction::{self, Transaction}, - utils::u256_to_padded_hex, - B256, -}; +use edr_eth::{transaction::SignedTransaction as _, utils::u256_to_padded_hex, B256}; use revm::{ db::DatabaseComponents, handler::{register::EvmHandler, CfgEnvWithChainSpec}, interpreter::{ - opcode::{self, BoxedInstruction, InstructionTables, OpCode}, - InstructionResult, Interpreter, InterpreterResult, + opcode::{self, DynInstruction, OpCode}, + Interpreter, InterpreterResult, }, primitives::{ - hex, Address, Block as _, Bytes, EVMError, ExecutionResult, InvalidTransaction, - ResultAndState, SpecId, Transaction as _, U256, + hex, Address, Block as _, Bytes, ExecutionResult, InvalidTransaction, ResultAndState, + SpecId, TransactionValidation, U256, }, - Database, Evm, EvmContext, JournalEntry, + Context, Database, Evm, EvmContext, JournalEntry, }; use crate::{ blockchain::SyncBlockchain, + chain_spec::ChainSpec, debug::GetContextData, state::SyncState, trace::{register_trace_collector_handles, Trace, TraceCollector}, @@ -33,7 +30,7 @@ where ChainSpecT: revm::primitives::ChainSpec, { eip3155: TracerEip3155, - raw: TraceCollector, + raw: TraceCollector, } impl Eip3155AndRawTracers @@ -49,11 +46,11 @@ where } } -impl GetContextData for Eip3155AndRawTracers +impl GetContextData> for Eip3155AndRawTracers where ChainSpecT: revm::primitives::ChainSpec, { - fn get_context_data(&mut self) -> &mut TraceCollector { + fn get_context_data(&mut self) -> &mut TraceCollector { &mut self.raw } } @@ -71,7 +68,7 @@ where pub fn register_eip_3155_and_raw_tracers_handles< ChainSpecT: revm::primitives::ChainSpec, DatabaseT: Database, - ContextT: GetContextData + GetContextData>, + ContextT: GetContextData> + GetContextData>, >( handler: &mut EvmHandler<'_, ChainSpecT, ContextT, DatabaseT>, ) where @@ -94,10 +91,14 @@ pub fn debug_trace_transaction( transactions: Vec, transaction_hash: &B256, verbose_tracing: bool, -) -> Result> +) -> Result< + DebugTraceResultWithTraces, + DebugTraceError, +> where - ChainSpecT: revm::primitives::ChainSpec< - TransactionValidationError: std::error::Error + From, + ChainSpecT: ChainSpec< + Block: Clone + Default, + Transaction: Default + TransactionValidation>, >, BlockchainErrorT: Debug + Send, StateErrorT: Debug + Send, @@ -154,7 +155,7 @@ where Err(DebugTraceError::InvalidTransactionHash { transaction_hash: *transaction_hash, - block_number: block.number(), + block_number: *block.number(), }) } @@ -162,7 +163,7 @@ where pub fn execution_result_to_debug_result( execution_result: ExecutionResult, tracer: Eip3155AndRawTracers, -) -> DebugTraceResultWithTraces +) -> DebugTraceResultWithTraces where ChainSpecT: revm::primitives::ChainSpec, { @@ -210,7 +211,7 @@ pub struct DebugTraceConfig { #[derive(Debug, thiserror::Error)] pub enum DebugTraceError where - ChainSpecT: revm::primitives::ChainSpec, + ChainSpecT: revm::primitives::ChainSpec, { /// Invalid hardfork spec argument. #[error("Invalid spec id: {spec_id:?}. `debug_traceTransaction` is not supported prior to Spurious Dragon")] @@ -247,11 +248,11 @@ pub struct DebugTraceResult { } /// Result of a `debug_traceTransaction` call with traces. -pub struct DebugTraceResultWithTraces { +pub struct DebugTraceResultWithTraces { /// The result of the transaction. pub result: DebugTraceResult, /// The raw traces of the debugged transaction. - pub traces: Vec, + pub traces: Vec>, } /// The output of an EIP-3155 trace. @@ -298,83 +299,55 @@ pub fn register_eip_3155_tracer_handles< >( handler: &mut EvmHandler<'_, ChainSpecT, ContextT, DatabaseT>, ) { - // Every instruction inside flat table that is going to be wrapped by tracer - // calls. - let table = handler - .instruction_table - .take() - .expect("Handler must have instruction table"); - - let table = match table { - InstructionTables::Plain(table) => table - .into_iter() - .map(|i| instruction_handler(i)) - .collect::>(), - InstructionTables::Boxed(table) => table - .into_iter() - .map(|i| instruction_handler(i)) - .collect::>(), - InstructionTables::_Unused(_) => unreachable!(), - }; + let table = &mut handler.instruction_table; - // cast vector to array. - handler.instruction_table = Some(InstructionTables::Boxed( - table.try_into().unwrap_or_else(|_| unreachable!()), - )); + // Update all instructions to call the instruction handler. + table.update_all(instruction_handler); // call outcome - let old_handle = handler.execution.insert_call_outcome.clone(); + let prev_handle = handler.execution.insert_call_outcome.clone(); handler.execution.insert_call_outcome = Arc::new(move |ctx, frame, shared_memory, outcome| { let tracer = ctx.external.get_context_data(); tracer.on_inner_frame_result(&outcome.result); - old_handle(ctx, frame, shared_memory, outcome) + prev_handle(ctx, frame, shared_memory, outcome) }); // create outcome - let old_handle = handler.execution.insert_create_outcome.clone(); + let prev_handle = handler.execution.insert_create_outcome.clone(); handler.execution.insert_create_outcome = Arc::new(move |ctx, frame, outcome| { let tracer = ctx.external.get_context_data(); tracer.on_inner_frame_result(&outcome.result); - old_handle(ctx, frame, outcome) + prev_handle(ctx, frame, outcome) }); } /// Outer closure that calls tracer for every instruction. -fn instruction_handler< - 'a, +fn instruction_handler( + prev: &DynInstruction<'_, Context>, + interpreter: &mut Interpreter, + host: &mut Context, +) where ChainSpecT: revm::primitives::ChainSpec, ContextT: GetContextData>, DatabaseT: Database, - Instruction: Fn(&mut Interpreter, &mut Evm<'a, ChainSpecT, ContextT, DatabaseT>) + 'a, ->( - instruction: Instruction, -) -> BoxedInstruction<'a, Evm<'a, ChainSpecT, ContextT, DatabaseT>> { - Box::new( - move |interpreter: &mut Interpreter, - host: &mut Evm<'a, ChainSpecT, ContextT, DatabaseT>| { - // SAFETY: as the PC was already incremented we need to subtract 1 to preserve - // the old Inspector behavior. - interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.sub(1) }; - - host.context.external.get_context_data().step(interpreter); - if interpreter.instruction_result != InstructionResult::Continue { - return; - } +{ + // SAFETY: as the PC was already incremented we need to subtract 1 to preserve + // the old Inspector behavior. + interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.sub(1) }; - // return PC to old value - interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.add(1) }; + host.external.get_context_data().step(interpreter); - // execute instruction. - instruction(interpreter, host); + // Reset PC to previous value. + interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.add(1) }; - host.context - .external - .get_context_data() - .step_end(interpreter, &mut host.context.evm); - }, - ) + // Execute instruction. + prev(interpreter, host); + + host.external + .get_context_data() + .step_end(interpreter, &host.evm); } /// An EIP-3155 compatible EVM tracer. @@ -418,7 +391,7 @@ where } } - fn step(&mut self, interp: &mut Interpreter) { + fn step(&mut self, interp: &Interpreter) { self.contract_address = interp.contract.target_address; self.gas_remaining = interp.gas().remaining(); @@ -439,8 +412,8 @@ where fn step_end( &mut self, - interp: &mut Interpreter, - context: &mut EvmContext, + interp: &Interpreter, + context: &EvmContext, ) { let depth = context.journaled_state.depth(); @@ -470,7 +443,7 @@ where .journal .last() .and_then(|v| v.last()); - if let Some(JournalEntry::StorageChange { address, key, .. }) = last_entry { + if let Some(JournalEntry::StorageChanged { address, key, .. }) = last_entry { let value = context.journaled_state.state[address].storage[key].present_value(); let contract_storage = self.storage.entry(self.contract_address).or_default(); contract_storage.insert(u256_to_padded_hex(key), u256_to_padded_hex(&value)); diff --git a/crates/edr_evm/src/mempool.rs b/crates/edr_evm/src/mempool.rs index 053654f67..47206a02c 100644 --- a/crates/edr_evm/src/mempool.rs +++ b/crates/edr_evm/src/mempool.rs @@ -1,13 +1,13 @@ use std::{cmp::Ordering, fmt::Debug, num::NonZeroU64}; use edr_eth::{ - transaction::{self, upfront_cost, SignedTransaction as _, Transaction as _}, + transaction::{self, upfront_cost, SignedTransaction as _}, Address, B256, U256, }; use indexmap::{map::Entry, IndexMap}; use revm::{ db::StateRef, - primitives::{AccountInfo, HashMap}, + primitives::{AccountInfo, HashMap, Transaction as _}, }; /// An iterator over pending transactions. @@ -573,8 +573,8 @@ fn validate_replacement_transaction( old_transaction: &transaction::Signed, new_transaction: &transaction::Signed, ) -> Result<(), MemPoolAddTransactionError> { - let min_new_max_fee_per_gas = min_new_fee(old_transaction.gas_price()); - if new_transaction.gas_price() < min_new_max_fee_per_gas { + let min_new_max_fee_per_gas = min_new_fee(*old_transaction.gas_price()); + if *new_transaction.gas_price() < min_new_max_fee_per_gas { return Err(MemPoolAddTransactionError::ReplacementMaxFeePerGasTooLow { min_new_max_fee_per_gas, transaction_nonce: old_transaction.nonce(), @@ -582,12 +582,12 @@ fn validate_replacement_transaction( } let min_new_max_priority_fee_per_gas = min_new_fee( - old_transaction + *old_transaction .max_priority_fee_per_gas() .unwrap_or_else(|| old_transaction.gas_price()), ); - if new_transaction + if *new_transaction .max_priority_fee_per_gas() .unwrap_or_else(|| new_transaction.gas_price()) < min_new_max_priority_fee_per_gas diff --git a/crates/edr_evm/src/miner.rs b/crates/edr_evm/src/miner.rs index 6f4d1e2a5..1b31fb5ce 100644 --- a/crates/edr_evm/src/miner.rs +++ b/crates/edr_evm/src/miner.rs @@ -3,10 +3,13 @@ use std::{cmp::Ordering, fmt::Debug, sync::Arc}; use edr_eth::{ block::{calculate_next_base_fee_per_blob_gas, BlockOptions}, signature::SignatureError, - transaction::{self, SignedTransaction as _, Transaction}, + transaction::{self, SignedTransaction}, U256, }; -use revm::primitives::{CfgEnvWithChainSpec, ExecutionResult, InvalidTransaction}; +use revm::{ + handler::CfgEnvWithChainSpec, + primitives::{ExecutionResult, InvalidTransaction, Transaction as _}, +}; use serde::{Deserialize, Serialize}; use crate::{ @@ -17,22 +20,29 @@ use crate::{ mempool::OrderedTransaction, state::{StateDiff, SyncState}, trace::Trace, + transaction::TransactionError, BlockBuilder, BlockTransactionError, BuildBlockResult, ExecutionResultWithContext, LocalBlock, MemPool, SyncBlock, }; /// The result of mining a block, after having been committed to the blockchain. #[derive(Debug)] -pub struct MineBlockResult { +pub struct MineBlockResult +where + ChainSpecT: revm::primitives::ChainSpec, +{ /// Mined block pub block: Arc>, /// Transaction results - pub transaction_results: Vec, + pub transaction_results: Vec>, /// Transaction traces - pub transaction_traces: Vec, + pub transaction_traces: Vec>, } -impl Clone for MineBlockResult { +impl Clone for MineBlockResult +where + ChainSpecT: revm::primitives::ChainSpec, +{ fn clone(&self) -> Self { Self { block: self.block.clone(), @@ -55,7 +65,7 @@ where /// State diff applied by block pub state_diff: StateDiff, /// Transaction results - pub transaction_results: Vec, + pub transaction_results: Vec>, } /// The type of ordering to use when selecting blocks to mine. @@ -69,19 +79,22 @@ pub enum MineOrdering { /// An error that occurred while mining a block. #[derive(Debug, thiserror::Error)] -pub enum MineBlockError { +pub enum MineBlockError +where + ChainSpecT: revm::primitives::ChainSpec, +{ /// An error that occurred while constructing a block builder. #[error(transparent)] BlockBuilderCreation(#[from] BlockBuilderCreationError), /// An error that occurred while executing a transaction. #[error(transparent)] - BlockTransaction(#[from] BlockTransactionError), + BlockTransaction(#[from] BlockTransactionError), /// An error that occurred while finalizing a block. #[error(transparent)] - BlockFinalize(SE), + BlockFinalize(StateErrorT), /// A blockchain error #[error(transparent)] - Blockchain(BE), + Blockchain(BlockchainErrorT), /// The block is expected to have a prevrandao, as the executor's config is /// on a post-merge hardfork. #[error("Post-merge transaction is missing prevrandao")] @@ -97,7 +110,7 @@ pub fn mine_block<'blockchain, 'evm, BlockchainErrorT, DebugDataT, StateErrorT>( blockchain: &'blockchain dyn SyncBlockchain, mut state: Box>, mem_pool: &MemPool, - cfg: &CfgEnvWithChainSpec, + cfg: &CfgEnvWithChainSpec, options: BlockOptions, min_gas_price: U256, mine_ordering: MineOrdering, @@ -114,7 +127,7 @@ pub fn mine_block<'blockchain, 'evm, BlockchainErrorT, DebugDataT, StateErrorT>( >, ) -> Result< MineBlockResultAndState, - MineBlockError, + MineBlockError, > where 'blockchain: 'evm, @@ -150,7 +163,7 @@ where let mut results = Vec::new(); while let Some(transaction) = pending_transactions.next() { - if transaction.gas_price() < min_gas_price { + if *transaction.gas_price() < min_gas_price { pending_transactions.remove_caller(transaction.caller()); continue; } @@ -164,9 +177,9 @@ where match result { Err( BlockTransactionError::ExceedsBlockGasLimit - | BlockTransactionError::InvalidTransaction( + | BlockTransactionError::Transaction(TransactionError::InvalidTransaction( InvalidTransaction::GasPriceLessThanBasefee, - ), + )), ) => { pending_transactions.remove_caller(&caller); state = evm_context.state; @@ -200,13 +213,16 @@ where /// An error that occurred while mining a block with a single transaction. #[derive(Debug, thiserror::Error)] -pub enum MineTransactionError { +pub enum MineTransactionError +where + ChainSpecT: revm::primitives::ChainSpec, +{ /// An error that occurred while constructing a block builder. #[error(transparent)] BlockBuilderCreation(#[from] BlockBuilderCreationError), /// An error that occurred while executing a transaction. #[error(transparent)] - BlockTransaction(#[from] BlockTransactionError), + BlockTransaction(#[from] BlockTransactionError), /// A blockchain error #[error(transparent)] Blockchain(BlockchainErrorT), @@ -289,7 +305,7 @@ pub fn mine_block_with_single_transaction< blockchain: &'blockchain dyn SyncBlockchain, state: Box>, transaction: transaction::Signed, - cfg: &CfgEnvWithChainSpec, + cfg: &CfgEnvWithChainSpec, options: BlockOptions, min_gas_price: U256, reward: U256, @@ -305,7 +321,7 @@ pub fn mine_block_with_single_transaction< >, ) -> Result< MineBlockResultAndState, - MineTransactionError, + MineTransactionError, > where 'blockchain: 'evm, @@ -316,10 +332,10 @@ where .max_priority_fee_per_gas() .unwrap_or_else(|| transaction.gas_price()); - if max_priority_fee_per_gas < min_gas_price { + if *max_priority_fee_per_gas < min_gas_price { return Err(MineTransactionError::PriorityFeeTooLow { expected: min_gas_price, - actual: max_priority_fee_per_gas, + actual: *max_priority_fee_per_gas, }); } @@ -333,10 +349,10 @@ where } } else { let gas_price = transaction.gas_price(); - if gas_price < base_fee_per_gas { + if *gas_price < base_fee_per_gas { return Err(MineTransactionError::GasPriceTooLow { expected: base_fee_per_gas, - actual: gas_price, + actual: *gas_price, }); } } @@ -348,10 +364,10 @@ where if let Some(max_fee_per_blob_gas) = transaction.max_fee_per_blob_gas() { let base_fee_per_blob_gas = calculate_next_base_fee_per_blob_gas(parent_block.header()); - if max_fee_per_blob_gas < base_fee_per_blob_gas { + if *max_fee_per_blob_gas < base_fee_per_blob_gas { return Err(MineTransactionError::MaxFeePerBlobGasTooLow { expected: base_fee_per_blob_gas, - actual: max_fee_per_blob_gas, + actual: *max_fee_per_blob_gas, }); } } @@ -409,12 +425,12 @@ where fn effective_miner_fee(transaction: &transaction::Signed, base_fee: Option) -> U256 { let max_fee_per_gas = transaction.gas_price(); - let max_priority_fee_per_gas = transaction + let max_priority_fee_per_gas = *transaction .max_priority_fee_per_gas() .unwrap_or(max_fee_per_gas); - base_fee.map_or(max_fee_per_gas, |base_fee| { - max_priority_fee_per_gas.min(max_fee_per_gas - base_fee) + base_fee.map_or(*max_fee_per_gas, |base_fee| { + max_priority_fee_per_gas.min(*max_fee_per_gas - base_fee) }) } diff --git a/crates/edr_evm/src/runtime.rs b/crates/edr_evm/src/runtime.rs index 34d23c725..6c30e32ea 100644 --- a/crates/edr_evm/src/runtime.rs +++ b/crates/edr_evm/src/runtime.rs @@ -1,17 +1,16 @@ use std::fmt::Debug; +use edr_eth::transaction::{self, SignedTransaction}; use revm::{ db::{DatabaseComponents, StateRef}, - primitives::{ - BlockEnv, CfgEnvWithChainSpec, EnvWithChainSpec, ExecutionResult, ResultAndState, SpecId, - TxEnv, - }, + handler::{CfgEnvWithChainSpec, EnvWithChainSpec}, + primitives::{BlockEnv, ExecutionResult, ResultAndState, SpecId}, DatabaseCommit, Evm, }; use crate::{ blockchain::SyncBlockchain, - chain_spec::L1ChainSpec, + chain_spec::{ChainSpec, L1ChainSpec}, debug::DebugContext, state::{StateOverrides, StateRefOverrider, SyncState}, transaction::TransactionError, @@ -32,8 +31,8 @@ pub fn dry_run<'blockchain, 'evm, 'overrides, 'state, DebugDataT, BlockchainErro blockchain: &'blockchain dyn SyncBlockchain, state: &'state dyn SyncState, state_overrides: &'overrides StateOverrides, - cfg: CfgEnvWithChainSpec, - transaction: TxEnv, + cfg: CfgEnvWithChainSpec, + transaction: transaction::Signed, block: BlockEnv, debug_context: Option< DebugContext< @@ -44,14 +43,17 @@ pub fn dry_run<'blockchain, 'evm, 'overrides, 'state, DebugDataT, BlockchainErro StateRefOverrider<'overrides, &'evm dyn SyncState>, >, >, -) -> Result> +) -> Result, TransactionError> where 'blockchain: 'evm, 'state: 'evm, BlockchainErrorT: Debug + Send, StateErrorT: Debug + Send, { - validate_configuration(&cfg, &block, &transaction)?; + validate_configuration::( + cfg.spec_id, + &transaction, + )?; let state_overrider = StateRefOverrider::new(state_overrides, state); @@ -64,6 +66,7 @@ where if let Some(debug_context) = debug_context { let mut evm = evm_builder + .with_chain_spec::() .with_external_context(debug_context.data) .with_env_with_handler_cfg(env) .append_handler_register(debug_context.register_handles_fn) @@ -71,7 +74,10 @@ where evm.transact() } else { - let mut evm = evm_builder.with_env_with_handler_cfg(env).build(); + let mut evm = evm_builder + .with_chain_spec::() + .with_env_with_handler_cfg(env) + .build(); evm.transact() } }; @@ -96,8 +102,8 @@ pub fn guaranteed_dry_run< blockchain: &'blockchain dyn SyncBlockchain, state: &'state dyn SyncState, state_overrides: &'overrides StateOverrides, - mut cfg: CfgEnvWithChainSpec, - mut transaction: TxEnv, + mut cfg: CfgEnvWithChainSpec, + mut transaction: transaction::Signed, block: BlockEnv, debug_context: Option< DebugContext< @@ -108,7 +114,7 @@ pub fn guaranteed_dry_run< StateRefOverrider<'overrides, &'evm dyn SyncState>, >, >, -) -> Result> +) -> Result, TransactionError> where 'blockchain: 'evm, 'state: 'evm, @@ -117,7 +123,7 @@ where { cfg.disable_balance_check = true; cfg.disable_block_gas_limit = true; - transaction.nonce = None; + cfg.disable_nonce_check = true; dry_run( blockchain, state, @@ -134,18 +140,24 @@ where pub fn run<'blockchain, 'evm, BlockchainErrorT, DebugDataT, StateT>( blockchain: &'blockchain dyn SyncBlockchain, state: StateT, - cfg: CfgEnvWithChainSpec, - transaction: TxEnv, + cfg: CfgEnvWithChainSpec, + transaction: transaction::Signed, block: BlockEnv, debug_context: Option>, -) -> Result> +) -> Result< + ExecutionResult, + TransactionError, +> where 'blockchain: 'evm, BlockchainErrorT: Debug + Send, StateT: StateRef + DatabaseCommit, StateT::Error: Debug + Send, { - validate_configuration(&cfg, &block, &transaction)?; + validate_configuration::( + cfg.spec_id, + &transaction, + )?; let env = EnvWithChainSpec::new_with_cfg_env(cfg, block, transaction); let evm_builder = Evm::builder().with_ref_db(DatabaseComponents { @@ -155,6 +167,7 @@ where let result = if let Some(debug_context) = debug_context { let mut evm = evm_builder + .with_chain_spec::() .with_external_context(debug_context.data) .with_env_with_handler_cfg(env) .append_handler_register(debug_context.register_handles_fn) @@ -162,7 +175,10 @@ where evm.transact_commit() } else { - let mut evm = evm_builder.with_env_with_handler_cfg(env).build(); + let mut evm = evm_builder + .with_chain_spec::() + .with_env_with_handler_cfg(env) + .build(); evm.transact_commit() }?; @@ -170,16 +186,11 @@ where Ok(result) } -fn validate_configuration( - cfg: &CfgEnvWithChainSpec, - block: &BlockEnv, - transaction: &TxEnv, -) -> Result<(), TransactionError> { - if cfg.spec_id > SpecId::MERGE && block.prevrandao.is_none() { - return Err(TransactionError::MissingPrevrandao); - } - - if transaction.gas_priority_fee.is_some() && cfg.spec_id < SpecId::LONDON { +fn validate_configuration( + hardfork: ChainSpecT::Hardfork, + transaction: &transaction::Signed, +) -> Result<(), TransactionError> { + if transaction.max_fee_per_gas().is_some() && Into::into(hardfork) < SpecId::LONDON { return Err(TransactionError::Eip1559Unsupported); } diff --git a/crates/edr_evm/src/state/diff.rs b/crates/edr_evm/src/state/diff.rs index 2238f63b8..1614bbece 100644 --- a/crates/edr_evm/src/state/diff.rs +++ b/crates/edr_evm/src/state/diff.rs @@ -1,5 +1,5 @@ use edr_eth::{Address, U256}; -use revm::primitives::{Account, AccountInfo, AccountStatus, HashMap, StorageSlot}; +use revm::primitives::{Account, AccountInfo, AccountStatus, EvmStorageSlot, HashMap}; /// The difference between two states, which can be applied to a state to get /// the new state using [`revm::db::DatabaseCommit::commit`]. @@ -34,7 +34,7 @@ impl StateDiff { &mut self, address: Address, index: U256, - slot: StorageSlot, + slot: EvmStorageSlot, account_info: Option, ) { self.inner diff --git a/crates/edr_evm/src/state/trie/storage_trie.rs b/crates/edr_evm/src/state/trie/storage_trie.rs index 7679c52ec..e68e024aa 100644 --- a/crates/edr_evm/src/state/trie/storage_trie.rs +++ b/crates/edr_evm/src/state/trie/storage_trie.rs @@ -74,7 +74,7 @@ pub(super) struct StorageTrieMutation<'a> { impl<'a> StorageTrieMutation<'a> { #[cfg_attr(feature = "tracing", tracing::instrument(skip(self)))] - pub fn set_storage_slots(&mut self, storage: &revm::primitives::Storage) { + pub fn set_storage_slots(&mut self, storage: &revm::primitives::EvmStorage) { storage.iter().for_each(|(index, value)| { self.set_storage_slot(index, &value.present_value); }); diff --git a/crates/edr_evm/src/trace.rs b/crates/edr_evm/src/trace.rs index 857675ab5..e6561960a 100644 --- a/crates/edr_evm/src/trace.rs +++ b/crates/edr_evm/src/trace.rs @@ -4,12 +4,12 @@ use edr_eth::{Address, Bytes, U256}; use revm::{ handler::register::EvmHandler, interpreter::{ - opcode::{self, BoxedInstruction, InstructionTables}, + opcode::{self, DynInstruction}, return_revert, CallInputs, CallOutcome, CallValue, CreateInputs, CreateOutcome, InstructionResult, Interpreter, SuccessOrHalt, }, - primitives::{Bytecode, EVMError, ExecutionResult, Output}, - Database, Evm, EvmContext, FrameOrResult, FrameResult, + primitives::{Bytecode, EVMErrorForChain, ExecutionResult, Output}, + Context, Database, EvmContext, FrameOrResult, FrameResult, }; use crate::debug::GetContextData; @@ -18,35 +18,16 @@ use crate::debug::GetContextData; pub fn register_trace_collector_handles< ChainSpecT: revm::primitives::ChainSpec, DatabaseT: Database, - ContextT: GetContextData, + ContextT: GetContextData>, >( handler: &mut EvmHandler<'_, ChainSpecT, ContextT, DatabaseT>, ) where DatabaseT::Error: Debug, { - // Every instruction inside flat table that is going to be wrapped by tracer - // calls. - let table = handler - .instruction_table - .take() - .expect("Handler must have instruction table"); - - let table = match table { - InstructionTables::Plain(table) => table - .into_iter() - .map(|i| instruction_handler(i)) - .collect::>(), - InstructionTables::Boxed(table) => table - .into_iter() - .map(|i| instruction_handler(i)) - .collect::>(), - InstructionTables::_Unused(_) => unreachable!(), - }; - - // cast vector to array. - handler.instruction_table = Some(InstructionTables::Boxed( - table.try_into().unwrap_or_else(|_| unreachable!()), - )); + let table = &mut handler.instruction_table; + + // Update all instructions to call the instruction handler. + table.update_all(instruction_handler); // call and create input stack shared between handlers. They are used to share // inputs in *_end Inspector calls. @@ -57,7 +38,9 @@ pub fn register_trace_collector_handles< let create_input_stack_inner = create_input_stack.clone(); let old_handle = handler.execution.create.clone(); handler.execution.create = Arc::new( - move |ctx, inputs| -> Result> { + move |ctx, + inputs| + -> Result> { let tracer = ctx.external.get_context_data(); tracer.create(&ctx.evm, &inputs); @@ -71,7 +54,9 @@ pub fn register_trace_collector_handles< let call_input_stack_inner = call_input_stack.clone(); let old_handle = handler.execution.call.clone(); handler.execution.call = Arc::new( - move |ctx, inputs| -> Result> { + move |ctx, + inputs| + -> Result> { let tracer = ctx.external.get_context_data(); tracer.call(&mut ctx.evm, &inputs); @@ -85,7 +70,10 @@ pub fn register_trace_collector_handles< let call_input_stack_inner = call_input_stack.clone(); let old_handle = handler.execution.insert_call_outcome.clone(); handler.execution.insert_call_outcome = Arc::new( - move |ctx: &mut revm::Context, frame, shared_memory, outcome| { + move |ctx: &mut revm::Context, + frame, + shared_memory, + outcome| { let call_inputs = call_input_stack_inner.borrow_mut().pop().unwrap(); let tracer = ctx.external.get_context_data(); @@ -102,7 +90,7 @@ pub fn register_trace_collector_handles< let create_inputs = create_input_stack_inner.borrow_mut().pop().unwrap(); let tracer = ctx.external.get_context_data(); - tracer.create_end(&mut ctx.evm, &create_inputs, &outcome); + tracer.create_end(&ctx.evm, &create_inputs, &outcome); old_handle(ctx, frame, outcome) }); @@ -118,7 +106,7 @@ pub fn register_trace_collector_handles< } FrameResult::Create(outcome) => { let create_inputs = create_input_stack.borrow_mut().pop().unwrap(); - tracer.create_transaction_end(&mut ctx.evm, &create_inputs, outcome); + tracer.create_transaction_end(&ctx.evm, &create_inputs, outcome); } // TODO: https://github.com/NomicFoundation/edr/issues/427 FrameResult::EOFCreate(_) => { @@ -130,43 +118,49 @@ pub fn register_trace_collector_handles< } /// Outer closure that calls tracer for every instruction. -fn instruction_handler< - 'a, - ContextT: GetContextData, +fn instruction_handler( + prev: &DynInstruction<'_, Context>, + interpreter: &mut Interpreter, + host: &mut Context, +) where + ChainSpecT: revm::primitives::ChainSpec, + ContextT: GetContextData>, DatabaseT: Database, - Instruction: Fn(&mut Interpreter, &mut Evm<'a, ContextT, DatabaseT>) + 'a, ->( - instruction: Instruction, -) -> BoxedInstruction<'a, Evm<'a, ContextT, DatabaseT>> { - Box::new( - move |interpreter: &mut Interpreter, host: &mut Evm<'a, ContextT, DatabaseT>| { - // SAFETY: as the PC was already incremented we need to subtract 1 to preserve - // the old Inspector behavior. - interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.sub(1) }; - - host.context - .external - .get_context_data() - .step(interpreter, &host.context.evm); - - // return PC to old value - interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.add(1) }; - - // execute instruction. - instruction(interpreter, host); - }, - ) +{ + // SAFETY: as the PC was already incremented we need to subtract 1 to preserve + // the old Inspector behavior. + interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.sub(1) }; + + host.external + .get_context_data() + .step(interpreter, &host.evm); + + // Reset PC to previous value. + interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.add(1) }; + + // Execute instruction. + prev(interpreter, host); } /// Stack tracing message -#[derive(Clone, Debug)] -pub enum TraceMessage { +#[derive(Debug)] +pub enum TraceMessage { /// Event that occurs before a call or create message. Before(BeforeMessage), /// Event that occurs every step of a call or create message. Step(Step), /// Event that occurs after a call or create message. - After(AfterMessage), + After(AfterMessage), +} + +impl Clone for TraceMessage { + fn clone(&self) -> Self { + match self { + Self::Before(message) => Self::Before(message.clone()), + Self::Step(step) => Self::Step(step.clone()), + Self::After(message) => Self::After(message.clone()), + } + } } /// Temporary before message type for handling traces @@ -193,26 +187,53 @@ pub struct BeforeMessage { } /// Event that occurs after a call or create message. -#[derive(Clone, Debug)] -pub struct AfterMessage { +#[derive(Debug)] +pub struct AfterMessage { /// The execution result - pub execution_result: ExecutionResult, + pub execution_result: ExecutionResult, /// The newly created contract address if it's a create tx. `None` /// if there was an error creating the contract. pub contract_address: Option
, } +impl Clone for AfterMessage { + fn clone(&self) -> Self { + Self { + execution_result: self.execution_result.clone(), + contract_address: self.contract_address.clone(), + } + } +} + /// A trace for an EVM call. -#[derive(Clone, Debug, Default)] -pub struct Trace { +#[derive(Debug)] +pub struct Trace { // /// The individual steps of the call // pub steps: Vec, /// Messages - pub messages: Vec, + pub messages: Vec>, /// The return value of the call pub return_value: Bytes, } +impl Clone for Trace { + fn clone(&self) -> Self { + Self { + messages: self.messages.clone(), + return_value: self.return_value.clone(), + } + } +} + +impl Default for Trace { + fn default() -> Self { + Self { + messages: Vec::new(), + return_value: Bytes::new(), + } + } +} + /// A single EVM step. #[derive(Clone, Debug)] pub struct Step { @@ -264,14 +285,14 @@ impl Stack { } } -impl Trace { +impl Trace { /// Adds a before message pub fn add_before(&mut self, message: BeforeMessage) { self.messages.push(TraceMessage::Before(message)); } /// Adds a result message - pub fn add_after(&mut self, message: AfterMessage) { + pub fn add_after(&mut self, message: AfterMessage) { self.messages.push(TraceMessage::After(message)); } @@ -284,14 +305,14 @@ impl Trace { /// Object that gathers trace information during EVM execution and can be turned /// into a trace upon completion. #[derive(Debug)] -pub struct TraceCollector { - traces: Vec, +pub struct TraceCollector { + traces: Vec>, pending_before: Option, is_new_trace: bool, verbose: bool, } -impl TraceCollector { +impl TraceCollector { /// Create a trace collector. If verbose is `true` full stack and memory /// will be recorded. pub fn new(verbose: bool) -> Self { @@ -304,16 +325,16 @@ impl TraceCollector { } /// Converts the [`TraceCollector`] into its [`Trace`]. - pub fn into_traces(self) -> Vec { + pub fn into_traces(self) -> Vec> { self.traces } /// Returns the traces collected so far. - pub fn traces(&self) -> &[Trace] { + pub fn traces(&self) -> &[Trace] { &self.traces } - fn current_trace_mut(&mut self) -> &mut Trace { + fn current_trace_mut(&mut self) -> &mut Trace { self.traces.last_mut().expect("Trace must have been added") } @@ -323,8 +344,11 @@ impl TraceCollector { } } - fn call(&mut self, data: &mut EvmContext, inputs: &CallInputs) - where + fn call( + &mut self, + data: &mut EvmContext, + inputs: &CallInputs, + ) where DatabaseT::Error: Debug, { if self.is_new_trace { @@ -377,7 +401,7 @@ impl TraceCollector { fn call_end( &mut self, - data: &EvmContext, + data: &EvmContext, _inputs: &CallInputs, outcome: &CallOutcome, ) { @@ -401,7 +425,7 @@ impl TraceCollector { ret }; - let execution_result = match safe_ret.into() { + let execution_result = match SuccessOrHalt::::from(safe_ret) { SuccessOrHalt::Success(reason) => ExecutionResult::Success { reason, gas_used: outcome.gas().spent(), @@ -429,7 +453,11 @@ impl TraceCollector { }); } - fn create(&mut self, data: &EvmContext, inputs: &CreateInputs) { + fn create( + &mut self, + data: &EvmContext, + inputs: &CreateInputs, + ) { if self.is_new_trace { self.is_new_trace = false; self.traces.push(Trace::default()); @@ -452,7 +480,7 @@ impl TraceCollector { fn create_end( &mut self, - data: &mut EvmContext, + data: &EvmContext, _inputs: &CreateInputs, outcome: &CreateOutcome, ) where @@ -468,7 +496,7 @@ impl TraceCollector { ret }; - let execution_result = match safe_ret.into() { + let execution_result = match SuccessOrHalt::::from(safe_ret) { SuccessOrHalt::Success(reason) => ExecutionResult::Success { reason, gas_used: outcome.gas().spent(), @@ -496,7 +524,11 @@ impl TraceCollector { }); } - fn step(&mut self, interp: &Interpreter, data: &EvmContext) { + fn step( + &mut self, + interp: &Interpreter, + data: &EvmContext, + ) { // Skip the step let skip_step = self.pending_before.as_ref().map_or(false, |message| { message.code.is_some() && interp.current_opcode() == opcode::STOP @@ -527,7 +559,7 @@ impl TraceCollector { fn call_transaction_end( &mut self, - data: &EvmContext, + data: &EvmContext, inputs: &CallInputs, outcome: &CallOutcome, ) { @@ -537,7 +569,7 @@ impl TraceCollector { fn create_transaction_end( &mut self, - data: &mut EvmContext, + data: &EvmContext, inputs: &CreateInputs, outcome: &CreateOutcome, ) where @@ -548,8 +580,10 @@ impl TraceCollector { } } -impl GetContextData for TraceCollector { - fn get_context_data(&mut self) -> &mut TraceCollector { +impl GetContextData> + for TraceCollector +{ + fn get_context_data(&mut self) -> &mut TraceCollector { self } } diff --git a/crates/edr_evm/src/transaction.rs b/crates/edr_evm/src/transaction.rs index 5c64ccf65..1a10158b5 100644 --- a/crates/edr_evm/src/transaction.rs +++ b/crates/edr_evm/src/transaction.rs @@ -6,18 +6,20 @@ use std::fmt::Debug; // Re-export the transaction types from `edr_eth`. pub use edr_eth::transaction::*; -use edr_eth::{Address, SpecId, U256}; +use edr_eth::{SpecId, U256}; use revm::{ - db::DatabaseComponentError, interpreter::gas::validate_initial_tx_gas, primitives::EVMError, + db::DatabaseComponentError, + interpreter::gas::validate_initial_tx_gas, + primitives::{EVMError, EVMErrorForChain, TransactionValidation}, }; pub use self::detailed::*; /// Invalid transaction error -#[derive(Debug, thiserror::Error)] -pub enum TransactionError +#[derive(thiserror::Error)] +pub enum TransactionError where - ChainErrorT: revm::primitives::ChainSpec, + ChainSpecT: revm::primitives::ChainSpec, { /// Blockchain errors #[error(transparent)] @@ -33,22 +35,48 @@ where InvalidHeader(revm::primitives::InvalidHeader), /// Corrupt transaction data #[error(transparent)] - InvalidTransaction(ChainErrorT::TransactionValidationError), + InvalidTransaction(::ValidationError), + /// Precompile errors + #[error("{0}")] + Precompile(String), /// State errors #[error(transparent)] State(StateErrorT), } +impl Debug + for TransactionError +where + ChainSpecT: + revm::primitives::ChainSpec>, + BlockchainErrorT: Debug, + StateErrorT: Debug, +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Blockchain(arg0) => f.debug_tuple("Blockchain").field(arg0).finish(), + Self::Custom(arg0) => f.debug_tuple("Custom").field(arg0).finish(), + Self::Eip1559Unsupported => write!(f, "Eip1559Unsupported"), + Self::InvalidHeader(arg0) => f.debug_tuple("InvalidHeader").field(arg0).finish(), + Self::InvalidTransaction(arg0) => { + f.debug_tuple("InvalidTransaction").field(arg0).finish() + } + Self::Precompile(arg0) => f.debug_tuple("Precompile").field(arg0).finish(), + Self::State(arg0) => f.debug_tuple("State").field(arg0).finish(), + } + } +} + impl - From>> + From, ChainSpecT>> for TransactionError where - ChainSpecT: revm::primitives::ChainSpec, + ChainSpecT: revm::primitives::ChainSpec, BlockchainErrorT: Debug + Send, StateErrorT: Debug + Send, { fn from( - error: EVMError>, + error: EVMErrorForChain, ChainSpecT>, ) -> Self { match error { EVMError::Transaction(error) => Self::InvalidTransaction(error), @@ -56,6 +84,7 @@ where EVMError::Database(DatabaseComponentError::State(e)) => Self::State(e), EVMError::Database(DatabaseComponentError::BlockHash(e)) => Self::Blockchain(e), EVMError::Custom(error) => Self::Custom(error), + EVMError::Precompile(error) => Self::Precompile(error), } } } @@ -77,7 +106,7 @@ pub enum CreationError { } /// Validates the transaction. -pub fn validate( +pub fn validate( transaction: TransactionT, spec_id: SpecId, ) -> Result { @@ -97,7 +126,7 @@ pub fn validate( } /// Calculates the initial cost of a transaction. -pub fn initial_cost(transaction: &impl Transaction, spec_id: SpecId) -> u64 { +pub fn initial_cost(transaction: &impl SignedTransaction, spec_id: SpecId) -> u64 { validate_initial_tx_gas( spec_id, transaction.data().as_ref(), @@ -108,7 +137,7 @@ pub fn initial_cost(transaction: &impl Transaction, spec_id: SpecId) -> u64 { #[cfg(test)] mod tests { - use edr_eth::{transaction, Bytes}; + use edr_eth::{transaction, Address, Bytes}; use super::*; diff --git a/crates/edr_evm/src/transaction/detailed.rs b/crates/edr_evm/src/transaction/detailed.rs index 05c9264df..65b74b03a 100644 --- a/crates/edr_evm/src/transaction/detailed.rs +++ b/crates/edr_evm/src/transaction/detailed.rs @@ -7,7 +7,7 @@ use crate::chain_spec::ChainSpec; /// Wrapper struct for a transaction and its receipt. pub struct DetailedTransaction<'transaction, ChainSpecT: ChainSpec> { /// The transaction - pub transaction: &'transaction ChainSpecT::SignedTransaction, + pub transaction: &'transaction ChainSpecT::Transaction, /// The transaction's receipt pub receipt: &'transaction Arc, } diff --git a/crates/edr_evm/tests/blockchain.rs b/crates/edr_evm/tests/blockchain.rs index bfd0f3680..cf8037edf 100644 --- a/crates/edr_evm/tests/blockchain.rs +++ b/crates/edr_evm/tests/blockchain.rs @@ -4,18 +4,17 @@ use std::sync::Arc; use edr_eth::{ block::PartialHeader, - log::FilterLog, + log::{FilterLog, Log}, receipt::{TransactionReceipt, TypedReceipt, TypedReceiptData}, - transaction::Transaction, - Address, Bloom, Bytes, B256, U256, + transaction::{SignedTransaction as _, Transaction as _}, + Address, Bloom, Bytes, HashSet, SpecId, B256, U256, }; use edr_evm::{ blockchain::{BlockchainError, GenesisBlockOptions, LocalBlockchain, SyncBlockchain}, chain_spec::L1ChainSpec, state::{StateDiff, StateError}, test_utils::dummy_eip155_transaction, - transaction::SignedTransaction as _, - HashSet, LocalBlock, Log, SpecId, SyncBlock, + LocalBlock, SyncBlock, }; use serial_test::serial; @@ -38,9 +37,8 @@ const REMOTE_BLOCK_LAST_TRANSACTION_HASH: &str = async fn create_forked_dummy_blockchain( fork_block_number: Option, ) -> Box> { - use edr_evm::{ - blockchain::ForkedBlockchain, state::IrregularState, HashMap, RandomHashGenerator, - }; + use edr_eth::HashMap; + use edr_evm::{blockchain::ForkedBlockchain, state::IrregularState, RandomHashGenerator}; use edr_rpc_eth::client::EthRpcClient; use edr_test_utils::env::get_alchemy_url; use parking_lot::Mutex; diff --git a/crates/edr_evm/tests/mem_pool.rs b/crates/edr_evm/tests/mem_pool.rs index 11cd094e0..31eeb2ae5 100644 --- a/crates/edr_evm/tests/mem_pool.rs +++ b/crates/edr_evm/tests/mem_pool.rs @@ -2,7 +2,7 @@ use std::num::NonZeroU64; -use edr_eth::{transaction::Transaction, AccountInfo, Address, U256}; +use edr_eth::{transaction::SignedTransaction, AccountInfo, Address, U256}; use edr_evm::{ state::{AccountModifierFn, StateDebug}, test_utils::{ diff --git a/crates/edr_evm/tests/transaction.rs b/crates/edr_evm/tests/transaction.rs index a9f11111c..2a7fd14ef 100644 --- a/crates/edr_evm/tests/transaction.rs +++ b/crates/edr_evm/tests/transaction.rs @@ -9,7 +9,7 @@ mod alchemy { #[tokio::test] async fn []() { use edr_eth::{ - transaction::{self, Transaction as _}, + transaction::{self, SignedTransaction as _}, PreEip1898BlockSpec, B256 }; diff --git a/crates/edr_napi/src/logger.rs b/crates/edr_napi/src/logger.rs index 80c54ca58..cafe12675 100644 --- a/crates/edr_napi/src/logger.rs +++ b/crates/edr_napi/src/logger.rs @@ -2,7 +2,7 @@ use std::{fmt::Display, sync::mpsc::channel}; use ansi_term::{Color, Style}; use edr_eth::{ - transaction::{self, Transaction}, + transaction::{self, SignedTransaction}, Bytes, B256, U256, }; use edr_evm::{ diff --git a/crates/edr_provider/src/data.rs b/crates/edr_provider/src/data.rs index 591d1a636..72b470bf5 100644 --- a/crates/edr_provider/src/data.rs +++ b/crates/edr_provider/src/data.rs @@ -24,7 +24,7 @@ use edr_eth::{ receipt::BlockReceipt, reward_percentile::RewardPercentile, signature::{self, RecoveryMessage}, - transaction::{request::TransactionRequestAndSender, Transaction, TransactionType}, + transaction::{request::TransactionRequestAndSender, SignedTransaction, TransactionType}, Address, BlockSpec, BlockTag, Bytes, Eip1898BlockSpec, SpecId, B256, U256, }; use edr_evm::{ @@ -658,7 +658,7 @@ impl ProviderData ProviderData ProviderData ProviderData ProviderData, pub state_overrides: &'a StateOverrides, - pub cfg_env: CfgEnvWithChainSpec, - pub tx_env: TxEnv, + pub cfg_env: CfgEnvWithChainSpec, + pub transaction: transaction::Signed, // `DebugContext` cannot be simplified further #[allow(clippy::type_complexity)] pub debug_context: Option< @@ -50,7 +51,7 @@ where state, state_overrides, cfg_env, - tx_env, + transaction: tx_env, debug_context, } = args; diff --git a/crates/edr_provider/src/data/gas.rs b/crates/edr_provider/src/data/gas.rs index 0b98c8c4b..6e1c7fcc4 100644 --- a/crates/edr_provider/src/data/gas.rs +++ b/crates/edr_provider/src/data/gas.rs @@ -1,13 +1,13 @@ use core::fmt::Debug; use std::cmp; -use edr_eth::{block::Header, reward_percentile::RewardPercentile, transaction::Transaction, U256}; +use edr_eth::{block::Header, reward_percentile::RewardPercentile, U256}; use edr_evm::{ blockchain::{BlockchainError, SyncBlockchain}, chain_spec::L1ChainSpec, state::{StateError, StateOverrides, SyncState}, trace::{register_trace_collector_handles, TraceCollector}, - CfgEnvWithChainSpec, DebugContext, ExecutionResult, SyncBlock, TxEnv, + transaction, CfgEnvWithChainSpec, DebugContext, ExecutionResult, SyncBlock, }; use itertools::Itertools; @@ -21,10 +21,10 @@ pub(super) struct CheckGasLimitArgs<'a> { pub header: &'a Header, pub state: &'a dyn SyncState, pub state_overrides: &'a StateOverrides, - pub cfg_env: CfgEnvWithChainSpec, - pub tx_env: TxEnv, + pub cfg_env: CfgEnvWithChainSpec, + pub transaction: transaction::Signed, pub gas_limit: u64, - pub trace_collector: &'a mut TraceCollector, + pub trace_collector: &'a mut TraceCollector, } /// Test if the transaction successfully executes with the given gas limit. @@ -39,12 +39,12 @@ pub(super) fn check_gas_limit( state, state_overrides, cfg_env, - mut tx_env, + mut transaction, gas_limit, trace_collector, } = args; - tx_env.gas_limit = gas_limit; + transaction.gas_limit = gas_limit; let result = call::run_call(RunCallArgs { blockchain, @@ -52,7 +52,7 @@ pub(super) fn check_gas_limit( state, state_overrides, cfg_env, - tx_env, + transaction, debug_context: Some(DebugContext { data: trace_collector, register_handles_fn: register_trace_collector_handles, @@ -67,11 +67,11 @@ pub(super) struct BinarySearchEstimationArgs<'a> { pub header: &'a Header, pub state: &'a dyn SyncState, pub state_overrides: &'a StateOverrides, - pub cfg_env: CfgEnvWithChainSpec, - pub tx_env: TxEnv, + pub cfg_env: CfgEnvWithChainSpec, + pub transaction: transaction::Signed, pub lower_bound: u64, pub upper_bound: u64, - pub trace_collector: &'a mut TraceCollector, + pub trace_collector: &'a mut TraceCollector, } /// Search for a tight upper bound on the gas limit that will allow the @@ -88,7 +88,7 @@ pub(super) fn binary_search_estimation( state, state_overrides, cfg_env, - tx_env, + transaction, mut lower_bound, mut upper_bound, trace_collector, @@ -111,7 +111,7 @@ pub(super) fn binary_search_estimation( state, state_overrides, cfg_env: cfg_env.clone(), - tx_env: tx_env.clone(), + transaction: transaction.clone(), gas_limit: mid, trace_collector, })?; diff --git a/crates/edr_provider/src/debug_mine.rs b/crates/edr_provider/src/debug_mine.rs index aa3fa10ea..102ca15b5 100644 --- a/crates/edr_provider/src/debug_mine.rs +++ b/crates/edr_provider/src/debug_mine.rs @@ -1,7 +1,7 @@ use core::fmt::Debug; use std::sync::Arc; -use edr_eth::{transaction::Transaction, Bytes, B256}; +use edr_eth::{transaction::SignedTransaction, Bytes, B256}; use edr_evm::{ chain_spec::L1ChainSpec, state::{StateDiff, SyncState}, diff --git a/crates/edr_provider/src/filter/criteria.rs b/crates/edr_provider/src/filter/criteria.rs index 494df1d33..2bb2cadf9 100644 --- a/crates/edr_provider/src/filter/criteria.rs +++ b/crates/edr_provider/src/filter/criteria.rs @@ -1,9 +1,8 @@ use edr_eth::{ filter::LogOutput, log::{matches_address_filter, matches_topics_filter, FilterLog}, - Address, Bloom, BloomInput, B256, + Address, Bloom, BloomInput, HashSet, B256, }; -use edr_evm::HashSet; #[derive(Clone, Debug, PartialEq)] pub struct LogFilter { diff --git a/crates/edr_provider/src/pending.rs b/crates/edr_provider/src/pending.rs index 030eb4526..99bf2e8d9 100644 --- a/crates/edr_provider/src/pending.rs +++ b/crates/edr_provider/src/pending.rs @@ -1,6 +1,6 @@ use std::{collections::BTreeMap, sync::Arc}; -use edr_eth::{receipt::BlockReceipt, transaction::Transaction as _, SpecId, B256, U256}; +use edr_eth::{receipt::BlockReceipt, transaction::SignedTransaction as _, SpecId, B256, U256}; use edr_evm::{ blockchain::{Blockchain, BlockchainError, BlockchainMut, SyncBlockchain}, chain_spec::L1ChainSpec, diff --git a/crates/edr_provider/src/requests/debug.rs b/crates/edr_provider/src/requests/debug.rs index 760643b30..ce6b13f0b 100644 --- a/crates/edr_provider/src/requests/debug.rs +++ b/crates/edr_provider/src/requests/debug.rs @@ -1,7 +1,10 @@ use core::fmt::Debug; use edr_eth::{BlockSpec, B256}; -use edr_evm::{state::StateOverrides, trace::Trace, DebugTraceResult, DebugTraceResultWithTraces}; +use edr_evm::{ + chain_spec::L1ChainSpec, state::StateOverrides, trace::Trace, DebugTraceResult, + DebugTraceResultWithTraces, +}; use edr_rpc_eth::CallRequest; use serde::{Deserialize, Deserializer}; @@ -19,7 +22,7 @@ pub fn handle_debug_trace_transaction, transaction_hash: B256, config: Option, -) -> Result<(DebugTraceResult, Vec), ProviderError> { +) -> Result<(DebugTraceResult, Vec>), ProviderError> { let DebugTraceResultWithTraces { result, traces } = data .debug_trace_transaction( &transaction_hash, @@ -40,7 +43,7 @@ pub fn handle_debug_trace_call, config: Option, -) -> Result<(DebugTraceResult, Vec), ProviderError> { +) -> Result<(DebugTraceResult, Vec>), ProviderError> { let block_spec = resolve_block_spec_for_call_request(block_spec); validate_call_request(data.spec_id(), &call_request, &block_spec)?; diff --git a/crates/edr_provider/src/requests/eth/blocks.rs b/crates/edr_provider/src/requests/eth/blocks.rs index 4c5a6cc52..5af7ea7b2 100644 --- a/crates/edr_provider/src/requests/eth/blocks.rs +++ b/crates/edr_provider/src/requests/eth/blocks.rs @@ -2,7 +2,7 @@ use core::fmt::Debug; use std::sync::Arc; use edr_eth::{ - transaction::Transaction as _, BlockSpec, PreEip1898BlockSpec, SpecId, B256, U256, U64, + transaction::SignedTransaction as _, BlockSpec, PreEip1898BlockSpec, SpecId, B256, U256, U64, }; use edr_evm::{blockchain::BlockchainError, chain_spec::L1ChainSpec, SyncBlock}; diff --git a/crates/edr_provider/src/requests/eth/call.rs b/crates/edr_provider/src/requests/eth/call.rs index c9aead4bc..4fa8588a9 100644 --- a/crates/edr_provider/src/requests/eth/call.rs +++ b/crates/edr_provider/src/requests/eth/call.rs @@ -1,7 +1,7 @@ use core::fmt::Debug; use edr_eth::{BlockSpec, Bytes, SpecId, U256}; -use edr_evm::{state::StateOverrides, trace::Trace, transaction}; +use edr_evm::{chain_spec::L1ChainSpec, state::StateOverrides, trace::Trace, transaction}; use edr_rpc_eth::{CallRequest, StateOverrideOptions}; use crate::{ @@ -14,7 +14,7 @@ pub fn handle_call_request( request: CallRequest, block_spec: Option, state_overrides: Option, -) -> Result<(Bytes, Trace), ProviderError> { +) -> Result<(Bytes, Trace), ProviderError> { let block_spec = resolve_block_spec_for_call_request(block_spec); validate_call_request(data.spec_id(), &request, &block_spec)?; @@ -160,7 +160,7 @@ pub(crate) fn resolve_call_request_inner( data: &mut ProviderData, timestamp: Option, -) -> Result<(String, Vec), ProviderError> { +) -> Result<(String, Vec>), ProviderError> { let mine_block_result = data.mine_and_commit_block(BlockOptions { timestamp: timestamp.map(Into::into), ..BlockOptions::default() diff --git a/crates/edr_provider/src/requests/eth/filter.rs b/crates/edr_provider/src/requests/eth/filter.rs index d529766db..f1d9e021e 100644 --- a/crates/edr_provider/src/requests/eth/filter.rs +++ b/crates/edr_provider/src/requests/eth/filter.rs @@ -3,9 +3,8 @@ use std::iter; use edr_eth::{ filter::{FilteredEvents, LogFilterOptions, LogOutput, OneOrMore, SubscriptionType}, - BlockSpec, BlockTag, Eip1898BlockSpec, U256, + BlockSpec, BlockTag, Eip1898BlockSpec, HashSet, U256, }; -use edr_evm::HashSet; use crate::{ data::ProviderData, filter::LogFilter, requests::validation::validate_post_merge_block_tags, diff --git a/crates/edr_provider/src/requests/eth/gas.rs b/crates/edr_provider/src/requests/eth/gas.rs index f17d78929..e6de08f43 100644 --- a/crates/edr_provider/src/requests/eth/gas.rs +++ b/crates/edr_provider/src/requests/eth/gas.rs @@ -4,7 +4,7 @@ use edr_eth::{ fee_history::FeeHistoryResult, reward_percentile::RewardPercentile, transaction, BlockSpec, SpecId, U256, U64, }; -use edr_evm::{state::StateOverrides, trace::Trace}; +use edr_evm::{chain_spec::L1ChainSpec, state::StateOverrides, trace::Trace}; use edr_rpc_eth::CallRequest; use super::resolve_call_request_inner; @@ -19,7 +19,7 @@ pub fn handle_estimate_gas( data: &mut ProviderData, call_request: CallRequest, block_spec: Option, -) -> Result<(U64, Vec), ProviderError> { +) -> Result<(U64, Vec>), ProviderError> { // Matching Hardhat behavior in defaulting to "pending" instead of "latest" for // estimate gas. let block_spec = block_spec.unwrap_or_else(BlockSpec::pending); @@ -148,7 +148,7 @@ fn resolve_estimate_gas_request( pub fn handle_send_transaction_request( data: &mut ProviderData, transaction_request: EthTransactionRequest, -) -> Result<(B256, Vec), ProviderError> { +) -> Result<(B256, Vec>), ProviderError> { validate_send_transaction_request(data, &transaction_request)?; let transaction_request = resolve_transaction_request(data, transaction_request)?; @@ -270,7 +270,7 @@ pub fn handle_send_transaction_request( data: &mut ProviderData, raw_transaction: Bytes, -) -> Result<(B256, Vec), ProviderError> { +) -> Result<(B256, Vec>), ProviderError> { let mut raw_transaction: &[u8] = raw_transaction.as_ref(); let pooled_transaction = PooledTransaction::decode(&mut raw_transaction).map_err(|err| match err { @@ -420,7 +420,7 @@ fn resolve_transaction_request( data: &mut ProviderData, signed_transaction: transaction::Signed, -) -> Result<(B256, Vec), ProviderError> { +) -> Result<(B256, Vec>), ProviderError> { let result = data.send_transaction(signed_transaction.clone())?; let spec_id = data.spec_id(); diff --git a/crates/edr_provider/src/requests/hardhat/miner.rs b/crates/edr_provider/src/requests/hardhat/miner.rs index a3e9b19fe..b5376349d 100644 --- a/crates/edr_provider/src/requests/hardhat/miner.rs +++ b/crates/edr_provider/src/requests/hardhat/miner.rs @@ -1,6 +1,6 @@ use core::fmt::Debug; -use edr_evm::trace::Trace; +use edr_evm::{chain_spec::L1ChainSpec, trace::Trace}; use crate::{data::ProviderData, time::TimeSinceEpoch, ProviderError}; @@ -14,7 +14,7 @@ pub fn handle_mine( data: &mut ProviderData, number_of_blocks: Option, interval: Option, -) -> Result<(bool, Vec), ProviderError> { +) -> Result<(bool, Vec>), ProviderError> { let number_of_blocks = number_of_blocks.unwrap_or(1); let interval = interval.unwrap_or(1); diff --git a/crates/edr_provider/src/requests/validation.rs b/crates/edr_provider/src/requests/validation.rs index 9e88c98f8..3883a4712 100644 --- a/crates/edr_provider/src/requests/validation.rs +++ b/crates/edr_provider/src/requests/validation.rs @@ -1,11 +1,9 @@ use core::fmt::Debug; use edr_eth::{ - access_list::AccessListItem, transaction::{self, EthTransactionRequest}, - Address, BlockSpec, BlockTag, PreEip1898BlockSpec, SpecId, B256, U256, + AccessListItem, Address, BlockSpec, BlockTag, Bytes, PreEip1898BlockSpec, SpecId, B256, U256, }; -use edr_evm::Bytes; use edr_rpc_eth::CallRequest; use crate::ProviderError; diff --git a/crates/edr_provider/tests/eip4844.rs b/crates/edr_provider/tests/eip4844.rs index 1ccd273a6..e97d80f75 100644 --- a/crates/edr_provider/tests/eip4844.rs +++ b/crates/edr_provider/tests/eip4844.rs @@ -6,9 +6,7 @@ use edr_defaults::SECRET_KEYS; use edr_eth::{ rlp::{self, Decodable}, signature::{secret_key_from_str, secret_key_to_address}, - transaction::{ - self, pooled::PooledTransaction, EthTransactionRequest, SignedTransaction, Transaction, - }, + transaction::{self, pooled::PooledTransaction, EthTransactionRequest, SignedTransaction}, AccountInfo, Address, Blob, Bytes, Bytes48, PreEip1898BlockSpec, SpecId, B256, BYTES_PER_BLOB, U256, }; From 3d3dfecee51f9f9a9f31260720d9afe7fec99e0b Mon Sep 17 00:00:00 2001 From: Wodann Date: Fri, 21 Jun 2024 04:39:37 +0000 Subject: [PATCH 04/13] finish adoption --- crates/edr_eth/src/lib.rs | 7 +- crates/edr_eth/src/state.rs | 2 + crates/edr_eth/src/transaction.rs | 5 + crates/edr_eth/src/transaction/signed.rs | 17 +++- crates/edr_evm/src/debug_trace.rs | 2 +- crates/edr_evm/src/lib.rs | 5 +- crates/edr_evm/src/runtime.rs | 2 +- crates/edr_evm/src/trace.rs | 2 +- crates/edr_napi/src/config.rs | 40 ++++---- crates/edr_napi/src/log.rs | 2 +- crates/edr_napi/src/logger.rs | 37 ++++---- crates/edr_napi/src/provider.rs | 5 +- crates/edr_napi/src/result.rs | 75 ++++++++------- crates/edr_napi/src/trace.rs | 8 +- crates/edr_provider/src/config.rs | 5 +- crates/edr_provider/src/console_log.rs | 17 ++-- crates/edr_provider/src/data.rs | 94 ++++++++++--------- crates/edr_provider/src/data/account.rs | 5 +- crates/edr_provider/src/data/call.rs | 10 +- crates/edr_provider/src/data/gas.rs | 15 ++- crates/edr_provider/src/debug_mine.rs | 14 +-- crates/edr_provider/src/debugger.rs | 15 +-- crates/edr_provider/src/error.rs | 40 +++++--- crates/edr_provider/src/lib.rs | 9 +- crates/edr_provider/src/mock.rs | 14 +-- crates/edr_provider/src/pending.rs | 8 +- crates/edr_provider/src/requests/eth/call.rs | 8 +- crates/edr_provider/src/requests/eth/gas.rs | 21 +++-- .../src/requests/eth/transactions.rs | 28 ++++-- .../edr_provider/src/requests/validation.rs | 7 +- crates/edr_provider/src/test_utils.rs | 11 ++- crates/edr_provider/tests/eip4844.rs | 53 ++++++++--- .../tests/eth_request_serialization.rs | 3 +- .../tests/hardhat_request_serialization.rs | 3 +- crates/edr_provider/tests/issues/issue_325.rs | 2 +- crates/edr_provider/tests/issues/issue_326.rs | 5 +- crates/edr_provider/tests/issues/issue_361.rs | 3 +- 37 files changed, 346 insertions(+), 253 deletions(-) diff --git a/crates/edr_eth/src/lib.rs b/crates/edr_eth/src/lib.rs index 352afd605..fd01aeabf 100644 --- a/crates/edr_eth/src/lib.rs +++ b/crates/edr_eth/src/lib.rs @@ -45,9 +45,10 @@ pub mod withdrawal; pub use c_kzg::{Blob, Bytes48, BYTES_PER_BLOB, BYTES_PER_COMMITMENT, BYTES_PER_PROOF}; pub use revm_primitives::{ - alloy_primitives::{Bloom, BloomInput, B512, B64, U64}, - hex_literal, AccessList, AccessListItem, Account, AccountInfo, AccountStatus, Address, - Bytecode, Bytes, HashMap, HashSet, SpecId, B256, KECCAK_EMPTY, MAX_INITCODE_SIZE, U256, + address, + alloy_primitives::{Bloom, BloomInput, ChainId, B512, B64, U160, U64}, + db, env, hex, hex_literal, result, AccessList, AccessListItem, AccountInfo, Address, Bytecode, + Bytes, HashMap, HashSet, SpecId, B256, KECCAK_EMPTY, MAX_INITCODE_SIZE, U256, }; pub use self::block_spec::{BlockSpec, BlockTag, Eip1898BlockSpec, PreEip1898BlockSpec}; diff --git a/crates/edr_eth/src/state.rs b/crates/edr_eth/src/state.rs index 6ed5b2ce1..fb30bf6ac 100644 --- a/crates/edr_eth/src/state.rs +++ b/crates/edr_eth/src/state.rs @@ -1,3 +1,5 @@ +pub use revm_primitives::state::*; + use crate::{account::BasicAccount, trie::sec_trie_root, Address, HashMap, B256, U256}; /// State mapping of addresses to accounts. diff --git a/crates/edr_eth/src/transaction.rs b/crates/edr_eth/src/transaction.rs index 32c41a7e5..5e127c8e6 100644 --- a/crates/edr_eth/src/transaction.rs +++ b/crates/edr_eth/src/transaction.rs @@ -72,6 +72,11 @@ pub trait SignedTransaction: Transaction { fn transaction_type(&self) -> TransactionType; } +pub trait TransactionMut { + /// Sets the gas limit of the transaction. + fn set_gas_limit(&mut self, gas_limit: u64); +} + pub fn max_cost(transaction: &impl SignedTransaction) -> U256 { U256::from(transaction.gas_limit()).saturating_mul(*transaction.gas_price()) } diff --git a/crates/edr_eth/src/transaction/signed.rs b/crates/edr_eth/src/transaction/signed.rs index 0575c1974..d2c84b3f2 100644 --- a/crates/edr_eth/src/transaction/signed.rs +++ b/crates/edr_eth/src/transaction/signed.rs @@ -15,7 +15,10 @@ pub use self::{ eip4844::Eip4844, legacy::{Legacy, PreOrPostEip155}, }; -use super::{Signed, SignedTransaction, TransactionType, TxKind, INVALID_TX_TYPE_ERROR_MESSAGE}; +use super::{ + Signed, SignedTransaction, TransactionMut, TransactionType, TxKind, + INVALID_TX_TYPE_ERROR_MESSAGE, +}; use crate::{ signature::{Fakeable, Signature}, utils::enveloped, @@ -350,6 +353,18 @@ impl revm_primitives::Transaction for Signed { } } +impl TransactionMut for Signed { + fn set_gas_limit(&mut self, gas_limit: u64) { + match self { + Signed::PreEip155Legacy(tx) => tx.gas_limit = gas_limit, + Signed::PostEip155Legacy(tx) => tx.gas_limit = gas_limit, + Signed::Eip2930(tx) => tx.gas_limit = gas_limit, + Signed::Eip1559(tx) => tx.gas_limit = gas_limit, + Signed::Eip4844(tx) => tx.gas_limit = gas_limit, + } + } +} + impl revm_primitives::TransactionValidation for Signed { type ValidationError = revm_primitives::InvalidTransaction; } diff --git a/crates/edr_evm/src/debug_trace.rs b/crates/edr_evm/src/debug_trace.rs index a8c97eae6..2271259b3 100644 --- a/crates/edr_evm/src/debug_trace.rs +++ b/crates/edr_evm/src/debug_trace.rs @@ -143,7 +143,7 @@ where }) .with_cfg_env_with_handler_cfg(evm_config.clone()) .with_block_env(block.clone()) - .with_tx_env(transaction.into()) + .with_tx_env(transaction) .build(); evm.transact().map_err(TransactionError::from)? diff --git a/crates/edr_evm/src/lib.rs b/crates/edr_evm/src/lib.rs index 7306d7a94..0b117f8fd 100644 --- a/crates/edr_evm/src/lib.rs +++ b/crates/edr_evm/src/lib.rs @@ -48,10 +48,7 @@ pub mod transaction; /// Types for interfacing with the evm pub mod evm { - pub use revm::{ - handler::register::{EvmHandler, HandleRegister}, - FrameOrResult, FrameResult, - }; + pub use revm::{handler, FrameOrResult, FrameResult}; } /// Types for interfacing with the interpreter diff --git a/crates/edr_evm/src/runtime.rs b/crates/edr_evm/src/runtime.rs index 6c30e32ea..69fe52e1b 100644 --- a/crates/edr_evm/src/runtime.rs +++ b/crates/edr_evm/src/runtime.rs @@ -103,7 +103,7 @@ pub fn guaranteed_dry_run< state: &'state dyn SyncState, state_overrides: &'overrides StateOverrides, mut cfg: CfgEnvWithChainSpec, - mut transaction: transaction::Signed, + transaction: transaction::Signed, block: BlockEnv, debug_context: Option< DebugContext< diff --git a/crates/edr_evm/src/trace.rs b/crates/edr_evm/src/trace.rs index e6561960a..a9feb2fa0 100644 --- a/crates/edr_evm/src/trace.rs +++ b/crates/edr_evm/src/trace.rs @@ -200,7 +200,7 @@ impl Clone for AfterMessage fn clone(&self) -> Self { Self { execution_result: self.execution_result.clone(), - contract_address: self.contract_address.clone(), + contract_address: self.contract_address, } } } diff --git a/crates/edr_napi/src/config.rs b/crates/edr_napi/src/config.rs index f9464ab61..e45a9e75d 100644 --- a/crates/edr_napi/src/config.rs +++ b/crates/edr_napi/src/config.rs @@ -43,28 +43,28 @@ pub enum SpecId { Latest = 18, } -impl From for edr_evm::SpecId { +impl From for edr_eth::SpecId { fn from(value: SpecId) -> Self { match value { - SpecId::Frontier => edr_evm::SpecId::FRONTIER, - SpecId::FrontierThawing => edr_evm::SpecId::FRONTIER_THAWING, - SpecId::Homestead => edr_evm::SpecId::HOMESTEAD, - SpecId::DaoFork => edr_evm::SpecId::DAO_FORK, - SpecId::Tangerine => edr_evm::SpecId::TANGERINE, - SpecId::SpuriousDragon => edr_evm::SpecId::SPURIOUS_DRAGON, - SpecId::Byzantium => edr_evm::SpecId::BYZANTIUM, - SpecId::Constantinople => edr_evm::SpecId::CONSTANTINOPLE, - SpecId::Petersburg => edr_evm::SpecId::PETERSBURG, - SpecId::Istanbul => edr_evm::SpecId::ISTANBUL, - SpecId::MuirGlacier => edr_evm::SpecId::MUIR_GLACIER, - SpecId::Berlin => edr_evm::SpecId::BERLIN, - SpecId::London => edr_evm::SpecId::LONDON, - SpecId::ArrowGlacier => edr_evm::SpecId::ARROW_GLACIER, - SpecId::GrayGlacier => edr_evm::SpecId::GRAY_GLACIER, - SpecId::Merge => edr_evm::SpecId::MERGE, - SpecId::Shanghai => edr_evm::SpecId::SHANGHAI, - SpecId::Cancun => edr_evm::SpecId::CANCUN, - SpecId::Latest => edr_evm::SpecId::LATEST, + SpecId::Frontier => edr_eth::SpecId::FRONTIER, + SpecId::FrontierThawing => edr_eth::SpecId::FRONTIER_THAWING, + SpecId::Homestead => edr_eth::SpecId::HOMESTEAD, + SpecId::DaoFork => edr_eth::SpecId::DAO_FORK, + SpecId::Tangerine => edr_eth::SpecId::TANGERINE, + SpecId::SpuriousDragon => edr_eth::SpecId::SPURIOUS_DRAGON, + SpecId::Byzantium => edr_eth::SpecId::BYZANTIUM, + SpecId::Constantinople => edr_eth::SpecId::CONSTANTINOPLE, + SpecId::Petersburg => edr_eth::SpecId::PETERSBURG, + SpecId::Istanbul => edr_eth::SpecId::ISTANBUL, + SpecId::MuirGlacier => edr_eth::SpecId::MUIR_GLACIER, + SpecId::Berlin => edr_eth::SpecId::BERLIN, + SpecId::London => edr_eth::SpecId::LONDON, + SpecId::ArrowGlacier => edr_eth::SpecId::ARROW_GLACIER, + SpecId::GrayGlacier => edr_eth::SpecId::GRAY_GLACIER, + SpecId::Merge => edr_eth::SpecId::MERGE, + SpecId::Shanghai => edr_eth::SpecId::SHANGHAI, + SpecId::Cancun => edr_eth::SpecId::CANCUN, + SpecId::Latest => edr_eth::SpecId::LATEST, } } } diff --git a/crates/edr_napi/src/log.rs b/crates/edr_napi/src/log.rs index 2137667c4..4c4aeb368 100644 --- a/crates/edr_napi/src/log.rs +++ b/crates/edr_napi/src/log.rs @@ -10,7 +10,7 @@ pub struct ExecutionLog { } impl ExecutionLog { - pub fn new(env: &Env, log: &edr_evm::Log) -> napi::Result { + pub fn new(env: &Env, log: &edr_eth::log::Log) -> napi::Result { let topics = log .topics() .iter() diff --git a/crates/edr_napi/src/logger.rs b/crates/edr_napi/src/logger.rs index cafe12675..4a76568bf 100644 --- a/crates/edr_napi/src/logger.rs +++ b/crates/edr_napi/src/logger.rs @@ -2,6 +2,7 @@ use std::{fmt::Display, sync::mpsc::channel}; use ansi_term::{Color, Style}; use edr_eth::{ + result::ExecutionResult, transaction::{self, SignedTransaction}, Bytes, B256, U256, }; @@ -10,8 +11,8 @@ use edr_evm::{ chain_spec::L1ChainSpec, precompile::{self, Precompiles}, trace::{AfterMessage, TraceMessage}, - transaction::SignedTransaction as _, - ExecutionResult, SyncBlock, + transaction::Transaction as _, + SyncBlock, }; use edr_provider::{ProviderError, TransactionFailure}; use itertools::izip; @@ -358,7 +359,7 @@ impl LogCollector { if let Some(to) = transaction.kind().to() { logger.log_with_title("To", format!("0x{to:x}")); } - if transaction.value() > U256::ZERO { + if *transaction.value() > U256::ZERO { logger.log_with_title("Value", wei_to_human_readable(transaction.value())); } @@ -714,8 +715,8 @@ impl LogCollector { &mut self, spec_id: edr_eth::SpecId, transaction: &edr_evm::transaction::Signed, - result: &edr_evm::ExecutionResult, - trace: &edr_evm::trace::Trace, + result: &edr_eth::result::ExecutionResult, + trace: &edr_evm::trace::Trace, console_log_inputs: &[Bytes], should_highlight_hash: bool, ) { @@ -805,7 +806,7 @@ impl LogCollector { fn log_contract_and_function_name( &mut self, spec_id: edr_eth::SpecId, - trace: &edr_evm::trace::Trace, + trace: &edr_evm::trace::Trace, ) { if let Some(TraceMessage::Before(before_message)) = trace.messages.first() { if let Some(to) = before_message.to { @@ -826,7 +827,7 @@ impl LogCollector { let is_code_empty = before_message .code .as_ref() - .map_or(true, edr_evm::Bytecode::is_empty); + .map_or(true, edr_eth::Bytecode::is_empty); if is_code_empty { if PRINT_INVALID_CONTRACT_WARNING { @@ -837,7 +838,7 @@ impl LogCollector { before_message .code .as_ref() - .map(edr_evm::Bytecode::original_bytes) + .map(edr_eth::Bytecode::original_bytes) .expect("Call must be defined"), Some(before_message.data.clone()), ); @@ -871,7 +872,7 @@ impl LogCollector { self.log_with_title("Contract deployment", contract_name); if let ExecutionResult::Success { output, .. } = result { - if let edr_evm::Output::Create(_, address) = output { + if let edr_eth::result::Output::Create(_, address) = output { if let Some(deployed_address) = address { self.log_with_title( "Contract address", @@ -1060,8 +1061,8 @@ impl LogCollector { spec_id: edr_eth::SpecId, block_result: &edr_provider::DebugMineBlockResult, transaction: &transaction::Signed, - transaction_result: &edr_evm::ExecutionResult, - trace: &edr_evm::trace::Trace, + transaction_result: &edr_eth::result::ExecutionResult, + trace: &edr_evm::trace::Trace, ) { self.indented(|logger| { logger.log("Currently sent transaction:"); @@ -1101,8 +1102,8 @@ impl LogCollector { spec_id: edr_eth::SpecId, block_result: &edr_provider::DebugMineBlockResult, transaction: &transaction::Signed, - transaction_result: &edr_evm::ExecutionResult, - trace: &edr_evm::trace::Trace, + transaction_result: &edr_eth::result::ExecutionResult, + trace: &edr_evm::trace::Trace, ) { self.indented(|logger| { logger.log_contract_and_function_name::(spec_id, trace); @@ -1218,12 +1219,12 @@ impl LogCollector { } } -fn wei_to_human_readable(wei: U256) -> String { - if wei == U256::ZERO { +fn wei_to_human_readable(wei: &U256) -> String { + if *wei == U256::ZERO { "0 ETH".to_string() - } else if wei < U256::from(100_000u64) { + } else if *wei < U256::from(100_000u64) { format!("{wei} wei") - } else if wei < U256::from(100_000_000_000_000u64) { + } else if *wei < U256::from(100_000_000_000_000u64) { let mut decimal = to_decimal_string(wei, 9); decimal.push_str(" gwei"); decimal @@ -1237,7 +1238,7 @@ fn wei_to_human_readable(wei: U256) -> String { /// Converts the provided `value` to a decimal string after dividing it by /// `10^exponent`. The returned string will have at most `MAX_DECIMALS` /// decimals. -fn to_decimal_string(value: U256, exponent: u8) -> String { +fn to_decimal_string(value: &U256, exponent: u8) -> String { const MAX_DECIMALS: u8 = 4; let (integer, remainder) = value.div_rem(U256::from(10).pow(U256::from(exponent))); diff --git a/crates/edr_napi/src/provider.rs b/crates/edr_napi/src/provider.rs index 7116b5091..864ef932f 100644 --- a/crates/edr_napi/src/provider.rs +++ b/crates/edr_napi/src/provider.rs @@ -2,6 +2,7 @@ mod config; use std::sync::Arc; +use edr_evm::chain_spec::L1ChainSpec; use edr_provider::{time::CurrentTime, InvalidRequestReason}; use edr_rpc_eth::jsonrpc; use napi::{tokio::runtime, Env, JsFunction, JsObject, Status}; @@ -212,9 +213,9 @@ pub struct Response { json: String, /// When a transaction fails to execute, the provider returns a trace of the /// transaction. - solidity_trace: Option>, + solidity_trace: Option>>, /// This may contain zero or more traces, depending on the (batch) request - traces: Vec>, + traces: Vec>>, } #[napi] diff --git a/crates/edr_napi/src/result.rs b/crates/edr_napi/src/result.rs index 5fb11ef6f..329e3ef56 100644 --- a/crates/edr_napi/src/result.rs +++ b/crates/edr_napi/src/result.rs @@ -1,4 +1,4 @@ -use edr_evm::trace::AfterMessage; +use edr_evm::{chain_spec::L1ChainSpec, trace::AfterMessage}; use napi::{ bindgen_prelude::{BigInt, Buffer, Either3}, Either, Env, JsBuffer, JsBufferValue, @@ -16,24 +16,27 @@ pub enum SuccessReason { Return, /// The opcode `SELFDESTRUCT` was called SelfDestruct, + EofReturnContract, } -impl From for SuccessReason { - fn from(eval: edr_evm::SuccessReason) -> Self { +impl From for SuccessReason { + fn from(eval: edr_eth::result::SuccessReason) -> Self { match eval { - edr_evm::SuccessReason::Stop => Self::Stop, - edr_evm::SuccessReason::Return => Self::Return, - edr_evm::SuccessReason::SelfDestruct => Self::SelfDestruct, + edr_eth::result::SuccessReason::Stop => Self::Stop, + edr_eth::result::SuccessReason::Return => Self::Return, + edr_eth::result::SuccessReason::SelfDestruct => Self::SelfDestruct, + edr_eth::result::SuccessReason::EofReturnContract => Self::EofReturnContract, } } } -impl From for edr_evm::SuccessReason { +impl From for edr_eth::result::SuccessReason { fn from(value: SuccessReason) -> Self { match value { SuccessReason::Stop => Self::Stop, SuccessReason::Return => Self::Return, SuccessReason::SelfDestruct => Self::SelfDestruct, + SuccessReason::EofReturnContract => Self::EofReturnContract, } } } @@ -99,44 +102,44 @@ pub enum ExceptionalHalt { CreateInitCodeSizeLimit, } -impl From for ExceptionalHalt { - fn from(halt: edr_evm::HaltReason) -> Self { +impl From for ExceptionalHalt { + fn from(halt: edr_eth::result::HaltReason) -> Self { match halt { - edr_evm::HaltReason::OutOfGas(..) => ExceptionalHalt::OutOfGas, - edr_evm::HaltReason::OpcodeNotFound => ExceptionalHalt::OpcodeNotFound, - edr_evm::HaltReason::InvalidFEOpcode => ExceptionalHalt::InvalidFEOpcode, - edr_evm::HaltReason::InvalidJump => ExceptionalHalt::InvalidJump, - edr_evm::HaltReason::NotActivated => ExceptionalHalt::NotActivated, - edr_evm::HaltReason::StackUnderflow => ExceptionalHalt::StackUnderflow, - edr_evm::HaltReason::StackOverflow => ExceptionalHalt::StackOverflow, - edr_evm::HaltReason::OutOfOffset => ExceptionalHalt::OutOfOffset, - edr_evm::HaltReason::CreateCollision => ExceptionalHalt::CreateCollision, - edr_evm::HaltReason::PrecompileError => ExceptionalHalt::PrecompileError, - edr_evm::HaltReason::NonceOverflow => ExceptionalHalt::NonceOverflow, - edr_evm::HaltReason::CreateContractSizeLimit => { + edr_eth::result::HaltReason::OutOfGas(..) => ExceptionalHalt::OutOfGas, + edr_eth::result::HaltReason::OpcodeNotFound => ExceptionalHalt::OpcodeNotFound, + edr_eth::result::HaltReason::InvalidFEOpcode => ExceptionalHalt::InvalidFEOpcode, + edr_eth::result::HaltReason::InvalidJump => ExceptionalHalt::InvalidJump, + edr_eth::result::HaltReason::NotActivated => ExceptionalHalt::NotActivated, + edr_eth::result::HaltReason::StackUnderflow => ExceptionalHalt::StackUnderflow, + edr_eth::result::HaltReason::StackOverflow => ExceptionalHalt::StackOverflow, + edr_eth::result::HaltReason::OutOfOffset => ExceptionalHalt::OutOfOffset, + edr_eth::result::HaltReason::CreateCollision => ExceptionalHalt::CreateCollision, + edr_eth::result::HaltReason::PrecompileError => ExceptionalHalt::PrecompileError, + edr_eth::result::HaltReason::NonceOverflow => ExceptionalHalt::NonceOverflow, + edr_eth::result::HaltReason::CreateContractSizeLimit => { ExceptionalHalt::CreateContractSizeLimit } - edr_evm::HaltReason::CreateContractStartingWithEF => { + edr_eth::result::HaltReason::CreateContractStartingWithEF => { ExceptionalHalt::CreateContractStartingWithEF } - edr_evm::HaltReason::CreateInitCodeSizeLimit => { + edr_eth::result::HaltReason::CreateInitCodeSizeLimit => { ExceptionalHalt::CreateInitCodeSizeLimit } - edr_evm::HaltReason::OverflowPayment - | edr_evm::HaltReason::StateChangeDuringStaticCall - | edr_evm::HaltReason::CallNotAllowedInsideStatic - | edr_evm::HaltReason::OutOfFunds - | edr_evm::HaltReason::CallTooDeep => { + edr_eth::result::HaltReason::OverflowPayment + | edr_eth::result::HaltReason::StateChangeDuringStaticCall + | edr_eth::result::HaltReason::CallNotAllowedInsideStatic + | edr_eth::result::HaltReason::OutOfFunds + | edr_eth::result::HaltReason::CallTooDeep => { unreachable!("Internal halts that can be only found inside Inspector: {halt:?}") } } } } -impl From for edr_evm::HaltReason { +impl From for edr_eth::result::HaltReason { fn from(value: ExceptionalHalt) -> Self { match value { - ExceptionalHalt::OutOfGas => Self::OutOfGas(edr_evm::OutOfGasError::Basic), + ExceptionalHalt::OutOfGas => Self::OutOfGas(edr_eth::result::OutOfGasError::Basic), ExceptionalHalt::OpcodeNotFound => Self::OpcodeNotFound, ExceptionalHalt::InvalidFEOpcode => Self::InvalidFEOpcode, ExceptionalHalt::InvalidJump => Self::InvalidJump, @@ -174,14 +177,14 @@ pub struct ExecutionResult { } impl ExecutionResult { - pub fn new(env: &Env, message: &AfterMessage) -> napi::Result { + pub fn new(env: &Env, message: &AfterMessage) -> napi::Result { let AfterMessage { execution_result, contract_address, } = message; let result = match execution_result { - edr_evm::ExecutionResult::Success { + edr_eth::result::ExecutionResult::Success { reason, gas_used, gas_refunded, @@ -199,14 +202,14 @@ impl ExecutionResult { gas_refunded: BigInt::from(*gas_refunded), logs, output: match output { - edr_evm::Output::Call(return_value) => { + edr_eth::result::Output::Call(return_value) => { let return_value = env .create_buffer_with_data(return_value.to_vec()) .map(JsBufferValue::into_raw)?; Either::A(CallOutput { return_value }) } - edr_evm::Output::Create(return_value, address) => { + edr_eth::result::Output::Create(return_value, address) => { let return_value = env .create_buffer_with_data(return_value.to_vec()) .map(JsBufferValue::into_raw)?; @@ -219,7 +222,7 @@ impl ExecutionResult { }, }) } - edr_evm::ExecutionResult::Revert { gas_used, output } => { + edr_eth::result::ExecutionResult::Revert { gas_used, output } => { let output = env .create_buffer_with_data(output.to_vec()) .map(JsBufferValue::into_raw)?; @@ -229,7 +232,7 @@ impl ExecutionResult { output, }) } - edr_evm::ExecutionResult::Halt { reason, gas_used } => Either3::C(HaltResult { + edr_eth::result::ExecutionResult::Halt { reason, gas_used } => Either3::C(HaltResult { reason: ExceptionalHalt::from(*reason), gas_used: BigInt::from(*gas_used), }), diff --git a/crates/edr_napi/src/trace.rs b/crates/edr_napi/src/trace.rs index 11d9959b0..b957607ab 100644 --- a/crates/edr_napi/src/trace.rs +++ b/crates/edr_napi/src/trace.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use edr_evm::{interpreter::OpCode, trace::BeforeMessage}; +use edr_evm::{chain_spec::L1ChainSpec, interpreter::OpCode, trace::BeforeMessage}; use napi::{ bindgen_prelude::{BigInt, Buffer, Either3}, Env, JsBuffer, JsBufferValue, @@ -135,7 +135,7 @@ impl TracingStep { } } -fn u256_to_bigint(v: &edr_evm::U256) -> BigInt { +fn u256_to_bigint(v: &edr_eth::U256) -> BigInt { BigInt { sign_bit: false, words: v.into_limbs().to_vec(), @@ -151,11 +151,11 @@ pub struct TracingMessageResult { #[napi] pub struct RawTrace { - inner: Arc, + inner: Arc>, } impl RawTrace { - pub fn new(inner: Arc) -> Self { + pub fn new(inner: Arc>) -> Self { Self { inner } } } diff --git a/crates/edr_provider/src/config.rs b/crates/edr_provider/src/config.rs index 0fa99c485..c9cb0b91d 100644 --- a/crates/edr_provider/src/config.rs +++ b/crates/edr_provider/src/config.rs @@ -1,9 +1,10 @@ use std::{num::NonZeroU64, path::PathBuf, time::SystemTime}; use edr_eth::{ - block::BlobGas, spec::HardforkActivations, AccountInfo, Address, HashMap, SpecId, B256, U256, + block::BlobGas, spec::HardforkActivations, AccountInfo, Address, ChainId, HashMap, SpecId, + B256, U256, }; -use edr_evm::{alloy_primitives::ChainId, MineOrdering}; +use edr_evm::MineOrdering; use rand::Rng; use serde::{Deserialize, Serialize}; diff --git a/crates/edr_provider/src/console_log.rs b/crates/edr_provider/src/console_log.rs index 79cbd130d..6e1f392c3 100644 --- a/crates/edr_provider/src/console_log.rs +++ b/crates/edr_provider/src/console_log.rs @@ -1,11 +1,10 @@ use std::sync::Arc; -use edr_eth::{Address, Bytes}; +use edr_eth::{address, db::Database, result::EVMErrorForChain, Address, Bytes}; use edr_evm::{ - address, - db::Database, - evm::{EvmHandler, FrameOrResult}, - EVMError, GetContextData, + chain_spec::L1ChainSpec, + evm::{handler::register::EvmHandler, FrameOrResult}, + GetContextData, }; const CONSOLE_ADDRESS: Address = address!("000000000000000000636F6e736F6c652e6c6f67"); @@ -15,11 +14,13 @@ pub fn register_console_log_handles< DatabaseT: Database, ContextT: GetContextData, >( - handler: &mut EvmHandler<'_, ContextT, DatabaseT>, + handler: &mut EvmHandler<'_, L1ChainSpec, ContextT, DatabaseT>, ) { let old_handle = handler.execution.call.clone(); handler.execution.call = Arc::new( - move |ctx, inputs| -> Result> { + move |ctx, + inputs| + -> Result> { if inputs.bytecode_address == CONSOLE_ADDRESS { let collector = ctx.external.get_context_data(); collector.record_console_log(inputs.input.clone()); @@ -52,10 +53,10 @@ pub(crate) mod tests { use anyhow::Context; use edr_eth::{ + hex, transaction::{self, request::TransactionRequestAndSender, TxKind}, Bytes, U256, }; - use edr_evm::hex; use crate::{data::ProviderData, time::TimeSinceEpoch}; diff --git a/crates/edr_provider/src/data.rs b/crates/edr_provider/src/data.rs index 72b470bf5..d1afb3391 100644 --- a/crates/edr_provider/src/data.rs +++ b/crates/edr_provider/src/data.rs @@ -18,14 +18,19 @@ use edr_eth::{ calculate_next_base_fee_per_blob_gas, calculate_next_base_fee_per_gas, miner_reward, BlobGas, BlockOptions, }, + db::StateRef, + env::{BlobExcessGasAndPrice, BlockEnv, CfgEnv}, fee_history::FeeHistoryResult, filter::{FilteredEvents, LogOutput, SubscriptionType}, log::FilterLog, receipt::BlockReceipt, + result::ExecutionResult, reward_percentile::RewardPercentile, signature::{self, RecoveryMessage}, + state::{Account, EvmStorageSlot}, transaction::{request::TransactionRequestAndSender, SignedTransaction, TransactionType}, - Address, BlockSpec, BlockTag, Bytes, Eip1898BlockSpec, SpecId, B256, U256, + AccountInfo, Address, BlockSpec, BlockTag, Bytecode, Bytes, Eip1898BlockSpec, HashMap, HashSet, + SpecId, B256, KECCAK_EMPTY, U256, }; use edr_evm::{ blockchain::{ @@ -33,20 +38,19 @@ use edr_evm::{ LocalBlockchain, LocalCreationError, SyncBlockchain, }, chain_spec::L1ChainSpec, - db::StateRef, - debug_trace_transaction, execution_result_to_debug_result, mempool, mine_block, - mine_block_with_single_transaction, register_eip_3155_and_raw_tracers_handles, + debug_trace_transaction, + evm::handler::CfgEnvWithChainSpec, + execution_result_to_debug_result, mempool, mine_block, mine_block_with_single_transaction, + register_eip_3155_and_raw_tracers_handles, state::{ AccountModifierFn, IrregularState, StateDiff, StateError, StateOverride, StateOverrides, SyncState, }, trace::Trace, - transaction::{self, SignedTransaction as _}, - Account, AccountInfo, BlobExcessGasAndPrice, Block as _, BlockAndTotalDifficulty, BlockEnv, - Bytecode, CfgEnv, CfgEnvWithChainSpec, DebugContext, DebugTraceConfig, - DebugTraceResultWithTraces, Eip3155AndRawTracers, ExecutionResult, HashMap, HashSet, MemPool, - MineBlockResultAndState, OrderedTransaction, RandomHashGenerator, StorageSlot, SyncBlock, - TxEnv, KECCAK_EMPTY, + transaction::{self, Transaction as _}, + Block as _, BlockAndTotalDifficulty, DebugContext, DebugTraceConfig, + DebugTraceResultWithTraces, Eip3155AndRawTracers, MemPool, MineBlockResultAndState, + OrderedTransaction, RandomHashGenerator, SyncBlock, }; use edr_rpc_eth::{ client::{EthRpcClient, HeaderMap, RpcClientError}, @@ -87,14 +91,14 @@ const DEFAULT_MAX_CACHED_STATES: usize = 100_000; #[derive(Clone, Debug)] pub struct CallResult { pub console_log_inputs: Vec, - pub execution_result: ExecutionResult, - pub trace: Trace, + pub execution_result: ExecutionResult, + pub trace: Trace, } #[derive(Clone)] pub struct EstimateGasResult { pub estimation: u64, - pub traces: Vec, + pub traces: Vec>, } pub struct SendTransactionResult { @@ -104,7 +108,9 @@ pub struct SendTransactionResult { impl SendTransactionResult { /// Present if the transaction was auto-mined. - pub fn transaction_result_and_trace(&self) -> Option<(&ExecutionResult, &Trace)> { + pub fn transaction_result_and_trace( + &self, + ) -> Option<(&ExecutionResult, &Trace)> { self.mining_results.iter().find_map(|result| { izip!( result.block.transactions().iter(), @@ -122,7 +128,7 @@ impl SendTransactionResult { } } -impl From for (B256, Vec) { +impl From for (B256, Vec>) { fn from(value: SendTransactionResult) -> Self { let SendTransactionResult { transaction_hash, @@ -586,7 +592,7 @@ impl ProviderData Result> { + ) -> Result, ProviderError> { let block = self .blockchain .block_by_transaction_hash(transaction_hash)? @@ -613,7 +619,7 @@ impl ProviderData= SpecId::MERGE { + prevrandao: if cfg_env.spec_id >= SpecId::MERGE { Some(header.mix_hash) } else { None @@ -644,11 +650,9 @@ impl ProviderData Result> { + ) -> Result, ProviderError> { let cfg_env = self.create_evm_config(Some(block_spec))?; - let tx_env: TxEnv = transaction.into(); - let mut tracer = Eip3155AndRawTracers::new(trace_config, self.verbose_tracing); self.execute_in_block_context(Some(block_spec), |blockchain, block, state| { @@ -658,7 +662,7 @@ impl ProviderData ProviderData ProviderData ProviderData ProviderData ProviderData, - &CfgEnvWithChainSpec, + &CfgEnvWithChainSpec, BlockOptions, &mut Debugger, ) -> Result< @@ -1403,7 +1406,6 @@ impl ProviderData Result> { let cfg_env = self.create_evm_config(Some(block_spec))?; - let tx_env = transaction.into(); let mut debugger = Debugger::with_mocker( Mocker::new(self.call_override.clone()), @@ -1417,7 +1419,7 @@ impl ProviderData ProviderData ProviderData, - ) -> Result, ProviderError> { + ) -> Result, ProviderError> { let block_number = block_spec .map(|block_spec| self.block_number_by_block_spec(block_spec)) .transpose()? @@ -1914,7 +1916,7 @@ impl ProviderData::new_with_spec_id(cfg_env, spec_id)) + Ok(CfgEnvWithChainSpec::::new(cfg_env, spec_id)) } fn execute_in_block_context( @@ -1960,7 +1962,7 @@ impl ProviderData, - &CfgEnvWithChainSpec, + &CfgEnvWithChainSpec, BlockOptions, &mut Debugger, ) -> Result< @@ -1975,11 +1977,11 @@ impl ProviderData= SpecId::MERGE { + if options.mix_hash.is_none() && evm_config.spec_id >= SpecId::MERGE { options.mix_hash = Some(self.prev_randao_generator.next_value()); } - if evm_config.handler_cfg.spec_id >= SpecId::CANCUN { + if evm_config.spec_id >= SpecId::CANCUN { options.parent_beacon_block_root = options .parent_beacon_block_root .or_else(|| Some(self.parent_beacon_block_root_generator.next_value())); @@ -2009,7 +2011,7 @@ impl ProviderData, + config: &CfgEnvWithChainSpec, options: BlockOptions, debugger: &mut Debugger, ) -> Result, ProviderError> { @@ -2022,7 +2024,7 @@ impl ProviderData ProviderData, + config: &CfgEnvWithChainSpec, options: BlockOptions, transaction: transaction::Signed, debugger: &mut Debugger, @@ -2048,7 +2050,7 @@ impl ProviderData ProviderData ProviderData anyhow::Result<()> { + fn assert_decoded_output(result: ExecutionResult) -> anyhow::Result<()> { let output = result.into_output().expect("Call must have output"); let decoded = HelloCall::abi_decode_returns(output.as_ref(), false)?; diff --git a/crates/edr_provider/src/data/account.rs b/crates/edr_provider/src/data/account.rs index 5c593e3c0..4cab54fa6 100644 --- a/crates/edr_provider/src/data/account.rs +++ b/crates/edr_provider/src/data/account.rs @@ -1,6 +1,7 @@ use edr_eth::{ - signature::public_key_to_address, Account, AccountInfo, AccountStatus, Address, HashMap, - KECCAK_EMPTY, + signature::public_key_to_address, + state::{Account, AccountStatus}, + AccountInfo, Address, HashMap, KECCAK_EMPTY, }; use indexmap::IndexMap; diff --git a/crates/edr_provider/src/data/call.rs b/crates/edr_provider/src/data/call.rs index fdfb6168f..e2da40b21 100644 --- a/crates/edr_provider/src/data/call.rs +++ b/crates/edr_provider/src/data/call.rs @@ -2,15 +2,17 @@ use core::fmt::Debug; use edr_eth::{ block::{BlobGas, Header}, + env::{BlobExcessGasAndPrice, BlockEnv}, + result::ExecutionResult, SpecId, U256, }; use edr_evm::{ blockchain::{BlockchainError, SyncBlockchain}, chain_spec::L1ChainSpec, + evm::handler::CfgEnvWithChainSpec, guaranteed_dry_run, state::{StateError, StateOverrides, StateRefOverrider, SyncState}, - transaction, BlobExcessGasAndPrice, BlockEnv, CfgEnvWithChainSpec, DebugContext, - ExecutionResult, + transaction, DebugContext, }; use crate::ProviderError; @@ -41,7 +43,7 @@ where /// Execute a transaction as a call. Returns the gas used and the output. pub(super) fn run_call<'a, 'evm, DebugDataT, LoggerErrorT: Debug>( args: RunCallArgs<'a, 'evm, DebugDataT>, -) -> Result> +) -> Result, ProviderError> where 'a: 'evm, { @@ -62,7 +64,7 @@ where gas_limit: U256::from(header.gas_limit), basefee: U256::ZERO, difficulty: header.difficulty, - prevrandao: if cfg_env.handler_cfg.spec_id >= SpecId::MERGE { + prevrandao: if cfg_env.spec_id >= SpecId::MERGE { Some(header.mix_hash) } else { None diff --git a/crates/edr_provider/src/data/gas.rs b/crates/edr_provider/src/data/gas.rs index 6e1c7fcc4..f8cb1afe6 100644 --- a/crates/edr_provider/src/data/gas.rs +++ b/crates/edr_provider/src/data/gas.rs @@ -1,13 +1,20 @@ use core::fmt::Debug; use std::cmp; -use edr_eth::{block::Header, reward_percentile::RewardPercentile, U256}; +use edr_eth::{ + block::Header, + result::ExecutionResult, + reward_percentile::RewardPercentile, + transaction::{Transaction as _, TransactionMut as _}, + U256, +}; use edr_evm::{ blockchain::{BlockchainError, SyncBlockchain}, chain_spec::L1ChainSpec, + evm::handler::CfgEnvWithChainSpec, state::{StateError, StateOverrides, SyncState}, trace::{register_trace_collector_handles, TraceCollector}, - transaction, CfgEnvWithChainSpec, DebugContext, ExecutionResult, SyncBlock, + transaction, DebugContext, SyncBlock, }; use itertools::Itertools; @@ -44,7 +51,7 @@ pub(super) fn check_gas_limit( trace_collector, } = args; - transaction.gas_limit = gas_limit; + transaction.set_gas_limit(gas_limit); let result = call::run_call(RunCallArgs { blockchain, @@ -170,7 +177,7 @@ pub(super) fn compute_rewards( let effective_reward = if let Some(max_priority_fee_per_gas) = transaction.max_priority_fee_per_gas() { - cmp::min(max_priority_fee_per_gas, gas_price - base_fee_per_gas) + cmp::min(*max_priority_fee_per_gas, gas_price - base_fee_per_gas) } else { gas_price.saturating_sub(base_fee_per_gas) }; diff --git a/crates/edr_provider/src/debug_mine.rs b/crates/edr_provider/src/debug_mine.rs index 102ca15b5..ed8502d7f 100644 --- a/crates/edr_provider/src/debug_mine.rs +++ b/crates/edr_provider/src/debug_mine.rs @@ -1,12 +1,12 @@ use core::fmt::Debug; use std::sync::Arc; -use edr_eth::{transaction::SignedTransaction, Bytes, B256}; +use edr_eth::{result::ExecutionResult, transaction::SignedTransaction, Bytes, B256}; use edr_evm::{ chain_spec::L1ChainSpec, state::{StateDiff, SyncState}, trace::Trace, - ExecutionResult, LocalBlock, MineBlockResultAndState, SyncBlock, + LocalBlock, MineBlockResultAndState, SyncBlock, }; /// The result of mining a block, including the state, in debug mode. This @@ -19,9 +19,9 @@ pub struct DebugMineBlockResultAndState { /// State diff applied by block pub state_diff: StateDiff, /// Transaction results - pub transaction_results: Vec, + pub transaction_results: Vec>, /// Transaction traces - pub transaction_traces: Vec, + pub transaction_traces: Vec>, /// Encoded `console.log` call inputs pub console_log_inputs: Vec, } @@ -31,7 +31,7 @@ impl DebugMineBlockResultAndState { /// transaction traces, and decoded console log messages. pub fn new( result: MineBlockResultAndState, - transaction_traces: Vec, + transaction_traces: Vec>, console_log_decoded_messages: Vec, ) -> Self { Self { @@ -52,9 +52,9 @@ pub struct DebugMineBlockResult { /// Mined block pub block: Arc>, /// Transaction results - pub transaction_results: Vec, + pub transaction_results: Vec>, /// Transaction traces - pub transaction_traces: Vec, + pub transaction_traces: Vec>, /// Encoded `console.log` call inputs pub console_log_inputs: Vec, } diff --git a/crates/edr_provider/src/debugger.rs b/crates/edr_provider/src/debugger.rs index bc7a0613f..b1a91ba74 100644 --- a/crates/edr_provider/src/debugger.rs +++ b/crates/edr_provider/src/debugger.rs @@ -1,8 +1,9 @@ use core::fmt::Debug; +use edr_eth::db::Database; use edr_evm::{ - db::Database, - evm::EvmHandler, + chain_spec::L1ChainSpec, + evm::handler::register::EvmHandler, trace::{register_trace_collector_handles, TraceCollector}, GetContextData, }; @@ -14,13 +15,13 @@ use crate::{ /// Registers the EIP-3155 tracer handles. pub fn register_debugger_handles( - handler: &mut EvmHandler<'_, ContextT, DatabaseT>, + handler: &mut EvmHandler<'_, L1ChainSpec, ContextT, DatabaseT>, ) where DatabaseT: Database, DatabaseT::Error: Debug, ContextT: GetContextData + GetContextData - + GetContextData, + + GetContextData>, { register_console_log_handles(handler); register_mocking_handles(handler); @@ -30,7 +31,7 @@ pub fn register_debugger_handles( pub struct Debugger { pub console_logger: ConsoleLogCollector, pub mocker: Mocker, - pub trace_collector: TraceCollector, + pub trace_collector: TraceCollector, } impl Debugger { @@ -58,8 +59,8 @@ impl GetContextData for Debugger { } } -impl GetContextData for Debugger { - fn get_context_data(&mut self) -> &mut TraceCollector { +impl GetContextData> for Debugger { + fn get_context_data(&mut self) -> &mut TraceCollector { &mut self.trace_collector } } diff --git a/crates/edr_provider/src/error.rs b/crates/edr_provider/src/error.rs index 2ebbdacc5..a2b1781a6 100644 --- a/crates/edr_provider/src/error.rs +++ b/crates/edr_provider/src/error.rs @@ -2,15 +2,19 @@ use core::fmt::Debug; use std::num::TryFromIntError; use alloy_sol_types::{ContractError, SolInterface}; -use edr_eth::{filter::SubscriptionType, Address, BlockSpec, BlockTag, Bytes, SpecId, B256, U256}; +use edr_eth::{ + filter::SubscriptionType, + hex, + result::{ExecutionResult, HaltReason, OutOfGasError}, + Address, BlockSpec, BlockTag, Bytes, SpecId, B256, U256, +}; use edr_evm::{ blockchain::BlockchainError, - hex, + chain_spec::L1ChainSpec, state::{AccountOverrideConversionError, StateError}, trace::Trace, transaction::{self, TransactionError}, - DebugTraceError, ExecutionResult, HaltReason, MemPoolAddTransactionError, MineBlockError, - MineTransactionError, OutOfGasError, + DebugTraceError, MemPoolAddTransactionError, MineBlockError, MineTransactionError, }; use edr_rpc_eth::{client::RpcClientError, jsonrpc}; @@ -51,7 +55,7 @@ pub enum ProviderError { #[error(transparent)] Creation(#[from] CreationError), #[error(transparent)] - DebugTrace(#[from] DebugTraceError), + DebugTrace(#[from] DebugTraceError), #[error("An EIP-4844 (shard blob) call request was received, but Hardhat only supports them via `eth_sendRawTransaction`. See https://github.com/NomicFoundation/hardhat/issues/5182")] Eip4844CallRequestUnsupported, #[error("An EIP-4844 (shard blob) transaction was received, but Hardhat only supports them via `eth_sendRawTransaction`. See https://github.com/NomicFoundation/hardhat/issues/5023")] @@ -117,10 +121,10 @@ pub enum ProviderError { MemPoolUpdate(StateError), /// An error occurred while mining a block. #[error(transparent)] - MineBlock(#[from] MineBlockError), + MineBlock(#[from] MineBlockError), /// An error occurred while mining a block with a single transaction. #[error(transparent)] - MineTransaction(#[from] MineTransactionError), + MineTransaction(#[from] MineTransactionError), /// Rpc client error #[error(transparent)] RpcClientError(#[from] RpcClientError), @@ -129,7 +133,7 @@ pub enum ProviderError { RpcVersion(jsonrpc::Version), /// Error while running a transaction #[error(transparent)] - RunTransaction(#[from] TransactionError), + RunTransaction(#[from] TransactionError), /// The `hardhat_setMinGasPrice` method is not supported when EIP-1559 is /// active. #[error("hardhat_setMinGasPrice is not supported when EIP-1559 is active")] @@ -322,7 +326,7 @@ impl std::fmt::Display for EstimateGasFailure { #[derive(Clone, Debug, thiserror::Error)] pub struct TransactionFailureWithTraces { pub failure: TransactionFailure, - pub traces: Vec, + pub traces: Vec>, } impl std::fmt::Display for TransactionFailureWithTraces { @@ -339,15 +343,15 @@ pub struct TransactionFailure { pub reason: TransactionFailureReason, pub data: String, #[serde(skip)] - pub solidity_trace: Trace, + pub solidity_trace: Trace, pub transaction_hash: Option, } impl TransactionFailure { pub fn from_execution_result( - execution_result: &ExecutionResult, + execution_result: &ExecutionResult, transaction_hash: Option<&B256>, - solidity_trace: &Trace, + solidity_trace: &Trace, ) -> Option { match execution_result { ExecutionResult::Success { .. } => None, @@ -364,7 +368,11 @@ impl TransactionFailure { } } - pub fn revert(output: Bytes, transaction_hash: Option, solidity_trace: Trace) -> Self { + pub fn revert( + output: Bytes, + transaction_hash: Option, + solidity_trace: Trace, + ) -> Self { let data = format!("0x{}", hex::encode(output.as_ref())); Self { reason: TransactionFailureReason::Revert(output), @@ -374,7 +382,11 @@ impl TransactionFailure { } } - pub fn halt(halt: HaltReason, tx_hash: Option, solidity_trace: Trace) -> Self { + pub fn halt( + halt: HaltReason, + tx_hash: Option, + solidity_trace: Trace, + ) -> Self { let reason = match halt { HaltReason::OpcodeNotFound | HaltReason::InvalidFEOpcode => { TransactionFailureReason::OpcodeNotFound diff --git a/crates/edr_provider/src/lib.rs b/crates/edr_provider/src/lib.rs index ca6e8b14c..edd1827b4 100644 --- a/crates/edr_provider/src/lib.rs +++ b/crates/edr_provider/src/lib.rs @@ -21,7 +21,8 @@ pub mod time; use core::fmt::Debug; use std::sync::Arc; -use edr_evm::{blockchain::BlockchainError, trace::Trace, HashSet}; +use edr_eth::HashSet; +use edr_evm::{blockchain::BlockchainError, chain_spec::L1ChainSpec, trace::Trace}; use lazy_static::lazy_static; use logger::SyncLogger; use mock::SyncCallOverride; @@ -63,7 +64,7 @@ lazy_static! { #[derive(Clone, Debug)] pub struct ResponseWithTraces { pub result: serde_json::Value, - pub traces: Vec, + pub traces: Vec>, } /// A JSON-RPC provider for Ethereum. @@ -492,7 +493,7 @@ fn to_json( } fn to_json_with_trace( - value: (T, Trace), + value: (T, Trace), ) -> Result> { let response = serde_json::to_value(value.0).map_err(ProviderError::Serialization)?; @@ -503,7 +504,7 @@ fn to_json_with_trace( } fn to_json_with_traces( - value: (T, Vec), + value: (T, Vec>), ) -> Result> { let response = serde_json::to_value(value.0).map_err(ProviderError::Serialization)?; diff --git a/crates/edr_provider/src/mock.rs b/crates/edr_provider/src/mock.rs index 2d8cede44..02d9e1cfc 100644 --- a/crates/edr_provider/src/mock.rs +++ b/crates/edr_provider/src/mock.rs @@ -1,12 +1,12 @@ use std::sync::Arc; use dyn_clone::DynClone; -use edr_eth::{Address, Bytes}; +use edr_eth::{db::Database, result::EVMErrorForChain, Address, Bytes}; use edr_evm::{ - db::Database, - evm::{EvmHandler, FrameOrResult, FrameResult}, + chain_spec::L1ChainSpec, + evm::{handler::register::EvmHandler, FrameOrResult, FrameResult}, interpreter::{CallOutcome, Gas, InstructionResult, InterpreterResult}, - EVMError, GetContextData, + GetContextData, }; /// The result of executing a call override. @@ -30,11 +30,13 @@ dyn_clone::clone_trait_object!(SyncCallOverride); /// Registers the `Mocker`'s handles. pub fn register_mocking_handles>( - handler: &mut EvmHandler<'_, ContextT, DatabaseT>, + handler: &mut EvmHandler<'_, L1ChainSpec, ContextT, DatabaseT>, ) { let old_handle = handler.execution.call.clone(); handler.execution.call = Arc::new( - move |ctx, inputs| -> Result> { + move |ctx, + inputs| + -> Result> { let mocker = ctx.external.get_context_data(); if let Some(CallOverrideResult { output, diff --git a/crates/edr_provider/src/pending.rs b/crates/edr_provider/src/pending.rs index 99bf2e8d9..6020269d3 100644 --- a/crates/edr_provider/src/pending.rs +++ b/crates/edr_provider/src/pending.rs @@ -1,10 +1,12 @@ use std::{collections::BTreeMap, sync::Arc}; -use edr_eth::{receipt::BlockReceipt, transaction::SignedTransaction as _, SpecId, B256, U256}; +use edr_eth::{ + db::BlockHashRef, receipt::BlockReceipt, transaction::SignedTransaction as _, HashSet, SpecId, + B256, U256, +}; use edr_evm::{ blockchain::{Blockchain, BlockchainError, BlockchainMut, SyncBlockchain}, chain_spec::L1ChainSpec, - db::BlockHashRef, state::{StateDiff, StateError, StateOverride, SyncState}, BlockAndTotalDifficulty, LocalBlock, SyncBlock, }; @@ -114,7 +116,7 @@ impl<'blockchain> Blockchain for BlockchainWithPending<'blockchain> &self, _from_block: u64, _to_block: u64, - _addresses: &edr_evm::HashSet, + _addresses: &HashSet, _normalized_topics: &[Option>], ) -> Result, Self::BlockchainError> { panic!("Retrieving logs from a pending blockchain is not supported."); diff --git a/crates/edr_provider/src/requests/eth/call.rs b/crates/edr_provider/src/requests/eth/call.rs index 4fa8588a9..082b3d549 100644 --- a/crates/edr_provider/src/requests/eth/call.rs +++ b/crates/edr_provider/src/requests/eth/call.rs @@ -160,7 +160,7 @@ pub(crate) fn resolve_call_request_inner( let max_fee_per_gas = signed_transaction .max_fee_per_gas() .expect("Transaction must be post EIP-1559 transaction."); - let max_priority_fee_per_gas = signed_transaction + let max_priority_fee_per_gas = *signed_transaction .max_priority_fee_per_gas() .expect("Transaction must be post EIP-1559 transaction."); @@ -226,6 +226,18 @@ pub fn transaction_to_rpc_result( block_data.as_ref().map(|bd| bd.transaction_index) }; + let access_list = if transaction.transaction_type() >= TransactionType::Eip2930 { + Some(transaction.access_list().to_vec()) + } else { + None + }; + + let blob_versioned_hashes = if transaction.transaction_type() == TransactionType::Eip4844 { + Some(transaction.blob_hashes().to_vec()) + } else { + None + }; + Ok(edr_rpc_eth::Transaction { hash: *transaction.transaction_hash(), nonce: transaction.nonce(), @@ -234,7 +246,7 @@ pub fn transaction_to_rpc_result( transaction_index, from: *transaction.caller(), to: transaction.kind().to().copied(), - value: transaction.value(), + value: *transaction.value(), gas_price, gas: U256::from(transaction.gas_limit()), input: transaction.data().clone(), @@ -245,13 +257,11 @@ pub fn transaction_to_rpc_result( s: signature.s(), chain_id, transaction_type: transaction_type.map(u64::from), - access_list: transaction - .access_list() - .map(|access_list| access_list.clone().into()), + access_list, max_fee_per_gas: transaction.max_fee_per_gas(), - max_priority_fee_per_gas: transaction.max_priority_fee_per_gas(), - max_fee_per_blob_gas: transaction.max_fee_per_blob_gas(), - blob_versioned_hashes: transaction.blob_hashes(), + max_priority_fee_per_gas: transaction.max_priority_fee_per_gas().cloned(), + max_fee_per_blob_gas: transaction.max_fee_per_blob_gas().cloned(), + blob_versioned_hashes, }) } diff --git a/crates/edr_provider/src/requests/validation.rs b/crates/edr_provider/src/requests/validation.rs index 3883a4712..f2000ff9a 100644 --- a/crates/edr_provider/src/requests/validation.rs +++ b/crates/edr_provider/src/requests/validation.rs @@ -2,7 +2,8 @@ use core::fmt::Debug; use edr_eth::{ transaction::{self, EthTransactionRequest}, - AccessListItem, Address, BlockSpec, BlockTag, Bytes, PreEip1898BlockSpec, SpecId, B256, U256, + AccessListItem, Address, BlockSpec, BlockTag, Bytes, PreEip1898BlockSpec, SpecId, B256, + MAX_INITCODE_SIZE, U256, }; use edr_rpc_eth::CallRequest; @@ -232,11 +233,11 @@ pub fn validate_eip3860_max_initcode_size( return Ok(()); } - if data.len() > edr_evm::MAX_INITCODE_SIZE { + if data.len() > MAX_INITCODE_SIZE { return Err(ProviderError::InvalidArgument(format!(" Trying to send a deployment transaction whose init code length is {}. The max length allowed by EIP-3860 is {}. -Enable the 'allowUnlimitedContractSize' option to allow init codes of any length.", data.len(), edr_evm::MAX_INITCODE_SIZE))); +Enable the 'allowUnlimitedContractSize' option to allow init codes of any length.", data.len(), MAX_INITCODE_SIZE))); } Ok(()) diff --git a/crates/edr_provider/src/test_utils.rs b/crates/edr_provider/src/test_utils.rs index 9f4f337aa..5603147f9 100644 --- a/crates/edr_provider/src/test_utils.rs +++ b/crates/edr_provider/src/test_utils.rs @@ -3,21 +3,22 @@ use std::{convert::Infallible, num::NonZeroU64, time::SystemTime}; use anyhow::anyhow; use edr_eth::{ block::{miner_reward, BlobGas, BlockOptions}, + env::CfgEnv, receipt::BlockReceipt, signature::secret_key_from_str, spec::chain_hardfork_activations, transaction::EthTransactionRequest, trie::KECCAK_NULL_RLP, withdrawal::Withdrawal, - Address, Bytes, HashMap, PreEip1898BlockSpec, SpecId, B256, U256, + Address, Bytes, HashMap, PreEip1898BlockSpec, SpecId, B256, U160, U256, }; use edr_evm::{ - alloy_primitives::U160, blockchain::{Blockchain as _, ForkedBlockchain}, chain_spec::L1ChainSpec, + evm::handler::CfgEnvWithChainSpec, state::IrregularState, - Block, BlockBuilder, CfgEnv, CfgEnvWithChainSpec, DebugContext, ExecutionResultWithContext, - IntoRemoteBlock, RandomHashGenerator, + Block, BlockBuilder, DebugContext, ExecutionResultWithContext, IntoRemoteBlock, + RandomHashGenerator, }; use edr_rpc_eth::client::EthRpcClient; @@ -181,7 +182,7 @@ pub async fn run_full_block(url: String, block_number: u64, chain_id: u64) -> an cfg.chain_id = chain_id; cfg.disable_eip3607 = true; - let cfg = CfgEnvWithChainSpec::new_with_spec_id(cfg, spec_id); + let cfg = CfgEnvWithChainSpec::::new(cfg, spec_id); let parent = blockchain.last_block()?; let replay_header = replay_block.header(); diff --git a/crates/edr_provider/tests/eip4844.rs b/crates/edr_provider/tests/eip4844.rs index e97d80f75..030dc6b06 100644 --- a/crates/edr_provider/tests/eip4844.rs +++ b/crates/edr_provider/tests/eip4844.rs @@ -6,11 +6,14 @@ use edr_defaults::SECRET_KEYS; use edr_eth::{ rlp::{self, Decodable}, signature::{secret_key_from_str, secret_key_to_address}, - transaction::{self, pooled::PooledTransaction, EthTransactionRequest, SignedTransaction}, + transaction::{ + self, pooled::PooledTransaction, EthTransactionRequest, SignedTransaction as _, + Transaction as _, TransactionType, + }, AccountInfo, Address, Blob, Bytes, Bytes48, PreEip1898BlockSpec, SpecId, B256, BYTES_PER_BLOB, - U256, + KECCAK_EMPTY, U256, }; -use edr_evm::{EnvKzgSettings, KECCAK_EMPTY}; +use edr_evm::interpreter::primitives::EnvKzgSettings; use edr_provider::{ test_utils::{create_test_config, deploy_contract, one_ether}, time::CurrentTime, @@ -147,19 +150,29 @@ fn fake_call_request() -> anyhow::Result { let transaction = transaction.into_payload(); let from = transaction.caller(); + let access_list = if transaction.transaction_type() >= TransactionType::Eip2930 { + Some(transaction.access_list().to_vec()) + } else { + None + }; + + let blob_hashes = if transaction.transaction_type() == TransactionType::Eip4844 { + Some(transaction.blob_hashes().to_vec()) + } else { + None + }; + Ok(CallRequest { from: Some(*from), to: transaction.kind().to().copied(), max_fee_per_gas: transaction.max_fee_per_gas(), - max_priority_fee_per_gas: transaction.max_priority_fee_per_gas(), + max_priority_fee_per_gas: transaction.max_priority_fee_per_gas().cloned(), gas: Some(transaction.gas_limit()), - value: Some(transaction.value()), + value: Some(*transaction.value()), data: Some(transaction.data().clone()), - access_list: transaction - .access_list() - .map(|access_list| access_list.0.clone()), + access_list, blobs, - blob_hashes: transaction.blob_hashes(), + blob_hashes, ..CallRequest::default() }) } @@ -176,22 +189,32 @@ fn fake_transaction_request() -> EthTransactionRequest { let transaction = transaction.into_payload(); let from = *transaction.caller(); + let access_list = if transaction.transaction_type() >= TransactionType::Eip2930 { + Some(transaction.access_list().to_vec()) + } else { + None + }; + + let blob_hashes = if transaction.transaction_type() == TransactionType::Eip4844 { + Some(transaction.blob_hashes().to_vec()) + } else { + None + }; + EthTransactionRequest { from, to: transaction.kind().to().copied(), max_fee_per_gas: transaction.max_fee_per_gas(), - max_priority_fee_per_gas: transaction.max_priority_fee_per_gas(), + max_priority_fee_per_gas: transaction.max_priority_fee_per_gas().cloned(), gas: Some(transaction.gas_limit()), - value: Some(transaction.value()), + value: Some(*transaction.value()), data: Some(transaction.data().clone()), nonce: Some(transaction.nonce()), chain_id: transaction.chain_id(), - access_list: transaction - .access_list() - .map(|access_list| access_list.0.clone()), + access_list, transaction_type: Some(transaction.transaction_type().into()), blobs, - blob_hashes: transaction.blob_hashes(), + blob_hashes, ..EthTransactionRequest::default() } } diff --git a/crates/edr_provider/tests/eth_request_serialization.rs b/crates/edr_provider/tests/eth_request_serialization.rs index 789a79a02..4cddcae8a 100644 --- a/crates/edr_provider/tests/eth_request_serialization.rs +++ b/crates/edr_provider/tests/eth_request_serialization.rs @@ -3,9 +3,8 @@ mod common; use edr_eth::{ filter::{LogFilterOptions, LogOutput, OneOrMore}, transaction::EthTransactionRequest, - Address, BlockSpec, BlockTag, Bytes, PreEip1898BlockSpec, B256, U256, + Address, BlockSpec, BlockTag, Bytes, PreEip1898BlockSpec, B256, U160, U256, }; -use edr_evm::alloy_primitives::U160; use edr_provider::{IntervalConfigRequest, MethodInvocation, Timestamp}; use edr_rpc_eth::CallRequest; diff --git a/crates/edr_provider/tests/hardhat_request_serialization.rs b/crates/edr_provider/tests/hardhat_request_serialization.rs index a4527f363..bd9c49ade 100644 --- a/crates/edr_provider/tests/hardhat_request_serialization.rs +++ b/crates/edr_provider/tests/hardhat_request_serialization.rs @@ -1,7 +1,6 @@ mod common; -use edr_eth::{Address, Bytes, B256, U256}; -use edr_evm::alloy_primitives::U160; +use edr_eth::{Address, Bytes, B256, U160, U256}; use edr_provider::{ hardhat_rpc_types::{CompilerInput, CompilerOutput, ForkConfig, ResetProviderConfig}, MethodInvocation, diff --git a/crates/edr_provider/tests/issues/issue_325.rs b/crates/edr_provider/tests/issues/issue_325.rs index 8557e3467..7e8ccfea3 100644 --- a/crates/edr_provider/tests/issues/issue_325.rs +++ b/crates/edr_provider/tests/issues/issue_325.rs @@ -1,7 +1,7 @@ use edr_eth::{ transaction::EthTransactionRequest, AccountInfo, Address, PreEip1898BlockSpec, SpecId, B256, + KECCAK_EMPTY, }; -use edr_evm::KECCAK_EMPTY; use edr_provider::{ test_utils::{create_test_config_with_fork, one_ether}, time::CurrentTime, diff --git a/crates/edr_provider/tests/issues/issue_326.rs b/crates/edr_provider/tests/issues/issue_326.rs index b93503f73..0a5433a11 100644 --- a/crates/edr_provider/tests/issues/issue_326.rs +++ b/crates/edr_provider/tests/issues/issue_326.rs @@ -1,7 +1,8 @@ use std::str::FromStr; -use edr_eth::{transaction::EthTransactionRequest, AccountInfo, Address, SpecId, U256}; -use edr_evm::KECCAK_EMPTY; +use edr_eth::{ + transaction::EthTransactionRequest, AccountInfo, Address, SpecId, KECCAK_EMPTY, U256, +}; use edr_provider::{ test_utils::{create_test_config_with_fork, one_ether}, time::CurrentTime, diff --git a/crates/edr_provider/tests/issues/issue_361.rs b/crates/edr_provider/tests/issues/issue_361.rs index 08319d536..7cd9f9691 100644 --- a/crates/edr_provider/tests/issues/issue_361.rs +++ b/crates/edr_provider/tests/issues/issue_361.rs @@ -1,8 +1,7 @@ use edr_eth::{ filter::LogFilterOptions, transaction::EthTransactionRequest, AccountInfo, Address, BlockSpec, - SpecId, + SpecId, KECCAK_EMPTY, }; -use edr_evm::KECCAK_EMPTY; use edr_provider::{ test_utils::{create_test_config_with_fork, one_ether}, time::CurrentTime, From 34debd383a91d9a829b40d43430e342234659b4f Mon Sep 17 00:00:00 2001 From: Wodann Date: Fri, 21 Jun 2024 04:44:22 +0000 Subject: [PATCH 05/13] fix: replace path --- Cargo.lock | 6 +++++- crates/edr_eth/Cargo.toml | 3 +-- crates/edr_evm/Cargo.toml | 3 +-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3f33389f2..fc8fde171 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1956,7 +1956,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" dependencies = [ "cfg-if", - "windows-targets 0.52.4", + "windows-targets 0.48.5", ] [[package]] @@ -2856,6 +2856,7 @@ dependencies = [ [[package]] name = "revm" version = "9.0.0" +source = "git+https://github.com/NomicFoundation/revm?rev=d1b8dd9#d1b8dd97c90c0bd58192d7f945b671b2a8e8a163" dependencies = [ "auto_impl", "dyn-clone", @@ -2867,6 +2868,7 @@ dependencies = [ [[package]] name = "revm-interpreter" version = "5.0.0" +source = "git+https://github.com/NomicFoundation/revm?rev=d1b8dd9#d1b8dd97c90c0bd58192d7f945b671b2a8e8a163" dependencies = [ "revm-primitives", "serde", @@ -2875,6 +2877,7 @@ dependencies = [ [[package]] name = "revm-precompile" version = "7.0.0" +source = "git+https://github.com/NomicFoundation/revm?rev=d1b8dd9#d1b8dd97c90c0bd58192d7f945b671b2a8e8a163" dependencies = [ "aurora-engine-modexp", "c-kzg", @@ -2889,6 +2892,7 @@ dependencies = [ [[package]] name = "revm-primitives" version = "4.0.0" +source = "git+https://github.com/NomicFoundation/revm?rev=d1b8dd9#d1b8dd97c90c0bd58192d7f945b671b2a8e8a163" dependencies = [ "alloy-eips", "alloy-primitives 0.7.6", diff --git a/crates/edr_eth/Cargo.toml b/crates/edr_eth/Cargo.toml index 046189272..e1262af82 100644 --- a/crates/edr_eth/Cargo.toml +++ b/crates/edr_eth/Cargo.toml @@ -15,8 +15,7 @@ itertools = { version = "0.10.5", default-features = false, features = ["use_all k256 = { version = "0.13.1", default-features = false, features = ["arithmetic", "ecdsa", "pkcs8", ] } log = { version = "0.4.17", default-features = false } once_cell = { version = "1.18.0", default-features = false, features = ["alloc", "race", "std"] } -# revm-primitives = { git = "https://github.com/NomicFoundation/revm", rev = "cb53dc8", version = "4.0", default-features = false, features = ["c-kzg", "hashbrown"] } -revm-primitives = { path = "../../../revm/crates/primitives", version = "4.0", default-features = false, features = ["c-kzg", "hashbrown"] } +revm-primitives = { git = "https://github.com/NomicFoundation/revm", rev = "d1b8dd9", version = "4.0", default-features = false, features = ["c-kzg", "hashbrown"] } serde = { version = "1.0.147", default-features = false, features = ["derive"], optional = true } sha2 = { version = "0.10.8", default-features = false } sha3 = { version = "0.10.8", default-features = false } diff --git a/crates/edr_evm/Cargo.toml b/crates/edr_evm/Cargo.toml index 85a73db56..23b7f4321 100644 --- a/crates/edr_evm/Cargo.toml +++ b/crates/edr_evm/Cargo.toml @@ -19,8 +19,7 @@ parking_lot = { version = "0.12.1", default-features = false } edr_defaults = { version = "0.3.5", path = "../edr_defaults" } edr_eth = { version = "0.3.5", path = "../edr_eth", features = ["rand", "serde"] } edr_rpc_eth = { version = "0.3.5", path = "../edr_rpc_eth" } -# revm = { git = "https://github.com/NomicFoundation/revm", rev = "cb53dc8", version = "9.0", default-features = false, features = ["c-kzg", "dev", "serde"] } -revm = { path = "../../../revm/crates/revm", version = "9.0", default-features = false, features = ["c-kzg", "dev", "serde"] } +revm = { git = "https://github.com/NomicFoundation/revm", rev = "d1b8dd9", version = "9.0", default-features = false, features = ["c-kzg", "dev", "serde"] } rpds = { version = "1.1.0", default-features = false, features = ["std"] } serde = { version = "1.0.158", default-features = false, features = ["std"] } serde_json = { version = "1.0.94", default-features = false, features = ["std"] } From 17f60a8bc70952b396c2f39425365ea2686c225c Mon Sep 17 00:00:00 2001 From: Wodann Date: Fri, 21 Jun 2024 04:46:57 +0000 Subject: [PATCH 06/13] fix: prettier --- .github/workflows/mdbook.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/mdbook.yml b/.github/workflows/mdbook.yml index dad2d2b77..9e5430d9b 100644 --- a/.github/workflows/mdbook.yml +++ b/.github/workflows/mdbook.yml @@ -31,7 +31,7 @@ jobs: - name: Setup mdBook uses: peaceiris/actions-mdbook@ee69d230fe19748b7abf22df32acaa93833fad08 # v2.0.0 with: - mdbook-version: '0.4.37' + mdbook-version: "0.4.37" - name: Setup Pages id: pages uses: actions/configure-pages@v5 From 4346115aef5f70fa7ee61ffbf2c8f752e2de1e59 Mon Sep 17 00:00:00 2001 From: Wodann Date: Fri, 21 Jun 2024 16:51:13 +0000 Subject: [PATCH 07/13] fix: LackOfFundForMaxFee error message --- crates/edr_napi/index.d.ts | 3 ++- crates/edr_provider/src/error.rs | 22 ++++++++++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/crates/edr_napi/index.d.ts b/crates/edr_napi/index.d.ts index 616c64b5b..916d01b54 100644 --- a/crates/edr_napi/index.d.ts +++ b/crates/edr_napi/index.d.ts @@ -260,7 +260,8 @@ export const enum SuccessReason { /** The opcode `RETURN` was called */ Return = 1, /** The opcode `SELFDESTRUCT` was called */ - SelfDestruct = 2 + SelfDestruct = 2, + EofReturnContract = 3 } export interface CallOutput { /** Return value */ diff --git a/crates/edr_provider/src/error.rs b/crates/edr_provider/src/error.rs index a2b1781a6..c9c5f8cdf 100644 --- a/crates/edr_provider/src/error.rs +++ b/crates/edr_provider/src/error.rs @@ -5,7 +5,7 @@ use alloy_sol_types::{ContractError, SolInterface}; use edr_eth::{ filter::SubscriptionType, hex, - result::{ExecutionResult, HaltReason, OutOfGasError}, + result::{ExecutionResult, HaltReason, InvalidTransaction, OutOfGasError}, Address, BlockSpec, BlockTag, Bytes, SpecId, B256, U256, }; use edr_evm::{ @@ -14,7 +14,8 @@ use edr_evm::{ state::{AccountOverrideConversionError, StateError}, trace::Trace, transaction::{self, TransactionError}, - DebugTraceError, MemPoolAddTransactionError, MineBlockError, MineTransactionError, + BlockTransactionError, DebugTraceError, MemPoolAddTransactionError, MineBlockError, + MineTransactionError, }; use edr_rpc_eth::{client::RpcClientError, jsonrpc}; @@ -291,6 +292,23 @@ impl From> for jsonrpc::Error { }; let message = match &value { + ProviderError::DebugTrace(DebugTraceError::TransactionError(error)) + | ProviderError::MineBlock(MineBlockError::BlockTransaction( + BlockTransactionError::Transaction(error), + )) + | ProviderError::MineTransaction(MineTransactionError::BlockTransaction( + BlockTransactionError::Transaction(error), + )) + | ProviderError::RunTransaction(error) => { + if let TransactionError::InvalidTransaction( + InvalidTransaction::LackOfFundForMaxFee { fee, balance }, + ) = error + { + format!("Sender doesn't have enough funds to send tx. The max upfront cost is: {fee} and the sender's balance is: {balance}.") + } else { + value.to_string() + } + } ProviderError::TransactionFailed(inner) if matches!( inner.failure.reason, From 2cfc0d98c385be4bbb888a9e6d5407f63705f069 Mon Sep 17 00:00:00 2001 From: Wodann Date: Fri, 21 Jun 2024 17:25:09 +0000 Subject: [PATCH 08/13] fix: AccessList deserialization --- Cargo.lock | 15 ++++++--------- crates/edr_eth/Cargo.toml | 2 +- crates/edr_eth/src/access_list.rs | 28 ---------------------------- crates/edr_eth/src/lib.rs | 2 -- crates/edr_evm/Cargo.toml | 2 +- 5 files changed, 8 insertions(+), 41 deletions(-) delete mode 100644 crates/edr_eth/src/access_list.rs diff --git a/Cargo.lock b/Cargo.lock index fc8fde171..9cdd57e60 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,8 +65,7 @@ dependencies = [ [[package]] name = "alloy-eips" version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32d6d8118b83b0489cfb7e6435106948add2b35217f4a5004ef895f613f60299" +source = "git+https://github.com/NomicFoundation/alloy.git?rev=905d846#905d846ce87c5097a8364244929b569f83f94ca8" dependencies = [ "alloy-primitives 0.7.6", "alloy-rlp", @@ -74,7 +73,6 @@ dependencies = [ "c-kzg", "once_cell", "serde", - "sha2", ] [[package]] @@ -158,8 +156,7 @@ dependencies = [ [[package]] name = "alloy-serde" version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d94da1c0c4e27cc344b05626fe22a89dc6b8b531b9475f3b7691dbf6913e4109" +source = "git+https://github.com/NomicFoundation/alloy.git?rev=905d846#905d846ce87c5097a8364244929b569f83f94ca8" dependencies = [ "alloy-primitives 0.7.6", "serde", @@ -2856,7 +2853,7 @@ dependencies = [ [[package]] name = "revm" version = "9.0.0" -source = "git+https://github.com/NomicFoundation/revm?rev=d1b8dd9#d1b8dd97c90c0bd58192d7f945b671b2a8e8a163" +source = "git+https://github.com/NomicFoundation/revm?rev=78dc55f#78dc55fcc94b19922d9f2ba6f3b8a27072c31ad6" dependencies = [ "auto_impl", "dyn-clone", @@ -2868,7 +2865,7 @@ dependencies = [ [[package]] name = "revm-interpreter" version = "5.0.0" -source = "git+https://github.com/NomicFoundation/revm?rev=d1b8dd9#d1b8dd97c90c0bd58192d7f945b671b2a8e8a163" +source = "git+https://github.com/NomicFoundation/revm?rev=78dc55f#78dc55fcc94b19922d9f2ba6f3b8a27072c31ad6" dependencies = [ "revm-primitives", "serde", @@ -2877,7 +2874,7 @@ dependencies = [ [[package]] name = "revm-precompile" version = "7.0.0" -source = "git+https://github.com/NomicFoundation/revm?rev=d1b8dd9#d1b8dd97c90c0bd58192d7f945b671b2a8e8a163" +source = "git+https://github.com/NomicFoundation/revm?rev=78dc55f#78dc55fcc94b19922d9f2ba6f3b8a27072c31ad6" dependencies = [ "aurora-engine-modexp", "c-kzg", @@ -2892,7 +2889,7 @@ dependencies = [ [[package]] name = "revm-primitives" version = "4.0.0" -source = "git+https://github.com/NomicFoundation/revm?rev=d1b8dd9#d1b8dd97c90c0bd58192d7f945b671b2a8e8a163" +source = "git+https://github.com/NomicFoundation/revm?rev=78dc55f#78dc55fcc94b19922d9f2ba6f3b8a27072c31ad6" dependencies = [ "alloy-eips", "alloy-primitives 0.7.6", diff --git a/crates/edr_eth/Cargo.toml b/crates/edr_eth/Cargo.toml index e1262af82..8422c4bbc 100644 --- a/crates/edr_eth/Cargo.toml +++ b/crates/edr_eth/Cargo.toml @@ -15,7 +15,7 @@ itertools = { version = "0.10.5", default-features = false, features = ["use_all k256 = { version = "0.13.1", default-features = false, features = ["arithmetic", "ecdsa", "pkcs8", ] } log = { version = "0.4.17", default-features = false } once_cell = { version = "1.18.0", default-features = false, features = ["alloc", "race", "std"] } -revm-primitives = { git = "https://github.com/NomicFoundation/revm", rev = "d1b8dd9", version = "4.0", default-features = false, features = ["c-kzg", "hashbrown"] } +revm-primitives = { git = "https://github.com/NomicFoundation/revm", rev = "78dc55f", version = "4.0", default-features = false, features = ["c-kzg", "hashbrown"] } serde = { version = "1.0.147", default-features = false, features = ["derive"], optional = true } sha2 = { version = "0.10.8", default-features = false } sha3 = { version = "0.10.8", default-features = false } diff --git a/crates/edr_eth/src/access_list.rs b/crates/edr_eth/src/access_list.rs deleted file mode 100644 index 5744aa4c7..000000000 --- a/crates/edr_eth/src/access_list.rs +++ /dev/null @@ -1,28 +0,0 @@ -// Part of this code was adapted from ethers-rs and is distributed under their -// license: -// - https://github.com/gakonst/ethers-rs/blob/cba6f071aedafb766e82e4c2f469ed5e4638337d/LICENSE-APACHE -// - https://github.com/gakonst/ethers-rs/blob/cba6f071aedafb766e82e4c2f469ed5e4638337d/LICENSE-MIT -// For the original context see: https://github.com/gakonst/ethers-rs/blob/3d9c3290d42b77c510e5b5d0b6f7a2f72913bfff/ethers-core/src/types/transaction/eip2930.rs - -use alloy_rlp::{RlpDecodable, RlpDecodableWrapper, RlpEncodable, RlpEncodableWrapper}; - -use crate::{Address, B256, U256}; - -/// Access list -// NB: Need to use `RlpEncodableWrapper` else we get an extra [] in the output -// https://github.com/gakonst/ethers-rs/pull/353#discussion_r680683869 -#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, RlpDecodableWrapper, RlpEncodableWrapper)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct AccessList(pub Vec); - -impl From> for AccessList { - fn from(src: Vec) -> AccessList { - AccessList(src) - } -} - -impl From for Vec { - fn from(src: AccessList) -> Vec { - src.0 - } -} diff --git a/crates/edr_eth/src/lib.rs b/crates/edr_eth/src/lib.rs index fd01aeabf..8fe45b295 100644 --- a/crates/edr_eth/src/lib.rs +++ b/crates/edr_eth/src/lib.rs @@ -5,8 +5,6 @@ //! Ethereum types as needed by EDR. In particular, they are based on the same //! primitive types as `revm`. -// /// Ethereum access list types -// pub mod access_list; /// Ethereum account types pub mod account; /// Parent beacon types and constants diff --git a/crates/edr_evm/Cargo.toml b/crates/edr_evm/Cargo.toml index 23b7f4321..be72de26e 100644 --- a/crates/edr_evm/Cargo.toml +++ b/crates/edr_evm/Cargo.toml @@ -19,7 +19,7 @@ parking_lot = { version = "0.12.1", default-features = false } edr_defaults = { version = "0.3.5", path = "../edr_defaults" } edr_eth = { version = "0.3.5", path = "../edr_eth", features = ["rand", "serde"] } edr_rpc_eth = { version = "0.3.5", path = "../edr_rpc_eth" } -revm = { git = "https://github.com/NomicFoundation/revm", rev = "d1b8dd9", version = "9.0", default-features = false, features = ["c-kzg", "dev", "serde"] } +revm = { git = "https://github.com/NomicFoundation/revm", rev = "78dc55f", version = "9.0", default-features = false, features = ["c-kzg", "dev", "serde"] } rpds = { version = "1.1.0", default-features = false, features = ["std"] } serde = { version = "1.0.158", default-features = false, features = ["std"] } serde_json = { version = "1.0.94", default-features = false, features = ["std"] } From 8af025fad399883f6061e555bf66153830452ad9 Mon Sep 17 00:00:00 2001 From: Wodann Date: Fri, 21 Jun 2024 21:18:02 +0000 Subject: [PATCH 09/13] fix: track warmed storage in debug_trace --- crates/edr_evm/src/debug_trace.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/crates/edr_evm/src/debug_trace.rs b/crates/edr_evm/src/debug_trace.rs index 2271259b3..58854cb59 100644 --- a/crates/edr_evm/src/debug_trace.rs +++ b/crates/edr_evm/src/debug_trace.rs @@ -443,7 +443,12 @@ where .journal .last() .and_then(|v| v.last()); - if let Some(JournalEntry::StorageChanged { address, key, .. }) = last_entry { + + if let Some( + JournalEntry::StorageChanged { address, key, .. } + | JournalEntry::StorageWarmed { address, key }, + ) = last_entry + { let value = context.journaled_state.state[address].storage[key].present_value(); let contract_storage = self.storage.entry(self.contract_address).or_default(); contract_storage.insert(u256_to_padded_hex(key), u256_to_padded_hex(&value)); From 165e5de29961aca8e0a4d865dd402c0539f9387f Mon Sep 17 00:00:00 2001 From: Wodann Date: Fri, 21 Jun 2024 21:36:19 +0000 Subject: [PATCH 10/13] fix: docs --- crates/edr_provider/src/error.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/edr_provider/src/error.rs b/crates/edr_provider/src/error.rs index c9c5f8cdf..f652042af 100644 --- a/crates/edr_provider/src/error.rs +++ b/crates/edr_provider/src/error.rs @@ -353,8 +353,8 @@ impl std::fmt::Display for TransactionFailureWithTraces { } } -/// Wrapper around [`edr_evm::HaltReason`] to convert error messages to match -/// Hardhat. +/// Wrapper around [`edr_eth::result::HaltReason`] to convert error messages to +/// match Hardhat. #[derive(Clone, Debug, thiserror::Error, serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct TransactionFailure { From 255137ab45eafcb0023ba8fc16515cef14edfdbb Mon Sep 17 00:00:00 2001 From: Wodann Date: Mon, 24 Jun 2024 18:50:45 +0000 Subject: [PATCH 11/13] misc: apply review suggestion --- crates/edr_evm/src/lib.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/crates/edr_evm/src/lib.rs b/crates/edr_evm/src/lib.rs index 0b117f8fd..4f3eb7db0 100644 --- a/crates/edr_evm/src/lib.rs +++ b/crates/edr_evm/src/lib.rs @@ -60,8 +60,3 @@ pub mod interpreter { pub mod precompile { pub use revm::precompile::{u64_to_address, PrecompileSpecId, Precompiles}; } - -// /// Primitive types of Ethereum -// pub mod primitives { -// pub use revm::primitives::*; -// } From 7fd28d00020cb0721ef79f49797ee398d696d23d Mon Sep 17 00:00:00 2001 From: Wodann Date: Mon, 24 Jun 2024 19:03:19 +0000 Subject: [PATCH 12/13] build: update to latest revm --- Cargo.lock | 37 ++++++++++++++++++------- crates/edr_eth/Cargo.toml | 2 +- crates/edr_evm/Cargo.toml | 2 +- crates/edr_evm/src/blockchain.rs | 3 -- crates/edr_evm/src/blockchain/forked.rs | 5 +--- crates/edr_evm/src/blockchain/local.rs | 5 +--- crates/edr_evm/src/trace.rs | 4 +-- crates/edr_napi/src/result.rs | 20 +++++++++++-- crates/edr_provider/src/error.rs | 2 +- crates/edr_provider/src/pending.rs | 4 +-- 10 files changed, 53 insertions(+), 31 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9cdd57e60..5f149db1e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,7 +65,8 @@ dependencies = [ [[package]] name = "alloy-eips" version = "0.1.2" -source = "git+https://github.com/NomicFoundation/alloy.git?rev=905d846#905d846ce87c5097a8364244929b569f83f94ca8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32d6d8118b83b0489cfb7e6435106948add2b35217f4a5004ef895f613f60299" dependencies = [ "alloy-primitives 0.7.6", "alloy-rlp", @@ -73,6 +74,7 @@ dependencies = [ "c-kzg", "once_cell", "serde", + "sha2", ] [[package]] @@ -156,7 +158,8 @@ dependencies = [ [[package]] name = "alloy-serde" version = "0.1.2" -source = "git+https://github.com/NomicFoundation/alloy.git?rev=905d846#905d846ce87c5097a8364244929b569f83f94ca8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d94da1c0c4e27cc344b05626fe22a89dc6b8b531b9475f3b7691dbf6913e4109" dependencies = [ "alloy-primitives 0.7.6", "serde", @@ -993,6 +996,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "derive-where" +version = "1.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62d671cc41a825ebabc75757b62d3d168c577f9149b2d49ece1dad1f72119d25" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.58", +] + [[package]] name = "derive_more" version = "0.99.17" @@ -2852,10 +2866,11 @@ dependencies = [ [[package]] name = "revm" -version = "9.0.0" -source = "git+https://github.com/NomicFoundation/revm?rev=78dc55f#78dc55fcc94b19922d9f2ba6f3b8a27072c31ad6" +version = "10.0.0" +source = "git+https://github.com/NomicFoundation/revm?rev=335551e#335551e68babfbd9c01fb5a427b59f5b237c3c74" dependencies = [ "auto_impl", + "derive-where", "dyn-clone", "revm-interpreter", "revm-precompile", @@ -2864,17 +2879,18 @@ dependencies = [ [[package]] name = "revm-interpreter" -version = "5.0.0" -source = "git+https://github.com/NomicFoundation/revm?rev=78dc55f#78dc55fcc94b19922d9f2ba6f3b8a27072c31ad6" +version = "6.0.0" +source = "git+https://github.com/NomicFoundation/revm?rev=335551e#335551e68babfbd9c01fb5a427b59f5b237c3c74" dependencies = [ + "derive-where", "revm-primitives", "serde", ] [[package]] name = "revm-precompile" -version = "7.0.0" -source = "git+https://github.com/NomicFoundation/revm?rev=78dc55f#78dc55fcc94b19922d9f2ba6f3b8a27072c31ad6" +version = "8.0.0" +source = "git+https://github.com/NomicFoundation/revm?rev=335551e#335551e68babfbd9c01fb5a427b59f5b237c3c74" dependencies = [ "aurora-engine-modexp", "c-kzg", @@ -2888,8 +2904,8 @@ dependencies = [ [[package]] name = "revm-primitives" -version = "4.0.0" -source = "git+https://github.com/NomicFoundation/revm?rev=78dc55f#78dc55fcc94b19922d9f2ba6f3b8a27072c31ad6" +version = "5.0.0" +source = "git+https://github.com/NomicFoundation/revm?rev=335551e#335551e68babfbd9c01fb5a427b59f5b237c3c74" dependencies = [ "alloy-eips", "alloy-primitives 0.7.6", @@ -2898,6 +2914,7 @@ dependencies = [ "bitvec", "c-kzg", "cfg-if", + "derive-where", "derive_more", "dyn-clone", "enumn", diff --git a/crates/edr_eth/Cargo.toml b/crates/edr_eth/Cargo.toml index 8422c4bbc..ba638bdc6 100644 --- a/crates/edr_eth/Cargo.toml +++ b/crates/edr_eth/Cargo.toml @@ -15,7 +15,7 @@ itertools = { version = "0.10.5", default-features = false, features = ["use_all k256 = { version = "0.13.1", default-features = false, features = ["arithmetic", "ecdsa", "pkcs8", ] } log = { version = "0.4.17", default-features = false } once_cell = { version = "1.18.0", default-features = false, features = ["alloc", "race", "std"] } -revm-primitives = { git = "https://github.com/NomicFoundation/revm", rev = "78dc55f", version = "4.0", default-features = false, features = ["c-kzg", "hashbrown"] } +revm-primitives = { git = "https://github.com/NomicFoundation/revm", rev = "335551e", version = "5.0", default-features = false, features = ["c-kzg", "hashbrown"] } serde = { version = "1.0.147", default-features = false, features = ["derive"], optional = true } sha2 = { version = "0.10.8", default-features = false } sha3 = { version = "0.10.8", default-features = false } diff --git a/crates/edr_evm/Cargo.toml b/crates/edr_evm/Cargo.toml index be72de26e..4586050a1 100644 --- a/crates/edr_evm/Cargo.toml +++ b/crates/edr_evm/Cargo.toml @@ -19,7 +19,7 @@ parking_lot = { version = "0.12.1", default-features = false } edr_defaults = { version = "0.3.5", path = "../edr_defaults" } edr_eth = { version = "0.3.5", path = "../edr_eth", features = ["rand", "serde"] } edr_rpc_eth = { version = "0.3.5", path = "../edr_rpc_eth" } -revm = { git = "https://github.com/NomicFoundation/revm", rev = "78dc55f", version = "9.0", default-features = false, features = ["c-kzg", "dev", "serde"] } +revm = { git = "https://github.com/NomicFoundation/revm", rev = "335551e", version = "10.0", default-features = false, features = ["c-kzg", "dev", "serde"] } rpds = { version = "1.1.0", default-features = false, features = ["std"] } serde = { version = "1.0.158", default-features = false, features = ["std"] } serde_json = { version = "1.0.94", default-features = false, features = ["std"] } diff --git a/crates/edr_evm/src/blockchain.rs b/crates/edr_evm/src/blockchain.rs index fa1d28b37..c044cc3ca 100644 --- a/crates/edr_evm/src/blockchain.rs +++ b/crates/edr_evm/src/blockchain.rs @@ -30,9 +30,6 @@ use crate::{ /// Combinatorial error for the blockchain API. #[derive(Debug, thiserror::Error)] pub enum BlockchainError { - /// Block number exceeds storage capacity (`usize::MAX`) - #[error("Block number exceeds storage capacity.")] - BlockNumberTooLarge, /// Forked blockchain error #[error(transparent)] Forked(#[from] ForkedBlockchainError), diff --git a/crates/edr_evm/src/blockchain/forked.rs b/crates/edr_evm/src/blockchain/forked.rs index 5b16f08f5..f18610cda 100644 --- a/crates/edr_evm/src/blockchain/forked.rs +++ b/crates/edr_evm/src/blockchain/forked.rs @@ -259,10 +259,7 @@ where type Error = BlockchainError; #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))] - fn block_hash(&self, number: U256) -> Result { - let number = - u64::try_from(number).map_err(|_error| BlockchainError::BlockNumberTooLarge)?; - + fn block_hash(&self, number: u64) -> Result { if number <= self.fork_block_number { tokio::task::block_in_place(move || { self.runtime().block_on(self.remote.block_by_number(number)) diff --git a/crates/edr_evm/src/blockchain/local.rs b/crates/edr_evm/src/blockchain/local.rs index 6dc6d1016..9ba25ce6c 100644 --- a/crates/edr_evm/src/blockchain/local.rs +++ b/crates/edr_evm/src/blockchain/local.rs @@ -413,10 +413,7 @@ where type Error = BlockchainError; #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))] - fn block_hash(&self, number: U256) -> Result { - let number = - u64::try_from(number).map_err(|_error| BlockchainError::BlockNumberTooLarge)?; - + fn block_hash(&self, number: u64) -> Result { self.storage .block_by_number(number)? .map(|block| *block.hash()) diff --git a/crates/edr_evm/src/trace.rs b/crates/edr_evm/src/trace.rs index a9feb2fa0..003af6d49 100644 --- a/crates/edr_evm/src/trace.rs +++ b/crates/edr_evm/src/trace.rs @@ -441,7 +441,7 @@ impl TraceCollector { reason, gas_used: outcome.gas().limit(), }, - SuccessOrHalt::InternalContinue | SuccessOrHalt::InternalCallOrCreate => { + SuccessOrHalt::Internal(_) => { panic!("Internal error: {safe_ret:?}") } SuccessOrHalt::FatalExternalError => panic!("Fatal external error"), @@ -512,7 +512,7 @@ impl TraceCollector { reason, gas_used: outcome.gas().limit(), }, - SuccessOrHalt::InternalContinue | SuccessOrHalt::InternalCallOrCreate => { + SuccessOrHalt::Internal(_) => { panic!("Internal error: {safe_ret:?}") } SuccessOrHalt::FatalExternalError => panic!("Fatal external error"), diff --git a/crates/edr_napi/src/result.rs b/crates/edr_napi/src/result.rs index 329e3ef56..89ee3b7e4 100644 --- a/crates/edr_napi/src/result.rs +++ b/crates/edr_napi/src/result.rs @@ -85,7 +85,7 @@ pub struct RevertResult { pub enum ExceptionalHalt { OutOfGas, OpcodeNotFound, - InvalidFEOpcode, + InvalidEFOpcode, InvalidJump, NotActivated, StackUnderflow, @@ -100,6 +100,12 @@ pub enum ExceptionalHalt { CreateContractStartingWithEF, /// EIP-3860: Limit and meter initcode. Initcode size limit exceeded. CreateInitCodeSizeLimit, + /// Aux data overflow, new aux data is larger tha u16 max size. + EofAuxDataOverflow, + /// Aud data is smaller then already present data size. + EofAuxDataTooSmall, + /// EOF Subroutine stack overflow + EOFFunctionStackOverflow, } impl From for ExceptionalHalt { @@ -107,7 +113,7 @@ impl From for ExceptionalHalt { match halt { edr_eth::result::HaltReason::OutOfGas(..) => ExceptionalHalt::OutOfGas, edr_eth::result::HaltReason::OpcodeNotFound => ExceptionalHalt::OpcodeNotFound, - edr_eth::result::HaltReason::InvalidFEOpcode => ExceptionalHalt::InvalidFEOpcode, + edr_eth::result::HaltReason::InvalidEFOpcode => ExceptionalHalt::InvalidEFOpcode, edr_eth::result::HaltReason::InvalidJump => ExceptionalHalt::InvalidJump, edr_eth::result::HaltReason::NotActivated => ExceptionalHalt::NotActivated, edr_eth::result::HaltReason::StackUnderflow => ExceptionalHalt::StackUnderflow, @@ -125,6 +131,11 @@ impl From for ExceptionalHalt { edr_eth::result::HaltReason::CreateInitCodeSizeLimit => { ExceptionalHalt::CreateInitCodeSizeLimit } + edr_eth::result::HaltReason::EofAuxDataOverflow => ExceptionalHalt::EofAuxDataOverflow, + edr_eth::result::HaltReason::EofAuxDataTooSmall => ExceptionalHalt::EofAuxDataTooSmall, + edr_eth::result::HaltReason::EOFFunctionStackOverflow => { + ExceptionalHalt::EOFFunctionStackOverflow + } edr_eth::result::HaltReason::OverflowPayment | edr_eth::result::HaltReason::StateChangeDuringStaticCall | edr_eth::result::HaltReason::CallNotAllowedInsideStatic @@ -141,7 +152,7 @@ impl From for edr_eth::result::HaltReason { match value { ExceptionalHalt::OutOfGas => Self::OutOfGas(edr_eth::result::OutOfGasError::Basic), ExceptionalHalt::OpcodeNotFound => Self::OpcodeNotFound, - ExceptionalHalt::InvalidFEOpcode => Self::InvalidFEOpcode, + ExceptionalHalt::InvalidEFOpcode => Self::InvalidEFOpcode, ExceptionalHalt::InvalidJump => Self::InvalidJump, ExceptionalHalt::NotActivated => Self::NotActivated, ExceptionalHalt::StackUnderflow => Self::StackUnderflow, @@ -153,6 +164,9 @@ impl From for edr_eth::result::HaltReason { ExceptionalHalt::CreateContractSizeLimit => Self::CreateContractSizeLimit, ExceptionalHalt::CreateContractStartingWithEF => Self::CreateContractStartingWithEF, ExceptionalHalt::CreateInitCodeSizeLimit => Self::CreateInitCodeSizeLimit, + ExceptionalHalt::EofAuxDataOverflow => Self::EofAuxDataOverflow, + ExceptionalHalt::EofAuxDataTooSmall => Self::EofAuxDataTooSmall, + ExceptionalHalt::EOFFunctionStackOverflow => Self::EOFFunctionStackOverflow, } } } diff --git a/crates/edr_provider/src/error.rs b/crates/edr_provider/src/error.rs index f652042af..cf7f64524 100644 --- a/crates/edr_provider/src/error.rs +++ b/crates/edr_provider/src/error.rs @@ -406,7 +406,7 @@ impl TransactionFailure { solidity_trace: Trace, ) -> Self { let reason = match halt { - HaltReason::OpcodeNotFound | HaltReason::InvalidFEOpcode => { + HaltReason::OpcodeNotFound | HaltReason::InvalidEFOpcode => { TransactionFailureReason::OpcodeNotFound } HaltReason::OutOfGas(error) => TransactionFailureReason::OutOfGas(error), diff --git a/crates/edr_provider/src/pending.rs b/crates/edr_provider/src/pending.rs index 6020269d3..7f4dd36f6 100644 --- a/crates/edr_provider/src/pending.rs +++ b/crates/edr_provider/src/pending.rs @@ -219,8 +219,8 @@ impl<'blockchain> BlockchainMut for BlockchainWithPending<'blockcha impl<'blockchain> BlockHashRef for BlockchainWithPending<'blockchain> { type Error = BlockchainError; - fn block_hash(&self, number: U256) -> Result { - if number == U256::from(self.pending_block.header().number) { + fn block_hash(&self, number: u64) -> Result { + if number == self.pending_block.header().number { Ok(*self.pending_block.hash()) } else { self.blockchain.block_hash(number) From 6904cd5361951f78a93f8aa07dfbb3d25b80c7f3 Mon Sep 17 00:00:00 2001 From: Wodann Date: Tue, 25 Jun 2024 15:08:26 +0000 Subject: [PATCH 13/13] build: use revm with fixed alloy-eips --- Cargo.lock | 15 ++++++--------- crates/edr_eth/Cargo.toml | 2 +- crates/edr_evm/Cargo.toml | 2 +- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5f149db1e..ba293550b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,8 +65,7 @@ dependencies = [ [[package]] name = "alloy-eips" version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32d6d8118b83b0489cfb7e6435106948add2b35217f4a5004ef895f613f60299" +source = "git+https://github.com/alloy-rs/alloy.git?rev=194f266#194f266fae46c1214004d04d4606010c3807b534" dependencies = [ "alloy-primitives 0.7.6", "alloy-rlp", @@ -74,7 +73,6 @@ dependencies = [ "c-kzg", "once_cell", "serde", - "sha2", ] [[package]] @@ -158,8 +156,7 @@ dependencies = [ [[package]] name = "alloy-serde" version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d94da1c0c4e27cc344b05626fe22a89dc6b8b531b9475f3b7691dbf6913e4109" +source = "git+https://github.com/alloy-rs/alloy.git?rev=194f266#194f266fae46c1214004d04d4606010c3807b534" dependencies = [ "alloy-primitives 0.7.6", "serde", @@ -2867,7 +2864,7 @@ dependencies = [ [[package]] name = "revm" version = "10.0.0" -source = "git+https://github.com/NomicFoundation/revm?rev=335551e#335551e68babfbd9c01fb5a427b59f5b237c3c74" +source = "git+https://github.com/NomicFoundation/revm?rev=14945e92#14945e9256fac36c4ace4683cb30a897221c5734" dependencies = [ "auto_impl", "derive-where", @@ -2880,7 +2877,7 @@ dependencies = [ [[package]] name = "revm-interpreter" version = "6.0.0" -source = "git+https://github.com/NomicFoundation/revm?rev=335551e#335551e68babfbd9c01fb5a427b59f5b237c3c74" +source = "git+https://github.com/NomicFoundation/revm?rev=14945e92#14945e9256fac36c4ace4683cb30a897221c5734" dependencies = [ "derive-where", "revm-primitives", @@ -2890,7 +2887,7 @@ dependencies = [ [[package]] name = "revm-precompile" version = "8.0.0" -source = "git+https://github.com/NomicFoundation/revm?rev=335551e#335551e68babfbd9c01fb5a427b59f5b237c3c74" +source = "git+https://github.com/NomicFoundation/revm?rev=14945e92#14945e9256fac36c4ace4683cb30a897221c5734" dependencies = [ "aurora-engine-modexp", "c-kzg", @@ -2905,7 +2902,7 @@ dependencies = [ [[package]] name = "revm-primitives" version = "5.0.0" -source = "git+https://github.com/NomicFoundation/revm?rev=335551e#335551e68babfbd9c01fb5a427b59f5b237c3c74" +source = "git+https://github.com/NomicFoundation/revm?rev=14945e92#14945e9256fac36c4ace4683cb30a897221c5734" dependencies = [ "alloy-eips", "alloy-primitives 0.7.6", diff --git a/crates/edr_eth/Cargo.toml b/crates/edr_eth/Cargo.toml index ba638bdc6..fb0e2ab7d 100644 --- a/crates/edr_eth/Cargo.toml +++ b/crates/edr_eth/Cargo.toml @@ -15,7 +15,7 @@ itertools = { version = "0.10.5", default-features = false, features = ["use_all k256 = { version = "0.13.1", default-features = false, features = ["arithmetic", "ecdsa", "pkcs8", ] } log = { version = "0.4.17", default-features = false } once_cell = { version = "1.18.0", default-features = false, features = ["alloc", "race", "std"] } -revm-primitives = { git = "https://github.com/NomicFoundation/revm", rev = "335551e", version = "5.0", default-features = false, features = ["c-kzg", "hashbrown"] } +revm-primitives = { git = "https://github.com/NomicFoundation/revm", rev = "14945e92", version = "5.0", default-features = false, features = ["c-kzg", "hashbrown"] } serde = { version = "1.0.147", default-features = false, features = ["derive"], optional = true } sha2 = { version = "0.10.8", default-features = false } sha3 = { version = "0.10.8", default-features = false } diff --git a/crates/edr_evm/Cargo.toml b/crates/edr_evm/Cargo.toml index 4586050a1..a3508b6b6 100644 --- a/crates/edr_evm/Cargo.toml +++ b/crates/edr_evm/Cargo.toml @@ -19,7 +19,7 @@ parking_lot = { version = "0.12.1", default-features = false } edr_defaults = { version = "0.3.5", path = "../edr_defaults" } edr_eth = { version = "0.3.5", path = "../edr_eth", features = ["rand", "serde"] } edr_rpc_eth = { version = "0.3.5", path = "../edr_rpc_eth" } -revm = { git = "https://github.com/NomicFoundation/revm", rev = "335551e", version = "10.0", default-features = false, features = ["c-kzg", "dev", "serde"] } +revm = { git = "https://github.com/NomicFoundation/revm", rev = "14945e92", version = "10.0", default-features = false, features = ["c-kzg", "dev", "serde"] } rpds = { version = "1.1.0", default-features = false, features = ["std"] } serde = { version = "1.0.158", default-features = false, features = ["std"] } serde_json = { version = "1.0.94", default-features = false, features = ["std"] }