diff --git a/Cargo.lock b/Cargo.lock index 2de671d16d..62ea3d9b6e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2118,7 +2118,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]] @@ -3039,7 +3039,7 @@ dependencies = [ [[package]] name = "revm" version = "14.0.1" -source = "git+https://github.com/Wodann/revm?rev=f57e3e6#f57e3e639ee157c7e659e740bd175a7357003570" +source = "git+https://github.com/Wodann/revm?rev=dfc2f28f#dfc2f28f0728420be07c18346cf81c5311f5d7e9" dependencies = [ "auto_impl", "derive-where", @@ -3053,7 +3053,7 @@ dependencies = [ [[package]] name = "revm-interpreter" version = "10.0.1" -source = "git+https://github.com/Wodann/revm?rev=f57e3e6#f57e3e639ee157c7e659e740bd175a7357003570" +source = "git+https://github.com/Wodann/revm?rev=dfc2f28f#dfc2f28f0728420be07c18346cf81c5311f5d7e9" dependencies = [ "derive-where", "revm-primitives", @@ -3063,7 +3063,7 @@ dependencies = [ [[package]] name = "revm-optimism" version = "1.0.0" -source = "git+https://github.com/Wodann/revm?rev=f57e3e6#f57e3e639ee157c7e659e740bd175a7357003570" +source = "git+https://github.com/Wodann/revm?rev=dfc2f28f#dfc2f28f0728420be07c18346cf81c5311f5d7e9" dependencies = [ "enumn", "revm", @@ -3074,7 +3074,7 @@ dependencies = [ [[package]] name = "revm-precompile" version = "11.0.1" -source = "git+https://github.com/Wodann/revm?rev=f57e3e6#f57e3e639ee157c7e659e740bd175a7357003570" +source = "git+https://github.com/Wodann/revm?rev=dfc2f28f#dfc2f28f0728420be07c18346cf81c5311f5d7e9" dependencies = [ "aurora-engine-modexp", "c-kzg", @@ -3092,7 +3092,7 @@ dependencies = [ [[package]] name = "revm-primitives" version = "9.0.1" -source = "git+https://github.com/Wodann/revm?rev=f57e3e6#f57e3e639ee157c7e659e740bd175a7357003570" +source = "git+https://github.com/Wodann/revm?rev=dfc2f28f#dfc2f28f0728420be07c18346cf81c5311f5d7e9" dependencies = [ "alloy-eips", "alloy-primitives 0.8.3", diff --git a/crates/edr_eth/Cargo.toml b/crates/edr_eth/Cargo.toml index c50b87ae34..eb7e64a158 100644 --- a/crates/edr_eth/Cargo.toml +++ b/crates/edr_eth/Cargo.toml @@ -17,8 +17,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 = { git = "https://github.com/Wodann/revm", rev = "f57e3e6", version = "14.0", default-features = false, features = ["c-kzg", "dev", "serde"] } -revm-primitives = { git = "https://github.com/Wodann/revm", rev = "f57e3e6", version = "9.0", default-features = false, features = ["c-kzg", "hashbrown"] } +revm = { git = "https://github.com/Wodann/revm", rev = "dfc2f28f", version = "14.0", default-features = false, features = ["c-kzg", "dev", "serde"] } +revm-primitives = { git = "https://github.com/Wodann/revm", rev = "dfc2f28f", version = "9.0", default-features = false, features = ["c-kzg", "hashbrown", "rand"] } serde = { version = "1.0.209", default-features = false, features = ["derive"], optional = true } sha2 = { version = "0.10.8", default-features = false } sha3 = { version = "0.10.8", default-features = false } @@ -41,7 +41,6 @@ tokio = { version = "1.23.0", features = ["macros"] } [features] default = ["std"] -rand = ["revm-primitives/rand"] serde = ["dep:serde", "c-kzg/serde", "revm/serde", "revm-primitives/serde"] std = ["alloy-eips/std", "hash256-std-hasher/std", "hash-db/std", "hex/std", "itertools/use_std", "k256/std", "k256/precomputed-tables", "revm/std", "revm-primitives/std", "serde?/std", "sha2/std", "sha3/std", "triehash/std"] test-remote = [] diff --git a/crates/edr_eth/src/chain_spec.rs b/crates/edr_eth/src/chain_spec.rs index 3c8ec2598d..f26b0cd338 100644 --- a/crates/edr_eth/src/chain_spec.rs +++ b/crates/edr_eth/src/chain_spec.rs @@ -3,44 +3,52 @@ use std::marker::PhantomData; use alloy_rlp::RlpEncodable; use revm::Database; pub use revm_primitives::EvmWiring; +use revm_primitives::{ChainSpec, InvalidTransaction, TransactionValidation}; use crate::{ eips::eip1559::{BaseFeeParams, ConstantBaseFeeParams}, transaction, }; -/// The chain specification for Ethereum Layer 1. -#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, RlpEncodable)] -pub struct L1ChainSpec { - phantom: PhantomData<(DatabaseT, ExternalContextT)>, +/// A wrapper around the EVM's wiring. +pub struct Wiring { + _phantom: PhantomData<(ChainSpecT, DatabaseT, ExternalContextT)>, } -impl EvmWiring for L1ChainSpec { +impl EvmWiring + for Wiring +{ + type ChainSpec = ChainSpecT; type ExternalContext = ExternalContextT; - - type ChainContext = (); - type Database = DatabaseT; - - type Block = revm_primitives::BlockEnv; - - type Hardfork = revm_primitives::SpecId; - - type HaltReason = revm_primitives::HaltReason; - - type Transaction = transaction::Signed; } -impl revm::EvmWiring - for L1ChainSpec +impl revm::EvmWiring + for Wiring +where + ChainSpecT: + ChainSpec>>, + DatabaseT: Database, { fn handler<'evm>(hardfork: Self::Hardfork) -> revm::EvmHandler<'evm, Self> { revm::EvmHandler::mainnet_with_spec(hardfork) } } +/// The chain specification for Ethereum Layer 1. +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, RlpEncodable)] +pub struct L1ChainSpec; + +impl ChainSpec for L1ChainSpec { + type ChainContext = (); + type Block = revm_primitives::BlockEnv; + type Transaction = transaction::Signed; + type Hardfork = revm_primitives::SpecId; + type HaltReason = revm_primitives::HaltReason; +} + /// Constants for constructing Ethereum headers. -pub trait EthHeaderConstants: revm_primitives::EvmWiring { +pub trait EthHeaderConstants: ChainSpec { /// Parameters for the EIP-1559 base fee calculation. const BASE_FEE_PARAMS: BaseFeeParams; @@ -48,9 +56,7 @@ pub trait EthHeaderConstants: revm_primitives::EvmWiring EthHeaderConstants - for L1ChainSpec -{ +impl EthHeaderConstants for L1ChainSpec { const BASE_FEE_PARAMS: BaseFeeParams = BaseFeeParams::Constant(ConstantBaseFeeParams::ethereum()); diff --git a/crates/edr_eth/tests/receipt.rs b/crates/edr_eth/tests/receipt.rs index a1d21d29fa..d7171aa452 100644 --- a/crates/edr_eth/tests/receipt.rs +++ b/crates/edr_eth/tests/receipt.rs @@ -13,7 +13,6 @@ mod remote { async fn []() -> anyhow::Result<()> { use edr_eth::{ chain_spec::L1ChainSpec, - db::EmptyDB, eips::eip2718::TypedEnvelope, log::FilterLog, receipt, @@ -23,7 +22,7 @@ mod remote { use edr_rpc_eth::{client::EthRpcClient}; use edr_test_utils::env::get_alchemy_url; - let client = EthRpcClient::>::new(&get_alchemy_url(), edr_defaults::CACHE_DIR.into(), None)?; + let client = EthRpcClient::::new(&get_alchemy_url(), edr_defaults::CACHE_DIR.into(), None)?; let block = client .get_block_by_number_with_transaction_data(PreEip1898BlockSpec::Number($block_number)) @@ -71,7 +70,6 @@ mod remote { use alloy_rlp::Decodable as _; use edr_eth::{ chain_spec::L1ChainSpec, - db::EmptyDB, eips::eip2718::TypedEnvelope, log::{ExecutionLog, FilterLog}, receipt::{self, MapReceiptLogs as _}, @@ -82,7 +80,7 @@ mod remote { use tempfile::TempDir; let tempdir = TempDir::new().unwrap(); - let client = EthRpcClient::>::new(&get_alchemy_url(), tempdir.path().into(), None).unwrap(); + let client = EthRpcClient::::new(&get_alchemy_url(), tempdir.path().into(), None).unwrap(); let transaction_hash = B256::from_slice(&hex::decode($transaction_hash).unwrap()); diff --git a/crates/edr_evm/Cargo.toml b/crates/edr_evm/Cargo.toml index 10d69cf0d1..f450d052bd 100644 --- a/crates/edr_evm/Cargo.toml +++ b/crates/edr_evm/Cargo.toml @@ -19,9 +19,9 @@ log = { version = "0.4.17", default-features = false } once_cell = { version = "1.18.0", default-features = false, features = ["alloc", "race", "std"] } 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_eth = { version = "0.3.5", path = "../edr_eth", features = ["serde"] } edr_rpc_eth = { version = "0.3.5", path = "../edr_rpc_eth" } -revm = { git = "https://github.com/Wodann/revm", rev = "f57e3e6", version = "14.0", default-features = false, features = ["c-kzg", "dev", "serde", "std"] } +revm = { git = "https://github.com/Wodann/revm", rev = "dfc2f28f", version = "14.0", default-features = false, features = ["c-kzg", "dev", "serde", "std"] } rpds = { version = "1.1.0", default-features = false, features = ["std"] } serde = { version = "1.0.209", default-features = false, features = ["std"] } serde_json = { version = "1.0.127", default-features = false, features = ["std"] } diff --git a/crates/edr_evm/src/block/builder.rs b/crates/edr_evm/src/block/builder.rs index c77955429b..d5080a1fef 100644 --- a/crates/edr_evm/src/block/builder.rs +++ b/crates/edr_evm/src/block/builder.rs @@ -5,6 +5,8 @@ use std::{ use edr_eth::{ block::{BlobGas, BlockOptions, PartialHeader}, + chain_spec::Wiring, + env::{CfgEnv, Env}, log::ExecutionLog, receipt::{ExecutionReceiptBuilder as _, Receipt as _, TransactionReceipt}, result::InvalidTransaction, @@ -14,8 +16,7 @@ use edr_eth::{ Address, Bloom, U256, }; use revm::{ - db::{DatabaseComponents, StateRef}, - handler::{CfgEnvWithEvmWiring, EnvWithEvmWiring}, + db::{DatabaseComponents, StateRef, WrapDatabaseRef}, primitives::{ ExecutionResult, ResultAndState, SpecId, Transaction as _, TransactionValidation, MAX_BLOB_GAS_PER_BLOCK, @@ -48,7 +49,7 @@ where #[derive(Debug, thiserror::Error)] pub enum BlockTransactionError where - ChainSpecT: revm::primitives::EvmWiring, + 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")] @@ -65,17 +66,15 @@ where /// was executed. pub struct ExecutionResultWithContext< 'evm, - ChainSpecT, + ChainSpecT: ChainSpec>>, BlockchainErrorT, StateErrorT, DebugDataT, StateT: StateRef, -> where - ChainSpecT: revm::EvmWiring, -{ +> { /// The result of executing the transaction. pub result: Result< - ExecutionResult, + ExecutionResult, BlockTransactionError, >, /// The context in which the transaction was executed. @@ -92,7 +91,8 @@ pub struct BuildBlockResult { /// A builder for constructing Ethereum blocks. pub struct BlockBuilder { - cfg: CfgEnvWithEvmWiring, + cfg: CfgEnv, + hardfork: ChainSpecT::Hardfork, header: PartialHeader, transactions: Vec, state_diff: StateDiff, @@ -108,12 +108,14 @@ where /// Creates an intance of [`BlockBuilder`]. #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))] pub fn new( - cfg: CfgEnvWithEvmWiring, + cfg: CfgEnv, + hardfork: ChainSpecT::Hardfork, parent: &dyn SyncBlock, mut options: BlockOptions, ) -> Result> { - if cfg.spec_id.into() < SpecId::BYZANTIUM { - return Err(BlockBuilderCreationError::UnsupportedHardfork(cfg.spec_id)); + let evm_spec_id = hardfork.into(); + if evm_spec_id < SpecId::BYZANTIUM { + return Err(BlockBuilderCreationError::UnsupportedHardfork(hardfork)); } let parent_header = parent.header(); @@ -124,7 +126,7 @@ where }; let withdrawals = std::mem::take(&mut options.withdrawals).or_else(|| { - if cfg.spec_id.into() >= SpecId::SHANGHAI { + if evm_spec_id >= SpecId::SHANGHAI { Some(Vec::new()) } else { None @@ -132,10 +134,11 @@ where }); options.parent_hash = Some(*parent.hash()); - let header = PartialHeader::new::(cfg.spec_id, options, Some(parent_header)); + let header = PartialHeader::new::(hardfork, options, Some(parent_header)); Ok(Self { cfg, + hardfork, header, transactions: Vec::new(), state_diff: StateDiff::default(), @@ -148,10 +151,15 @@ where impl BlockBuilder { /// Retrieves the config of the block builder. - pub fn config(&self) -> &CfgEnvWithEvmWiring { + pub fn config(&self) -> &CfgEnv { &self.cfg } + /// Retrieves the hardfork of the block builder. + pub fn hardfork(&self) -> ChainSpecT::Hardfork { + self.hardfork + } + /// Retrieves the amount of gas used in the block, so far. pub fn gas_used(&self) -> u64 { self.header.gas_used @@ -296,8 +304,7 @@ where } } - let spec_id = self.cfg.spec_id; - let block = ChainSpecT::Block::new_block_env(&self.header, spec_id); + let block = ChainSpecT::Block::new_block_env(&self.header, self.hardfork); let receipt_builder = { let builder = ChainSpecT::ReceiptBuilder::new_receipt_builder(&state, &transaction); @@ -316,12 +323,11 @@ where } }; - let env = EnvWithEvmWiring::new_with_cfg_env(self.cfg.clone(), block, transaction.clone()); - - let db = DatabaseComponents { + let env = Env::boxed(self.cfg.clone(), block, transaction.clone()); + let db = WrapDatabaseRef(DatabaseComponents { state, block_hash: blockchain, - }; + }); let ( mut evm_context, @@ -331,11 +337,10 @@ where }, ) = { if let Some(debug_context) = debug_context { - let mut evm = Evm::builder() - .with_chain_spec::() - .with_ref_db(db) + let mut evm = Evm::>::builder() + .with_db(db) .with_external_context(debug_context.data) - .with_env_with_handler_cfg(env) + .with_env(env) .append_handler_register(debug_context.register_handles_fn) .build(); @@ -367,10 +372,9 @@ where } } } else { - let mut evm = Evm::builder() - .with_chain_spec::() - .with_ref_db(db) - .with_env_with_handler_cfg(env) + let mut evm = Evm::>::builder() + .with_db(db) + .with_env(env) .build(); let result = evm.transact(); @@ -412,14 +416,15 @@ where *gas_used += blob_gas_used; } - let receipt = receipt_builder.build_receipt(&self.header, &transaction, &result, spec_id); + let receipt = + receipt_builder.build_receipt(&self.header, &transaction, &result, self.hardfork); let receipt = TransactionReceipt::new( receipt, &transaction, &result, self.transactions.len() as u64, self.header.base_fee.unwrap_or(U256::ZERO), - spec_id, + self.hardfork, ); self.receipts.push(receipt); diff --git a/crates/edr_evm/src/chain_spec.rs b/crates/edr_evm/src/chain_spec.rs index 7d8af77de5..29ece5e8c2 100644 --- a/crates/edr_evm/src/chain_spec.rs +++ b/crates/edr_evm/src/chain_spec.rs @@ -11,7 +11,7 @@ use edr_eth::{ SpecId, B256, U256, }; use edr_rpc_eth::{spec::RpcSpec, RpcTypeFrom, TransactionConversionError}; -use revm::primitives::TransactionValidation; +use revm::primitives::{HardforkTrait, TransactionValidation}; pub use revm::EvmWiring; use crate::{ @@ -28,8 +28,8 @@ pub trait ChainSpec: alloy_rlp::Encodable // Defines the chain's internal types like blocks/headers or transactions + EthHeaderConstants - + EvmWiring< - Block: BlockEnvConstructor + BlockEnvConstructor, + + revm::primitives::ChainSpec< + Block: BlockEnvConstructor + BlockEnvConstructor, Transaction: alloy_rlp::Encodable + Clone + Debug @@ -48,7 +48,7 @@ pub trait ChainSpec: + TryInto, Error = Self::RpcReceiptConversionError>, RpcTransaction: EthRpcTransaction + RpcTypeFrom, Hardfork = Self::Hardfork> - + TryInto<::Transaction, Error = Self::RpcTransactionConversionError>, + + TryInto<::Transaction, Error = Self::RpcTransactionConversionError>, > + RpcSpec: Debug> + RpcSpec< @@ -59,7 +59,9 @@ pub trait ChainSpec: { /// Type representing a builder that constructs an execution receipt. type ReceiptBuilder: ExecutionReceiptBuilder< - Self, + Self::HaltReason, + Self::Hardfork, + Self::Transaction, Receipt = Self::ExecutionReceipt, >; @@ -91,12 +93,12 @@ pub trait ChainSpec: } /// A trait for constructing a (partial) block header into an EVM block. -pub trait BlockEnvConstructor { +pub trait BlockEnvConstructor { /// Converts the instance into an EVM block. - fn new_block_env(header: &HeaderT, hardfork: ChainSpecT::Hardfork) -> Self; + fn new_block_env(header: &HeaderT, hardfork: HardforkT) -> Self; } -impl BlockEnvConstructor for BlockEnv { +impl BlockEnvConstructor for BlockEnv { fn new_block_env(header: &PartialHeader, hardfork: SpecId) -> Self { Self { number: U256::from(header.number), @@ -118,7 +120,7 @@ impl BlockEnvConstructor for BlockEnv { } } -impl BlockEnvConstructor for BlockEnv { +impl BlockEnvConstructor for BlockEnv { fn new_block_env(header: &block::Header, hardfork: SpecId) -> Self { Self { number: U256::from(header.number), diff --git a/crates/edr_evm/src/debug.rs b/crates/edr_evm/src/debug.rs index e6cae1bc4c..90766aab67 100644 --- a/crates/edr_evm/src/debug.rs +++ b/crates/edr_evm/src/debug.rs @@ -1,18 +1,28 @@ use auto_impl::auto_impl; -use revm::db::{DatabaseComponents, StateRef, WrapDatabaseRef}; +use edr_eth::{chain_spec::Wiring, result::InvalidTransaction}; +use revm::{ + db::{DatabaseComponents, StateRef, WrapDatabaseRef}, + primitives::TransactionValidation, +}; -use crate::blockchain::SyncBlockchain; +use crate::{blockchain::SyncBlockchain, chain_spec::ChainSpec}; /// 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< - StateT, - &'evm dyn SyncBlockchain::Error>, + Wiring< + ChainSpecT, + WrapDatabaseRef< + DatabaseComponents< + StateT, + &'evm dyn SyncBlockchain< + ChainSpecT, + BlockchainErrorT, + ::Error, + >, + >, >, + DebugDataT, >, >; @@ -20,7 +30,8 @@ pub type HandleRegister<'evm, ChainSpecT, BlockchainErrorT, DebugDataT, StateT> /// `EvmBuilder`. pub struct DebugContext<'evm, ChainSpecT, BlockchainErrorT, DebugDataT, StateT> where - ChainSpecT: revm::EvmWiring, + ChainSpecT: + ChainSpec>>, StateT: StateRef, { /// The contextual data. @@ -31,7 +42,8 @@ where pub struct EvmContext<'evm, ChainSpecT, BlockchainErrorT, DebugDataT, StateT> where - ChainSpecT: revm::EvmWiring, + ChainSpecT: + ChainSpec>>, StateT: StateRef, { pub debug: Option>, diff --git a/crates/edr_evm/src/debug_trace.rs b/crates/edr_evm/src/debug_trace.rs index 259e5006af..dd6ca2cc56 100644 --- a/crates/edr_evm/src/debug_trace.rs +++ b/crates/edr_evm/src/debug_trace.rs @@ -1,18 +1,24 @@ -use std::{collections::HashMap, fmt::Debug, marker::PhantomData, sync::Arc}; - -use edr_eth::{transaction::ExecutableTransaction as _, utils::u256_to_padded_hex, B256}; +use std::{collections::HashMap, fmt::Debug, sync::Arc}; + +use edr_eth::{ + chain_spec::Wiring, + env::{CfgEnv, Env}, + transaction::ExecutableTransaction as _, + utils::u256_to_padded_hex, + B256, +}; use revm::{ - db::DatabaseComponents, - handler::{register::EvmHandler, CfgEnvWithEvmWiring}, + db::{DatabaseComponents, WrapDatabaseRef}, + handler::register::EvmHandler, interpreter::{ opcode::{self, DynInstruction, OpCode}, Interpreter, InterpreterResult, }, primitives::{ - hex, Address, Block as _, Bytes, ExecutionResult, InvalidTransaction, ResultAndState, - SpecId, TransactionValidation, U256, + hex, Address, Block as _, Bytes, ExecutionResult, HaltReasonTrait, InvalidTransaction, + ResultAndState, SpecId, TransactionValidation, U256, }, - Context, Database, Evm, EvmContext, JournalEntry, + Context, Database, Evm, EvmContext, EvmWiring, JournalEntry, }; use crate::{ @@ -25,18 +31,12 @@ use crate::{ }; /// EIP-3155 and raw tracers. -pub struct Eip3155AndRawTracers -where - ChainSpecT: revm::EvmWiring, -{ - eip3155: TracerEip3155, - raw: TraceCollector, +pub struct Eip3155AndRawTracers { + eip3155: TracerEip3155, + raw: TraceCollector, } -impl Eip3155AndRawTracers -where - ChainSpecT: revm::EvmWiring, -{ +impl Eip3155AndRawTracers { /// Creates a new instance. pub fn new(config: DebugTraceConfig, verbose_tracing: bool) -> Self { Self { @@ -46,34 +46,32 @@ where } } -impl GetContextData> for Eip3155AndRawTracers -where - ChainSpecT: revm::EvmWiring, +impl GetContextData> + for Eip3155AndRawTracers { - fn get_context_data(&mut self) -> &mut TraceCollector { + fn get_context_data(&mut self) -> &mut TraceCollector { &mut self.raw } } -impl GetContextData> for Eip3155AndRawTracers -where - ChainSpecT: revm::EvmWiring, +impl GetContextData + for Eip3155AndRawTracers { - fn get_context_data(&mut self) -> &mut TracerEip3155 { + 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::EvmWiring, - DatabaseT: Database, - ContextT: GetContextData> + GetContextData>, + EvmWiringT: revm::EvmWiring< + ExternalContext: GetContextData> + + GetContextData, + Database: Database, + >, >( - handler: &mut EvmHandler<'_, ChainSpecT, ContextT, DatabaseT>, -) where - DatabaseT::Error: Debug, -{ + handler: &mut EvmHandler<'_, EvmWiringT>, +) { register_trace_collector_handles(handler); register_eip_3155_tracer_handles(handler); } @@ -85,14 +83,15 @@ 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: CfgEnvWithEvmWiring, + evm_config: CfgEnv, + hardfork: ChainSpecT::Hardfork, trace_config: DebugTraceConfig, block: ChainSpecT::Block, transactions: Vec, transaction_hash: &B256, verbose_tracing: bool, ) -> Result< - DebugTraceResultWithTraces, + DebugTraceResultWithTraces, DebugTraceError, > where @@ -103,11 +102,11 @@ where BlockchainErrorT: Debug + Send, StateErrorT: Debug + Send, { - let l1_spec_id = evm_config.spec_id.into(); - if l1_spec_id < SpecId::SPURIOUS_DRAGON { + let evm_spec_id = hardfork.into(); + if evm_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: l1_spec_id, + spec_id: evm_spec_id, }); } @@ -116,17 +115,16 @@ where let mut tracer = Eip3155AndRawTracers::new(trace_config, verbose_tracing); let ResultAndState { result, .. } = { - let mut evm = Evm::builder() - .with_chain_spec::() - .with_ref_db(DatabaseComponents { + let env = Env::boxed(evm_config, block, transaction); + + let mut evm = Evm::>::builder() + .with_db(WrapDatabaseRef(DatabaseComponents { state: state.as_ref(), block_hash: blockchain, - }) + })) .with_external_context(&mut tracer) - .with_cfg_env_with_handler_cfg(evm_config) + .with_env(env) .append_handler_register(register_eip_3155_and_raw_tracers_handles) - .with_block_env(block) - .with_tx_env(transaction) .build(); evm.transact().map_err(TransactionError::from)? @@ -135,15 +133,14 @@ where return Ok(execution_result_to_debug_result(result, tracer)); } else { let ResultAndState { state: changes, .. } = { - let mut evm = Evm::builder() - .with_chain_spec::() - .with_ref_db(DatabaseComponents { + let env = Env::boxed(evm_config.clone(), block.clone(), transaction); + + let mut evm = Evm::>::builder() + .with_db(WrapDatabaseRef(DatabaseComponents { state: state.as_ref(), block_hash: blockchain, - }) - .with_cfg_env_with_handler_cfg(evm_config.clone()) - .with_block_env(block.clone()) - .with_tx_env(transaction) + })) + .with_env(env) .build(); evm.transact().map_err(TransactionError::from)? @@ -160,13 +157,10 @@ where } /// Convert an `ExecutionResult` to a `DebugTraceResult`. -pub fn execution_result_to_debug_result( - execution_result: ExecutionResult, - tracer: Eip3155AndRawTracers, -) -> DebugTraceResultWithTraces -where - ChainSpecT: revm::EvmWiring, -{ +pub fn execution_result_to_debug_result( + execution_result: ExecutionResult, + tracer: Eip3155AndRawTracers, +) -> DebugTraceResultWithTraces { let Eip3155AndRawTracers { eip3155, raw } = tracer; let traces = raw.into_traces(); @@ -211,7 +205,7 @@ pub struct DebugTraceConfig { #[derive(Debug, thiserror::Error)] pub enum DebugTraceError where - ChainSpecT: revm::EvmWiring, + ChainSpecT: revm::primitives::ChainSpec, { /// Invalid hardfork spec argument. #[error("Invalid spec id: {spec_id:?}. `debug_traceTransaction` is not supported prior to Spurious Dragon")] @@ -248,11 +242,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. @@ -293,11 +287,9 @@ pub struct DebugTraceLogItem { /// Register EIP-3155 tracer handles. pub fn register_eip_3155_tracer_handles< - ChainSpecT: revm::EvmWiring, - DatabaseT: Database, - ContextT: GetContextData>, + EvmWiringT: revm::EvmWiring>, >( - handler: &mut EvmHandler<'_, ChainSpecT, ContextT, DatabaseT>, + handler: &mut EvmHandler<'_, EvmWiringT>, ) { let table = &mut handler.instruction_table; @@ -324,15 +316,11 @@ pub fn register_eip_3155_tracer_handles< } /// Outer closure that calls tracer for every instruction. -fn instruction_handler( - prev: &DynInstruction<'_, Context>, +fn instruction_handler>>( + prev: &DynInstruction<'_, Context>, interpreter: &mut Interpreter, - host: &mut Context, -) where - ChainSpecT: revm::EvmWiring, - ContextT: GetContextData>, - DatabaseT: Database, -{ + host: &mut Context, +) { // 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) }; @@ -352,10 +340,7 @@ fn instruction_handler( /// An EIP-3155 compatible EVM tracer. #[derive(Debug)] -pub struct TracerEip3155 -where - ChainSpecT: revm::EvmWiring, -{ +pub struct TracerEip3155 { config: DebugTraceConfig, logs: Vec, contract_address: Address, @@ -367,13 +352,9 @@ where stack: Vec, // Contract-specific storage storage: HashMap>, - phantom: PhantomData, } -impl TracerEip3155 -where - ChainSpecT: revm::EvmWiring, -{ +impl TracerEip3155 { /// Create a new tracer. pub fn new(config: DebugTraceConfig) -> Self { Self { @@ -387,7 +368,6 @@ where memory: Vec::default(), mem_size: 0, storage: HashMap::default(), - phantom: PhantomData, } } @@ -410,10 +390,10 @@ where self.pc = interp.program_counter(); } - fn step_end( + fn step_end( &mut self, interp: &Interpreter, - context: &EvmContext, + context: &EvmContext, ) { let depth = context.journaled_state.depth(); @@ -500,11 +480,8 @@ where } } -impl GetContextData> for TracerEip3155 -where - ChainSpecT: revm::EvmWiring, -{ - fn get_context_data(&mut self) -> &mut TracerEip3155 { +impl GetContextData for TracerEip3155 { + fn get_context_data(&mut self) -> &mut TracerEip3155 { self } } diff --git a/crates/edr_evm/src/miner.rs b/crates/edr_evm/src/miner.rs index 414806bdb6..6657a89e7a 100644 --- a/crates/edr_evm/src/miner.rs +++ b/crates/edr_evm/src/miner.rs @@ -2,14 +2,12 @@ use std::{cmp::Ordering, fmt::Debug, sync::Arc}; use edr_eth::{ block::{calculate_next_base_fee_per_blob_gas, BlockOptions}, + env::CfgEnv, signature::SignatureError, transaction::{ExecutableTransaction as _, Transaction}, U256, }; -use revm::{ - handler::CfgEnvWithEvmWiring, - primitives::{ExecutionResult, InvalidTransaction, TransactionValidation}, -}; +use revm::primitives::{ExecutionResult, InvalidTransaction, TransactionValidation}; use serde::{Deserialize, Serialize}; use crate::{ @@ -34,9 +32,9 @@ where /// 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 @@ -65,7 +63,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. @@ -110,7 +108,8 @@ pub fn mine_block<'blockchain, 'evm, ChainSpecT, DebugDataT, BlockchainErrorT, S blockchain: &'blockchain dyn SyncBlockchain, mut state: Box>, mem_pool: &MemPool, - cfg: &CfgEnvWithEvmWiring, + cfg: &CfgEnv, + hardfork: ChainSpecT::Hardfork, options: BlockOptions, min_gas_price: U256, mine_ordering: MineOrdering, @@ -145,7 +144,7 @@ where .last_block() .map_err(MineBlockError::Blockchain)?; - let mut block_builder = BlockBuilder::new(cfg.clone(), &parent_block, options)?; + let mut block_builder = BlockBuilder::new(cfg.clone(), hardfork, &parent_block, options)?; let mut pending_transactions = { type MineOrderComparator = dyn Fn(&OrderedTransaction, &OrderedTransaction) -> Ordering @@ -308,7 +307,8 @@ pub fn mine_block_with_single_transaction< blockchain: &'blockchain dyn SyncBlockchain, state: Box>, transaction: ChainSpecT::Transaction, - cfg: &CfgEnvWithEvmWiring, + cfg: &CfgEnv, + hardfork: ChainSpecT::Hardfork, options: BlockOptions, min_gas_price: U256, reward: U256, @@ -404,7 +404,8 @@ where } } - let mut block_builder = BlockBuilder::new(cfg.clone(), parent_block.as_ref(), options)?; + let mut block_builder = + BlockBuilder::new(cfg.clone(), hardfork, parent_block.as_ref(), options)?; let ExecutionResultWithContext { result, diff --git a/crates/edr_evm/src/precompiles.rs b/crates/edr_evm/src/precompiles.rs index 83a43ae223..97cd548a35 100644 --- a/crates/edr_evm/src/precompiles.rs +++ b/crates/edr_evm/src/precompiles.rs @@ -1,16 +1,13 @@ -use std::{fmt::Debug, sync::Arc}; +use std::sync::Arc; use edr_eth::{Address, HashMap}; -use revm::{db::Database, ContextPrecompile, EvmHandler}; +use revm::{ContextPrecompile, EvmHandler, EvmWiring}; /// Registers custom precompiles. -pub fn register_precompiles_handles( - handler: &mut EvmHandler<'_, ChainSpecT, ContextT, DatabaseT>, - precompiles: HashMap>, -) where - ChainSpecT: revm::EvmWiring, - DatabaseT: Database, -{ +pub fn register_precompiles_handles( + handler: &mut EvmHandler<'_, EvmWiringT>, + precompiles: HashMap>, +) { let old_handle = handler.pre_execution.load_precompiles(); handler.pre_execution.load_precompiles = Arc::new(move || { let mut new_handle = old_handle.clone(); diff --git a/crates/edr_evm/src/runtime.rs b/crates/edr_evm/src/runtime.rs index 0e7c2a2f6b..e5b9dbd8b5 100644 --- a/crates/edr_evm/src/runtime.rs +++ b/crates/edr_evm/src/runtime.rs @@ -1,23 +1,18 @@ use std::fmt::Debug; use edr_eth::{ + chain_spec::Wiring, db::{DatabaseComponents, StateRef}, + env::{CfgEnv, Env}, result::{ExecutionResult, InvalidTransaction, ResultAndState}, transaction::{ExecutableTransaction as _, TransactionValidation}, Address, HashMap, Precompile, SpecId, }; -use revm::{ - handler::{CfgEnvWithEvmWiring, EnvWithEvmWiring}, - ContextPrecompile, DatabaseCommit, Evm, -}; +use revm::{db::WrapDatabaseRef, ContextPrecompile, DatabaseCommit, Evm}; use crate::{ - blockchain::SyncBlockchain, - chain_spec::ChainSpec, - debug::DebugContext, - precompiles::register_precompiles_handles, - state::{StateOverrides, StateRefOverrider, SyncState}, - transaction::TransactionError, + blockchain::SyncBlockchain, chain_spec::ChainSpec, debug::DebugContext, + precompiles::register_precompiles_handles, transaction::TransactionError, }; /// Asynchronous implementation of the Database super-trait @@ -29,66 +24,51 @@ pub type SyncDatabase<'blockchain, 'state, ChainSpecT, BlockchainErrorT, StateEr /// Runs a transaction without committing the state. // `DebugContext` cannot be simplified further -#[allow(clippy::too_many_arguments, clippy::type_complexity)] +#[allow(clippy::too_many_arguments)] #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))] -pub fn dry_run< - 'blockchain, - 'evm, - 'overrides, - 'state, - ChainSpecT, - DebugDataT, - BlockchainErrorT, - StateErrorT, ->( - blockchain: &'blockchain dyn SyncBlockchain, - state: &'state dyn SyncState, - state_overrides: &'overrides StateOverrides, - cfg: CfgEnvWithEvmWiring, +pub fn dry_run<'blockchain, 'evm, ChainSpecT, DebugDataT, BlockchainErrorT, StateT>( + blockchain: &'blockchain dyn SyncBlockchain, + state: StateT, + cfg: CfgEnv, + hardfork: ChainSpecT::Hardfork, transaction: ChainSpecT::Transaction, block: ChainSpecT::Block, custom_precompiles: &HashMap, - debug_context: Option< - DebugContext< - 'evm, - ChainSpecT, - BlockchainErrorT, - DebugDataT, - StateRefOverrider<'overrides, &'evm dyn SyncState>, - >, - >, -) -> Result, TransactionError> + debug_context: Option>, +) -> Result< + ResultAndState, + TransactionError, +> where 'blockchain: 'evm, - 'state: 'evm, ChainSpecT: ChainSpec< Block: Default, Transaction: Default + TransactionValidation>, >, BlockchainErrorT: Debug + Send, - StateErrorT: Debug + Send, + StateT: StateRef, { - validate_configuration::(cfg.spec_id, &transaction)?; - - let state_overrider = StateRefOverrider::new(state_overrides, state); + validate_configuration::(hardfork, &transaction)?; - let env = EnvWithEvmWiring::new_with_cfg_env(cfg, block, transaction); + let env = Env::boxed(cfg, block, transaction); let result = { - let evm_builder = Evm::builder().with_ref_db(DatabaseComponents { - state: state_overrider, + let builder = Evm::builder().with_db(WrapDatabaseRef(DatabaseComponents { + state, block_hash: blockchain, - }); - - let precompiles: HashMap> = custom_precompiles - .iter() - .map(|(address, precompile)| (*address, ContextPrecompile::from(precompile.clone()))) - .collect(); + })); if let Some(debug_context) = debug_context { - let mut evm = evm_builder - .with_chain_spec::() + let precompiles: HashMap>> = + custom_precompiles + .iter() + .map(|(address, precompile)| { + (*address, ContextPrecompile::from(precompile.clone())) + }) + .collect(); + + let mut evm = builder .with_external_context(debug_context.data) - .with_env_with_handler_cfg(env) + .with_env(env) .append_handler_register(debug_context.register_handles_fn) .append_handler_register_box(Box::new(move |handler| { register_precompiles_handles(handler, precompiles.clone()); @@ -97,9 +77,16 @@ where evm.transact() } else { - let mut evm = evm_builder - .with_chain_spec::() - .with_env_with_handler_cfg(env) + let precompiles: HashMap>> = + custom_precompiles + .iter() + .map(|(address, precompile)| { + (*address, ContextPrecompile::from(precompile.clone())) + }) + .collect(); + + let mut evm = builder + .with_env(env) .append_handler_register_box(Box::new(move |handler| { register_precompiles_handles(handler, precompiles.clone()); })) @@ -115,35 +102,29 @@ where /// Runs a transaction without committing the state, while disabling balance /// checks and creating accounts for new addresses. // `DebugContext` cannot be simplified further -#[allow(clippy::too_many_arguments, clippy::type_complexity)] +#[allow(clippy::too_many_arguments)] #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))] pub fn guaranteed_dry_run< 'blockchain, 'evm, - 'overrides, 'state, ChainSpecT, DebugDataT, BlockchainErrorT, - StateErrorT, + StateT, >( - blockchain: &'blockchain dyn SyncBlockchain, - state: &'state dyn SyncState, - state_overrides: &'overrides StateOverrides, - mut cfg: CfgEnvWithEvmWiring, + blockchain: &'blockchain dyn SyncBlockchain, + state: StateT, + mut cfg: CfgEnv, + hardfork: ChainSpecT::Hardfork, transaction: ChainSpecT::Transaction, block: ChainSpecT::Block, custom_precompiles: &HashMap, - debug_context: Option< - DebugContext< - 'evm, - ChainSpecT, - BlockchainErrorT, - DebugDataT, - StateRefOverrider<'overrides, &'evm dyn SyncState>, - >, - >, -) -> Result, TransactionError> + debug_context: Option>, +) -> Result< + ResultAndState, + TransactionError, +> where 'blockchain: 'evm, 'state: 'evm, @@ -152,7 +133,7 @@ where Transaction: Default + TransactionValidation>, >, BlockchainErrorT: Debug + Send, - StateErrorT: Debug + Send, + StateT: StateRef, { cfg.disable_balance_check = true; cfg.disable_block_gas_limit = true; @@ -160,8 +141,8 @@ where dry_run( blockchain, state, - state_overrides, cfg, + hardfork, transaction, block, custom_precompiles, @@ -171,16 +152,18 @@ where /// Runs a transaction, committing the state in the process. #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))] +#[allow(clippy::too_many_arguments)] pub fn run<'blockchain, 'evm, ChainSpecT, BlockchainErrorT, DebugDataT, StateT>( blockchain: &'blockchain dyn SyncBlockchain, state: StateT, - cfg: CfgEnvWithEvmWiring, + cfg: CfgEnv, + hardfork: ChainSpecT::Hardfork, transaction: ChainSpecT::Transaction, block: ChainSpecT::Block, custom_precompiles: &HashMap, debug_context: Option>, ) -> Result< - ExecutionResult, + ExecutionResult, TransactionError, > where @@ -193,27 +176,26 @@ where StateT: StateRef + DatabaseCommit, StateT::Error: Debug + Send, { - validate_configuration::( - cfg.spec_id, - &transaction, - )?; + validate_configuration::(hardfork, &transaction)?; - let env = EnvWithEvmWiring::new_with_cfg_env(cfg, block, transaction); - let evm_builder = Evm::builder().with_ref_db(DatabaseComponents { + let env = Env::boxed(cfg, block, transaction); + let evm_builder = Evm::builder().with_db(WrapDatabaseRef(DatabaseComponents { state, block_hash: blockchain, - }); - - let precompiles: HashMap> = custom_precompiles - .iter() - .map(|(address, precompile)| (*address, ContextPrecompile::from(precompile.clone()))) - .collect(); + })); let result = if let Some(debug_context) = debug_context { + let precompiles: HashMap>> = + custom_precompiles + .iter() + .map(|(address, precompile)| { + (*address, ContextPrecompile::from(precompile.clone())) + }) + .collect(); + let mut evm = evm_builder - .with_chain_spec::() .with_external_context(debug_context.data) - .with_env_with_handler_cfg(env) + .with_env(env) .append_handler_register(debug_context.register_handles_fn) .append_handler_register_box(Box::new(move |handler| { register_precompiles_handles(handler, precompiles.clone()); @@ -222,9 +204,16 @@ where evm.transact_commit() } else { + let precompiles: HashMap>> = + custom_precompiles + .iter() + .map(|(address, precompile)| { + (*address, ContextPrecompile::from(precompile.clone())) + }) + .collect(); + let mut evm = evm_builder - .with_chain_spec::() - .with_env_with_handler_cfg(env) + .with_env(env) .append_handler_register_box(Box::new(move |handler| { register_precompiles_handles(handler, precompiles.clone()); })) diff --git a/crates/edr_evm/src/test_utils.rs b/crates/edr_evm/src/test_utils.rs index 8ff8d6fec7..1740d804fd 100644 --- a/crates/edr_evm/src/test_utils.rs +++ b/crates/edr_evm/src/test_utils.rs @@ -17,7 +17,6 @@ use edr_rpc_eth::client::EthRpcClient; use crate::{ blockchain::{Blockchain as _, ForkedBlockchain}, chain_spec::SyncChainSpec, - evm::handler::CfgEnvWithEvmWiring, state::{AccountTrie, IrregularState, StateError, TrieState}, transaction, Block, BlockBuilder, DebugContext, ExecutionResultWithContext, MemPool, MemPoolAddTransactionError, RandomHashGenerator, RemoteBlock, @@ -217,12 +216,11 @@ pub async fn run_full_block< cfg.chain_id = chain_id; cfg.disable_eip3607 = true; - let cfg = CfgEnvWithEvmWiring::::new(cfg, hardfork); - let parent = blockchain.last_block()?; let mut builder = BlockBuilder::new( cfg, + hardfork, &parent, BlockOptions { beneficiary: Some(replay_header.beneficiary), diff --git a/crates/edr_evm/src/trace.rs b/crates/edr_evm/src/trace.rs index 9cb1455e2f..f1dd8cad3c 100644 --- a/crates/edr_evm/src/trace.rs +++ b/crates/edr_evm/src/trace.rs @@ -1,7 +1,7 @@ use std::{cell::RefCell, fmt::Debug, rc::Rc, sync::Arc}; use derive_where::derive_where; -use edr_eth::{Address, Bytes, U256}; +use edr_eth::{result::EVMErrorWiring, Address, Bytes, U256}; use revm::{ handler::register::EvmHandler, interpreter::{ @@ -9,7 +9,7 @@ use revm::{ return_revert, CallInputs, CallOutcome, CallValue, CreateInputs, CreateOutcome, InstructionResult, Interpreter, SuccessOrHalt, }, - primitives::{Bytecode, EVMErrorForChain, ExecutionResult, Output}, + primitives::{Bytecode, ExecutionResult, HaltReasonTrait, Output}, Context, Database, EvmContext, FrameOrResult, FrameResult, }; @@ -17,14 +17,13 @@ use crate::{chain_spec::EvmWiring, debug::GetContextData}; /// Registers trace collector handles to the EVM handler. pub fn register_trace_collector_handles< - ChainSpecT: revm::EvmWiring, - DatabaseT: Database, - ContextT: GetContextData>, + EvmWiringT: revm::EvmWiring< + ExternalContext: GetContextData>, + Database: Database, + >, >( - handler: &mut EvmHandler<'_, ChainSpecT, ContextT, DatabaseT>, -) where - DatabaseT::Error: Debug, -{ + handler: &mut EvmHandler<'_, EvmWiringT>, +) { let table = &mut handler.instruction_table; // Update all instructions to call the instruction handler. @@ -39,9 +38,7 @@ 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); @@ -55,9 +52,7 @@ 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); @@ -71,10 +66,7 @@ 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(); @@ -119,14 +111,15 @@ pub fn register_trace_collector_handles< } /// Outer closure that calls tracer for every instruction. -fn instruction_handler( - prev: &DynInstruction<'_, Context>, +fn instruction_handler( + prev: &DynInstruction<'_, Context>, interpreter: &mut Interpreter, - host: &mut Context, + host: &mut Context, ) where - ChainSpecT: revm::EvmWiring, - ContextT: GetContextData>, - DatabaseT: Database, + EvmWiringT: revm::EvmWiring< + Database: Database, + ExternalContext: GetContextData>, + >, { // SAFETY: as the PC was already incremented we need to subtract 1 to preserve // the old Inspector behavior. @@ -144,15 +137,14 @@ fn instruction_handler( } /// Stack tracing message -#[derive(Debug)] -#[derive_where(Clone; ChainSpecT::HaltReason)] -pub enum TraceMessage { +#[derive(Clone, 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), } /// Temporary before message type for handling traces @@ -179,25 +171,23 @@ pub struct BeforeMessage { } /// Event that occurs after a call or create message. -#[derive(Debug)] -#[derive_where(Clone; ChainSpecT::HaltReason)] -pub struct AfterMessage { +#[derive(Clone, 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
, } /// A trace for an EVM call. -#[derive(Debug)] -#[derive_where(Clone; ChainSpecT::HaltReason)] +#[derive(Clone, Debug)] #[derive_where(Default)] -pub struct Trace { +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, } @@ -253,14 +243,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)); } @@ -273,14 +263,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 { @@ -293,16 +283,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") } @@ -312,13 +302,11 @@ impl TraceCollector { } } - fn call( + fn call, HaltReason = HaltReasonT>>( &mut self, - data: &mut EvmContext, + data: &mut EvmContext, inputs: &CallInputs, - ) where - DatabaseT::Error: Debug, - { + ) { if self.is_new_trace { self.is_new_trace = false; self.traces.push(Trace::default()); @@ -367,9 +355,9 @@ impl TraceCollector { }); } - fn call_end( + fn call_end>( &mut self, - data: &EvmContext, + data: &EvmContext, _inputs: &CallInputs, outcome: &CallOutcome, ) { @@ -393,7 +381,7 @@ impl TraceCollector { ret }; - let execution_result = match SuccessOrHalt::::from(safe_ret) { + let execution_result = match SuccessOrHalt::from(safe_ret) { SuccessOrHalt::Success(reason) => ExecutionResult::Success { reason, gas_used: outcome.gas().spent(), @@ -421,9 +409,9 @@ impl TraceCollector { }); } - fn create( + fn create>( &mut self, - data: &EvmContext, + data: &EvmContext, inputs: &CreateInputs, ) { if self.is_new_trace { @@ -446,14 +434,12 @@ impl TraceCollector { }); } - fn create_end( + fn create_end>( &mut self, - data: &EvmContext, + data: &EvmContext, _inputs: &CreateInputs, outcome: &CreateOutcome, - ) where - ::Error: Debug, - { + ) { self.validate_before_message(); let ret = *outcome.instruction_result(); @@ -464,7 +450,7 @@ impl TraceCollector { ret }; - let execution_result = match SuccessOrHalt::::from(safe_ret) { + let execution_result = match SuccessOrHalt::from(safe_ret) { SuccessOrHalt::Success(reason) => ExecutionResult::Success { reason, gas_used: outcome.gas().spent(), @@ -492,10 +478,10 @@ impl TraceCollector { }); } - fn step( + fn step>( &mut self, interp: &Interpreter, - data: &EvmContext, + data: &EvmContext, ) { // Skip the step let skip_step = self.pending_before.as_ref().map_or(false, |message| { @@ -525,9 +511,9 @@ impl TraceCollector { } } - fn call_transaction_end( + fn call_transaction_end>( &mut self, - data: &EvmContext, + data: &EvmContext, inputs: &CallInputs, outcome: &CallOutcome, ) { @@ -535,23 +521,21 @@ impl TraceCollector { self.call_end(data, inputs, outcome); } - fn create_transaction_end( + fn create_transaction_end>( &mut self, - data: &EvmContext, + data: &EvmContext, inputs: &CreateInputs, outcome: &CreateOutcome, - ) where - DatabaseT::Error: Debug, - { + ) { self.is_new_trace = true; self.create_end(data, inputs, outcome); } } -impl GetContextData> - for TraceCollector +impl GetContextData> + for TraceCollector { - fn get_context_data(&mut self) -> &mut 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 492360b1e2..b30f265090 100644 --- a/crates/edr_evm/src/transaction.rs +++ b/crates/edr_evm/src/transaction.rs @@ -7,11 +7,12 @@ use std::fmt::Debug; use derive_where::derive_where; // Re-export the transaction types from `edr_eth`. pub use edr_eth::transaction::*; -use edr_eth::{result::InvalidHeader, SpecId, U256}; +use edr_eth::{ + result::{EVMErrorForChain, InvalidHeader}, + SpecId, U256, +}; use revm::{ - db::DatabaseComponentError, - interpreter::gas::validate_initial_tx_gas, - primitives::{EVMError, EVMErrorForChain}, + db::DatabaseComponentError, interpreter::gas::validate_initial_tx_gas, primitives::EVMError, }; pub use self::detailed::*; @@ -22,7 +23,7 @@ use crate::chain_spec::ChainSpec; #[derive_where(Debug; ::ValidationError, BlockchainErrorT, StateErrorT)] pub enum TransactionError where - ChainSpecT: revm::primitives::EvmWiring, + ChainSpecT: revm::primitives::ChainSpec, { /// Blockchain errors #[error(transparent)] @@ -57,13 +58,13 @@ where } impl - From, ChainSpecT>> + From>> for TransactionError where ChainSpecT: ChainSpec, { fn from( - error: EVMErrorForChain, ChainSpecT>, + error: EVMErrorForChain>, ) -> Self { match error { EVMError::Transaction(error) => ChainSpecT::cast_transaction_error(error), diff --git a/crates/edr_generic/Cargo.toml b/crates/edr_generic/Cargo.toml index 856e26bea3..14f9d8437c 100644 --- a/crates/edr_generic/Cargo.toml +++ b/crates/edr_generic/Cargo.toml @@ -12,8 +12,8 @@ edr_evm = { path = "../edr_evm" } edr_provider = { path = "../edr_provider" } edr_rpc_eth = { path = "../edr_rpc_eth" } log = { version = "0.4.17", default-features = false } -revm = { git = "https://github.com/Wodann/revm", rev = "f57e3e6", version = "14.0", default-features = false, features = ["c-kzg", "dev", "serde"] } -revm-primitives = { git = "https://github.com/Wodann/revm", rev = "f57e3e6", version = "9.0", default-features = false, features = ["c-kzg", "hashbrown"] } +revm = { git = "https://github.com/Wodann/revm", rev = "dfc2f28f", version = "14.0", default-features = false, features = ["c-kzg", "dev", "serde"] } +revm-primitives = { git = "https://github.com/Wodann/revm", rev = "dfc2f28f", version = "9.0", default-features = false, features = ["c-kzg", "hashbrown"] } serde = { version = "1.0.209", default-features = false, features = ["derive"] } thiserror = { version = "1.0.37", default-features = false } diff --git a/crates/edr_optimism/Cargo.toml b/crates/edr_optimism/Cargo.toml index 8882c1fdad..3c277cc41b 100644 --- a/crates/edr_optimism/Cargo.toml +++ b/crates/edr_optimism/Cargo.toml @@ -14,8 +14,8 @@ edr_napi_core = { path = "../edr_napi_core" } edr_provider = { path = "../edr_provider" } edr_rpc_eth = { path = "../edr_rpc_eth" } log = { version = "0.4.17", default-features = false } -revm = { git = "https://github.com/Wodann/revm", rev = "f57e3e6", version = "14.0", default-features = false, features = ["c-kzg", "dev", "serde", "std"] } -revm-optimism = { git = "https://github.com/Wodann/revm", rev = "f57e3e6", version = "1.0", default-features = false, features = ["c-kzg", "dev", "serde", "std"] } +revm = { git = "https://github.com/Wodann/revm", rev = "dfc2f28f", version = "14.0", default-features = false, features = ["c-kzg", "dev", "serde", "std"] } +revm-optimism = { git = "https://github.com/Wodann/revm", rev = "dfc2f28f", version = "1.0", default-features = false, features = ["c-kzg", "dev", "serde", "std"] } serde = { version = "1.0.209", default-features = false, features = ["derive", "std"] } thiserror = { version = "1.0.37", default-features = false } tokio = { version = "1.21.2", default-features = false, features = ["macros", "rt-multi-thread", "sync"] } diff --git a/crates/edr_optimism/src/spec.rs b/crates/edr_optimism/src/spec.rs index 6c36283ad5..e1c0afe9d2 100644 --- a/crates/edr_optimism/src/spec.rs +++ b/crates/edr_optimism/src/spec.rs @@ -41,7 +41,8 @@ impl RpcSpec for OptimismChainSpec { type RpcTransactionRequest = edr_rpc_eth::TransactionRequest; } -impl revm::primitives::EvmWiring for OptimismChainSpec { +impl revm::primitives::ChainSpec for OptimismChainSpec { + type ChainContext = revm::optimism::Context; type Block = edr_eth::env::BlockEnv; type Transaction = transaction::Signed; type Hardfork = OptimismSpecId; @@ -49,8 +50,6 @@ impl revm::primitives::EvmWiring for OptimismChainSpec { } impl revm::EvmWiring for OptimismChainSpec { - type Context = revm::optimism::Context; - fn handler<'evm, EXT, DB>(hardfork: Self::Hardfork) -> EvmHandler<'evm, Self, EXT, DB> where DB: revm::Database, diff --git a/crates/edr_provider/Cargo.toml b/crates/edr_provider/Cargo.toml index 0efec1820f..59ba0fccc1 100644 --- a/crates/edr_provider/Cargo.toml +++ b/crates/edr_provider/Cargo.toml @@ -11,7 +11,7 @@ auto_impl = { version = "1.2", default-features = false } derive-where = { version = "1.2.7", default-features = false } dyn-clone = { version = "1.0.13", default-features = false } edr_defaults = { version = "0.3.5", path = "../edr_defaults" } -edr_eth = { version = "0.3.5", path = "../edr_eth", features = ["rand"] } +edr_eth = { version = "0.3.5", path = "../edr_eth" } edr_evm = { version = "0.3.5", path = "../edr_evm", features = ["tracing"] } edr_rpc_eth = { version = "0.3.5", path = "../edr_rpc_eth" } indexmap = { version = "2.0.0", default-features = false, features = ["std"] } @@ -21,7 +21,7 @@ lazy_static = { version = "1.4.0", default-features = false } log = { version = "0.4.20", default-features = false } parking_lot = { version = "0.12.1", default-features = false } rand = { version = "0.8.5", default-features = false } -revm-precompile = { git = "https://github.com/Wodann/revm", rev = "f57e3e6", version = "11.0", default-features = false, features = ["c-kzg", "secp256r1", "std"] } +revm-precompile = { git = "https://github.com/Wodann/revm", rev = "dfc2f28f", version = "11.0", default-features = false, features = ["c-kzg", "secp256r1", "std"] } rpds = { version = "1.1.0", default-features = false, features = ["std"] } serde = { version = "1.0.209", default-features = false, features = ["derive"] } serde_json = { version = "1.0.127" } diff --git a/crates/edr_provider/src/data/call.rs b/crates/edr_provider/src/data/call.rs index fbf8b14741..9819c68b3d 100644 --- a/crates/edr_provider/src/data/call.rs +++ b/crates/edr_provider/src/data/call.rs @@ -2,6 +2,7 @@ use core::fmt::Debug; use edr_eth::{ block::Header, + env::CfgEnv, result::{ExecutionResult, InvalidTransaction}, transaction::TransactionValidation, Address, HashMap, Precompile, U256, @@ -9,7 +10,6 @@ use edr_eth::{ use edr_evm::{ blockchain::{BlockchainError, SyncBlockchain}, chain_spec::{BlockEnvConstructor as _, ChainSpec, SyncChainSpec}, - evm::handler::CfgEnvWithEvmWiring, guaranteed_dry_run, state::{StateError, StateOverrides, StateRefOverrider, SyncState}, DebugContext, @@ -17,15 +17,20 @@ use edr_evm::{ use crate::ProviderError; -pub(super) struct RunCallArgs<'a, 'evm, ChainSpecT: ChainSpec, DebugDataT> -where +pub(super) struct RunCallArgs< + 'a, + 'evm, + ChainSpecT: ChainSpec>>, + DebugDataT, +> where 'a: 'evm, { pub blockchain: &'a dyn SyncBlockchain, StateError>, pub header: &'a Header, pub state: &'a dyn SyncState, pub state_overrides: &'a StateOverrides, - pub cfg_env: CfgEnvWithEvmWiring, + pub cfg_env: CfgEnv, + pub hardfork: ChainSpecT::Hardfork, pub transaction: ChainSpecT::Transaction, pub precompiles: &'a HashMap, // `DebugContext` cannot be simplified further @@ -44,7 +49,7 @@ where /// Execute a transaction as a call. Returns the gas used and the output. pub(super) fn run_call<'a, 'evm, ChainSpecT, DebugDataT>( args: RunCallArgs<'a, 'evm, ChainSpecT, DebugDataT>, -) -> Result, ProviderError> +) -> Result, ProviderError> where 'a: 'evm, ChainSpecT: SyncChainSpec< @@ -59,6 +64,7 @@ where state, state_overrides, cfg_env, + hardfork, transaction, precompiles, debug_context, @@ -68,13 +74,15 @@ where let mut header = header.clone(); header.base_fee_per_gas = header.base_fee_per_gas.map(|_| U256::ZERO); - let block = ChainSpecT::Block::new_block_env(&header, cfg_env.spec_id); + let block = ChainSpecT::Block::new_block_env(&header, hardfork); + + let state_overrider = StateRefOverrider::new(state_overrides, state); guaranteed_dry_run( blockchain, - state, - state_overrides, + state_overrider, cfg_env, + hardfork, transaction, block, precompiles, diff --git a/crates/edr_rpc_eth/src/client.rs b/crates/edr_rpc_eth/src/client.rs index aa354cf255..c697de18f2 100644 --- a/crates/edr_rpc_eth/src/client.rs +++ b/crates/edr_rpc_eth/src/client.rs @@ -329,7 +329,7 @@ mod tests { use super::*; struct TestRpcClient { - client: EthRpcClient>, + client: EthRpcClient, // Need to keep the tempdir around to prevent it from being deleted // Only accessed when feature = "test-remote", hence the allow. @@ -348,7 +348,7 @@ mod tests { } impl Deref for TestRpcClient { - type Target = EthRpcClient>; + type Target = EthRpcClient; fn deref(&self) -> &Self::Target { &self.client diff --git a/crates/edr_rpc_eth/src/receipt.rs b/crates/edr_rpc_eth/src/receipt.rs index b2f8e73416..347b811fc3 100644 --- a/crates/edr_rpc_eth/src/receipt.rs +++ b/crates/edr_rpc_eth/src/receipt.rs @@ -242,7 +242,7 @@ mod test { } impl_execution_receipt_tests! { - L1ChainSpec => { + L1ChainSpec => { legacy => TypedEnvelope::Legacy(edr_eth::receipt::Execution::Legacy(edr_eth::receipt::execution::Legacy { root: B256::random(), cumulative_gas_used: 0xffff, diff --git a/crates/edr_rpc_eth/src/spec.rs b/crates/edr_rpc_eth/src/spec.rs index db57a608fb..6ae63529af 100644 --- a/crates/edr_rpc_eth/src/spec.rs +++ b/crates/edr_rpc_eth/src/spec.rs @@ -1,6 +1,4 @@ -use edr_eth::{ - chain_spec::L1ChainSpec, db::Database, eips::eip2718::TypedEnvelope, receipt::Receipt, -}; +use edr_eth::{chain_spec::L1ChainSpec, eips::eip2718::TypedEnvelope, receipt::Receipt}; use serde::{de::DeserializeOwned, Serialize}; use crate::{receipt::Block, CallRequest}; @@ -32,7 +30,7 @@ pub trait GetBlockNumber { fn number(&self) -> Option; } -impl RpcSpec for L1ChainSpec { +impl RpcSpec for L1ChainSpec { type ExecutionReceipt = TypedEnvelope>; type RpcBlock = crate::block::Block where Data: Default + DeserializeOwned + Serialize; type RpcCallRequest = CallRequest;