From d423e3740f2062474f545e1905058d01afb4bcae Mon Sep 17 00:00:00 2001 From: rakita Date: Tue, 23 Dec 2025 17:25:12 +0100 Subject: [PATCH] feat: stagging revm v34.0.0 --- Cargo.lock | 64 ++++----- Cargo.toml | 72 ++++++++-- .../engine/invalid-block-hooks/src/witness.rs | 2 + crates/engine/tree/benches/channel_perf.rs | 2 + crates/engine/tree/benches/state_root_task.rs | 3 + crates/engine/tree/src/tree/metrics.rs | 2 + .../tree/src/tree/payload_processor/mod.rs | 6 +- .../src/tree/payload_processor/multiproof.rs | 58 +++++--- crates/ethereum/evm/src/lib.rs | 9 +- crates/ethereum/evm/tests/execute.rs | 3 + crates/ethereum/payload/src/lib.rs | 24 ++-- crates/evm/evm/src/execute.rs | 19 ++- crates/evm/evm/src/lib.rs | 2 +- .../execution-types/src/execution_outcome.rs | 24 +++- crates/optimism/evm/src/lib.rs | 10 +- crates/optimism/node/tests/it/builder.rs | 6 +- crates/optimism/payload/src/builder.rs | 26 ++-- crates/primitives-traits/src/account.rs | 20 +-- crates/rpc/rpc-eth-api/src/helpers/call.rs | 20 +-- .../rpc/rpc-eth-api/src/helpers/estimate.rs | 26 ++-- crates/rpc/rpc-eth-api/src/helpers/trace.rs | 11 +- crates/rpc/rpc-eth-types/src/error/api.rs | 15 +- crates/rpc/rpc-eth-types/src/error/mod.rs | 133 ++++++++++-------- crates/stateless/src/witness_db.rs | 1 + crates/storage/errors/Cargo.toml | 1 + crates/storage/errors/src/provider.rs | 12 +- crates/trie/common/src/hashed_state.rs | 15 +- 27 files changed, 369 insertions(+), 217 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d6e7a6b94c..71faa4d388 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -259,6 +259,17 @@ dependencies = [ "serde", ] +[[package]] +name = "alloy-eip7928" +version = "0.2.0" +source = "git+https://github.com/alloy-rs/eips.git?rev=734beaf#734beafea409bdd87b3a4e33ac72ac68654bb8dd" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "borsh", + "serde", +] + [[package]] name = "alloy-eips" version = "1.1.3" @@ -288,8 +299,7 @@ dependencies = [ [[package]] name = "alloy-evm" version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ccc4c702c840148af1ce784cc5c6ed9274a020ef32417c5b1dbeab8c317673" +source = "git+https://github.com/alloy-rs/evm?rev=9f9fbf3#9f9fbf32f18544b4ad651a31556f7e32e0154416" dependencies = [ "alloy-consensus", "alloy-eips", @@ -405,8 +415,7 @@ dependencies = [ [[package]] name = "alloy-op-evm" version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f640da852f93ddaa3b9a602b7ca41d80e0023f77a67b68aaaf511c32f1fe0ce" +source = "git+https://github.com/alloy-rs/evm?rev=9f9fbf3#9f9fbf32f18544b4ad651a31556f7e32e0154416" dependencies = [ "alloy-consensus", "alloy-eips", @@ -6432,8 +6441,7 @@ dependencies = [ [[package]] name = "op-revm" version = "14.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1475a779c73999fc803778524042319691b31f3d6699d2b560c4ed8be1db802a" +source = "git+https://github.com/bluealloy/revm?rev=473d1ae3#473d1ae3baae76d300733e9ad348ee031d0b1eb5" dependencies = [ "auto_impl", "revm", @@ -8325,7 +8333,7 @@ name = "reth-engine-tree" version = "1.9.3" dependencies = [ "alloy-consensus", - "alloy-eip7928", + "alloy-eip7928 0.1.0", "alloy-eips", "alloy-evm", "alloy-primitives", @@ -10838,6 +10846,7 @@ dependencies = [ "reth-prune-types", "reth-static-file-types", "revm-database-interface", + "revm-state", "thiserror 2.0.17", ] @@ -11186,8 +11195,7 @@ dependencies = [ [[package]] name = "revm" version = "33.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c85ed0028f043f87b3c88d4a4cb6f0a76440085523b6a8afe5ff003cf418054" +source = "git+https://github.com/bluealloy/revm?rev=473d1ae3#473d1ae3baae76d300733e9ad348ee031d0b1eb5" dependencies = [ "revm-bytecode", "revm-context", @@ -11205,8 +11213,7 @@ dependencies = [ [[package]] name = "revm-bytecode" version = "7.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2c6b5e6e8dd1e28a4a60e5f46615d4ef0809111c9e63208e55b5c7058200fb0" +source = "git+https://github.com/bluealloy/revm?rev=473d1ae3#473d1ae3baae76d300733e9ad348ee031d0b1eb5" dependencies = [ "bitvec", "phf", @@ -11217,8 +11224,7 @@ dependencies = [ [[package]] name = "revm-context" version = "12.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f038f0c9c723393ac897a5df9140b21cfa98f5753a2cb7d0f28fa430c4118abf" +source = "git+https://github.com/bluealloy/revm?rev=473d1ae3#473d1ae3baae76d300733e9ad348ee031d0b1eb5" dependencies = [ "bitvec", "cfg-if", @@ -11234,8 +11240,7 @@ dependencies = [ [[package]] name = "revm-context-interface" version = "13.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "431c9a14e4ef1be41ae503708fd02d974f80ef1f2b6b23b5e402e8d854d1b225" +source = "git+https://github.com/bluealloy/revm?rev=473d1ae3#473d1ae3baae76d300733e9ad348ee031d0b1eb5" dependencies = [ "alloy-eip2930", "alloy-eip7702", @@ -11250,8 +11255,7 @@ dependencies = [ [[package]] name = "revm-database" version = "9.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "980d8d6bba78c5dd35b83abbb6585b0b902eb25ea4448ed7bfba6283b0337191" +source = "git+https://github.com/bluealloy/revm?rev=473d1ae3#473d1ae3baae76d300733e9ad348ee031d0b1eb5" dependencies = [ "alloy-eips", "revm-bytecode", @@ -11264,21 +11268,20 @@ dependencies = [ [[package]] name = "revm-database-interface" version = "8.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cce03e3780287b07abe58faf4a7f5d8be7e81321f93ccf3343c8f7755602bae" +source = "git+https://github.com/bluealloy/revm?rev=473d1ae3#473d1ae3baae76d300733e9ad348ee031d0b1eb5" dependencies = [ "auto_impl", "either", "revm-primitives", "revm-state", "serde", + "thiserror 2.0.17", ] [[package]] name = "revm-handler" version = "14.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d44f8f6dbeec3fecf9fe55f78ef0a758bdd92ea46cd4f1ca6e2a946b32c367f3" +source = "git+https://github.com/bluealloy/revm?rev=473d1ae3#473d1ae3baae76d300733e9ad348ee031d0b1eb5" dependencies = [ "auto_impl", "derive-where", @@ -11296,8 +11299,7 @@ dependencies = [ [[package]] name = "revm-inspector" version = "14.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5617e49216ce1ca6c8826bcead0386bc84f49359ef67cde6d189961735659f93" +source = "git+https://github.com/bluealloy/revm?rev=473d1ae3#473d1ae3baae76d300733e9ad348ee031d0b1eb5" dependencies = [ "auto_impl", "either", @@ -11314,8 +11316,7 @@ dependencies = [ [[package]] name = "revm-inspectors" version = "0.33.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01def7351cd9af844150b8e88980bcd11304f33ce23c3d7c25f2a8dab87c1345" +source = "git+https://github.com/paradigmxyz/revm-inspectors?rev=b126b72#b126b722b0034d11f7ab86addd013e05243d180d" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", @@ -11334,8 +11335,7 @@ dependencies = [ [[package]] name = "revm-interpreter" version = "31.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26ec36405f7477b9dccdc6caa3be19adf5662a7a0dffa6270cdb13a090c077e5" +source = "git+https://github.com/bluealloy/revm?rev=473d1ae3#473d1ae3baae76d300733e9ad348ee031d0b1eb5" dependencies = [ "revm-bytecode", "revm-context-interface", @@ -11347,8 +11347,7 @@ dependencies = [ [[package]] name = "revm-precompile" version = "31.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a62958af953cc4043e93b5be9b8497df84cc3bd612b865c49a7a7dfa26a84e2" +source = "git+https://github.com/bluealloy/revm?rev=473d1ae3#473d1ae3baae76d300733e9ad348ee031d0b1eb5" dependencies = [ "ark-bls12-381", "ark-bn254", @@ -11372,8 +11371,7 @@ dependencies = [ [[package]] name = "revm-primitives" version = "21.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29e161db429d465c09ba9cbff0df49e31049fe6b549e28eb0b7bd642fcbd4412" +source = "git+https://github.com/bluealloy/revm?rev=473d1ae3#473d1ae3baae76d300733e9ad348ee031d0b1eb5" dependencies = [ "alloy-primitives", "num_enum", @@ -11384,9 +11382,9 @@ dependencies = [ [[package]] name = "revm-state" version = "8.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d8be953b7e374dbdea0773cf360debed8df394ea8d82a8b240a6b5da37592fc" +source = "git+https://github.com/bluealloy/revm?rev=473d1ae3#473d1ae3baae76d300733e9ad348ee031d0b1eb5" dependencies = [ + "alloy-eip7928 0.2.0", "bitflags 2.10.0", "revm-bytecode", "revm-primitives", diff --git a/Cargo.toml b/Cargo.toml index f3c4e2e204..9dddf981f8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -489,8 +489,12 @@ alloy-dyn-abi = "1.4.1" alloy-eip2124 = { version = "0.2.0", default-features = false } alloy-eip7928 = { version = "0.1.0" } alloy-evm = { version = "0.25.1", default-features = false } -alloy-primitives = { version = "1.5.0", default-features = false, features = ["map-foldhash"] } -alloy-rlp = { version = "0.3.10", default-features = false, features = ["core-net"] } +alloy-primitives = { version = "1.5.0", default-features = false, features = [ + "map-foldhash", +] } +alloy-rlp = { version = "0.3.10", default-features = false, features = [ + "core-net", +] } alloy-sol-macro = "1.5.0" alloy-sol-types = { version = "1.5.0", default-features = false } alloy-trie = { version = "0.9.1", default-features = false } @@ -504,10 +508,15 @@ alloy-genesis = { version = "1.1.3", default-features = false } alloy-json-rpc = { version = "1.1.3", default-features = false } alloy-network = { version = "1.1.3", default-features = false } alloy-network-primitives = { version = "1.1.3", default-features = false } -alloy-provider = { version = "1.1.3", features = ["reqwest", "debug-api"], default-features = false } +alloy-provider = { version = "1.1.3", features = [ + "reqwest", + "debug-api", +], default-features = false } alloy-pubsub = { version = "1.1.3", default-features = false } alloy-rpc-client = { version = "1.1.3", default-features = false } -alloy-rpc-types = { version = "1.1.3", features = ["eth"], default-features = false } +alloy-rpc-types = { version = "1.1.3", features = [ + "eth", +], default-features = false } alloy-rpc-types-admin = { version = "1.1.3", default-features = false } alloy-rpc-types-anvil = { version = "1.1.3", default-features = false } alloy-rpc-types-beacon = { version = "1.1.3", default-features = false } @@ -521,7 +530,9 @@ alloy-serde = { version = "1.1.3", default-features = false } alloy-signer = { version = "1.1.3", default-features = false } alloy-signer-local = { version = "1.1.3", default-features = false } alloy-transport = { version = "1.1.3" } -alloy-transport-http = { version = "1.1.3", features = ["reqwest-rustls-tls"], default-features = false } +alloy-transport-http = { version = "1.1.3", features = [ + "reqwest-rustls-tls", +], default-features = false } alloy-transport-ipc = { version = "1.1.3", default-features = false } alloy-transport-ws = { version = "1.1.3", default-features = false } @@ -540,7 +551,10 @@ either = { version = "1.15.0", default-features = false } arrayvec = { version = "0.7.6", default-features = false } aquamarine = "0.6" auto_impl = "1" -backon = { version = "1.2", default-features = false, features = ["std-blocking-sleep", "tokio-sleep"] } +backon = { version = "1.2", default-features = false, features = [ + "std-blocking-sleep", + "tokio-sleep", +] } bincode = "1.3" bitflags = "2.4" boyer-moore-magiclen = "0.2.16" @@ -561,9 +575,13 @@ itertools = { version = "0.14", default-features = false } linked_hash_set = "0.1" lz4 = "1.28.1" modular-bitfield = "0.11.2" -notify = { version = "8.0.0", default-features = false, features = ["macos_fsevent"] } +notify = { version = "8.0.0", default-features = false, features = [ + "macos_fsevent", +] } nybbles = { version = "0.4.2", default-features = false } -once_cell = { version = "1.19", default-features = false, features = ["critical-section"] } +once_cell = { version = "1.19", default-features = false, features = [ + "critical-section", +] } parking_lot = "0.12" paste = "1.0" rand = "0.9" @@ -646,7 +664,10 @@ proptest-arbitrary-interop = "0.1.0" # crypto enr = { version = "0.13", default-features = false } k256 = { version = "0.13", default-features = false, features = ["ecdsa"] } -secp256k1 = { version = "0.30", default-features = false, features = ["global-context", "recovery"] } +secp256k1 = { version = "0.30", default-features = false, features = [ + "global-context", + "recovery", +] } # rand 8 for secp256k1 rand_08 = { package = "rand", version = "0.8" } @@ -743,7 +764,7 @@ vergen-git2 = "1.0.5" # networking ipnet = "2.11" -# [patch.crates-io] +[patch.crates-io] # alloy-consensus = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" } # alloy-contract = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" } # alloy-eips = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" } @@ -788,3 +809,34 @@ ipnet = "2.11" # alloy-evm = { git = "https://github.com/alloy-rs/evm", rev = "a69f0b45a6b0286e16072cb8399e02ce6ceca353" } # alloy-op-evm = { git = "https://github.com/alloy-rs/evm", rev = "a69f0b45a6b0286e16072cb8399e02ce6ceca353" } + +# alloy-consensus = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" } + +# alloy-hardforks = { git = "https://github.com/Rimeeeeee/hardforks", branch = "amsterdam" } +# alloy-op-hardforks = { git = "https://github.com/Rimeeeeee/hardforks", branch = "amsterdam" } +# op-alloy-consensus = { git = "https://github.com/alloy-rs/op-alloy", rev = "a79d6fc" } +# op-alloy-network = { git = "https://github.com/alloy-rs/op-alloy", rev = "a79d6fc" } +# op-alloy-rpc-types = { git = "https://github.com/alloy-rs/op-alloy", rev = "a79d6fc" } +# op-alloy-rpc-types-engine = { git = "https://github.com/alloy-rs/op-alloy", rev = "a79d6fc" } +# op-alloy-rpc-jsonrpsee = { git = "https://github.com/alloy-rs/op-alloy", rev = "a79d6fc" } +# +# jsonrpsee = { git = "https://github.com/paradigmxyz/jsonrpsee", branch = "matt/make-rpc-service-pub" } +# jsonrpsee-core = { git = "https://github.com/paradigmxyz/jsonrpsee", branch = "matt/make-rpc-service-pub" } +# jsonrpsee-server = { git = "https://github.com/paradigmxyz/jsonrpsee", branch = "matt/make-rpc-service-pub" } +# jsonrpsee-http-client = { git = "https://github.com/paradigmxyz/jsonrpsee", branch = "matt/make-rpc-service-pub" } +# jsonrpsee-types = { git = "https://github.com/paradigmxyz/jsonrpsee", branch = "matt/make-rpc-service-pub" } + +revm-inspectors = { git = "https://github.com/paradigmxyz/revm-inspectors", rev = "b126b72" } + +alloy-evm = { git = "https://github.com/alloy-rs/evm", rev = "9f9fbf3" } +alloy-op-evm = { git = "https://github.com/alloy-rs/evm", rev = "9f9fbf3" } + +# revm +revm = { git = "https://github.com/bluealloy/revm", rev = "473d1ae3" } +revm-bytecode = { git = "https://github.com/bluealloy/revm", rev = "473d1ae3" } +revm-database = { git = "https://github.com/bluealloy/revm", rev = "473d1ae3" } +revm-state = { git = "https://github.com/bluealloy/revm", rev = "473d1ae3" } +revm-primitives = { git = "https://github.com/bluealloy/revm", rev = "473d1ae3" } +revm-interpreter = { git = "https://github.com/bluealloy/revm", rev = "473d1ae3" } +revm-database-interface = { git = "https://github.com/bluealloy/revm", rev = "473d1ae3" } +op-revm = { git = "https://github.com/bluealloy/revm", rev = "473d1ae3" } diff --git a/crates/engine/invalid-block-hooks/src/witness.rs b/crates/engine/invalid-block-hooks/src/witness.rs index d2437eae8f..16a05ad4e3 100644 --- a/crates/engine/invalid-block-hooks/src/witness.rs +++ b/crates/engine/invalid-block-hooks/src/witness.rs @@ -448,12 +448,14 @@ mod tests { nonce: account.nonce, code_hash: account.bytecode_hash.unwrap_or_default(), code: None, + account_id: None, }), original_info: (i == 0).then(|| AccountInfo { balance: account.balance.checked_div(U256::from(2)).unwrap_or(U256::ZERO), nonce: 0, code_hash: account.bytecode_hash.unwrap_or_default(), code: None, + account_id: None, }), storage, status: AccountStatus::default(), diff --git a/crates/engine/tree/benches/channel_perf.rs b/crates/engine/tree/benches/channel_perf.rs index 41dd651c89..1bc5d7ceac 100644 --- a/crates/engine/tree/benches/channel_perf.rs +++ b/crates/engine/tree/benches/channel_perf.rs @@ -26,7 +26,9 @@ fn create_bench_state(num_accounts: usize) -> EvmState { nonce: 10, code_hash: B256::from_slice(&rng.random::<[u8; 32]>()), code: Default::default(), + account_id: None, }, + original_info: Box::new(AccountInfo::default()), storage, status: AccountStatus::empty(), transaction_id: 0, diff --git a/crates/engine/tree/benches/state_root_task.rs b/crates/engine/tree/benches/state_root_task.rs index cfd17a8ecf..a7022e5a4a 100644 --- a/crates/engine/tree/benches/state_root_task.rs +++ b/crates/engine/tree/benches/state_root_task.rs @@ -62,6 +62,7 @@ fn create_bench_state_updates(params: &BenchParams) -> Vec { storage: HashMap::default(), status: AccountStatus::SelfDestructed, transaction_id: 0, + original_info: Box::new(AccountInfo::default()), } } else { RevmAccount { @@ -70,6 +71,7 @@ fn create_bench_state_updates(params: &BenchParams) -> Vec { nonce: rng.random::(), code_hash: KECCAK_EMPTY, code: Some(Default::default()), + account_id: None, }, storage: (0..rng.random_range(0..=params.storage_slots_per_account)) .map(|_| { @@ -84,6 +86,7 @@ fn create_bench_state_updates(params: &BenchParams) -> Vec { }) .collect(), status: AccountStatus::Touched, + original_info: Box::new(AccountInfo::default()), transaction_id: 0, } }; diff --git a/crates/engine/tree/src/tree/metrics.rs b/crates/engine/tree/src/tree/metrics.rs index 8fd08e32a1..5637270afa 100644 --- a/crates/engine/tree/src/tree/metrics.rs +++ b/crates/engine/tree/src/tree/metrics.rs @@ -570,7 +570,9 @@ mod tests { nonce: 10, code_hash: B256::random(), code: Default::default(), + account_id: None, }, + original_info: Box::new(AccountInfo::default()), storage, status: AccountStatus::default(), transaction_id: 0, diff --git a/crates/engine/tree/src/tree/payload_processor/mod.rs b/crates/engine/tree/src/tree/payload_processor/mod.rs index 02ca39f277..1ed9b63215 100644 --- a/crates/engine/tree/src/tree/payload_processor/mod.rs +++ b/crates/engine/tree/src/tree/payload_processor/mod.rs @@ -377,8 +377,8 @@ where let _ = execute_tx.send(tx); next_for_execution += 1; - while let Some(entry) = queue.first_entry() && - *entry.key() == next_for_execution + while let Some(entry) = queue.first_entry() + && *entry.key() == next_for_execution { let _ = execute_tx.send(entry.remove()); next_for_execution += 1; @@ -1024,7 +1024,9 @@ mod tests { nonce: rng.random::(), code_hash: KECCAK_EMPTY, code: Some(Default::default()), + account_id: None, }, + original_info: Box::new(AccountInfo::default()), storage, status: AccountStatus::Touched, transaction_id: 0, diff --git a/crates/engine/tree/src/tree/payload_processor/multiproof.rs b/crates/engine/tree/src/tree/payload_processor/multiproof.rs index 5695787cf1..12ce57693b 100644 --- a/crates/engine/tree/src/tree/payload_processor/multiproof.rs +++ b/crates/engine/tree/src/tree/payload_processor/multiproof.rs @@ -155,7 +155,7 @@ impl ProofSequencer { // return early if we don't have the next expected proof if !self.pending_proofs.contains_key(&self.next_to_deliver) { - return Vec::new() + return Vec::new(); } let mut consecutive_proofs = Vec::with_capacity(self.pending_proofs.len()); @@ -896,8 +896,8 @@ impl MultiProofTask { ctx.accumulated_prefetch_targets.push(targets); // Batch consecutive prefetch messages up to limits. - while accumulated_count < PREFETCH_MAX_BATCH_TARGETS && - ctx.accumulated_prefetch_targets.len() < PREFETCH_MAX_BATCH_MESSAGES + while accumulated_count < PREFETCH_MAX_BATCH_TARGETS + && ctx.accumulated_prefetch_targets.len() < PREFETCH_MAX_BATCH_MESSAGES { match self.rx.try_recv() { Ok(MultiProofMessage::PrefetchProofs(next_targets)) => { @@ -1378,8 +1378,8 @@ fn get_proof_targets( .storage .keys() .filter(|slot| { - !fetched.is_some_and(|f| f.contains(*slot)) || - storage_added_removed_keys.is_some_and(|k| k.is_removed(slot)) + !fetched.is_some_and(|f| f.contains(*slot)) + || storage_added_removed_keys.is_some_and(|k| k.is_removed(slot)) }) .peekable(); @@ -1412,13 +1412,13 @@ fn dispatch_with_chunking( where I: IntoIterator, { - let should_chunk = chunking_len > max_targets_for_chunking || - available_account_workers > 1 || - available_storage_workers > 1; + let should_chunk = chunking_len > max_targets_for_chunking + || available_account_workers > 1 + || available_storage_workers > 1; - if should_chunk && - let Some(chunk_size) = chunk_size && - chunking_len > chunk_size + if should_chunk + && let Some(chunk_size) = chunk_size + && chunking_len > chunk_size { let mut num_chunks = 0usize; for chunk in chunker(items, chunk_size) { @@ -1451,8 +1451,8 @@ fn can_batch_state_update( ( Source::Evm(StateChangeSource::PreBlock(_)), Source::Evm(StateChangeSource::PreBlock(_)), - ) | - ( + ) + | ( Source::Evm(StateChangeSource::PostBlock(_)), Source::Evm(StateChangeSource::PostBlock(_)), ) => batch_update == next_update, @@ -2041,7 +2041,9 @@ mod tests { nonce: 1, code_hash: Default::default(), code: Default::default(), + account_id: None, }, + original_info: Box::new(revm_state::AccountInfo::default()), transaction_id: Default::default(), storage: Default::default(), status: revm_state::AccountStatus::Touched, @@ -2057,7 +2059,9 @@ mod tests { nonce: 2, code_hash: Default::default(), code: Default::default(), + account_id: None, }, + original_info: Box::new(revm_state::AccountInfo::default()), transaction_id: Default::default(), storage: Default::default(), status: revm_state::AccountStatus::Touched, @@ -2117,7 +2121,9 @@ mod tests { nonce: 1, code_hash: Default::default(), code: Default::default(), + account_id: None, }, + original_info: Box::new(revm_state::AccountInfo::default()), transaction_id: Default::default(), storage: Default::default(), status: revm_state::AccountStatus::Touched, @@ -2153,8 +2159,8 @@ mod tests { } match task.rx.try_recv() { Ok(MultiProofMessage::StateUpdate(next_source, next_update)) => { - if let Some((batch_source, batch_update)) = accumulated_updates.first() && - !can_batch_state_update( + if let Some((batch_source, batch_update)) = accumulated_updates.first() + && !can_batch_state_update( *batch_source, batch_update, next_source, @@ -2172,8 +2178,8 @@ mod tests { Some(MultiProofMessage::StateUpdate(next_source, next_update)); break; } - if accumulated_targets + next_estimate > STATE_UPDATE_MAX_BATCH_TARGETS && - !accumulated_updates.is_empty() + if accumulated_targets + next_estimate > STATE_UPDATE_MAX_BATCH_TARGETS + && !accumulated_updates.is_empty() { pending_msg = Some(MultiProofMessage::StateUpdate(next_source, next_update)); @@ -2240,7 +2246,9 @@ mod tests { nonce: 1, code_hash: Default::default(), code: Default::default(), + account_id: None, }, + original_info: Box::new(revm_state::AccountInfo::default()), transaction_id: Default::default(), storage: Default::default(), status: revm_state::AccountStatus::Touched, @@ -2275,8 +2283,8 @@ mod tests { } match task.rx.try_recv() { Ok(MultiProofMessage::StateUpdate(next_source, next_update)) => { - if let Some((batch_source, batch_update)) = accumulated_updates.first() && - !can_batch_state_update( + if let Some((batch_source, batch_update)) = accumulated_updates.first() + && !can_batch_state_update( *batch_source, batch_update, next_source, @@ -2294,8 +2302,8 @@ mod tests { Some(MultiProofMessage::StateUpdate(next_source, next_update)); break; } - if accumulated_targets + next_estimate > STATE_UPDATE_MAX_BATCH_TARGETS && - !accumulated_updates.is_empty() + if accumulated_targets + next_estimate > STATE_UPDATE_MAX_BATCH_TARGETS + && !accumulated_updates.is_empty() { pending_msg = Some(MultiProofMessage::StateUpdate(next_source, next_update)); @@ -2368,7 +2376,9 @@ mod tests { nonce: 1, code_hash: Default::default(), code: Default::default(), + account_id: None, }, + original_info: Box::new(revm_state::AccountInfo::default()), transaction_id: Default::default(), storage: Default::default(), status: revm_state::AccountStatus::Touched, @@ -2385,7 +2395,9 @@ mod tests { nonce: 2, code_hash: Default::default(), code: Default::default(), + account_id: None, }, + original_info: Box::new(revm_state::AccountInfo::default()), transaction_id: Default::default(), storage: Default::default(), status: revm_state::AccountStatus::Touched, @@ -2487,7 +2499,9 @@ mod tests { nonce: 1, code_hash: Default::default(), code: Default::default(), + account_id: None, }, + original_info: Box::new(revm_state::AccountInfo::default()), transaction_id: Default::default(), storage: Default::default(), status: revm_state::AccountStatus::Touched, @@ -2580,7 +2594,9 @@ mod tests { nonce: 1, code_hash: Default::default(), code: Default::default(), + account_id: None, }, + original_info: Box::new(revm_state::AccountInfo::default()), transaction_id: Default::default(), storage: Default::default(), status: revm_state::AccountStatus::Touched, diff --git a/crates/ethereum/evm/src/lib.rs b/crates/ethereum/evm/src/lib.rs index dbc686fe4f..9fd4b31d82 100644 --- a/crates/ethereum/evm/src/lib.rs +++ b/crates/ethereum/evm/src/lib.rs @@ -238,8 +238,9 @@ where revm_spec_by_timestamp_and_block_number(self.chain_spec(), timestamp, block_number); // configure evm env based on parent block - let mut cfg_env = - CfgEnv::new().with_chain_id(self.chain_spec().chain().id()).with_spec(spec); + let mut cfg_env = CfgEnv::new() + .with_chain_id(self.chain_spec().chain().id()) + .with_spec_and_mainnet_gas_params(spec); if let Some(blob_params) = &blob_params { cfg_env.set_max_blobs_per_tx(blob_params.max_blobs_per_tx); @@ -407,7 +408,7 @@ mod tests { let db = CacheDB::>::default(); let evm_env = EvmEnv { - cfg_env: CfgEnv::new().with_spec(SpecId::CONSTANTINOPLE), + cfg_env: CfgEnv::new().with_spec_and_mainnet_gas_params(SpecId::CONSTANTINOPLE), ..Default::default() }; @@ -474,7 +475,7 @@ mod tests { let db = CacheDB::>::default(); let evm_env = EvmEnv { - cfg_env: CfgEnv::new().with_spec(SpecId::CONSTANTINOPLE), + cfg_env: CfgEnv::new().with_spec_and_mainnet_gas_params(SpecId::CONSTANTINOPLE), ..Default::default() }; diff --git a/crates/ethereum/evm/tests/execute.rs b/crates/ethereum/evm/tests/execute.rs index 61e0c1c4b6..c7d0a08337 100644 --- a/crates/ethereum/evm/tests/execute.rs +++ b/crates/ethereum/evm/tests/execute.rs @@ -38,6 +38,7 @@ fn create_database_with_beacon_root_contract() -> CacheDB { code_hash: keccak256(BEACON_ROOTS_CODE.clone()), nonce: 1, code: Some(Bytecode::new_raw(BEACON_ROOTS_CODE.clone())), + account_id: None, }; db.insert_account_info(BEACON_ROOTS_ADDRESS, beacon_root_contract_account); @@ -53,6 +54,7 @@ fn create_database_with_withdrawal_requests_contract() -> CacheDB { balance: U256::ZERO, code_hash: keccak256(WITHDRAWAL_REQUEST_PREDEPLOY_CODE.clone()), code: Some(Bytecode::new_raw(WITHDRAWAL_REQUEST_PREDEPLOY_CODE.clone())), + account_id: None, }; db.insert_account_info( @@ -339,6 +341,7 @@ fn create_database_with_block_hashes(latest_block: u64) -> CacheDB { code_hash: keccak256(HISTORY_STORAGE_CODE.clone()), code: Some(Bytecode::new_raw(HISTORY_STORAGE_CODE.clone())), nonce: 1, + account_id: None, }; db.insert_account_info(HISTORY_STORAGE_ADDRESS, blockhashes_contract_account); diff --git a/crates/ethereum/payload/src/lib.rs b/crates/ethereum/payload/src/lib.rs index b803e9a351..7a21f0d3fd 100644 --- a/crates/ethereum/payload/src/lib.rs +++ b/crates/ethereum/payload/src/lib.rs @@ -155,7 +155,7 @@ where let state_provider = client.state_by_block_hash(parent_header.hash())?; let state = StateProviderDatabase::new(state_provider.as_ref()); let mut db = - State::builder().with_database_ref(cached_reads.as_db(state)).with_bundle_update().build(); + State::builder().with_database(cached_reads.as_db_mut(state)).with_bundle_update().build(); let mut builder = evm_config .builder_for_next_block( @@ -221,21 +221,21 @@ where &pool_tx, &InvalidPoolTransactionError::ExceedsGasLimit(pool_tx.gas_limit(), block_gas_limit), ); - continue + continue; } // check if the job was cancelled, if so we can exit early if cancel.is_cancelled() { - return Ok(BuildOutcome::Cancelled) + return Ok(BuildOutcome::Cancelled); } // convert tx to a signed transaction let tx = pool_tx.to_consensus(); - let estimated_block_size_with_tx = block_transactions_rlp_length + - tx.inner().length() + - attributes.withdrawals().length() + - 1024; // 1Kb of overhead for the block header + let estimated_block_size_with_tx = block_transactions_rlp_length + + tx.inner().length() + + attributes.withdrawals().length() + + 1024; // 1Kb of overhead for the block header if is_osaka && estimated_block_size_with_tx > MAX_RLP_BLOCK_SIZE { best_txs.mark_invalid( @@ -269,14 +269,14 @@ where }, ), ); - continue + continue; } let blob_sidecar_result = 'sidecar: { let Some(sidecar) = pool.get_blob(*tx.hash()).map_err(PayloadBuilderError::other)? else { - break 'sidecar Err(Eip4844PoolTransactionError::MissingEip4844BlobSidecar) + break 'sidecar Err(Eip4844PoolTransactionError::MissingEip4844BlobSidecar); }; if is_osaka { @@ -296,7 +296,7 @@ where Ok(sidecar) => Some(sidecar), Err(error) => { best_txs.mark_invalid(&pool_tx, &InvalidPoolTransactionError::Eip4844(error)); - continue + continue; } }; } @@ -320,7 +320,7 @@ where ), ); } - continue + continue; } // this is an error that we should treat as fatal for this attempt Err(err) => return Err(PayloadBuilderError::evm(err)), @@ -355,7 +355,7 @@ where // Release db drop(builder); // can skip building the block - return Ok(BuildOutcome::Aborted { fees: total_fees, cached_reads }) + return Ok(BuildOutcome::Aborted { fees: total_fees, cached_reads }); } let BlockBuilderOutcome { execution_result, block, .. } = diff --git a/crates/evm/evm/src/execute.rs b/crates/evm/evm/src/execute.rs index fca8f6241d..e70db5296b 100644 --- a/crates/evm/evm/src/execute.rs +++ b/crates/evm/evm/src/execute.rs @@ -741,6 +741,7 @@ mod tests { nonce, code_hash: KECCAK_EMPTY, code: None, + account_id: None, }; state.insert_account(addr, account_info); state @@ -777,8 +778,13 @@ mod tests { let mut state = setup_state_with_account(addr1, 100, 1); - let account2 = - AccountInfo { balance: U256::from(200), nonce: 1, code_hash: KECCAK_EMPTY, code: None }; + let account2 = AccountInfo { + balance: U256::from(200), + nonce: 1, + code_hash: KECCAK_EMPTY, + code: None, + account_id: None, + }; state.insert_account(addr2, account2); let mut increments = HashMap::default(); @@ -799,8 +805,13 @@ mod tests { let mut state = setup_state_with_account(addr1, 100, 1); - let account2 = - AccountInfo { balance: U256::from(200), nonce: 1, code_hash: KECCAK_EMPTY, code: None }; + let account2 = AccountInfo { + balance: U256::from(200), + nonce: 1, + code_hash: KECCAK_EMPTY, + code: None, + account_id: None, + }; state.insert_account(addr2, account2); let mut increments = HashMap::default(); diff --git a/crates/evm/evm/src/lib.rs b/crates/evm/evm/src/lib.rs index b370c15302..356f48284d 100644 --- a/crates/evm/evm/src/lib.rs +++ b/crates/evm/evm/src/lib.rs @@ -399,7 +399,7 @@ pub trait ConfigureEvm: Clone + Debug + Send + Sync + Unpin { /// // Complete block building /// let outcome = builder.finish(state_provider)?; /// ``` - fn builder_for_next_block<'a, DB: Database>( + fn builder_for_next_block<'a, DB: Database + 'a>( &'a self, db: &'a mut State, parent: &'a SealedHeader<::BlockHeader>, diff --git a/crates/evm/execution-types/src/execution_outcome.rs b/crates/evm/execution-types/src/execution_outcome.rs index 25c8ba17ab..911c47f11e 100644 --- a/crates/evm/execution-types/src/execution_outcome.rs +++ b/crates/evm/execution-types/src/execution_outcome.rs @@ -208,11 +208,11 @@ impl ExecutionOutcome { /// Transform block number to the index of block. pub const fn block_number_to_index(&self, block_number: BlockNumber) -> Option { if self.first_block > block_number { - return None + return None; } let index = block_number - self.first_block; if index >= self.receipts.len() as u64 { - return None + return None; } Some(index as usize) } @@ -301,7 +301,7 @@ impl ExecutionOutcome { T: Clone, { if at == self.first_block { - return (None, self) + return (None, self); } let (mut lower_state, mut higher_state) = (self.clone(), self); @@ -929,10 +929,20 @@ mod tests { let address3 = Address::random(); // Set up account info with some changes - let account_info1 = - AccountInfo { nonce: 1, balance: U256::from(100), code_hash: B256::ZERO, code: None }; - let account_info2 = - AccountInfo { nonce: 2, balance: U256::from(200), code_hash: B256::ZERO, code: None }; + let account_info1 = AccountInfo { + nonce: 1, + balance: U256::from(100), + code_hash: B256::ZERO, + code: None, + account_id: None, + }; + let account_info2 = AccountInfo { + nonce: 2, + balance: U256::from(200), + code_hash: B256::ZERO, + code: None, + account_id: None, + }; // Set up the bundle state with these accounts let mut bundle_state = BundleState::default(); diff --git a/crates/optimism/evm/src/lib.rs b/crates/optimism/evm/src/lib.rs index 1805cc4036..1d0460ff72 100644 --- a/crates/optimism/evm/src/lib.rs +++ b/crates/optimism/evm/src/lib.rs @@ -230,7 +230,7 @@ where let spec = revm_spec_by_timestamp_after_bedrock(self.chain_spec(), timestamp); - let cfg_env = CfgEnv::new().with_chain_id(self.chain_spec().chain().id()).with_spec(spec); + let cfg_env = CfgEnv::new().with_chain_id(self.chain_spec().chain().id()).with_spec_and_mainnet_gas_params(spec); let blob_excess_gas_and_price = spec .into_eth_spec() @@ -361,7 +361,7 @@ mod tests { let db = CacheDB::>::default(); // Create a custom configuration environment with a chain ID of 111 - let cfg = CfgEnv::new().with_chain_id(111).with_spec(OpSpecId::default()); + let cfg = CfgEnv::new().with_chain_id(111).with_spec_and_mainnet_gas_params(OpSpecId::default()); let evm_env = EvmEnv { cfg_env: cfg.clone(), ..Default::default() }; @@ -400,7 +400,7 @@ mod tests { let db = CacheDB::>::default(); let evm_env = - EvmEnv { cfg_env: CfgEnv::new().with_spec(OpSpecId::ECOTONE), ..Default::default() }; + EvmEnv { cfg_env: CfgEnv::new().with_spec_and_mainnet_gas_params(OpSpecId::ECOTONE), ..Default::default() }; let evm = evm_config.evm_with_env(db, evm_env.clone()); @@ -426,7 +426,7 @@ mod tests { let evm_config = test_evm_config(); let db = CacheDB::>::default(); - let cfg = CfgEnv::new().with_chain_id(111).with_spec(OpSpecId::default()); + let cfg = CfgEnv::new().with_chain_id(111).with_spec_and_mainnet_gas_params(OpSpecId::default()); let block = BlockEnv::default(); let evm_env = EvmEnv { block_env: block, cfg_env: cfg.clone() }; @@ -463,7 +463,7 @@ mod tests { let db = CacheDB::>::default(); let evm_env = - EvmEnv { cfg_env: CfgEnv::new().with_spec(OpSpecId::ECOTONE), ..Default::default() }; + EvmEnv { cfg_env: CfgEnv::new().with_spec_and_mainnet_gas_params(OpSpecId::ECOTONE), ..Default::default() }; let evm = evm_config.evm_with_env_and_inspector(db, evm_env.clone(), NoOpInspector {}); diff --git a/crates/optimism/node/tests/it/builder.rs b/crates/optimism/node/tests/it/builder.rs index b495fdb47c..3d4eda33f7 100644 --- a/crates/optimism/node/tests/it/builder.rs +++ b/crates/optimism/node/tests/it/builder.rs @@ -19,7 +19,7 @@ use reth_optimism_node::{args::RollupArgs, OpEvmConfig, OpExecutorBuilder, OpNod use reth_optimism_primitives::OpPrimitives; use reth_provider::providers::BlockchainProvider; use revm::{ - context::{BlockEnv, Cfg, ContextTr, TxEnv}, + context::{BlockEnv, ContextTr, TxEnv}, context_interface::result::EVMError, inspector::NoOpInspector, interpreter::interpreter::EthInterpreter, @@ -103,7 +103,7 @@ fn test_setup_custom_precompiles() { input: EvmEnv, ) -> Self::Evm { let mut op_evm = OpEvmFactory::default().create_evm(db, input); - *op_evm.components_mut().2 = UniPrecompiles::precompiles(op_evm.ctx().cfg().spec()); + *op_evm.components_mut().2 = UniPrecompiles::precompiles(*op_evm.ctx().cfg().spec()); op_evm } @@ -119,7 +119,7 @@ fn test_setup_custom_precompiles() { ) -> Self::Evm { let mut op_evm = OpEvmFactory::default().create_evm_with_inspector(db, input, inspector); - *op_evm.components_mut().2 = UniPrecompiles::precompiles(op_evm.ctx().cfg().spec()); + *op_evm.components_mut().2 = UniPrecompiles::precompiles(*op_evm.ctx().cfg().spec()); op_evm } diff --git a/crates/optimism/payload/src/builder.rs b/crates/optimism/payload/src/builder.rs index 99bc07065a..0980a778cf 100644 --- a/crates/optimism/payload/src/builder.rs +++ b/crates/optimism/payload/src/builder.rs @@ -359,13 +359,13 @@ impl OpBuilder<'_, Txs> { if !ctx.attributes().no_tx_pool() { let best_txs = best(ctx.best_transaction_attributes(builder.evm_mut().block())); if ctx.execute_best_transactions(&mut info, &mut builder, best_txs)?.is_some() { - return Ok(BuildOutcomeKind::Cancelled) + return Ok(BuildOutcomeKind::Cancelled); } // check if the new payload is even more valuable if !ctx.is_better_payload(info.total_fees) { // can skip building the block - return Ok(BuildOutcomeKind::Aborted { fees: info.total_fees }) + return Ok(BuildOutcomeKind::Aborted { fees: info.total_fees }); } } @@ -634,7 +634,7 @@ where if sequencer_tx.value().is_eip4844() { return Err(PayloadBuilderError::other( OpPayloadBuilderError::BlobTransactionRejected, - )) + )); } // Convert the transaction to a [RecoveredTx]. This is @@ -652,11 +652,11 @@ where .. })) => { trace!(target: "payload_builder", %error, ?sequencer_tx, "Error in sequencer transaction, skipping."); - continue + continue; } Err(err) => { // this is an error that we should treat as fatal for this attempt - return Err(PayloadBuilderError::EvmExecutionError(Box::new(err))) + return Err(PayloadBuilderError::EvmExecutionError(Box::new(err))); } }; @@ -718,26 +718,26 @@ where // invalid which also removes all dependent transaction from // the iterator before we can continue best_txs.mark_invalid(tx.signer(), tx.nonce()); - continue + continue; } // A sequencer's block should never contain blob or deposit transactions from the pool. if tx.is_eip4844() || tx.is_deposit() { best_txs.mark_invalid(tx.signer(), tx.nonce()); - continue + continue; } // We skip invalid cross chain txs, they would be removed on the next block update in // the maintenance job - if let Some(interop) = interop && - !is_valid_interop(interop, self.config.attributes.timestamp()) + if let Some(interop) = interop + && !is_valid_interop(interop, self.config.attributes.timestamp()) { best_txs.mark_invalid(tx.signer(), tx.nonce()); - continue + continue; } // check if the job was cancelled, if so we can exit early if self.cancel.is_cancelled() { - return Ok(Some(())) + return Ok(Some(())); } let gas_used = match builder.execute_transaction(tx.clone()) { @@ -755,11 +755,11 @@ where trace!(target: "payload_builder", %error, ?tx, "skipping invalid transaction and its descendants"); best_txs.mark_invalid(tx.signer(), tx.nonce()); } - continue + continue; } Err(err) => { // this is an error that we should treat as fatal for this attempt - return Err(PayloadBuilderError::EvmExecutionError(Box::new(err))) + return Err(PayloadBuilderError::EvmExecutionError(Box::new(err))); } }; diff --git a/crates/primitives-traits/src/account.rs b/crates/primitives-traits/src/account.rs index 8c4a496dab..56b4dc12a8 100644 --- a/crates/primitives-traits/src/account.rs +++ b/crates/primitives-traits/src/account.rs @@ -47,9 +47,9 @@ impl Account { /// After `SpuriousDragon` empty account is defined as account with nonce == 0 && balance == 0 /// && bytecode = None (or hash is [`KECCAK_EMPTY`]). pub fn is_empty(&self) -> bool { - self.nonce == 0 && - self.balance.is_zero() && - self.bytecode_hash.is_none_or(|hash| hash == KECCAK_EMPTY) + self.nonce == 0 + && self.balance.is_zero() + && self.bytecode_hash.is_none_or(|hash| hash == KECCAK_EMPTY) } /// Returns an account bytecode's hash. @@ -238,12 +238,15 @@ impl From for AccountInfo { nonce: reth_acc.nonce, code_hash: reth_acc.bytecode_hash.unwrap_or(KECCAK_EMPTY), code: None, + account_id: None, } } } #[cfg(test)] mod tests { + use std::sync::Arc; + use super::*; use alloy_primitives::{hex_literal::hex, B256, U256}; use reth_codecs::Compact; @@ -304,11 +307,12 @@ mod tests { assert_eq!(len, 17); let mut buf = vec![]; - let bytecode = Bytecode(RevmBytecode::LegacyAnalyzed(LegacyAnalyzedBytecode::new( - Bytes::from(&hex!("ff00")), - 2, - JumpTable::from_slice(&[0], 2), - ))); + let bytecode = + Bytecode(RevmBytecode::LegacyAnalyzed(Arc::new(LegacyAnalyzedBytecode::new( + Bytes::from(&hex!("ff00")), + 2, + JumpTable::from_slice(&[0], 2), + )))); let len = bytecode.to_compact(&mut buf); assert_eq!(len, 16); diff --git a/crates/rpc/rpc-eth-api/src/helpers/call.rs b/crates/rpc/rpc-eth-api/src/helpers/call.rs index d3790251e5..d4ce573efd 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/call.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/call.rs @@ -25,7 +25,11 @@ use reth_evm::{ }; use reth_node_api::BlockBody; use reth_primitives_traits::Recovered; -use reth_revm::{cancelled::CancelOnDrop, database::StateProviderDatabase, db::State}; +use reth_revm::{ + cancelled::CancelOnDrop, + database::StateProviderDatabase, + db::{bal::EvmDatabaseError, State}, +}; use reth_rpc_convert::{RpcConvert, RpcTxReq}; use reth_rpc_eth_types::{ cache::db::StateProviderTraitObjWrapper, @@ -69,7 +73,7 @@ pub trait EthCall: EstimateCall + Call + LoadPendingBlock + LoadBlock + FullEthA ) -> impl Future> + Send { async move { if payload.block_state_calls.len() > self.max_simulate_blocks() as usize { - return Err(EthApiError::InvalidParams("too many blocks.".to_string()).into()) + return Err(EthApiError::InvalidParams("too many blocks.".to_string()).into()); } let block = block.unwrap_or_default(); @@ -82,7 +86,7 @@ pub trait EthCall: EstimateCall + Call + LoadPendingBlock + LoadBlock + FullEthA } = payload; if block_state_calls.is_empty() { - return Err(EthApiError::InvalidParams(String::from("calls are empty.")).into()) + return Err(EthApiError::InvalidParams(String::from("calls are empty.")).into()); } let base_block = @@ -508,7 +512,7 @@ pub trait Call: tx_env: TxEnvFor, ) -> Result>, Self::Error> where - DB: Database + fmt::Debug, + DB: Database> + fmt::Debug, { let mut evm = self.evm_config().evm_with_env(db, evm_env); let res = evm.transact(tx_env).map_err(Self::Error::from_evm_err)?; @@ -526,7 +530,7 @@ pub trait Call: inspector: I, ) -> Result>, Self::Error> where - DB: Database + fmt::Debug, + DB: Database> + fmt::Debug, I: InspectorFor, { let mut evm = self.evm_config().evm_with_env_and_inspector(db, evm_env, inspector); @@ -559,7 +563,7 @@ pub trait Call: .spawn_with_call_at(request, at, overrides, move |db, evm_env, tx_env| { if cancel.is_cancelled() { // callsite dropped the guard - return Err(EthApiError::InternalEthError.into()) + return Err(EthApiError::InternalEthError.into()); } this.transact(db, evm_env, tx_env) }) @@ -703,7 +707,7 @@ pub trait Call: target_tx_hash: B256, ) -> Result where - DB: Database + DatabaseCommit + core::fmt::Debug, + DB: Database> + DatabaseCommit + core::fmt::Debug, I: IntoIterator>>, { let mut evm = self.evm_config().evm_with_env(db, evm_env); @@ -711,7 +715,7 @@ pub trait Call: for tx in transactions { if *tx.tx_hash() == target_tx_hash { // reached the target transaction - break + break; } let tx_env = self.evm_config().tx_env(tx); diff --git a/crates/rpc/rpc-eth-api/src/helpers/estimate.rs b/crates/rpc/rpc-eth-api/src/helpers/estimate.rs index fa9dec303a..aad32417b4 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/estimate.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/estimate.rs @@ -12,7 +12,7 @@ use reth_errors::ProviderError; use reth_evm::{ConfigureEvm, Database, Evm, EvmEnvFor, EvmFor, TransactionEnv, TxEnvFor}; use reth_revm::{ database::{EvmStateProvider, StateProviderDatabase}, - db::State, + db::{bal::EvmDatabaseError, State}, }; use reth_rpc_convert::{RpcConvert, RpcTxReq}; use reth_rpc_eth_types::{ @@ -97,8 +97,8 @@ pub trait EstimateCall: Call { let mut tx_env = self.create_txn_env(&evm_env, request, &mut db)?; // Check if this is a basic transfer (no input data to account with no code) - let is_basic_transfer = if tx_env.input().is_empty() && - let TxKind::Call(to) = tx_env.kind() + let is_basic_transfer = if tx_env.input().is_empty() + && let TxKind::Call(to) = tx_env.kind() { match db.database.basic_account(&to) { Ok(Some(account)) => { @@ -136,10 +136,10 @@ pub trait EstimateCall: Call { min_tx_env.set_gas_limit(MIN_TRANSACTION_GAS); // Reuse the same EVM instance - if let Ok(res) = evm.transact(min_tx_env).map_err(Self::Error::from_evm_err) && - res.result.is_success() + if let Ok(res) = evm.transact(min_tx_env).map_err(Self::Error::from_evm_err) + && res.result.is_success() { - return Ok(U256::from(MIN_TRANSACTION_GAS)) + return Ok(U256::from(MIN_TRANSACTION_GAS)); } } @@ -152,8 +152,8 @@ pub trait EstimateCall: Call { // retry the transaction with the block's gas limit to determine if // the failure was due to insufficient gas. Err(err) - if err.is_gas_too_high() && - (tx_request_gas_limit.is_some() || tx_request_gas_price.is_some()) => + if err.is_gas_too_high() + && (tx_request_gas_limit.is_some() || tx_request_gas_price.is_some()) => { return Self::map_out_of_gas_err(&mut evm, tx_env, max_gas_limit); } @@ -165,7 +165,7 @@ pub trait EstimateCall: Call { return Err(RpcInvalidTransactionError::GasRequiredExceedsAllowance { gas_limit: tx_env.gas_limit(), } - .into_eth_err()) + .into_eth_err()); } // Propagate other results (successful or other errors). ethres => ethres?, @@ -176,7 +176,7 @@ pub trait EstimateCall: Call { ExecutionResult::Halt { reason, .. } => { // here we don't check for invalid opcode because already executed with highest gas // limit - return Err(Self::Error::from_evm_halt(reason, tx_env.gas_limit())) + return Err(Self::Error::from_evm_halt(reason, tx_env.gas_limit())); } ExecutionResult::Revert { output, .. } => { // if price or limit was included in the request then we can execute the request @@ -186,7 +186,7 @@ pub trait EstimateCall: Call { } else { // the transaction did revert Err(Self::Error::from_revert(output)) - } + }; } }; @@ -246,7 +246,7 @@ pub trait EstimateCall: Call { // Result where - DB: Database, + DB: Database>, EthApiError: From, { let req_gas_limit = tx_env.gas_limit(); diff --git a/crates/rpc/rpc-eth-api/src/helpers/trace.rs b/crates/rpc/rpc-eth-api/src/helpers/trace.rs index 20440725a8..e759e26a70 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/trace.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/trace.rs @@ -13,7 +13,10 @@ use reth_evm::{ Evm, EvmEnvFor, EvmFor, HaltReasonFor, InspectorFor, TxEnvFor, }; use reth_primitives_traits::{BlockBody, Recovered, RecoveredBlock}; -use reth_revm::{database::StateProviderDatabase, db::State}; +use reth_revm::{ + database::StateProviderDatabase, + db::{bal::EvmDatabaseError, State}, +}; use reth_rpc_eth_types::{cache::db::StateCacheDb, EthApiError}; use reth_storage_api::{ProviderBlock, ProviderTx}; use revm::{context::Block, context_interface::result::ResultAndState, DatabaseCommit}; @@ -32,7 +35,7 @@ pub trait Trace: LoadState> + Call { inspector: I, ) -> Result>, Self::Error> where - DB: Database, + DB: Database>, I: InspectorFor, { let mut evm = self.evm_config().evm_with_env_and_inspector(db, evm_env, inspector); @@ -265,7 +268,7 @@ pub trait Trace: LoadState> + Call { async move { let block = async { if block.is_some() { - return Ok(block) + return Ok(block); } self.recovered_block(block_id).await }; @@ -276,7 +279,7 @@ pub trait Trace: LoadState> + Call { if block.body().transactions().is_empty() { // nothing to trace - return Ok(Some(Vec::new())) + return Ok(Some(Vec::new())); } // replay all transactions of the block diff --git a/crates/rpc/rpc-eth-types/src/error/api.rs b/crates/rpc/rpc-eth-types/src/error/api.rs index 744314ecb0..a761119b4c 100644 --- a/crates/rpc/rpc-eth-types/src/error/api.rs +++ b/crates/rpc/rpc-eth-types/src/error/api.rs @@ -5,6 +5,7 @@ use crate::{simulate::EthSimulateError, EthApiError, RevertError}; use alloy_primitives::Bytes; use reth_errors::ProviderError; use reth_evm::{ConfigureEvm, EvmErrorFor, HaltReasonFor}; +use reth_revm::db::bal::EvmDatabaseError; use revm::{context::result::ExecutionResult, context_interface::result::HaltReason}; use super::RpcInvalidTransactionError; @@ -59,7 +60,7 @@ pub trait AsEthApiError { /// [`RpcInvalidTransactionError::GasTooHigh`]. fn is_gas_too_high(&self) -> bool { if let Some(err) = self.as_err() { - return err.is_gas_too_high() + return err.is_gas_too_high(); } false @@ -69,7 +70,7 @@ pub trait AsEthApiError { /// [`RpcInvalidTransactionError::GasTooLow`]. fn is_gas_too_low(&self) -> bool { if let Some(err) = self.as_err() { - return err.is_gas_too_low() + return err.is_gas_too_low(); } false @@ -110,10 +111,12 @@ impl AsEthApiError for EthApiError { /// Helper trait to convert from revm errors. pub trait FromEvmError: - From> + FromEvmHalt> + FromRevert + From>> + + FromEvmHalt> + + FromRevert { /// Converts from EVM error to this type. - fn from_evm_err(err: EvmErrorFor) -> Self { + fn from_evm_err(err: EvmErrorFor>) -> Self { err.into() } @@ -131,7 +134,9 @@ pub trait FromEvmError: impl FromEvmError for T where - T: From> + FromEvmHalt> + FromRevert, + T: From>> + + FromEvmHalt> + + FromRevert, Evm: ConfigureEvm, { } diff --git a/crates/rpc/rpc-eth-types/src/error/mod.rs b/crates/rpc/rpc-eth-types/src/error/mod.rs index 2a7e5141c3..83bc92a1fd 100644 --- a/crates/rpc/rpc-eth-types/src/error/mod.rs +++ b/crates/rpc/rpc-eth-types/src/error/mod.rs @@ -11,6 +11,7 @@ pub use api::{AsEthApiError, FromEthApiError, FromEvmError, IntoEthApiError}; use core::time::Duration; use reth_errors::{BlockExecutionError, BlockValidationError, RethError}; use reth_primitives_traits::transaction::{error::InvalidTransactionError, signed::RecoveryError}; +use reth_revm::db::bal::EvmDatabaseError; use reth_rpc_convert::{CallFeesError, EthTxEnvError, TransactionConversionError}; use reth_rpc_server_types::result::{ block_id_to_str, internal_rpc_err, invalid_params_rpc_err, rpc_err, rpc_error_with_code, @@ -19,9 +20,9 @@ use reth_transaction_pool::error::{ Eip4844PoolTransactionError, Eip7702PoolTransactionError, InvalidPoolTransactionError, PoolError, PoolErrorKind, PoolTransactionError, }; -use revm::context_interface::result::{ +use revm::{context_interface::result::{ EVMError, HaltReason, InvalidHeader, InvalidTransaction, OutOfGasError, -}; +}, state::bal::BalError}; use revm_inspectors::tracing::{DebugInspectorError, MuxError}; use std::convert::Infallible; use tokio::sync::oneshot::error::RecvError; @@ -220,8 +221,8 @@ impl EthApiError { matches!( self, Self::InvalidTransaction( - RpcInvalidTransactionError::GasTooHigh | - RpcInvalidTransactionError::GasLimitTooHigh + RpcInvalidTransactionError::GasTooHigh + | RpcInvalidTransactionError::GasLimitTooHigh ) ) } @@ -264,25 +265,25 @@ impl EthApiError { impl From for jsonrpsee_types::error::ErrorObject<'static> { fn from(error: EthApiError) -> Self { match error { - EthApiError::FailedToDecodeSignedTransaction | - EthApiError::InvalidTransactionSignature | - EthApiError::EmptyRawTransactionData | - EthApiError::InvalidBlockRange | - EthApiError::ExceedsMaxProofWindow | - EthApiError::ConflictingFeeFieldsInRequest | - EthApiError::Signing(_) | - EthApiError::BothStateAndStateDiffInOverride(_) | - EthApiError::InvalidTracerConfig | - EthApiError::TransactionConversionError(_) | - EthApiError::InvalidRewardPercentiles | - EthApiError::InvalidBytecode(_) => invalid_params_rpc_err(error.to_string()), + EthApiError::FailedToDecodeSignedTransaction + | EthApiError::InvalidTransactionSignature + | EthApiError::EmptyRawTransactionData + | EthApiError::InvalidBlockRange + | EthApiError::ExceedsMaxProofWindow + | EthApiError::ConflictingFeeFieldsInRequest + | EthApiError::Signing(_) + | EthApiError::BothStateAndStateDiffInOverride(_) + | EthApiError::InvalidTracerConfig + | EthApiError::TransactionConversionError(_) + | EthApiError::InvalidRewardPercentiles + | EthApiError::InvalidBytecode(_) => invalid_params_rpc_err(error.to_string()), EthApiError::InvalidTransaction(err) => err.into(), EthApiError::PoolError(err) => err.into(), - EthApiError::PrevrandaoNotSet | - EthApiError::ExcessBlobGasNotSet | - EthApiError::InvalidBlockData(_) | - EthApiError::Internal(_) | - EthApiError::EvmCustom(_) => internal_rpc_err(error.to_string()), + EthApiError::PrevrandaoNotSet + | EthApiError::ExcessBlobGasNotSet + | EthApiError::InvalidBlockData(_) + | EthApiError::Internal(_) + | EthApiError::EvmCustom(_) => internal_rpc_err(error.to_string()), EthApiError::UnknownBlockOrTxIndex | EthApiError::TransactionNotFound => { rpc_error_with_code(EthRpcErrorCode::ResourceNotFound.code(), error.to_string()) } @@ -395,6 +396,24 @@ impl From for EthApiError { } } +impl From> for EthApiError +where + E: Into, +{ + fn from(value: EvmDatabaseError) -> Self { + match value { + EvmDatabaseError::Bal(err) => err.into(), + EvmDatabaseError::Database(err) => err.into(), + } + } +} + +impl From for EthApiError { + fn from(err: BalError) -> Self { + Self::EvmCustom(format!("bal error: {:?}", err)) + } +} + #[cfg(feature = "js-tracer")] impl From for EthApiError { fn from(error: revm_inspectors::tracing::js::JsInspectorError) -> Self { @@ -708,14 +727,14 @@ impl RpcInvalidTransactionError { /// Returns the rpc error code for this error. pub const fn error_code(&self) -> i32 { match self { - Self::InvalidChainId | - Self::GasTooLow | - Self::GasTooHigh | - Self::GasRequiredExceedsAllowance { .. } | - Self::NonceTooLow { .. } | - Self::NonceTooHigh { .. } | - Self::FeeCapTooLow | - Self::FeeCapVeryHigh => EthRpcErrorCode::InvalidInput.code(), + Self::InvalidChainId + | Self::GasTooLow + | Self::GasTooHigh + | Self::GasRequiredExceedsAllowance { .. } + | Self::NonceTooLow { .. } + | Self::NonceTooHigh { .. } + | Self::FeeCapTooLow + | Self::FeeCapVeryHigh => EthRpcErrorCode::InvalidInput.code(), Self::Revert(_) => EthRpcErrorCode::ExecutionError.code(), _ => EthRpcErrorCode::TransactionRejected.code(), } @@ -776,8 +795,8 @@ impl From for RpcInvalidTransactionError { } InvalidTransaction::PriorityFeeGreaterThanMaxFee => Self::TipAboveFeeCap, InvalidTransaction::GasPriceLessThanBasefee => Self::FeeCapTooLow, - InvalidTransaction::CallerGasLimitMoreThanBlock | - InvalidTransaction::TxGasLimitGreaterThanCap { .. } => { + InvalidTransaction::CallerGasLimitMoreThanBlock + | InvalidTransaction::TxGasLimitGreaterThanCap { .. } => { // tx.gas > block.gas_limit Self::GasTooHigh } @@ -814,13 +833,13 @@ impl From for RpcInvalidTransactionError { InvalidTransaction::AuthorizationListNotSupported => { Self::AuthorizationListNotSupported } - InvalidTransaction::AuthorizationListInvalidFields | - InvalidTransaction::EmptyAuthorizationList => Self::AuthorizationListInvalidFields, - InvalidTransaction::Eip2930NotSupported | - InvalidTransaction::Eip1559NotSupported | - InvalidTransaction::Eip4844NotSupported | - InvalidTransaction::Eip7702NotSupported | - InvalidTransaction::Eip7873NotSupported => Self::TxTypeNotSupported, + InvalidTransaction::AuthorizationListInvalidFields + | InvalidTransaction::EmptyAuthorizationList => Self::AuthorizationListInvalidFields, + InvalidTransaction::Eip2930NotSupported + | InvalidTransaction::Eip1559NotSupported + | InvalidTransaction::Eip4844NotSupported + | InvalidTransaction::Eip7702NotSupported + | InvalidTransaction::Eip7873NotSupported => Self::TxTypeNotSupported, InvalidTransaction::Eip7873MissingTarget => { Self::other(internal_rpc_err(err.to_string())) } @@ -846,11 +865,11 @@ impl From for RpcInvalidTransactionError { Self::OldLegacyChainId } InvalidTransactionError::ChainIdMismatch => Self::InvalidChainId, - InvalidTransactionError::Eip2930Disabled | - InvalidTransactionError::Eip1559Disabled | - InvalidTransactionError::Eip4844Disabled | - InvalidTransactionError::Eip7702Disabled | - InvalidTransactionError::TxTypeNotSupported => Self::TxTypeNotSupported, + InvalidTransactionError::Eip2930Disabled + | InvalidTransactionError::Eip1559Disabled + | InvalidTransactionError::Eip4844Disabled + | InvalidTransactionError::Eip7702Disabled + | InvalidTransactionError::TxTypeNotSupported => Self::TxTypeNotSupported, InvalidTransactionError::GasUintOverflow => Self::GasUintOverflow, InvalidTransactionError::GasTooLow => Self::GasTooLow, InvalidTransactionError::GasTooHigh => Self::GasTooHigh, @@ -986,20 +1005,20 @@ impl From for jsonrpsee_types::error::ErrorObject<'static> { RpcPoolError::TxPoolOverflow => { rpc_error_with_code(EthRpcErrorCode::TransactionRejected.code(), error.to_string()) } - RpcPoolError::AlreadyKnown | - RpcPoolError::InvalidSender | - RpcPoolError::Underpriced | - RpcPoolError::ReplaceUnderpriced | - RpcPoolError::ExceedsGasLimit | - RpcPoolError::MaxTxGasLimitExceeded | - RpcPoolError::ExceedsFeeCap { .. } | - RpcPoolError::NegativeValue | - RpcPoolError::OversizedData { .. } | - RpcPoolError::ExceedsMaxInitCodeSize | - RpcPoolError::PoolTransactionError(_) | - RpcPoolError::Eip4844(_) | - RpcPoolError::Eip7702(_) | - RpcPoolError::AddressAlreadyReserved => { + RpcPoolError::AlreadyKnown + | RpcPoolError::InvalidSender + | RpcPoolError::Underpriced + | RpcPoolError::ReplaceUnderpriced + | RpcPoolError::ExceedsGasLimit + | RpcPoolError::MaxTxGasLimitExceeded + | RpcPoolError::ExceedsFeeCap { .. } + | RpcPoolError::NegativeValue + | RpcPoolError::OversizedData { .. } + | RpcPoolError::ExceedsMaxInitCodeSize + | RpcPoolError::PoolTransactionError(_) + | RpcPoolError::Eip4844(_) + | RpcPoolError::Eip7702(_) + | RpcPoolError::AddressAlreadyReserved => { rpc_error_with_code(EthRpcErrorCode::InvalidInput.code(), error.to_string()) } RpcPoolError::Other(other) => internal_rpc_err(other.to_string()), diff --git a/crates/stateless/src/witness_db.rs b/crates/stateless/src/witness_db.rs index 466b4de30b..86ced51804 100644 --- a/crates/stateless/src/witness_db.rs +++ b/crates/stateless/src/witness_db.rs @@ -76,6 +76,7 @@ where nonce: account.nonce, code_hash: account.code_hash, code: None, + account_id: None, }) }) } diff --git a/crates/storage/errors/Cargo.toml b/crates/storage/errors/Cargo.toml index ac390343c5..58af0c3afc 100644 --- a/crates/storage/errors/Cargo.toml +++ b/crates/storage/errors/Cargo.toml @@ -26,6 +26,7 @@ derive_more.workspace = true thiserror.workspace = true revm-database-interface.workspace = true +revm-state.workspace = true [features] default = ["std"] diff --git a/crates/storage/errors/src/provider.rs b/crates/storage/errors/src/provider.rs index 4aadd6a8b1..e84fbafb4f 100644 --- a/crates/storage/errors/src/provider.rs +++ b/crates/storage/errors/src/provider.rs @@ -6,7 +6,8 @@ use derive_more::Display; use reth_primitives_traits::{transaction::signed::RecoveryError, GotExpected}; use reth_prune_types::PruneSegmentError; use reth_static_file_types::StaticFileSegment; -use revm_database_interface::DBErrorMarker; +use revm_database_interface::{bal::EvmDatabaseError, DBErrorMarker}; +use revm_state::bal::BalError; /// Provider result type. pub type ProviderResult = Result; @@ -17,6 +18,9 @@ pub enum ProviderError { /// Database error. #[error(transparent)] Database(#[from] DatabaseError), + /// BAL error. + #[error("BAL error:{_0}")] + Bal(BalError), /// Pruning error. #[error(transparent)] Pruning(#[from] PruneSegmentError), @@ -195,6 +199,12 @@ impl From for ProviderError { } } +impl From for EvmDatabaseError { + fn from(error: ProviderError) -> Self { + EvmDatabaseError::Database(error) + } +} + /// A root mismatch error at a given block height. #[derive(Clone, Debug, PartialEq, Eq, Display)] #[display("root mismatch at #{block_number} ({block_hash}): {root}")] diff --git a/crates/trie/common/src/hashed_state.rs b/crates/trie/common/src/hashed_state.rs index edfb821bc6..f51282f7d0 100644 --- a/crates/trie/common/src/hashed_state.rs +++ b/crates/trie/common/src/hashed_state.rs @@ -224,10 +224,10 @@ impl HashedPostState { Some(storage_in_targets) => { let mut storage_not_in_targets = HashedStorage::default(); storage.storage.retain(|&slot, value| { - if storage_in_targets.contains(&slot) && - !storage_added_removed_keys.is_some_and(|k| k.is_removed(&slot)) + if storage_in_targets.contains(&slot) + && !storage_added_removed_keys.is_some_and(|k| k.is_removed(&slot)) { - return true + return true; } storage_not_in_targets.storage.insert(slot, *value); @@ -262,7 +262,7 @@ impl HashedPostState { }); self.accounts.retain(|&address, account| { if targets.contains_key(&address) { - return true + return true; } state_updates_not_in_targets.accounts.insert(address, *account); @@ -281,8 +281,9 @@ impl HashedPostState { /// Returns the number of items that will be considered during chunking in `[Self::chunks]`. pub fn chunking_length(&self) -> usize { - self.accounts.len() + - self.storages + self.accounts.len() + + self + .storages .values() .map(|storage| if storage.wiped { 1 } else { 0 } + storage.storage.len()) .sum::() @@ -861,6 +862,7 @@ mod tests { nonce: 42, code_hash: B256::random(), code: Some(Bytecode::new_raw(Bytes::from(vec![1, 2]))), + account_id: None, }; let mut storage = StorageWithOriginalValues::default(); @@ -905,6 +907,7 @@ mod tests { nonce: 1, code_hash: B256::random(), code: None, + account_id: None, }; // Create hashed accounts with addresses.