From e650c9e8fba905bfc9f8b1ebaf6a5d98f8bf45d7 Mon Sep 17 00:00:00 2001 From: Franco Victorio Date: Tue, 9 Jul 2024 17:57:40 +0200 Subject: [PATCH] feat: upgrade revm dependencies (#546) * feat: upgrade revm dependencies * Create wild-phones-drum.md --- .changeset/wild-phones-drum.md | 5 ++ Cargo.lock | 87 ++++++++++--------- crates/edr_eth/Cargo.toml | 4 +- .../edr_eth/src/transaction/signed/eip155.rs | 3 - .../edr_eth/src/transaction/signed/eip1559.rs | 3 - .../edr_eth/src/transaction/signed/eip2930.rs | 3 - .../edr_eth/src/transaction/signed/eip4844.rs | 3 - .../edr_eth/src/transaction/signed/legacy.rs | 3 - crates/edr_evm/Cargo.toml | 2 +- crates/edr_evm/src/block/builder.rs | 4 + crates/edr_evm/src/debug_trace.rs | 78 +++++++---------- crates/edr_evm/src/state/diff.rs | 4 +- crates/edr_evm/src/state/trie/storage_trie.rs | 2 +- crates/edr_evm/src/trace.rs | 77 ++++++---------- crates/edr_evm/src/transaction.rs | 6 +- crates/edr_napi/src/result.rs | 23 ++++- crates/edr_provider/Cargo.toml | 2 +- crates/edr_provider/src/data.rs | 6 +- crates/edr_provider/src/error.rs | 2 +- 19 files changed, 146 insertions(+), 171 deletions(-) create mode 100644 .changeset/wild-phones-drum.md diff --git a/.changeset/wild-phones-drum.md b/.changeset/wild-phones-drum.md new file mode 100644 index 000000000..9adee4f3e --- /dev/null +++ b/.changeset/wild-phones-drum.md @@ -0,0 +1,5 @@ +--- +"@nomicfoundation/edr": patch +--- + +Upgraded revm to v37 diff --git a/Cargo.lock b/Cargo.lock index 6a8093aea..76fc909ef 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.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8425a283510106b1a6ad25dd4bb648ecde7da3fd2baeb9400a85ad62f51ec90b" +checksum = "413902aa18a97569e60f679c23f46a18db1656d87ab4d4e49d0e1e52042f66df" dependencies = [ "alloy-json-abi", - "alloy-primitives 0.7.4", + "alloy-primitives 0.7.7", "alloy-sol-type-parser", - "alloy-sol-types 0.7.4", + "alloy-sol-types 0.7.7", "const-hex", "derive_more", "itoa", @@ -64,11 +64,11 @@ dependencies = [ [[package]] name = "alloy-json-abi" -version = "0.7.4" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e30946aa6173020259055a44971f5cf40a7d76c931d209caeb51b333263df4f" +checksum = "bc05b04ac331a9f07e3a4036ef7926e49a8bf84a99a1ccfc7e2ab55a5fcbb372" dependencies = [ - "alloy-primitives 0.7.4", + "alloy-primitives 0.7.7", "alloy-sol-type-parser", "serde", "serde_json", @@ -97,9 +97,9 @@ dependencies = [ [[package]] name = "alloy-primitives" -version = "0.7.4" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db8aa973e647ec336810a9356af8aea787249c9d00b1525359f3db29a68d231b" +checksum = "ccb3ead547f4532bc8af961649942f0b9c16ee9226e26caa3f38420651cc0bf4" dependencies = [ "alloy-rlp", "bytes", @@ -160,9 +160,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro" -version = "0.7.4" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dbd17d67f3e89478c8a634416358e539e577899666c927bc3d2b1328ee9b6ca" +checksum = "2b40397ddcdcc266f59f959770f601ce1280e699a91fc1862f29cef91707cd09" dependencies = [ "alloy-sol-macro-expander", "alloy-sol-macro-input", @@ -174,27 +174,27 @@ dependencies = [ [[package]] name = "alloy-sol-macro-expander" -version = "0.7.4" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6da95adcf4760bb4b108fefa51d50096c5e5fdd29ee72fed3e86ee414f2e34" +checksum = "867a5469d61480fea08c7333ffeca52d5b621f5ca2e44f271b117ec1fc9a0525" 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.7", "tiny-keccak", ] [[package]] name = "alloy-sol-macro-input" -version = "0.7.4" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32c8da04c1343871fb6ce5a489218f9c85323c8340a36e9106b5fc98d4dd59d5" +checksum = "2e482dc33a32b6fadbc0f599adea520bd3aaa585c141a80b404d0a3e3fa72528" dependencies = [ "const-hex", "dunce", @@ -202,15 +202,16 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.58", - "syn-solidity 0.7.4", + "syn-solidity 0.7.7", ] [[package]] name = "alloy-sol-type-parser" -version = "0.7.4" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368cae4dc052cad1d8f72eb2ae0c38027116933eeb49213c200a9e9875f208d7" +checksum = "cbcba3ca07cf7975f15d871b721fb18031eec8bce51103907f6dcce00b255d98" dependencies = [ + "serde", "winnow 0.6.8", ] @@ -228,12 +229,12 @@ dependencies = [ [[package]] name = "alloy-sol-types" -version = "0.7.4" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40a64d2d2395c1ac636b62419a7b17ec39031d6b2367e66e9acbf566e6055e9c" +checksum = "a91ca40fa20793ae9c3841b83e74569d1cc9af29a2f5237314fd3452d51e38c7" dependencies = [ - "alloy-primitives 0.7.4", - "alloy-sol-macro 0.7.4", + "alloy-primitives 0.7.7", + "alloy-sol-macro 0.7.7", "const-hex", "serde", ] @@ -618,9 +619,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 +2830,9 @@ dependencies = [ [[package]] name = "revm" -version = "8.0.0" -source = "git+https://github.com/NomicFoundation/revm?rev=aceb093#aceb0939b1712faa0e8f45c1f5621c11b81df94e" +version = "10.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "355bde4e21578c241f9379fbb344a73d254969b5007239115e094dda1511cd34" dependencies = [ "auto_impl", "cfg-if", @@ -2842,8 +2844,9 @@ dependencies = [ [[package]] name = "revm-interpreter" -version = "4.0.0" -source = "git+https://github.com/NomicFoundation/revm?rev=aceb093#aceb0939b1712faa0e8f45c1f5621c11b81df94e" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23dfd24faa3cbbd96e0976103d1e174d6559b8036730f70415488ee21870d578" dependencies = [ "revm-primitives", "serde", @@ -2851,8 +2854,9 @@ dependencies = [ [[package]] name = "revm-precompile" -version = "6.0.0" -source = "git+https://github.com/NomicFoundation/revm?rev=aceb093#aceb0939b1712faa0e8f45c1f5621c11b81df94e" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c669c9b105dbb41133c17bf7f34d29368e358a7fee8fcc289e90dbfb024dfc4" dependencies = [ "aurora-engine-modexp", "c-kzg", @@ -2866,10 +2870,11 @@ dependencies = [ [[package]] name = "revm-primitives" -version = "3.1.1" -source = "git+https://github.com/NomicFoundation/revm?rev=aceb093#aceb0939b1712faa0e8f45c1f5621c11b81df94e" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "902184a7a781550858d4b96707098da357429f1e4545806fd5b589f455555cf2" dependencies = [ - "alloy-primitives 0.7.4", + "alloy-primitives 0.7.7", "auto_impl", "bitflags 2.5.0", "bitvec", @@ -2924,9 +2929,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", @@ -2948,9 +2953,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" @@ -3348,9 +3353,9 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "0.7.4" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8db114c44cf843a8bacd37a146e37987a0b823a0e8bc4fdc610c9c72ab397a5" +checksum = "c837dc8852cb7074e46b444afb81783140dab12c58867b49fb3898fbafedf7ea" dependencies = [ "paste", "proc-macro2", diff --git a/crates/edr_eth/Cargo.toml b/crates/edr_eth/Cargo.toml index 51be60cea..eb66abb38 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 = "aceb093", version = "3.1", default-features = false, features = ["c-kzg", "hashbrown"] } +revm-primitives = { 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_eth/src/transaction/signed/eip155.rs b/crates/edr_eth/src/transaction/signed/eip155.rs index 6f6c50f9d..16f06b126 100644 --- a/crates/edr_eth/src/transaction/signed/eip155.rs +++ b/crates/edr_eth/src/transaction/signed/eip155.rs @@ -1,7 +1,6 @@ use std::sync::OnceLock; use alloy_rlp::RlpEncodable; -use hashbrown::HashMap; use revm_primitives::{keccak256, TxEnv}; use super::kind_to_transact_to; @@ -79,8 +78,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..e2a67d5dd 100644 --- a/crates/edr_eth/src/transaction/signed/eip1559.rs +++ b/crates/edr_eth/src/transaction/signed/eip1559.rs @@ -1,7 +1,6 @@ use std::sync::OnceLock; use alloy_rlp::{RlpDecodable, RlpEncodable}; -use hashbrown::HashMap; use revm_primitives::{keccak256, TxEnv}; use super::kind_to_transact_to; @@ -69,8 +68,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(), } } } diff --git a/crates/edr_eth/src/transaction/signed/eip2930.rs b/crates/edr_eth/src/transaction/signed/eip2930.rs index d90ad7be3..84d0a1af8 100644 --- a/crates/edr_eth/src/transaction/signed/eip2930.rs +++ b/crates/edr_eth/src/transaction/signed/eip2930.rs @@ -1,7 +1,6 @@ use std::sync::OnceLock; use alloy_rlp::{RlpDecodable, RlpEncodable}; -use hashbrown::HashMap; use revm_primitives::{keccak256, TxEnv}; use super::kind_to_transact_to; @@ -68,8 +67,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/eip4844.rs b/crates/edr_eth/src/transaction/signed/eip4844.rs index dd74df5d9..c0aaf48ae 100644 --- a/crates/edr_eth/src/transaction/signed/eip4844.rs +++ b/crates/edr_eth/src/transaction/signed/eip4844.rs @@ -1,7 +1,6 @@ use std::sync::OnceLock; use alloy_rlp::{RlpDecodable, RlpEncodable}; -use hashbrown::HashMap; use revm_primitives::{keccak256, TransactTo, TxEnv, GAS_PER_BLOB}; use crate::{ @@ -79,8 +78,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..7d61460a6 100644 --- a/crates/edr_eth/src/transaction/signed/legacy.rs +++ b/crates/edr_eth/src/transaction/signed/legacy.rs @@ -1,7 +1,6 @@ use std::sync::OnceLock; use alloy_rlp::{RlpDecodable, RlpEncodable}; -use hashbrown::HashMap; use revm_primitives::{keccak256, TxEnv}; use super::kind_to_transact_to; @@ -58,8 +57,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 1e8251083..095eba061 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 = { 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/block/builder.rs b/crates/edr_evm/src/block/builder.rs index 8f87207ad..4e03d7a6d 100644 --- a/crates/edr_evm/src/block/builder.rs +++ b/crates/edr_evm/src/block/builder.rs @@ -70,6 +70,9 @@ pub enum BlockTransactionError { /// Corrupt transaction data #[error("Invalid transaction: {0:?}")] InvalidTransaction(InvalidTransaction), + /// Precompile errors + #[error("{0}")] + Precompile(String), /// State errors #[error(transparent)] State(SE), @@ -99,6 +102,7 @@ where error @ (InvalidHeader::ExcessBlobGasNotSet | InvalidHeader::PrevrandaoNotSet), ) => Self::Custom(error.to_string()), EVMError::Custom(error) => Self::Custom(error), + EVMError::Precompile(error) => Self::Precompile(error), } } } diff --git a/crates/edr_evm/src/debug_trace.rs b/crates/edr_evm/src/debug_trace.rs index e4f8c968f..4f97680e4 100644 --- a/crates/edr_evm/src/debug_trace.rs +++ b/crates/edr_evm/src/debug_trace.rs @@ -9,14 +9,14 @@ use revm::{ db::DatabaseComponents, handler::register::EvmHandler, interpreter::{ - opcode::{self, BoxedInstruction, InstructionTables, OpCode}, - InstructionResult, Interpreter, InterpreterResult, + opcode::{self, DynInstruction, OpCode}, + Interpreter, InterpreterResult, }, primitives::{ hex, Address, BlockEnv, Bytes, CfgEnvWithHandlerCfg, ExecutionResult, ResultAndState, SpecId, U256, }, - Database, Evm, EvmContext, JournalEntry, + Context, Database, Evm, EvmContext, JournalEntry, }; use crate::{ @@ -278,26 +278,10 @@ pub fn register_eip_3155_tracer_handles< ) { // 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::>(), - }; + 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(); @@ -319,37 +303,29 @@ pub fn register_eip_3155_tracer_handles< } /// 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 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); - 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, &mut host.evm); } /// An EIP-3155 compatible EVM tracer. @@ -437,7 +413,11 @@ impl TracerEip3155 { .journal .last() .and_then(|v| v.last()); - if let Some(JournalEntry::StorageChange { 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)); 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 189b6827b..cdd90d67c 100644 --- a/crates/edr_evm/src/state/trie/storage_trie.rs +++ b/crates/edr_evm/src/state/trie/storage_trie.rs @@ -76,7 +76,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 ae0db95aa..946ef9d3b 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, + Context, Database, EvmContext, FrameOrResult, FrameResult, }; use crate::debug::GetContextData; @@ -23,28 +23,10 @@ pub fn register_trace_collector_handles< ) 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::>(), - }; - - // 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. @@ -128,32 +110,27 @@ pub fn register_trace_collector_handles< } /// 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 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 @@ -415,7 +392,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"), @@ -482,7 +459,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_evm/src/transaction.rs b/crates/edr_evm/src/transaction.rs index 99d1c796a..0e1f8fe83 100644 --- a/crates/edr_evm/src/transaction.rs +++ b/crates/edr_evm/src/transaction.rs @@ -34,6 +34,9 @@ pub enum TransactionError { /// config is on a post-merge hardfork. #[error("Post-merge transaction is missing prevrandao")] MissingPrevrandao, + /// Precompile errors + #[error("{0}")] + Precompile(String), /// State errors #[error(transparent)] State(SE), @@ -53,6 +56,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), } } } @@ -107,8 +111,6 @@ pub fn initial_cost(transaction: &impl Transaction, spec_id: SpecId) -> u64 { access_list .as_ref() .map_or(&[], |access_list| access_list.as_slice()), - // TODO: https://github.com/NomicFoundation/edr/issues/427 - &[], ) } diff --git a/crates/edr_napi/src/result.rs b/crates/edr_napi/src/result.rs index 5fb11ef6f..6891e15dc 100644 --- a/crates/edr_napi/src/result.rs +++ b/crates/edr_napi/src/result.rs @@ -16,6 +16,7 @@ pub enum SuccessReason { Return, /// The opcode `SELFDESTRUCT` was called SelfDestruct, + EofReturnContract, } impl From for SuccessReason { @@ -24,6 +25,7 @@ impl From for SuccessReason { edr_evm::SuccessReason::Stop => Self::Stop, edr_evm::SuccessReason::Return => Self::Return, edr_evm::SuccessReason::SelfDestruct => Self::SelfDestruct, + edr_evm::SuccessReason::EofReturnContract => Self::EofReturnContract, } } } @@ -34,6 +36,7 @@ impl From for edr_evm::SuccessReason { SuccessReason::Stop => Self::Stop, SuccessReason::Return => Self::Return, SuccessReason::SelfDestruct => Self::SelfDestruct, + SuccessReason::EofReturnContract => Self::EofReturnContract, } } } @@ -82,7 +85,7 @@ pub struct RevertResult { pub enum ExceptionalHalt { OutOfGas, OpcodeNotFound, - InvalidFEOpcode, + InvalidEFOpcode, InvalidJump, NotActivated, StackUnderflow, @@ -97,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 { @@ -104,7 +113,7 @@ impl From for ExceptionalHalt { match halt { edr_evm::HaltReason::OutOfGas(..) => ExceptionalHalt::OutOfGas, edr_evm::HaltReason::OpcodeNotFound => ExceptionalHalt::OpcodeNotFound, - edr_evm::HaltReason::InvalidFEOpcode => ExceptionalHalt::InvalidFEOpcode, + edr_evm::HaltReason::InvalidEFOpcode => ExceptionalHalt::InvalidEFOpcode, edr_evm::HaltReason::InvalidJump => ExceptionalHalt::InvalidJump, edr_evm::HaltReason::NotActivated => ExceptionalHalt::NotActivated, edr_evm::HaltReason::StackUnderflow => ExceptionalHalt::StackUnderflow, @@ -122,6 +131,11 @@ impl From for ExceptionalHalt { edr_evm::HaltReason::CreateInitCodeSizeLimit => { ExceptionalHalt::CreateInitCodeSizeLimit } + edr_evm::HaltReason::EofAuxDataOverflow => ExceptionalHalt::EofAuxDataOverflow, + edr_evm::HaltReason::EofAuxDataTooSmall => ExceptionalHalt::EofAuxDataTooSmall, + edr_evm::HaltReason::EOFFunctionStackOverflow => { + ExceptionalHalt::EOFFunctionStackOverflow + } edr_evm::HaltReason::OverflowPayment | edr_evm::HaltReason::StateChangeDuringStaticCall | edr_evm::HaltReason::CallNotAllowedInsideStatic @@ -138,7 +152,7 @@ impl From for edr_evm::HaltReason { match value { ExceptionalHalt::OutOfGas => Self::OutOfGas(edr_evm::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, @@ -150,6 +164,9 @@ impl From for edr_evm::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/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_provider/src/data.rs b/crates/edr_provider/src/data.rs index 861145018..93f884e02 100644 --- a/crates/edr_provider/src/data.rs +++ b/crates/edr_provider/src/data.rs @@ -44,8 +44,8 @@ use edr_evm::{ transaction::{self, SignedTransaction as _}, Account, AccountInfo, BlobExcessGasAndPrice, Block as _, BlockAndTotalDifficulty, BlockEnv, Bytecode, CfgEnv, CfgEnvWithHandlerCfg, DebugContext, DebugTraceConfig, - DebugTraceResultWithTraces, Eip3155AndRawTracers, ExecutionResult, HashMap, HashSet, MemPool, - MineBlockResultAndState, OrderedTransaction, RandomHashGenerator, StorageSlot, SyncBlock, + DebugTraceResultWithTraces, Eip3155AndRawTracers, EvmStorageSlot, ExecutionResult, HashMap, + HashSet, MemPool, MineBlockResultAndState, OrderedTransaction, RandomHashGenerator, SyncBlock, TxEnv, KECCAK_EMPTY, }; use edr_rpc_eth::{ @@ -1756,7 +1756,7 @@ impl ProviderData, solidity_trace: Trace) -> Self { let reason = match halt { - HaltReason::OpcodeNotFound | HaltReason::InvalidFEOpcode => { + HaltReason::OpcodeNotFound | HaltReason::InvalidEFOpcode => { TransactionFailureReason::OpcodeNotFound } HaltReason::OutOfGas(error) => TransactionFailureReason::OutOfGas(error),