From 7f88e62781e1d33a04db90d4831b82f50487eed6 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Mon, 2 Dec 2024 04:55:17 +0400 Subject: [PATCH 01/68] feat: bump alloy (#12930) Co-authored-by: Ryan Schneider --- Cargo.lock | 174 +++++++++++------- Cargo.toml | 131 ++++++------- .../src/commands/debug_cmd/build_block.rs | 2 + crates/chain-state/src/in_memory.rs | 4 +- crates/consensus/common/src/validation.rs | 3 +- crates/engine/local/src/payload.rs | 2 + crates/engine/util/Cargo.toml | 1 + crates/engine/util/src/reorg.rs | 3 +- .../ethereum/engine-primitives/src/payload.rs | 6 + crates/ethereum/evm/src/execute.rs | 15 +- crates/ethereum/node/tests/e2e/rpc.rs | 3 +- crates/ethereum/node/tests/e2e/utils.rs | 2 + crates/ethereum/payload/src/lib.rs | 28 ++- .../execution-types/src/execution_outcome.rs | 2 +- crates/evm/src/system_calls/mod.rs | 24 ++- crates/net/eth-wire-types/src/blocks.rs | 12 +- crates/net/eth-wire-types/src/header.rs | 5 +- crates/optimism/evm/Cargo.toml | 1 + crates/optimism/node/src/engine.rs | 2 + crates/optimism/node/src/utils.rs | 2 + crates/optimism/payload/src/builder.rs | 1 + crates/optimism/payload/src/payload.rs | 4 +- crates/optimism/primitives/src/bedrock.rs | 1 + .../primitives/src/transaction/mod.rs | 4 + crates/primitives-traits/src/receipt.rs | 2 +- crates/primitives/src/alloy_compat.rs | 2 + crates/primitives/src/receipt.rs | 2 + crates/primitives/src/traits.rs | 18 +- crates/primitives/src/transaction/mod.rs | 18 +- crates/primitives/src/transaction/pooled.rs | 10 + crates/revm/src/batch.rs | 6 +- crates/rpc/rpc-engine-api/src/engine_api.rs | 15 +- .../rpc-eth-api/src/helpers/pending_block.rs | 1 + .../rpc-eth-api/src/helpers/transaction.rs | 2 +- crates/rpc/rpc-eth-types/src/receipt.rs | 2 +- .../rpc-types-compat/src/engine/payload.rs | 4 +- crates/rpc/rpc/src/debug.rs | 35 +++- crates/rpc/rpc/src/eth/bundle.rs | 16 +- crates/rpc/rpc/src/validation.rs | 10 +- crates/storage/codecs/src/alloy/header.rs | 10 +- testing/ef-tests/src/models.rs | 3 + 41 files changed, 385 insertions(+), 203 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4da864b1beaf..8f68f71bffb8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -112,14 +112,15 @@ dependencies = [ [[package]] name = "alloy-consensus" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae09ffd7c29062431dd86061deefe4e3c6f07fa0d674930095f8dcedb0baf02c" +checksum = "3a1ff8439834ab71a4b0ecd1a8ff80b3921c87615f158940c3364f399c732786" dependencies = [ "alloy-eips", "alloy-primitives", "alloy-rlp", "alloy-serde", + "alloy-trie", "arbitrary", "auto_impl", "c-kzg", @@ -129,11 +130,25 @@ dependencies = [ "serde_with", ] +[[package]] +name = "alloy-consensus-any" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "519a86faaa6729464365a90c04eba68539b6d3a30f426edb4b3dafd78920d42f" +dependencies = [ + "alloy-consensus", + "alloy-eips", + "alloy-primitives", + "alloy-rlp", + "alloy-serde", + "serde", +] + [[package]] name = "alloy-contract" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66430a72d5bf5edead101c8c2f0a24bada5ec9f3cf9909b3e08b6d6899b4803e" +checksum = "cca2b353d8b7f160dc930dfa174557acefece6deab5ecd7e6230d38858579eea" dependencies = [ "alloy-dyn-abi", "alloy-json-abi", @@ -198,9 +213,9 @@ dependencies = [ [[package]] name = "alloy-eips" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b6aa3961694b30ba53d41006131a2fca3bdab22e4c344e46db2c639e7c2dfdd" +checksum = "8dedb328c2114284f767e075589ca9de8d5e9c8a91333402f4804a584ed71a38" dependencies = [ "alloy-eip2930", "alloy-eip7702", @@ -219,9 +234,9 @@ dependencies = [ [[package]] name = "alloy-genesis" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e53f7877ded3921d18a0a9556d55bedf84535567198c9edab2aa23106da91855" +checksum = "4841e8dd4e0f53d76b501fd4c6bc21d95d688bc8ebf0ea359fc6c7ab65b48742" dependencies = [ "alloy-primitives", "alloy-serde", @@ -242,9 +257,9 @@ dependencies = [ [[package]] name = "alloy-json-rpc" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3694b7e480728c0b3e228384f223937f14c10caef5a4c766021190fc8f283d35" +checksum = "254f770918f96dc4ec88a15e6e2e243358e1719d66b40ef814428e7697079d25" dependencies = [ "alloy-primitives", "alloy-sol-types", @@ -256,15 +271,17 @@ dependencies = [ [[package]] name = "alloy-network" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea94b8ceb5c75d7df0a93ba0acc53b55a22b47b532b600a800a87ef04eb5b0b4" +checksum = "931dd176c6e33355f3dc0170ec69cf5b951f4d73870b276e2c837ab35f9c5136" dependencies = [ "alloy-consensus", + "alloy-consensus-any", "alloy-eips", "alloy-json-rpc", "alloy-network-primitives", "alloy-primitives", + "alloy-rpc-types-any", "alloy-rpc-types-eth", "alloy-serde", "alloy-signer", @@ -279,9 +296,9 @@ dependencies = [ [[package]] name = "alloy-network-primitives" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df9f3e281005943944d15ee8491534a1c7b3cbf7a7de26f8c433b842b93eb5f9" +checksum = "fa6ec0f23be233e851e31c5e4badfedfa9c7bc177bc37f4e03616072cd40a806" dependencies = [ "alloy-consensus", "alloy-eips", @@ -292,9 +309,9 @@ dependencies = [ [[package]] name = "alloy-node-bindings" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9805d126f24be459b958973c0569c73e1aadd27d4535eee82b2b6764aa03616" +checksum = "e3bce85f0f67b2248c2eb42941bb75079ac53648569a668e8bfd7de5a831ec64" dependencies = [ "alloy-genesis", "alloy-primitives", @@ -341,9 +358,9 @@ dependencies = [ [[package]] name = "alloy-provider" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40c1f9eede27bf4c13c099e8e64d54efd7ce80ef6ea47478aa75d5d74e2dba3b" +checksum = "5545e2cbf2f8f24c68bb887ba0294fa12a2f816b9e72c4f226cd137b77d0e294" dependencies = [ "alloy-chains", "alloy-consensus", @@ -382,9 +399,9 @@ dependencies = [ [[package]] name = "alloy-pubsub" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f1f34232f77341076541c405482e4ae12f0ee7153d8f9969fc1691201b2247" +checksum = "b633f7731a3df2f4f334001bf80436565113816c5aa5c136c1ded563051e049b" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -423,9 +440,9 @@ dependencies = [ [[package]] name = "alloy-rpc-client" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374dbe0dc3abdc2c964f36b3d3edf9cdb3db29d16bda34aa123f03d810bec1dd" +checksum = "aed9e40c2a73265ebf70f1e48303ee55920282e1ea5971e832873fb2d32cea74" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -448,9 +465,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c74832aa474b670309c20fffc2a869fa141edab7c79ff7963fad0a08de60bae1" +checksum = "42dea20fa715a6f39ec7adc735cfd9567342870737270ac67795d55896527772" dependencies = [ "alloy-primitives", "alloy-rpc-types-engine", @@ -461,9 +478,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-admin" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bfd9b2cc3a1985f1f6da5afc41120256f9f9316fcd89e054cea99dbb10172f6" +checksum = "c9eab93eabf53697b4b9095c0f9203fca3702e78d083c77a5c677bdc02bebab8" dependencies = [ "alloy-genesis", "alloy-primitives", @@ -473,9 +490,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-anvil" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca97963132f78ddfc60e43a017348e6d52eea983925c23652f5b330e8e02291" +checksum = "2750f4f694b27461915b9794df60177198bf733da38dde71aadfbe2946a3c0be" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", @@ -483,15 +500,28 @@ dependencies = [ "serde", ] +[[package]] +name = "alloy-rpc-types-any" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79d7620e22d6ed7c58451dd303d0501ade5a8bec9dc8daef0fbc48ceffabbae1" +dependencies = [ + "alloy-consensus", + "alloy-consensus-any", + "alloy-rpc-types-eth", + "alloy-serde", +] + [[package]] name = "alloy-rpc-types-beacon" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "922fa76678d2f9f07ea1b19309b5cfbf244c6029dcba3515227b515fdd6ed4a7" +checksum = "fdbfc1b5ee81b1ef6d5e770f3bd6018eab66c7ac2ee1e897f88973b327e2fc20" dependencies = [ "alloy-eips", "alloy-primitives", "alloy-rpc-types-engine", + "alloy-serde", "serde", "serde_with", "thiserror 1.0.69", @@ -499,9 +529,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-debug" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba2253bee958658ebd614c07a61c40580e09dd1fad3f017684314442332ab753" +checksum = "51d2d4a265fb1198272cc43d8d418c0423cdfc1aebcd283be9105464874a1dda" dependencies = [ "alloy-primitives", "serde", @@ -509,9 +539,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-engine" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f56294dce86af23ad6ee8df46cf8b0d292eb5d1ff67dc88a0886051e32b1faf" +checksum = "9fb843daa6feb011475f0db8c499fff5ac62e1e6012fc01d97477ddb3217a83f" dependencies = [ "alloy-consensus", "alloy-eips", @@ -530,11 +560,12 @@ dependencies = [ [[package]] name = "alloy-rpc-types-eth" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8a477281940d82d29315846c7216db45b15e90bcd52309da9f54bcf7ad94a11" +checksum = "df34b88df4deeac9ecfc80ad7cbb26a33e57437b9db8be5b952792feef6134bc" dependencies = [ "alloy-consensus", + "alloy-consensus-any", "alloy-eips", "alloy-network-primitives", "alloy-primitives", @@ -551,9 +582,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-mev" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8647f8135ee3d5de1cf196706c905c05728a4e38bb4a5b61a7214bd1ba8f60a6" +checksum = "be601847f0b13112249ed577eaa7501755e7dd3df7b037088f8b8236a4602d59" dependencies = [ "alloy-eips", "alloy-primitives", @@ -564,9 +595,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-trace" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecd8b4877ef520c138af702097477cdd19504a8e1e4675ba37e92ba40f2d3c6f" +checksum = "db32f30a55ea4fa9d893127a84eef52fc54d23acb34c1a5a39bfe9bd95fbc149" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", @@ -578,9 +609,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-txpool" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d4ab49acf90a71f7fb894dc5fd485f1f07a1e348966c714c4d1e0b7478850a8" +checksum = "af1588d8d799095a9bd55d9045b76add042ab725c37316a77da933683754aa4b" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", @@ -590,9 +621,9 @@ dependencies = [ [[package]] name = "alloy-serde" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dfa4a7ccf15b2492bb68088692481fd6b2604ccbee1d0d6c44c21427ae4df83" +checksum = "43a89fd4cc3f96b3c5c0dd1cebeb63323e4659bbdc837117fa3fd5ac168df7d9" dependencies = [ "alloy-primitives", "arbitrary", @@ -602,9 +633,9 @@ dependencies = [ [[package]] name = "alloy-signer" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e10aec39d60dc27edcac447302c7803d2371946fb737245320a05b78eb2fafd" +checksum = "532010243a96d1f8593c2246ec3971bc52303884fa1e43ca0a776798ba178910" dependencies = [ "alloy-primitives", "async-trait", @@ -616,9 +647,9 @@ dependencies = [ [[package]] name = "alloy-signer-local" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8396f6dff60700bc1d215ee03d86ff56de268af96e2bf833a14d0bafcab9882" +checksum = "e8080c0ab2dc729b0cbb183843d08e78d2a1629140c9fc16234d2272abb483bd" dependencies = [ "alloy-consensus", "alloy-network", @@ -704,9 +735,9 @@ dependencies = [ [[package]] name = "alloy-transport" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f99acddb34000d104961897dbb0240298e8b775a7efffb9fda2a1a3efedd65b3" +checksum = "b6f295f4b745fb9e4e663d70bc57aed991288912c7aaaf25767def921050ee43" dependencies = [ "alloy-json-rpc", "base64 0.22.1", @@ -724,9 +755,9 @@ dependencies = [ [[package]] name = "alloy-transport-http" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dc013132e34eeadaa0add7e74164c1503988bfba8bae885b32e0918ba85a8a6" +checksum = "39139015a5ec127d9c895b49b484608e27fe4538544f84cdf5eae0bd36339bc6" dependencies = [ "alloy-json-rpc", "alloy-transport", @@ -739,9 +770,9 @@ dependencies = [ [[package]] name = "alloy-transport-ipc" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "063edc0660e81260653cc6a95777c29d54c2543a668aa5da2359fb450d25a1ba" +checksum = "d9b4f865b13bb8648e93f812b19b74838b9165212a2beb95fc386188c443a5e3" dependencies = [ "alloy-json-rpc", "alloy-pubsub", @@ -758,9 +789,9 @@ dependencies = [ [[package]] name = "alloy-transport-ws" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abd170e600801116d5efe64f74a4fc073dbbb35c807013a7d0a388742aeebba0" +checksum = "6af91e3521b8b3eac26809b1c6f9b86e3ed455dfab812f036836aabdf709b921" dependencies = [ "alloy-pubsub", "alloy-transport", @@ -5297,9 +5328,9 @@ checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" [[package]] name = "op-alloy-consensus" -version = "0.6.8" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fce158d886815d419222daa67fcdf949a34f7950653a4498ebeb4963331f70ed" +checksum = "75353c94e7515fac7d3c280bae56bff3375784a05cb44b317260606292ff6ba9" dependencies = [ "alloy-consensus", "alloy-eips", @@ -5315,9 +5346,9 @@ dependencies = [ [[package]] name = "op-alloy-genesis" -version = "0.6.8" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2734e9a65efb90fe4520303f984c124766b7d2f2e5dd51cbe54d6269c85a3c91" +checksum = "f24feef0404861c836b8fc0a3eb0cf6f20507e63ab59a61eeb1491c0f57bc352" dependencies = [ "alloy-consensus", "alloy-eips", @@ -5330,9 +5361,9 @@ dependencies = [ [[package]] name = "op-alloy-network" -version = "0.6.8" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87e4aef8ed017004a176ab1de49df419f59c0fb4a6ce3b693a10fe099fe1afe7" +checksum = "3dda5a5c4bc786f35f6c53ba611863a889790cc40a07c8160465072026795cba" dependencies = [ "alloy-consensus", "alloy-network", @@ -5345,9 +5376,9 @@ dependencies = [ [[package]] name = "op-alloy-protocol" -version = "0.6.8" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c68a3e2770890da3ad2fd20d7fe0c8e15672707577b4168a60e388c8eceaca0" +checksum = "ef2ab185601941f4ed04418d71e42b220a9c59353c8fb98ba8993c42590c6742" dependencies = [ "alloc-no-stdlib", "alloy-consensus", @@ -5357,6 +5388,7 @@ dependencies = [ "alloy-serde", "async-trait", "brotli", + "cfg-if", "miniz_oxide", "op-alloy-consensus", "op-alloy-genesis", @@ -5368,9 +5400,9 @@ dependencies = [ [[package]] name = "op-alloy-rpc-types" -version = "0.6.8" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "060ebeaea8c772e396215f69bb86d231ec8b7f36aca0dd6ce367ceaa9a8c33e6" +checksum = "680a86b63fe4c45fbd5dbf1ac6779409565211c4b234d20af94cf1f79d11f23a" dependencies = [ "alloy-consensus", "alloy-eips", @@ -5387,9 +5419,9 @@ dependencies = [ [[package]] name = "op-alloy-rpc-types-engine" -version = "0.6.8" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "864dbd5511ef4ef00b6c2c980739259b25b24048007b7751ca0069b30b1e3fee" +checksum = "eeff9cf6fcdf8ef7183f254f9ad59b6e87af5084f21dfa17ba00c4448a84ddf1" dependencies = [ "alloy-eips", "alloy-primitives", @@ -7312,6 +7344,7 @@ dependencies = [ "futures", "itertools 0.13.0", "pin-project", + "reth-consensus-common", "reth-engine-primitives", "reth-errors", "reth-ethereum-forks", @@ -8301,6 +8334,7 @@ dependencies = [ "op-alloy-consensus", "reth-chainspec", "reth-consensus", + "reth-consensus-common", "reth-ethereum-forks", "reth-evm", "reth-execution-errors", @@ -9519,9 +9553,9 @@ dependencies = [ [[package]] name = "revm-inspectors" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "747291a18ad6726a08dd73f8b6a6b3a844db582ecae2063ccf0a04880c44f482" +checksum = "41bbeb6004cc4ed48d27756f0479011df91a6f5642a3abab9309eda5ce67c4ad" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", diff --git a/Cargo.toml b/Cargo.toml index 0f6193812c41..d0f32114944b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -423,7 +423,7 @@ reth-trie-sparse = { path = "crates/trie/sparse" } # revm revm = { version = "18.0.0", features = ["std"], default-features = false } -revm-inspectors = "0.11.0" +revm-inspectors = "0.12.0" revm-primitives = { version = "14.0.0", features = [ "std", ], default-features = false } @@ -436,46 +436,46 @@ alloy-rlp = { version = "0.3.4", default-features = false } alloy-sol-types = "0.8.11" alloy-trie = { version = "0.7", default-features = false } -alloy-consensus = { version = "0.6.4", default-features = false } -alloy-contract = { version = "0.6.4", default-features = false } -alloy-eips = { version = "0.6.4", default-features = false } -alloy-genesis = { version = "0.6.4", default-features = false } -alloy-json-rpc = { version = "0.6.4", default-features = false } -alloy-network = { version = "0.6.4", default-features = false } -alloy-network-primitives = { version = "0.6.4", default-features = false } -alloy-node-bindings = { version = "0.6.4", default-features = false } -alloy-provider = { version = "0.6.4", features = [ +alloy-consensus = { version = "0.7.0", default-features = false } +alloy-contract = { version = "0.7.0", default-features = false } +alloy-eips = { version = "0.7.0", default-features = false } +alloy-genesis = { version = "0.7.0", default-features = false } +alloy-json-rpc = { version = "0.7.0", default-features = false } +alloy-network = { version = "0.7.0", default-features = false } +alloy-network-primitives = { version = "0.7.0", default-features = false } +alloy-node-bindings = { version = "0.7.0", default-features = false } +alloy-provider = { version = "0.7.0", features = [ "reqwest", ], default-features = false } -alloy-pubsub = { version = "0.6.4", default-features = false } -alloy-rpc-client = { version = "0.6.4", default-features = false } -alloy-rpc-types = { version = "0.6.4", features = [ +alloy-pubsub = { version = "0.7.0", default-features = false } +alloy-rpc-client = { version = "0.7.0", default-features = false } +alloy-rpc-types = { version = "0.7.0", features = [ "eth", ], default-features = false } -alloy-rpc-types-admin = { version = "0.6.4", default-features = false } -alloy-rpc-types-anvil = { version = "0.6.4", default-features = false } -alloy-rpc-types-beacon = { version = "0.6.4", default-features = false } -alloy-rpc-types-debug = { version = "0.6.4", default-features = false } -alloy-rpc-types-engine = { version = "0.6.4", default-features = false } -alloy-rpc-types-eth = { version = "0.6.4", default-features = false } -alloy-rpc-types-mev = { version = "0.6.4", default-features = false } -alloy-rpc-types-trace = { version = "0.6.4", default-features = false } -alloy-rpc-types-txpool = { version = "0.6.4", default-features = false } -alloy-serde = { version = "0.6.4", default-features = false } -alloy-signer = { version = "0.6.4", default-features = false } -alloy-signer-local = { version = "0.6.4", default-features = false } -alloy-transport = { version = "0.6.4" } -alloy-transport-http = { version = "0.6.4", features = [ +alloy-rpc-types-admin = { version = "0.7.0", default-features = false } +alloy-rpc-types-anvil = { version = "0.7.0", default-features = false } +alloy-rpc-types-beacon = { version = "0.7.0", default-features = false } +alloy-rpc-types-debug = { version = "0.7.0", default-features = false } +alloy-rpc-types-engine = { version = "0.7.0", default-features = false } +alloy-rpc-types-eth = { version = "0.7.0", default-features = false } +alloy-rpc-types-mev = { version = "0.7.0", default-features = false } +alloy-rpc-types-trace = { version = "0.7.0", default-features = false } +alloy-rpc-types-txpool = { version = "0.7.0", default-features = false } +alloy-serde = { version = "0.7.0", default-features = false } +alloy-signer = { version = "0.7.0", default-features = false } +alloy-signer-local = { version = "0.7.0", default-features = false } +alloy-transport = { version = "0.7.0" } +alloy-transport-http = { version = "0.7.0", features = [ "reqwest-rustls-tls", ], default-features = false } -alloy-transport-ipc = { version = "0.6.4", default-features = false } -alloy-transport-ws = { version = "0.6.4", default-features = false } +alloy-transport-ipc = { version = "0.7.0", default-features = false } +alloy-transport-ws = { version = "0.7.0", default-features = false } # op -op-alloy-rpc-types = "0.6.7" -op-alloy-rpc-types-engine = "0.6.7" -op-alloy-network = "0.6.7" -op-alloy-consensus = "0.6.7" +op-alloy-rpc-types = "0.7.1" +op-alloy-rpc-types-engine = "0.7.1" +op-alloy-network = "0.7.1" +op-alloy-consensus = "0.7.1" # misc aquamarine = "0.6" @@ -611,35 +611,36 @@ tikv-jemalloc-ctl = "0.6" tikv-jemallocator = "0.6" tracy-client = "0.17.3" -#[patch.crates-io] -#alloy-consensus = { git = "https://github.com/alloy-rs/alloy", rev = "a971b3a" } -#alloy-eips = { git = "https://github.com/alloy-rs/alloy", rev = "a971b3a" } -#alloy-genesis = { git = "https://github.com/alloy-rs/alloy", rev = "a971b3a" } -#alloy-json-rpc = { git = "https://github.com/alloy-rs/alloy", rev = "a971b3a" } -#alloy-network = { git = "https://github.com/alloy-rs/alloy", rev = "a971b3a" } -#alloy-node-bindings = { git = "https://github.com/alloy-rs/alloy", rev = "a971b3a" } -#alloy-provider = { git = "https://github.com/alloy-rs/alloy", rev = "a971b3a" } -#alloy-pubsub = { git = "https://github.com/alloy-rs/alloy", rev = "a971b3a" } -#alloy-rpc-client = { git = "https://github.com/alloy-rs/alloy", rev = "a971b3a" } -#alloy-rpc-types = { git = "https://github.com/alloy-rs/alloy", rev = "a971b3a" } -#alloy-rpc-types-admin = { git = "https://github.com/alloy-rs/alloy", rev = "a971b3a" } -#alloy-rpc-types-anvil = { git = "https://github.com/alloy-rs/alloy", rev = "a971b3a" } -#alloy-rpc-types-beacon = { git = "https://github.com/alloy-rs/alloy", rev = "a971b3a" } -#alloy-rpc-types-debug = { git = "https://github.com/alloy-rs/alloy", rev = "a971b3a" } -#alloy-rpc-types-engine = { git = "https://github.com/alloy-rs/alloy", rev = "a971b3a" } -#alloy-rpc-types-eth = { git = "https://github.com/alloy-rs/alloy", rev = "a971b3a" } -#alloy-rpc-types-mev = { git = "https://github.com/alloy-rs/alloy", rev = "a971b3a" } -#alloy-rpc-types-trace = { git = "https://github.com/alloy-rs/alloy", rev = "a971b3a" } -#alloy-rpc-types-txpool = { git = "https://github.com/alloy-rs/alloy", rev = "a971b3a" } -#alloy-serde = { git = "https://github.com/alloy-rs/alloy", rev = "a971b3a" } -#alloy-signer = { git = "https://github.com/alloy-rs/alloy", rev = "a971b3a" } -#alloy-signer-local = { git = "https://github.com/alloy-rs/alloy", rev = "a971b3a" } -#alloy-transport = { git = "https://github.com/alloy-rs/alloy", rev = "a971b3a" } -#alloy-transport-http = { git = "https://github.com/alloy-rs/alloy", rev = "a971b3a" } -#alloy-transport-ipc = { git = "https://github.com/alloy-rs/alloy", rev = "a971b3a" } -#alloy-transport-ws = { git = "https://github.com/alloy-rs/alloy", rev = "a971b3a" } - -#op-alloy-consensus = { git = "https://github.com/alloy-rs/op-alloy", rev = "6a042e7681b1" } -#op-alloy-network = { git = "https://github.com/alloy-rs/op-alloy", rev = "6a042e7681b1" } -#op-alloy-rpc-types = { git = "https://github.com/alloy-rs/op-alloy", rev = "6a042e7681b1" } -#op-alloy-rpc-types-engine = { git = "https://github.com/alloy-rs/op-alloy", rev = "6a042e7681b1" } +# [patch.crates-io] +# alloy-consensus = { git = "https://github.com/alloy-rs/alloy", rev = "5492e40" } +# alloy-eips = { git = "https://github.com/alloy-rs/alloy", rev = "5492e40" } +# alloy-genesis = { git = "https://github.com/alloy-rs/alloy", rev = "5492e40" } +# alloy-json-rpc = { git = "https://github.com/alloy-rs/alloy", rev = "5492e40" } +# alloy-network = { git = "https://github.com/alloy-rs/alloy", rev = "5492e40" } +# alloy-network-primitives = { git = "https://github.com/alloy-rs/alloy", rev = "5492e40" } +# alloy-node-bindings = { git = "https://github.com/alloy-rs/alloy", rev = "5492e40" } +# alloy-provider = { git = "https://github.com/alloy-rs/alloy", rev = "5492e40" } +# alloy-pubsub = { git = "https://github.com/alloy-rs/alloy", rev = "5492e40" } +# alloy-rpc-client = { git = "https://github.com/alloy-rs/alloy", rev = "5492e40" } +# alloy-rpc-types = { git = "https://github.com/alloy-rs/alloy", rev = "5492e40" } +# alloy-rpc-types-admin = { git = "https://github.com/alloy-rs/alloy", rev = "5492e40" } +# alloy-rpc-types-anvil = { git = "https://github.com/alloy-rs/alloy", rev = "5492e40" } +# alloy-rpc-types-beacon = { git = "https://github.com/alloy-rs/alloy", rev = "5492e40" } +# alloy-rpc-types-debug = { git = "https://github.com/alloy-rs/alloy", rev = "5492e40" } +# alloy-rpc-types-engine = { git = "https://github.com/alloy-rs/alloy", rev = "5492e40" } +# alloy-rpc-types-eth = { git = "https://github.com/alloy-rs/alloy", rev = "5492e40" } +# alloy-rpc-types-mev = { git = "https://github.com/alloy-rs/alloy", rev = "5492e40" } +# alloy-rpc-types-trace = { git = "https://github.com/alloy-rs/alloy", rev = "5492e40" } +# alloy-rpc-types-txpool = { git = "https://github.com/alloy-rs/alloy", rev = "5492e40" } +# alloy-serde = { git = "https://github.com/alloy-rs/alloy", rev = "5492e40" } +# alloy-signer = { git = "https://github.com/alloy-rs/alloy", rev = "5492e40" } +# alloy-signer-local = { git = "https://github.com/alloy-rs/alloy", rev = "5492e40" } +# alloy-transport = { git = "https://github.com/alloy-rs/alloy", rev = "5492e40" } +# alloy-transport-http = { git = "https://github.com/alloy-rs/alloy", rev = "5492e40" } +# alloy-transport-ipc = { git = "https://github.com/alloy-rs/alloy", rev = "5492e40" } +# alloy-transport-ws = { git = "https://github.com/alloy-rs/alloy", rev = "5492e40" } + +# op-alloy-consensus = { git = "https://github.com/alloy-rs/op-alloy", rev = "debfc29" } +# op-alloy-network = { git = "https://github.com/alloy-rs/op-alloy", rev = "debfc29" } +# op-alloy-rpc-types = { git = "https://github.com/alloy-rs/op-alloy", rev = "debfc29" } +# op-alloy-rpc-types-engine = { git = "https://github.com/alloy-rs/op-alloy", rev = "debfc29" } diff --git a/bin/reth/src/commands/debug_cmd/build_block.rs b/bin/reth/src/commands/debug_cmd/build_block.rs index e08c32b93a4f..c7e1be893af8 100644 --- a/bin/reth/src/commands/debug_cmd/build_block.rs +++ b/bin/reth/src/commands/debug_cmd/build_block.rs @@ -224,6 +224,8 @@ impl> Command { suggested_fee_recipient: self.suggested_fee_recipient, // TODO: add support for withdrawals withdrawals: None, + target_blobs_per_block: None, + max_blobs_per_block: None, }; let payload_config = PayloadConfig::new( Arc::new(SealedHeader::new(best_block.header().clone(), best_block.hash())), diff --git a/crates/chain-state/src/in_memory.rs b/crates/chain-state/src/in_memory.rs index 349758725aaf..3cd6f4645628 100644 --- a/crates/chain-state/src/in_memory.rs +++ b/crates/chain-state/src/in_memory.rs @@ -12,8 +12,8 @@ use reth_chainspec::ChainInfo; use reth_execution_types::{Chain, ExecutionOutcome}; use reth_metrics::{metrics::Gauge, Metrics}; use reth_primitives::{ - BlockWithSenders, EthPrimitives, HeaderExt, NodePrimitives, Receipts, SealedBlock, - SealedBlockFor, SealedBlockWithSenders, SealedHeader, TransactionMeta, + BlockWithSenders, EthPrimitives, NodePrimitives, Receipts, SealedBlock, SealedBlockFor, + SealedBlockWithSenders, SealedHeader, TransactionMeta, }; use reth_primitives_traits::{Block, BlockBody as _, SignedTransaction}; use reth_storage_api::StateProviderBox; diff --git a/crates/consensus/common/src/validation.rs b/crates/consensus/common/src/validation.rs index 8035f8bf61c3..dce7d2579540 100644 --- a/crates/consensus/common/src/validation.rs +++ b/crates/consensus/common/src/validation.rs @@ -495,7 +495,8 @@ mod tests { blob_gas_used: None, excess_blob_gas: None, parent_beacon_block_root: None, - requests_hash: None + requests_hash: None, + target_blobs_per_block: None, }; // size: 0x9b5 diff --git a/crates/engine/local/src/payload.rs b/crates/engine/local/src/payload.rs index 5111360d5bf6..6355a2a00af2 100644 --- a/crates/engine/local/src/payload.rs +++ b/crates/engine/local/src/payload.rs @@ -39,6 +39,8 @@ where .chain_spec .is_cancun_active_at_timestamp(timestamp) .then(B256::random), + target_blobs_per_block: None, + max_blobs_per_block: None, } } } diff --git a/crates/engine/util/Cargo.toml b/crates/engine/util/Cargo.toml index 6eb22340ec10..54f9321f239a 100644 --- a/crates/engine/util/Cargo.toml +++ b/crates/engine/util/Cargo.toml @@ -14,6 +14,7 @@ workspace = true # reth reth-primitives.workspace = true reth-errors.workspace = true +reth-consensus-common.workspace = true reth-fs-util.workspace = true reth-rpc-types-compat.workspace = true reth-engine-primitives.workspace = true diff --git a/crates/engine/util/src/reorg.rs b/crates/engine/util/src/reorg.rs index 20e2b21446ae..8e9a195a1818 100644 --- a/crates/engine/util/src/reorg.rs +++ b/crates/engine/util/src/reorg.rs @@ -415,11 +415,12 @@ where transactions_root: proofs::calculate_transaction_root(&transactions), receipts_root: outcome.receipts_root_slow(reorg_target.header.number).unwrap(), logs_bloom: outcome.block_logs_bloom(reorg_target.header.number).unwrap(), - requests_hash: None, // TODO(prague) gas_used: cumulative_gas_used, blob_gas_used: blob_gas_used.map(Into::into), excess_blob_gas: excess_blob_gas.map(Into::into), state_root: state_provider.state_root(hashed_state)?, + requests_hash: None, // TODO(prague) + target_blobs_per_block: None, // TODO(prague) }, body: BlockBody { transactions, diff --git a/crates/ethereum/engine-primitives/src/payload.rs b/crates/ethereum/engine-primitives/src/payload.rs index 094a1df26577..ff07856f1ca6 100644 --- a/crates/ethereum/engine-primitives/src/payload.rs +++ b/crates/ethereum/engine-primitives/src/payload.rs @@ -332,6 +332,8 @@ mod tests { .unwrap(), withdrawals: None, parent_beacon_block_root: None, + target_blobs_per_block: None, + max_blobs_per_block: None, }; // Verify that the generated payload ID matches the expected value @@ -369,6 +371,8 @@ mod tests { }, ]), parent_beacon_block_root: None, + target_blobs_per_block: None, + max_blobs_per_block: None, }; // Verify that the generated payload ID matches the expected value @@ -401,6 +405,8 @@ mod tests { ) .unwrap(), ), + target_blobs_per_block: None, + max_blobs_per_block: None, }; // Verify that the generated payload ID matches the expected value diff --git a/crates/ethereum/evm/src/execute.rs b/crates/ethereum/evm/src/execute.rs index fdbc9eefd3dd..3bfc3cb2ed65 100644 --- a/crates/ethereum/evm/src/execute.rs +++ b/crates/ethereum/evm/src/execute.rs @@ -4,7 +4,7 @@ use crate::{ dao_fork::{DAO_HARDFORK_BENEFICIARY, DAO_HARDKFORK_ACCOUNTS}, EthEvmConfig, }; -use alloc::{boxed::Box, sync::Arc, vec, vec::Vec}; +use alloc::{boxed::Box, sync::Arc, vec::Vec}; use alloy_consensus::Transaction as _; use alloy_eips::eip7685::Requests; use core::fmt::Display; @@ -232,7 +232,12 @@ where let deposit_requests = crate::eip6110::parse_deposits_from_receipts(&self.chain_spec, receipts)?; - let mut requests = Requests::new(vec![deposit_requests]); + let mut requests = Requests::default(); + + if !deposit_requests.is_empty() { + requests.push_request(core::iter::once(0).chain(deposit_requests).collect()); + } + requests.extend(self.system_caller.apply_post_execution_changes(&mut evm)?); requests } else { @@ -1127,9 +1132,9 @@ mod tests { let receipt = receipts.first().unwrap(); assert!(receipt.success); - assert!(requests[0].is_empty(), "there should be no deposits"); - assert!(!requests[1].is_empty(), "there should be a withdrawal"); - assert!(requests[2].is_empty(), "there should be no consolidations"); + // There should be exactly one entry with withdrawal requests + assert_eq!(requests.len(), 1); + assert_eq!(requests[0][0], 1); } #[test] diff --git a/crates/ethereum/node/tests/e2e/rpc.rs b/crates/ethereum/node/tests/e2e/rpc.rs index 54bfbc8205e5..664f447cf25c 100644 --- a/crates/ethereum/node/tests/e2e/rpc.rs +++ b/crates/ethereum/node/tests/e2e/rpc.rs @@ -1,5 +1,5 @@ use crate::utils::eth_payload_attributes; -use alloy_eips::{calc_next_block_base_fee, eip2718::Encodable2718}; +use alloy_eips::{calc_next_block_base_fee, eip2718::Encodable2718, eip4844}; use alloy_primitives::{Address, B256, U256}; use alloy_provider::{network::EthereumWallet, Provider, ProviderBuilder, SendableTx}; use alloy_rpc_types_beacon::relay::{ @@ -240,6 +240,7 @@ async fn test_flashbots_validate_v4() -> eyre::Result<()> { execution_payload: block_to_payload_v3(payload.block().clone()), blobs_bundle: BlobsBundleV1::new([]), execution_requests: payload.requests().unwrap_or_default().to_vec(), + target_blobs_per_block: eip4844::TARGET_BLOBS_PER_BLOCK, signature: Default::default(), }, parent_beacon_block_root: attrs.parent_beacon_block_root.unwrap(), diff --git a/crates/ethereum/node/tests/e2e/utils.rs b/crates/ethereum/node/tests/e2e/utils.rs index ee451b8f3c5b..84741a46aa69 100644 --- a/crates/ethereum/node/tests/e2e/utils.rs +++ b/crates/ethereum/node/tests/e2e/utils.rs @@ -26,6 +26,8 @@ pub(crate) fn eth_payload_attributes(timestamp: u64) -> EthPayloadBuilderAttribu suggested_fee_recipient: Address::ZERO, withdrawals: Some(vec![]), parent_beacon_block_root: Some(B256::ZERO), + target_blobs_per_block: None, + max_blobs_per_block: None, }; EthPayloadBuilderAttributes::new(B256::ZERO, attributes) } diff --git a/crates/ethereum/payload/src/lib.rs b/crates/ethereum/payload/src/lib.rs index 43bb04504884..a5c6434310e8 100644 --- a/crates/ethereum/payload/src/lib.rs +++ b/crates/ethereum/payload/src/lib.rs @@ -10,7 +10,10 @@ #![allow(clippy::useless_let_if_seq)] use alloy_consensus::{Header, EMPTY_OMMER_ROOT_HASH}; -use alloy_eips::{eip4844::MAX_DATA_GAS_PER_BLOCK, eip7685::Requests, merge::BEACON_NONCE}; +use alloy_eips::{ + eip4844::MAX_DATA_GAS_PER_BLOCK, eip7002::WITHDRAWAL_REQUEST_TYPE, + eip7251::CONSOLIDATION_REQUEST_TYPE, eip7685::Requests, merge::BEACON_NONCE, +}; use alloy_primitives::U256; use reth_basic_payload_builder::{ commit_withdrawals, is_better_payload, BuildArguments, BuildOutcome, PayloadBuilder, @@ -365,7 +368,27 @@ where ) .map_err(|err| PayloadBuilderError::Internal(err.into()))?; - Some(Requests::new(vec![deposit_requests, withdrawal_requests, consolidation_requests])) + let mut requests = Requests::default(); + + if !deposit_requests.is_empty() { + requests.push_request(core::iter::once(0).chain(deposit_requests).collect()); + } + + if !withdrawal_requests.is_empty() { + requests.push_request( + core::iter::once(WITHDRAWAL_REQUEST_TYPE).chain(withdrawal_requests).collect(), + ); + } + + if !consolidation_requests.is_empty() { + requests.push_request( + core::iter::once(CONSOLIDATION_REQUEST_TYPE) + .chain(consolidation_requests) + .collect(), + ); + } + + Some(requests) } else { None }; @@ -452,6 +475,7 @@ where blob_gas_used: blob_gas_used.map(Into::into), excess_blob_gas: excess_blob_gas.map(Into::into), requests_hash, + target_blobs_per_block: None, }; let withdrawals = chain_spec diff --git a/crates/evm/execution-types/src/execution_outcome.rs b/crates/evm/execution-types/src/execution_outcome.rs index 412269ace9cd..7acbfea33669 100644 --- a/crates/evm/execution-types/src/execution_outcome.rs +++ b/crates/evm/execution-types/src/execution_outcome.rs @@ -334,7 +334,7 @@ impl ExecutionOutcome { } } -impl ExecutionOutcome { +impl> ExecutionOutcome { /// Returns an iterator over all block logs. pub fn logs(&self, block_number: BlockNumber) -> Option> { let index = self.block_number_to_index(block_number)?; diff --git a/crates/evm/src/system_calls/mod.rs b/crates/evm/src/system_calls/mod.rs index fd9a1bf5f229..2a5b80ad66d9 100644 --- a/crates/evm/src/system_calls/mod.rs +++ b/crates/evm/src/system_calls/mod.rs @@ -1,9 +1,11 @@ //! System contract call functions. use crate::ConfigureEvm; -use alloc::{boxed::Box, sync::Arc, vec}; +use alloc::{boxed::Box, sync::Arc}; use alloy_consensus::Header; -use alloy_eips::eip7685::Requests; +use alloy_eips::{ + eip7002::WITHDRAWAL_REQUEST_TYPE, eip7251::CONSOLIDATION_REQUEST_TYPE, eip7685::Requests, +}; use alloy_primitives::Bytes; use core::fmt::Display; use reth_chainspec::EthereumHardforks; @@ -127,13 +129,27 @@ where DB: Database + DatabaseCommit, DB::Error: Display, { - // todo + let mut requests = Requests::default(); + // Collect all EIP-7685 requests let withdrawal_requests = self.apply_withdrawal_requests_contract_call(evm)?; + if !withdrawal_requests.is_empty() { + requests.push_request( + core::iter::once(WITHDRAWAL_REQUEST_TYPE).chain(withdrawal_requests).collect(), + ); + } // Collect all EIP-7251 requests let consolidation_requests = self.apply_consolidation_requests_contract_call(evm)?; - Ok(Requests::new(vec![withdrawal_requests, consolidation_requests])) + if !consolidation_requests.is_empty() { + requests.push_request( + core::iter::once(CONSOLIDATION_REQUEST_TYPE) + .chain(consolidation_requests) + .collect(), + ); + } + + Ok(requests) } /// Applies the pre-block call to the EIP-2935 blockhashes contract. diff --git a/crates/net/eth-wire-types/src/blocks.rs b/crates/net/eth-wire-types/src/blocks.rs index 97bbe36b3d61..e6506e86ad7c 100644 --- a/crates/net/eth-wire-types/src/blocks.rs +++ b/crates/net/eth-wire-types/src/blocks.rs @@ -258,7 +258,8 @@ mod tests { blob_gas_used: None, excess_blob_gas: None, parent_beacon_block_root: None, - requests_hash: None + requests_hash: None, + target_blobs_per_block: None, }, ]), }.encode(&mut data); @@ -293,7 +294,8 @@ mod tests { blob_gas_used: None, excess_blob_gas: None, parent_beacon_block_root: None, - requests_hash: None + requests_hash: None, + target_blobs_per_block: None, }, ]), }; @@ -393,7 +395,8 @@ mod tests { blob_gas_used: None, excess_blob_gas: None, parent_beacon_block_root: None, - requests_hash: None + requests_hash: None, + target_blobs_per_block: None, }, ], withdrawals: None, @@ -468,7 +471,8 @@ mod tests { blob_gas_used: None, excess_blob_gas: None, parent_beacon_block_root: None, - requests_hash: None + requests_hash: None, + target_blobs_per_block: None, }, ], withdrawals: None, diff --git a/crates/net/eth-wire-types/src/header.rs b/crates/net/eth-wire-types/src/header.rs index 9fa3b150d9e1..883db625c6e6 100644 --- a/crates/net/eth-wire-types/src/header.rs +++ b/crates/net/eth-wire-types/src/header.rs @@ -142,7 +142,8 @@ mod tests { blob_gas_used: None, excess_blob_gas: None, parent_beacon_block_root: None, - requests_hash: None + requests_hash: None, + target_blobs_per_block: None, }; assert_eq!(header.hash_slow(), expected_hash); } @@ -256,6 +257,7 @@ mod tests { excess_blob_gas: Some(0), parent_beacon_block_root: None, requests_hash: None, + target_blobs_per_block: None, }; let header = Header::decode(&mut data.as_slice()).unwrap(); @@ -296,6 +298,7 @@ mod tests { blob_gas_used: Some(0), excess_blob_gas: Some(0x1600000), requests_hash: None, + target_blobs_per_block: None, }; let header = Header::decode(&mut data.as_slice()).unwrap(); diff --git a/crates/optimism/evm/Cargo.toml b/crates/optimism/evm/Cargo.toml index b5d6fac50733..d03a1c6490cb 100644 --- a/crates/optimism/evm/Cargo.toml +++ b/crates/optimism/evm/Cargo.toml @@ -21,6 +21,7 @@ reth-execution-errors.workspace = true reth-execution-types.workspace = true reth-prune-types.workspace = true reth-consensus.workspace = true +reth-consensus-common.workspace = true # ethereum alloy-eips.workspace = true diff --git a/crates/optimism/node/src/engine.rs b/crates/optimism/node/src/engine.rs index 57b76b904bd3..063ac3617af5 100644 --- a/crates/optimism/node/src/engine.rs +++ b/crates/optimism/node/src/engine.rs @@ -229,6 +229,8 @@ mod test { suggested_fee_recipient: Address::ZERO, withdrawals: Some(vec![]), parent_beacon_block_root: Some(B256::ZERO), + target_blobs_per_block: None, + max_blobs_per_block: None, }, } } diff --git a/crates/optimism/node/src/utils.rs b/crates/optimism/node/src/utils.rs index 9cadcdcf7a15..147aaac59dcc 100644 --- a/crates/optimism/node/src/utils.rs +++ b/crates/optimism/node/src/utils.rs @@ -55,6 +55,8 @@ pub fn optimism_payload_attributes(timestamp: u64) -> OpPayloadBuilderAttributes suggested_fee_recipient: Address::ZERO, withdrawals: Some(vec![]), parent_beacon_block_root: Some(B256::ZERO), + target_blobs_per_block: None, + max_blobs_per_block: None, }; OpPayloadBuilderAttributes { diff --git a/crates/optimism/payload/src/builder.rs b/crates/optimism/payload/src/builder.rs index fbf99c78d9e7..aeaa8ef40790 100644 --- a/crates/optimism/payload/src/builder.rs +++ b/crates/optimism/payload/src/builder.rs @@ -410,6 +410,7 @@ where blob_gas_used, excess_blob_gas, requests_hash: None, + target_blobs_per_block: None, }; // seal the block diff --git a/crates/optimism/payload/src/payload.rs b/crates/optimism/payload/src/payload.rs index 1a951abadcae..e243745cea68 100644 --- a/crates/optimism/payload/src/payload.rs +++ b/crates/optimism/payload/src/payload.rs @@ -370,7 +370,9 @@ mod tests { prev_randao: b256!("9158595abbdab2c90635087619aa7042bbebe47642dfab3c9bfb934f6b082765"), suggested_fee_recipient: address!("4200000000000000000000000000000000000011"), withdrawals: Some([].into()), - parent_beacon_block_root: b256!("8fe0193b9bf83cb7e5a08538e494fecc23046aab9a497af3704f4afdae3250ff").into() + parent_beacon_block_root: b256!("8fe0193b9bf83cb7e5a08538e494fecc23046aab9a497af3704f4afdae3250ff").into(), + target_blobs_per_block: None, + max_blobs_per_block: None, }, transactions: Some([bytes!("7ef8f8a0dc19cfa777d90980e4875d0a548a881baaa3f83f14d1bc0d3038bc329350e54194deaddeaddeaddeaddeaddeaddeaddeaddead00019442000000000000000000000000000000000000158080830f424080b8a4440a5e20000f424000000000000000000000000300000000670d6d890000000000000125000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000014bf9181db6e381d4384bbf69c48b0ee0eed23c6ca26143c6d2544f9d39997a590000000000000000000000007f83d659683caf2767fd3c720981d51f5bc365bc")].into()), no_tx_pool: None, diff --git a/crates/optimism/primitives/src/bedrock.rs b/crates/optimism/primitives/src/bedrock.rs index 204b34d33782..3a345abe20ab 100644 --- a/crates/optimism/primitives/src/bedrock.rs +++ b/crates/optimism/primitives/src/bedrock.rs @@ -85,6 +85,7 @@ pub const BEDROCK_HEADER: Header = Header { excess_blob_gas: None, parent_beacon_block_root: None, requests_hash: None, + target_blobs_per_block: None, }; /// Bedrock total difficulty on Optimism Mainnet. diff --git a/crates/optimism/primitives/src/transaction/mod.rs b/crates/optimism/primitives/src/transaction/mod.rs index 070b3d984e0b..5861a3229fe8 100644 --- a/crates/optimism/primitives/src/transaction/mod.rs +++ b/crates/optimism/primitives/src/transaction/mod.rs @@ -123,6 +123,10 @@ impl alloy_consensus::Transaction for OpTransaction { self.0.kind() } + fn is_create(&self) -> bool { + self.0.is_create() + } + fn value(&self) -> Uint<256, 4> { self.0.value() } diff --git a/crates/primitives-traits/src/receipt.rs b/crates/primitives-traits/src/receipt.rs index e2af40c447ed..435748c4e1bd 100644 --- a/crates/primitives-traits/src/receipt.rs +++ b/crates/primitives-traits/src/receipt.rs @@ -22,7 +22,7 @@ pub trait Receipt: + Clone + Default + fmt::Debug - + TxReceipt + + TxReceipt + alloy_rlp::Encodable + alloy_rlp::Decodable + MaybeSerde diff --git a/crates/primitives/src/alloy_compat.rs b/crates/primitives/src/alloy_compat.rs index a72c83996c01..06451c30b9e5 100644 --- a/crates/primitives/src/alloy_compat.rs +++ b/crates/primitives/src/alloy_compat.rs @@ -58,6 +58,7 @@ impl TryFrom for Block { excess_blob_gas, parent_beacon_block_root, requests_hash, + target_blobs_per_block, } = block.header.inner; Ok(Self { @@ -84,6 +85,7 @@ impl TryFrom for Block { excess_blob_gas, parent_beacon_block_root, requests_hash, + target_blobs_per_block, }, body: BlockBody { transactions, diff --git a/crates/primitives/src/receipt.rs b/crates/primitives/src/receipt.rs index 95d707d1b2d5..79e15b89d7d6 100644 --- a/crates/primitives/src/receipt.rs +++ b/crates/primitives/src/receipt.rs @@ -73,6 +73,8 @@ impl Receipt { } impl TxReceipt for Receipt { + type Log = Log; + fn status_or_post_state(&self) -> Eip658Value { self.success.into() } diff --git a/crates/primitives/src/traits.rs b/crates/primitives/src/traits.rs index ec4e75c8c6d0..73eabd8ec986 100644 --- a/crates/primitives/src/traits.rs +++ b/crates/primitives/src/traits.rs @@ -3,8 +3,8 @@ use crate::{ BlockWithSenders, SealedBlock, }; use alloc::vec::Vec; -use alloy_eips::{eip2718::Encodable2718, BlockNumHash}; -use reth_primitives_traits::{Block, BlockBody, BlockHeader, SealedHeader, SignedTransaction}; +use alloy_eips::eip2718::Encodable2718; +use reth_primitives_traits::{Block, BlockBody, SealedHeader, SignedTransaction}; use revm_primitives::{Address, B256}; /// Extension trait for [`reth_primitives_traits::Block`] implementations @@ -121,17 +121,3 @@ pub trait BlockBodyTxExt: BlockBody { } impl BlockBodyTxExt for T {} - -/// Extension trait for [`BlockHeader`] adding useful helper methods. -pub trait HeaderExt: BlockHeader { - /// TODO: remove once is released - /// - /// Returns the parent block's number and hash - /// - /// Note: for the genesis block the parent number is 0 and the parent hash is the zero hash. - fn parent_num_hash(&self) -> BlockNumHash { - BlockNumHash::new(self.number().saturating_sub(1), self.parent_hash()) - } -} - -impl HeaderExt for T {} diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index e1524aa1dc87..f4c4a0f2997e 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -308,7 +308,7 @@ impl Transaction { set_code_tx.eip2718_encode(signature, out); } #[cfg(feature = "optimism")] - Self::Deposit(deposit_tx) => deposit_tx.eip2718_encode(out), + Self::Deposit(deposit_tx) => deposit_tx.encode_2718(out), } } @@ -675,6 +675,18 @@ impl alloy_consensus::Transaction for Transaction { } } + fn is_create(&self) -> bool { + match self { + Self::Legacy(tx) => tx.is_create(), + Self::Eip2930(tx) => tx.is_create(), + Self::Eip1559(tx) => tx.is_create(), + Self::Eip4844(tx) => tx.is_create(), + Self::Eip7702(tx) => tx.is_create(), + #[cfg(feature = "optimism")] + Self::Deposit(tx) => tx.is_create(), + } + } + fn value(&self) -> U256 { match self { Self::Legacy(tx) => tx.value(), @@ -1392,6 +1404,10 @@ impl alloy_consensus::Transaction for TransactionSigned { self.deref().kind() } + fn is_create(&self) -> bool { + self.deref().is_create() + } + fn value(&self) -> U256 { self.deref().value() } diff --git a/crates/primitives/src/transaction/pooled.rs b/crates/primitives/src/transaction/pooled.rs index 979a55f2739e..5015f5b8e46c 100644 --- a/crates/primitives/src/transaction/pooled.rs +++ b/crates/primitives/src/transaction/pooled.rs @@ -525,6 +525,16 @@ impl alloy_consensus::Transaction for PooledTransactionsElement { } } + fn is_create(&self) -> bool { + match self { + Self::Legacy(tx) => tx.tx().is_create(), + Self::Eip2930(tx) => tx.tx().is_create(), + Self::Eip1559(tx) => tx.tx().is_create(), + Self::Eip7702(tx) => tx.tx().is_create(), + Self::BlobTransaction(tx) => tx.tx().is_create(), + } + } + fn value(&self) -> U256 { match self { Self::Legacy(tx) => tx.tx().value(), diff --git a/crates/revm/src/batch.rs b/crates/revm/src/batch.rs index 36708b5ff328..c980bdc987c3 100644 --- a/crates/revm/src/batch.rs +++ b/crates/revm/src/batch.rs @@ -3,7 +3,7 @@ use alloc::vec::Vec; use alloy_eips::eip7685::Requests; -use alloy_primitives::{map::HashSet, Address, BlockNumber}; +use alloy_primitives::{map::HashSet, Address, BlockNumber, Log}; use reth_execution_errors::{BlockExecutionError, InternalBlockExecutionError}; use reth_primitives::Receipts; use reth_primitives_traits::Receipt; @@ -131,7 +131,7 @@ impl BlockBatchRecord { /// Save receipts to the executor. pub fn save_receipts(&mut self, receipts: Vec) -> Result<(), BlockExecutionError> where - T: Receipt, + T: Receipt, { let mut receipts = receipts.into_iter().map(Some).collect(); // Prune receipts if necessary. @@ -144,7 +144,7 @@ impl BlockBatchRecord { /// Prune receipts according to the pruning configuration. fn prune_receipts(&mut self, receipts: &mut Vec>) -> Result<(), PruneSegmentError> where - T: Receipt, + T: Receipt, { let (Some(first_block), Some(tip)) = (self.first_block, self.tip) else { return Ok(()) }; diff --git a/crates/rpc/rpc-engine-api/src/engine_api.rs b/crates/rpc/rpc-engine-api/src/engine_api.rs index 1062363eafb8..8b57cb1f19ee 100644 --- a/crates/rpc/rpc-engine-api/src/engine_api.rs +++ b/crates/rpc/rpc-engine-api/src/engine_api.rs @@ -1,12 +1,17 @@ use crate::{ capabilities::EngineCapabilities, metrics::EngineApiMetrics, EngineApiError, EngineApiResult, }; -use alloy_eips::{eip1898::BlockHashOrNumber, eip4844::BlobAndProofV1, eip7685::Requests}; +use alloy_eips::{ + eip1898::BlockHashOrNumber, + eip4844::BlobAndProofV1, + eip7685::{Requests, RequestsOrHash}, +}; use alloy_primitives::{BlockHash, BlockNumber, B256, U64}; use alloy_rpc_types_engine::{ CancunPayloadFields, ClientVersionV1, ExecutionPayload, ExecutionPayloadBodiesV1, ExecutionPayloadInputV2, ExecutionPayloadSidecar, ExecutionPayloadV1, ExecutionPayloadV3, - ForkchoiceState, ForkchoiceUpdated, PayloadId, PayloadStatus, TransitionConfiguration, + ForkchoiceState, ForkchoiceUpdated, PayloadId, PayloadStatus, PraguePayloadFields, + TransitionConfiguration, }; use async_trait::async_trait; use jsonrpsee_core::RpcResult; @@ -279,7 +284,11 @@ where payload, ExecutionPayloadSidecar::v4( CancunPayloadFields { versioned_hashes, parent_beacon_block_root }, - execution_requests, + PraguePayloadFields { + requests: RequestsOrHash::Requests(execution_requests), + // TODO: add as an argument and handle in `try_into_block` + target_blobs_per_block: 0, + }, ), ) .await diff --git a/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs b/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs index e1cd8f5c3c29..e3ef6621bcba 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs @@ -467,6 +467,7 @@ pub trait LoadPendingBlock: extra_data: Default::default(), parent_beacon_block_root, requests_hash, + target_blobs_per_block: None, }; // Convert Vec> to Vec diff --git a/crates/rpc/rpc-eth-api/src/helpers/transaction.rs b/crates/rpc/rpc-eth-api/src/helpers/transaction.rs index 5bf6b0c02bac..43ac03adaf71 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/transaction.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/transaction.rs @@ -282,7 +282,7 @@ pub trait EthTransactions: LoadTransaction { block .transactions_with_sender() .enumerate() - .find(|(_, (signer, tx))| **signer == sender && tx.nonce() == nonce) + .find(|(_, (signer, tx))| **signer == sender && (*tx).nonce() == nonce) .map(|(index, (signer, tx))| { let tx_info = TransactionInfo { hash: Some(tx.hash()), diff --git a/crates/rpc/rpc-eth-types/src/receipt.rs b/crates/rpc/rpc-eth-types/src/receipt.rs index 3136d42e9580..b7f82782b0bc 100644 --- a/crates/rpc/rpc-eth-types/src/receipt.rs +++ b/crates/rpc/rpc-eth-types/src/receipt.rs @@ -14,7 +14,7 @@ pub fn build_receipt( meta: TransactionMeta, receipt: &Receipt, all_receipts: &[Receipt], - build_envelope: impl FnOnce(ReceiptWithBloom) -> T, + build_envelope: impl FnOnce(ReceiptWithBloom>) -> T, ) -> EthResult> { // Note: we assume this transaction is valid, because it's mined (or part of pending block) // and we don't need to check for pre EIP-2 diff --git a/crates/rpc/rpc-types-compat/src/engine/payload.rs b/crates/rpc/rpc-types-compat/src/engine/payload.rs index afe50d3af5a2..f504d57addc7 100644 --- a/crates/rpc/rpc-types-compat/src/engine/payload.rs +++ b/crates/rpc/rpc-types-compat/src/engine/payload.rs @@ -5,7 +5,6 @@ use alloy_consensus::{constants::MAXIMUM_EXTRA_DATA_SIZE, Header, EMPTY_OMMER_RO use alloy_eips::{ eip2718::{Decodable2718, Encodable2718}, eip4895::Withdrawals, - eip7685::Requests, }; use alloy_primitives::{B256, U256}; use alloy_rpc_types_engine::{ @@ -77,6 +76,7 @@ pub fn try_payload_v1_to_block(payload: ExecutionPayloadV1) -> Result let db = db.0; + let tx_info = TransactionInfo { + block_number: Some( + env.block.number.try_into().unwrap_or_default(), + ), + base_fee: Some( + env.block.basefee.try_into().unwrap_or_default(), + ), + hash: None, + block_hash: None, + index: None, + }; + let (res, _) = this.eth_api().inspect(&mut *db, env, &mut inspector)?; let frame = inspector - .try_into_mux_frame(&res, db) + .try_into_mux_frame(&res, db, tx_info) .map_err(Eth::Error::from_eth_err)?; Ok(frame.into()) }) @@ -658,6 +670,17 @@ where ) -> Result<(GethTrace, revm_primitives::EvmState), Eth::Error> { let GethDebugTracingOptions { config, tracer, tracer_config, .. } = opts; + let tx_info = TransactionInfo { + hash: transaction_context.as_ref().map(|c| c.tx_hash).unwrap_or_default(), + index: transaction_context + .as_ref() + .map(|c| c.tx_index.map(|i| i as u64)) + .unwrap_or_default(), + block_hash: transaction_context.as_ref().map(|c| c.block_hash).unwrap_or_default(), + block_number: Some(env.block.number.try_into().unwrap_or_default()), + base_fee: Some(env.block.basefee.try_into().unwrap_or_default()), + }; + if let Some(tracer) = tracer { return match tracer { GethDebugTracerType::BuiltInTracer(tracer) => match tracer { @@ -723,7 +746,7 @@ where let (res, _) = self.eth_api().inspect(&mut *db, env, &mut inspector)?; let frame = inspector - .try_into_mux_frame(&res, db) + .try_into_mux_frame(&res, db, tx_info) .map_err(Eth::Error::from_eth_err)?; return Ok((frame.into(), res.state)) } @@ -738,14 +761,6 @@ where ); let (res, env) = self.eth_api().inspect(db, env, &mut inspector)?; - - let tx_info = TransactionInfo { - hash: transaction_context.unwrap().tx_hash, - index: transaction_context.unwrap().tx_index.map(|index| index as u64), - block_hash: transaction_context.unwrap().block_hash, - block_number: Some(env.block.number.try_into().unwrap_or_default()), - base_fee: Some(env.block.basefee.try_into().unwrap_or_default()), - }; let frame: FlatCallFrame = inspector .with_transaction_gas_limit(env.tx.gas_limit) .into_parity_builder() diff --git a/crates/rpc/rpc/src/eth/bundle.rs b/crates/rpc/rpc/src/eth/bundle.rs index 10eec4dbf974..a80060b3377c 100644 --- a/crates/rpc/rpc/src/eth/bundle.rs +++ b/crates/rpc/rpc/src/eth/bundle.rs @@ -55,7 +55,9 @@ where let EthCallBundle { txs, block_number, + coinbase, state_block_number, + timeout: _, timestamp, gas_limit, difficulty, @@ -106,6 +108,10 @@ where // Note: the block number is considered the `parent` block: let (cfg, mut block_env, at) = self.eth_api().evm_env_at(block_id).await?; + if let Some(coinbase) = coinbase { + block_env.coinbase = coinbase; + } + // need to adjust the timestamp for the next block if let Some(timestamp) = timestamp { block_env.timestamp = U256::from(timestamp); @@ -117,8 +123,16 @@ where block_env.difficulty = U256::from(difficulty); } + // default to call gas limit unless user requests a smaller limit + block_env.gas_limit = U256::from(self.inner.eth_api.call_gas_limit()); if let Some(gas_limit) = gas_limit { - block_env.gas_limit = U256::from(gas_limit); + let gas_limit = U256::from(gas_limit); + if gas_limit > block_env.gas_limit { + return Err( + EthApiError::InvalidTransaction(RpcInvalidTransactionError::GasTooHigh).into() + ) + } + block_env.gas_limit = gas_limit; } if let Some(base_fee) = base_fee { diff --git a/crates/rpc/rpc/src/validation.rs b/crates/rpc/rpc/src/validation.rs index 1aa502c1f104..91a3dae2ce7c 100644 --- a/crates/rpc/rpc/src/validation.rs +++ b/crates/rpc/rpc/src/validation.rs @@ -1,11 +1,12 @@ use alloy_consensus::{BlobTransactionValidationError, EnvKzgSettings, Transaction, TxReceipt}; -use alloy_eips::eip4844::kzg_to_versioned_hash; +use alloy_eips::{eip4844::kzg_to_versioned_hash, eip7685::RequestsOrHash}; use alloy_rpc_types_beacon::relay::{ BidTrace, BuilderBlockValidationRequest, BuilderBlockValidationRequestV2, BuilderBlockValidationRequestV3, BuilderBlockValidationRequestV4, }; use alloy_rpc_types_engine::{ BlobsBundleV1, CancunPayloadFields, ExecutionPayload, ExecutionPayloadSidecar, PayloadError, + PraguePayloadFields, }; use async_trait::async_trait; use jsonrpsee::core::RpcResult; @@ -386,7 +387,12 @@ where versioned_hashes: self .validate_blobs_bundle(request.request.blobs_bundle)?, }, - request.request.execution_requests.into(), + PraguePayloadFields { + requests: RequestsOrHash::Requests( + request.request.execution_requests.into(), + ), + target_blobs_per_block: request.request.target_blobs_per_block, + }, ), )? .try_seal_with_senders() diff --git a/crates/storage/codecs/src/alloy/header.rs b/crates/storage/codecs/src/alloy/header.rs index 04b7d6ab718b..418b8b9032b6 100644 --- a/crates/storage/codecs/src/alloy/header.rs +++ b/crates/storage/codecs/src/alloy/header.rs @@ -58,6 +58,7 @@ pub(crate) struct Header { #[reth_codecs(crate = "crate")] pub(crate) struct HeaderExt { requests_hash: Option, + target_blobs_per_block: Option, } impl HeaderExt { @@ -65,7 +66,7 @@ impl HeaderExt { /// /// Required since [`Header`] uses `Option` as a field. const fn into_option(self) -> Option { - if self.requests_hash.is_some() { + if self.requests_hash.is_some() || self.target_blobs_per_block.is_some() { Some(self) } else { None @@ -78,7 +79,7 @@ impl Compact for AlloyHeader { where B: bytes::BufMut + AsMut<[u8]>, { - let extra_fields = HeaderExt { requests_hash: self.requests_hash }; + let extra_fields = HeaderExt { requests_hash: self.requests_hash, target_blobs_per_block: self.target_blobs_per_block }; let header = Header { parent_hash: self.parent_hash, @@ -128,8 +129,9 @@ impl Compact for AlloyHeader { blob_gas_used: header.blob_gas_used, excess_blob_gas: header.excess_blob_gas, parent_beacon_block_root: header.parent_beacon_block_root, - requests_hash: header.extra_fields.and_then(|h| h.requests_hash), + requests_hash: header.extra_fields.as_ref().and_then(|h| h.requests_hash), extra_data: header.extra_data, + target_blobs_per_block: header.extra_fields.as_ref().and_then(|h| h.target_blobs_per_block), }; (alloy_header, buf) } @@ -188,7 +190,7 @@ mod tests { #[test] fn test_extra_fields() { let mut header = HOLESKY_BLOCK; - header.extra_fields = Some(HeaderExt { requests_hash: Some(B256::random()) }); + header.extra_fields = Some(HeaderExt { requests_hash: Some(B256::random()), target_blobs_per_block: Some(3) }); let mut encoded_header = vec![]; let len = header.to_compact(&mut encoded_header); diff --git a/testing/ef-tests/src/models.rs b/testing/ef-tests/src/models.rs index 292b32e8ce0f..742498e81bfc 100644 --- a/testing/ef-tests/src/models.rs +++ b/testing/ef-tests/src/models.rs @@ -88,6 +88,8 @@ pub struct Header { pub parent_beacon_block_root: Option, /// Requests root. pub requests_hash: Option, + /// Target blobs per block. + pub target_blobs_per_block: Option, } impl From
for SealedHeader { @@ -114,6 +116,7 @@ impl From
for SealedHeader { excess_blob_gas: value.excess_blob_gas.map(|v| v.to::()), parent_beacon_block_root: value.parent_beacon_block_root, requests_hash: value.requests_hash, + target_blobs_per_block: value.target_blobs_per_block.map(|v| v.to::()), }; Self::new(header, value.hash) } From 3f93f35c20a9e01350a21b288d4fc917e96d4854 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Mon, 2 Dec 2024 04:56:00 +0400 Subject: [PATCH 02/68] feat: add `Header` AT to `EthChainSpec` (#13046) --- crates/chainspec/src/api.rs | 9 +++++++-- crates/cli/commands/src/common.rs | 19 +++++++++++-------- crates/cli/commands/src/stage/drop.rs | 9 ++++++--- crates/exex/exex/src/dyn_context.rs | 9 +++++---- crates/node/types/src/lib.rs | 8 ++++---- crates/optimism/chainspec/src/lib.rs | 4 +++- crates/storage/db-common/src/init.rs | 5 +++-- 7 files changed, 39 insertions(+), 24 deletions(-) diff --git a/crates/chainspec/src/api.rs b/crates/chainspec/src/api.rs index 94b4285f92dd..348051bef9cc 100644 --- a/crates/chainspec/src/api.rs +++ b/crates/chainspec/src/api.rs @@ -14,6 +14,9 @@ pub trait EthChainSpec: Send + Sync + Unpin + Debug { // todo: make chain spec type generic over hardfork //type Hardfork: Clone + Copy + 'static; + /// The header type of the network. + type Header; + /// Returns the [`Chain`] object this spec targets. fn chain(&self) -> Chain; @@ -41,7 +44,7 @@ pub trait EthChainSpec: Send + Sync + Unpin + Debug { fn display_hardforks(&self) -> Box; /// The genesis header. - fn genesis_header(&self) -> &Header; + fn genesis_header(&self) -> &Self::Header; /// The genesis block specification. fn genesis(&self) -> &Genesis; @@ -64,6 +67,8 @@ pub trait EthChainSpec: Send + Sync + Unpin + Debug { } impl EthChainSpec for ChainSpec { + type Header = Header; + fn chain(&self) -> Chain { self.chain } @@ -92,7 +97,7 @@ impl EthChainSpec for ChainSpec { Box::new(Self::display_hardforks(self)) } - fn genesis_header(&self) -> &Header { + fn genesis_header(&self) -> &Self::Header { self.genesis_header() } diff --git a/crates/cli/commands/src/common.rs b/crates/cli/commands/src/common.rs index b2ad1452aa46..174eeffa396e 100644 --- a/crates/cli/commands/src/common.rs +++ b/crates/cli/commands/src/common.rs @@ -3,7 +3,7 @@ use alloy_primitives::B256; use clap::Parser; use reth_beacon_consensus::EthBeaconConsensus; -use reth_chainspec::{EthChainSpec, EthereumHardforks}; +use reth_chainspec::EthChainSpec; use reth_cli::chainspec::ChainSpecParser; use reth_config::{config::EtlConfig, Config}; use reth_db::{init_db, open_db_read_only, DatabaseEnv}; @@ -54,13 +54,13 @@ pub struct EnvironmentArgs { pub db: DatabaseArgs, } -impl> EnvironmentArgs { +impl EnvironmentArgs { /// Initializes environment according to [`AccessRights`] and returns an instance of /// [`Environment`]. - pub fn init>( - &self, - access: AccessRights, - ) -> eyre::Result> { + pub fn init(&self, access: AccessRights) -> eyre::Result> + where + C: ChainSpecParser, + { let data_dir = self.datadir.clone().resolve_datadir(self.chain.chain()); let db_path = data_dir.db(); let sf_path = data_dir.static_files(); @@ -109,12 +109,15 @@ impl> Environmen /// If it's a read-write environment and an issue is found, it will attempt to heal (including a /// pipeline unwind). Otherwise, it will print out an warning, advising the user to restart the /// node to heal. - fn create_provider_factory>( + fn create_provider_factory( &self, config: &Config, db: Arc, static_file_provider: StaticFileProvider, - ) -> eyre::Result>>> { + ) -> eyre::Result>>> + where + C: ChainSpecParser, + { let has_receipt_pruning = config.prune.as_ref().is_some_and(|a| a.has_receipts_pruning()); let prune_modes = config.prune.as_ref().map(|prune| prune.segments.clone()).unwrap_or_default(); diff --git a/crates/cli/commands/src/stage/drop.rs b/crates/cli/commands/src/stage/drop.rs index 49bbc55ec241..b93ab1a3c40e 100644 --- a/crates/cli/commands/src/stage/drop.rs +++ b/crates/cli/commands/src/stage/drop.rs @@ -2,7 +2,7 @@ use crate::common::{AccessRights, CliNodeTypes, Environment, EnvironmentArgs}; use clap::Parser; use itertools::Itertools; -use reth_chainspec::{EthChainSpec, EthereumHardforks}; +use reth_chainspec::EthChainSpec; use reth_cli::chainspec::ChainSpecParser; use reth_db::{mdbx::tx::Tx, static_file::iter_static_files, tables, DatabaseError}; use reth_db_api::transaction::{DbTx, DbTxMut}; @@ -27,9 +27,12 @@ pub struct Command { stage: StageEnum, } -impl> Command { +impl Command { /// Execute `db` command - pub async fn execute>(self) -> eyre::Result<()> { + pub async fn execute(self) -> eyre::Result<()> + where + C: ChainSpecParser, + { let Environment { provider_factory, .. } = self.env.init::(AccessRights::RW)?; let tool = DbTool::new(provider_factory)?; diff --git a/crates/exex/exex/src/dyn_context.rs b/crates/exex/exex/src/dyn_context.rs index 12efa5f069b7..8bda75cac45d 100644 --- a/crates/exex/exex/src/dyn_context.rs +++ b/crates/exex/exex/src/dyn_context.rs @@ -4,7 +4,7 @@ use std::fmt::Debug; use reth_chainspec::{EthChainSpec, Head}; -use reth_node_api::{FullNodeComponents, NodePrimitives, NodeTypes}; +use reth_node_api::{FullNodeComponents, HeaderTy, NodePrimitives, NodeTypes}; use reth_node_core::node_config::NodeConfig; use reth_primitives::EthPrimitives; use reth_provider::BlockReader; @@ -18,7 +18,7 @@ pub struct ExExContextDyn { /// The current head of the blockchain at launch. pub head: Head, /// The config of the node - pub config: NodeConfig>, + pub config: NodeConfig + 'static>>, /// The loaded node config pub reth_config: reth_config::Config, /// Channel used to send [`ExExEvent`]s to the rest of the node. @@ -57,8 +57,9 @@ where Node::Executor: Debug, { fn from(ctx: ExExContext) -> Self { - let config = - ctx.config.map_chainspec(|chainspec| Box::new(chainspec) as Box); + let config = ctx.config.map_chainspec(|chainspec| { + Box::new(chainspec) as Box>> + }); let notifications = Box::new(ctx.notifications) as Box<_>; Self { diff --git a/crates/node/types/src/lib.rs b/crates/node/types/src/lib.rs index c0d266e57755..6e1eb81a0c8b 100644 --- a/crates/node/types/src/lib.rs +++ b/crates/node/types/src/lib.rs @@ -31,7 +31,7 @@ pub trait NodeTypes: Send + Sync + Unpin + 'static { /// The node's primitive types, defining basic operations and structures. type Primitives: NodePrimitives; /// The type used for configuration of the EVM. - type ChainSpec: EthChainSpec; + type ChainSpec: EthChainSpec
::BlockHeader>; /// The type used to perform state commitment operations. type StateCommitment: StateCommitment; /// The type responsible for writing chain primitives to storage. @@ -151,7 +151,7 @@ impl AnyNodeTypes { impl NodeTypes for AnyNodeTypes where P: NodePrimitives + Send + Sync + Unpin + 'static, - C: EthChainSpec + 'static, + C: EthChainSpec
+ 'static, SC: StateCommitment, S: Default + Send + Sync + Unpin + Debug + 'static, { @@ -212,7 +212,7 @@ impl NodeTypes for AnyNodeTypesWithEngine where P: NodePrimitives + Send + Sync + Unpin + 'static, E: EngineTypes + Send + Sync + Unpin, - C: EthChainSpec + 'static, + C: EthChainSpec
+ 'static, SC: StateCommitment, S: Default + Send + Sync + Unpin + Debug + 'static, { @@ -226,7 +226,7 @@ impl NodeTypesWithEngine for AnyNodeTypesWithEngine + 'static, SC: StateCommitment, S: Default + Send + Sync + Unpin + Debug + 'static, { diff --git a/crates/optimism/chainspec/src/lib.rs b/crates/optimism/chainspec/src/lib.rs index d552d08f18ca..f3450e873241 100644 --- a/crates/optimism/chainspec/src/lib.rs +++ b/crates/optimism/chainspec/src/lib.rs @@ -253,6 +253,8 @@ pub fn decode_holocene_1559_params(extra_data: Bytes) -> Result<(u32, u32), Deco } impl EthChainSpec for OpChainSpec { + type Header = Header; + fn chain(&self) -> alloy_chains::Chain { self.inner.chain() } @@ -281,7 +283,7 @@ impl EthChainSpec for OpChainSpec { Box::new(ChainSpec::display_hardforks(self)) } - fn genesis_header(&self) -> &Header { + fn genesis_header(&self) -> &Self::Header { self.inner.genesis_header() } diff --git a/crates/storage/db-common/src/init.rs b/crates/storage/db-common/src/init.rs index ec31edd06823..9d4fb4ff02c5 100644 --- a/crates/storage/db-common/src/init.rs +++ b/crates/storage/db-common/src/init.rs @@ -70,7 +70,7 @@ impl From for InitDatabaseError { pub fn init_genesis(factory: &PF) -> Result where PF: DatabaseProviderFactory + StaticFileProviderFactory + ChainSpecProvider + BlockHashReader, - PF::ProviderRW: StaticFileProviderFactory + PF::ProviderRW: StaticFileProviderFactory + StageCheckpointWriter + HistoryWriter + HeaderProvider @@ -78,6 +78,7 @@ where + StateWriter + StateWriter + AsRef, + PF::ChainSpec: EthChainSpec
, { let chain = factory.chain_spec(); @@ -307,7 +308,7 @@ pub fn insert_genesis_header( ) -> ProviderResult<()> where Provider: StaticFileProviderFactory + DBProvider, - Spec: EthChainSpec, + Spec: EthChainSpec
, { let (header, block_hash) = (chain.genesis_header(), chain.genesis_hash()); let static_file_provider = provider.static_file_provider(); From c2ab690ad1a826c519dacc818222b47074c57a13 Mon Sep 17 00:00:00 2001 From: Tien Nguyen Date: Mon, 2 Dec 2024 17:02:05 +0700 Subject: [PATCH 03/68] feat: introduce EthMessage variant to NetworkHandleMessage (#13033) --- crates/net/network/src/manager.rs | 3 +++ crates/net/network/src/network.rs | 16 ++++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/crates/net/network/src/manager.rs b/crates/net/network/src/manager.rs index c1db91773e38..e123377acd23 100644 --- a/crates/net/network/src/manager.rs +++ b/crates/net/network/src/manager.rs @@ -644,6 +644,9 @@ impl NetworkManager { let _ = tx.send(None); } } + NetworkHandleMessage::EthMessage { peer_id, message } => { + self.swarm.sessions_mut().send_message(&peer_id, message) + } } } diff --git a/crates/net/network/src/network.rs b/crates/net/network/src/network.rs index eadeccb15493..7e0b000cf343 100644 --- a/crates/net/network/src/network.rs +++ b/crates/net/network/src/network.rs @@ -1,6 +1,6 @@ use crate::{ - config::NetworkMode, protocol::RlpxSubProtocol, swarm::NetworkConnectionState, - transactions::TransactionsHandle, FetchClient, + config::NetworkMode, message::PeerMessage, protocol::RlpxSubProtocol, + swarm::NetworkConnectionState, transactions::TransactionsHandle, FetchClient, }; use alloy_primitives::B256; use enr::Enr; @@ -136,6 +136,11 @@ impl NetworkHandle { }) } + /// Send eth message to the peer. + pub fn send_eth_message(&self, peer_id: PeerId, message: PeerMessage) { + self.send_message(NetworkHandleMessage::EthMessage { peer_id, message }) + } + /// Send message to get the [`TransactionsHandle`]. /// /// Returns `None` if no transaction task is installed. @@ -481,6 +486,13 @@ pub(crate) enum NetworkHandleMessage, }, + /// Sends an `eth` protocol message to the peer. + EthMessage { + /// The peer to send the message to. + peer_id: PeerId, + /// The message to send to the peer's sessions. + message: PeerMessage, + }, /// Applies a reputation change to the given peer. ReputationChange(PeerId, ReputationChangeKind), /// Returns the client that can be used to interact with the network. From 04f8c58485d07a40c85d34f45a4be5610567e836 Mon Sep 17 00:00:00 2001 From: Roman Krasiuk Date: Mon, 2 Dec 2024 11:07:32 +0100 Subject: [PATCH 04/68] perf(trie): storage multiproof overallocation (#12959) --- crates/trie/parallel/src/proof.rs | 6 +++++- crates/trie/trie/src/proof.rs | 12 ++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/crates/trie/parallel/src/proof.rs b/crates/trie/parallel/src/proof.rs index f285079f2526..94138823e005 100644 --- a/crates/trie/parallel/src/proof.rs +++ b/crates/trie/parallel/src/proof.rs @@ -203,7 +203,11 @@ where account.encode(&mut account_rlp as &mut dyn BufMut); hash_builder.add_leaf(Nibbles::unpack(hashed_address), &account_rlp); - storages.insert(hashed_address, storage_multiproof); + + // We might be adding leaves that are not necessarily our proof targets. + if targets.contains_key(&hashed_address) { + storages.insert(hashed_address, storage_multiproof); + } } } } diff --git a/crates/trie/trie/src/proof.rs b/crates/trie/trie/src/proof.rs index 34315416cb8d..3cb0ff6f2f70 100644 --- a/crates/trie/trie/src/proof.rs +++ b/crates/trie/trie/src/proof.rs @@ -115,19 +115,20 @@ where hash_builder.add_branch(node.key, node.value, node.children_are_in_trie); } TrieElement::Leaf(hashed_address, account) => { + let proof_targets = targets.remove(&hashed_address); + let leaf_is_proof_target = proof_targets.is_some(); let storage_prefix_set = self .prefix_sets .storage_prefix_sets .remove(&hashed_address) .unwrap_or_default(); - let proof_targets = targets.remove(&hashed_address).unwrap_or_default(); let storage_multiproof = StorageProof::new_hashed( self.trie_cursor_factory.clone(), self.hashed_cursor_factory.clone(), hashed_address, ) .with_prefix_set_mut(storage_prefix_set) - .storage_multiproof(proof_targets)?; + .storage_multiproof(proof_targets.unwrap_or_default())?; // Encode account account_rlp.clear(); @@ -136,8 +137,11 @@ where hash_builder.add_leaf(Nibbles::unpack(hashed_address), &account_rlp); - // Overwrite storage multiproof. - storages.insert(hashed_address, storage_multiproof); + // We might be adding leaves that are not necessarily our proof targets. + if leaf_is_proof_target { + // Overwrite storage multiproof. + storages.insert(hashed_address, storage_multiproof); + } } } } From ae3b3ddf427233db05f1654bdde9ee567ef3cb4e Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Mon, 2 Dec 2024 11:09:24 +0100 Subject: [PATCH 05/68] chore: use alloy's blockwithparent (#13052) --- .../src/headers/reverse_headers.rs | 3 +-- crates/net/p2p/src/headers/downloader.rs | 3 +-- crates/primitives-traits/src/header/mod.rs | 2 +- crates/primitives-traits/src/header/sealed.rs | 19 +++---------------- crates/primitives-traits/src/lib.rs | 2 +- 5 files changed, 7 insertions(+), 22 deletions(-) diff --git a/crates/net/downloaders/src/headers/reverse_headers.rs b/crates/net/downloaders/src/headers/reverse_headers.rs index 63a20ff27f5b..be359134e79d 100644 --- a/crates/net/downloaders/src/headers/reverse_headers.rs +++ b/crates/net/downloaders/src/headers/reverse_headers.rs @@ -1225,11 +1225,10 @@ mod tests { use super::*; use crate::headers::test_utils::child_header; use alloy_consensus::Header; - use alloy_eips::BlockNumHash; + use alloy_eips::{eip1898::BlockWithParent, BlockNumHash}; use assert_matches::assert_matches; use reth_consensus::test_utils::TestConsensus; use reth_network_p2p::test_utils::TestHeadersClient; - use reth_primitives_traits::BlockWithParent; /// Tests that `replace_number` works the same way as `Option::replace` #[test] diff --git a/crates/net/p2p/src/headers/downloader.rs b/crates/net/p2p/src/headers/downloader.rs index eca03bdb4e79..1bc76924a6c8 100644 --- a/crates/net/p2p/src/headers/downloader.rs +++ b/crates/net/p2p/src/headers/downloader.rs @@ -1,12 +1,11 @@ use super::error::HeadersDownloaderResult; use crate::error::{DownloadError, DownloadResult}; use alloy_consensus::BlockHeader; -use alloy_eips::BlockHashOrNumber; +use alloy_eips::{eip1898::BlockWithParent, BlockHashOrNumber}; use alloy_primitives::B256; use futures::Stream; use reth_consensus::HeaderValidator; use reth_primitives::SealedHeader; -use reth_primitives_traits::BlockWithParent; use std::fmt::Debug; /// A downloader capable of fetching and yielding block headers. diff --git a/crates/primitives-traits/src/header/mod.rs b/crates/primitives-traits/src/header/mod.rs index ea5f7eafb518..abcdf4ee0cca 100644 --- a/crates/primitives-traits/src/header/mod.rs +++ b/crates/primitives-traits/src/header/mod.rs @@ -1,5 +1,5 @@ mod sealed; -pub use sealed::{BlockWithParent, Header, SealedHeader}; +pub use sealed::{Header, SealedHeader}; mod error; pub use error::HeaderError; diff --git a/crates/primitives-traits/src/header/sealed.rs b/crates/primitives-traits/src/header/sealed.rs index f167ffbf2847..1a5163e6ba3f 100644 --- a/crates/primitives-traits/src/header/sealed.rs +++ b/crates/primitives-traits/src/header/sealed.rs @@ -1,26 +1,13 @@ +use crate::InMemorySize; pub use alloy_consensus::Header; - -use core::mem; - use alloy_consensus::Sealed; use alloy_eips::BlockNumHash; -use alloy_primitives::{keccak256, BlockHash, Sealable, B256}; +use alloy_primitives::{keccak256, BlockHash, Sealable}; use alloy_rlp::{Decodable, Encodable}; use bytes::BufMut; +use core::mem; use derive_more::{AsRef, Deref}; -use crate::InMemorySize; - -/// A helper struct to store the block number/hash and its parent hash. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct BlockWithParent { - /// Parent hash. - pub parent: B256, - /// Block number/hash. - pub block: BlockNumHash, -} - /// A [`Header`] that is sealed at a precalculated hash, use [`SealedHeader::unseal()`] if you want /// to modify header. #[derive(Debug, Clone, PartialEq, Eq, Hash, AsRef, Deref)] diff --git a/crates/primitives-traits/src/lib.rs b/crates/primitives-traits/src/lib.rs index 5bdfd01eb9ce..c88da5ad7a7b 100644 --- a/crates/primitives-traits/src/lib.rs +++ b/crates/primitives-traits/src/lib.rs @@ -58,7 +58,7 @@ pub use storage::StorageEntry; pub mod header; #[cfg(any(test, feature = "arbitrary", feature = "test-utils"))] pub use header::test_utils; -pub use header::{BlockWithParent, Header, HeaderError, SealedHeader}; +pub use header::{Header, HeaderError, SealedHeader}; /// Bincode-compatible serde implementations for common abstracted types in Reth. /// From b91d0f871198812f8bb390437af5c43424e6314b Mon Sep 17 00:00:00 2001 From: Roman Krasiuk Date: Mon, 2 Dec 2024 11:10:37 +0100 Subject: [PATCH 06/68] feat(trie): blinded node provider (#13027) --- crates/trie/sparse/src/blinded.rs | 58 ++++ crates/trie/sparse/src/errors.rs | 5 + crates/trie/sparse/src/lib.rs | 2 + crates/trie/sparse/src/state.rs | 168 +++++----- crates/trie/sparse/src/trie.rs | 488 ++++++++++++++++++------------ 5 files changed, 456 insertions(+), 265 deletions(-) create mode 100644 crates/trie/sparse/src/blinded.rs diff --git a/crates/trie/sparse/src/blinded.rs b/crates/trie/sparse/src/blinded.rs new file mode 100644 index 000000000000..3875e819da63 --- /dev/null +++ b/crates/trie/sparse/src/blinded.rs @@ -0,0 +1,58 @@ +//! Traits and default implementations related to retrieval of blinded trie nodes. + +use crate::SparseTrieError; +use alloy_primitives::Bytes; +use reth_trie_common::Nibbles; +use std::convert::Infallible; + +/// Factory for instantiating blinded node providers. +pub trait BlindedProviderFactory { + /// Type capable of fetching blinded account nodes. + type AccountNodeProvider: BlindedProvider; + /// Type capable of fetching blinded storage nodes. + type StorageNodeProvider: BlindedProvider; + + /// Returns blinded account node provider. + fn account_node_provider(&self) -> Self::AccountNodeProvider; + + /// Returns blinded storage node provider. + fn storage_node_provider(&self) -> Self::StorageNodeProvider; +} + +/// Trie node provider for retrieving blinded nodes. +pub trait BlindedProvider { + /// The error type for the provider. + type Error: Into; + + /// Retrieve blinded node by path. + fn blinded_node(&mut self, path: Nibbles) -> Result, Self::Error>; +} + +/// Default blinded node provider factory that creates [`DefaultBlindedProvider`]. +#[derive(PartialEq, Eq, Clone, Default, Debug)] +pub struct DefaultBlindedProviderFactory; + +impl BlindedProviderFactory for DefaultBlindedProviderFactory { + type AccountNodeProvider = DefaultBlindedProvider; + type StorageNodeProvider = DefaultBlindedProvider; + + fn account_node_provider(&self) -> Self::AccountNodeProvider { + DefaultBlindedProvider + } + + fn storage_node_provider(&self) -> Self::StorageNodeProvider { + DefaultBlindedProvider + } +} + +/// Default blinded node provider that always returns `Ok(None)`. +#[derive(PartialEq, Eq, Clone, Default, Debug)] +pub struct DefaultBlindedProvider; + +impl BlindedProvider for DefaultBlindedProvider { + type Error = Infallible; + + fn blinded_node(&mut self, _path: Nibbles) -> Result, Self::Error> { + Ok(None) + } +} diff --git a/crates/trie/sparse/src/errors.rs b/crates/trie/sparse/src/errors.rs index a38a92395d9b..ca3b279ce421 100644 --- a/crates/trie/sparse/src/errors.rs +++ b/crates/trie/sparse/src/errors.rs @@ -1,5 +1,7 @@ //! Errors for sparse trie. +use std::convert::Infallible; + use alloy_primitives::{Bytes, B256}; use reth_trie_common::Nibbles; use thiserror::Error; @@ -56,4 +58,7 @@ pub enum SparseTrieError { /// RLP error. #[error(transparent)] Rlp(#[from] alloy_rlp::Error), + /// Infallible. + #[error(transparent)] + Infallible(#[from] Infallible), } diff --git a/crates/trie/sparse/src/lib.rs b/crates/trie/sparse/src/lib.rs index b3cb2c5fdffa..ec5117fdbc1f 100644 --- a/crates/trie/sparse/src/lib.rs +++ b/crates/trie/sparse/src/lib.rs @@ -8,3 +8,5 @@ pub use trie::*; mod errors; pub use errors::*; + +pub mod blinded; diff --git a/crates/trie/sparse/src/state.rs b/crates/trie/sparse/src/state.rs index 6444c7cd2c42..877744954ae1 100644 --- a/crates/trie/sparse/src/state.rs +++ b/crates/trie/sparse/src/state.rs @@ -1,4 +1,5 @@ use crate::{ + blinded::{BlindedProvider, BlindedProviderFactory, DefaultBlindedProviderFactory}, RevealedSparseTrie, SparseStateTrieError, SparseStateTrieResult, SparseTrie, SparseTrieError, }; use alloy_primitives::{ @@ -16,11 +17,13 @@ use std::iter::Peekable; /// Sparse state trie representing lazy-loaded Ethereum state trie. #[derive(Debug)] -pub struct SparseStateTrie { +pub struct SparseStateTrie { + /// Blinded node provider factory. + provider_factory: F, /// Sparse account trie. - state: SparseTrie, + state: SparseTrie, /// Sparse storage tries. - storages: HashMap, + storages: HashMap>, /// Collection of revealed account and storage keys. revealed: HashMap>, /// Flag indicating whether trie updates should be retained. @@ -35,6 +38,7 @@ impl Default for SparseStateTrie { state: Default::default(), storages: Default::default(), revealed: Default::default(), + provider_factory: Default::default(), retain_updates: false, account_rlp_buf: Vec::with_capacity(TRIE_ACCOUNT_RLP_MAX_SIZE), } @@ -46,7 +50,9 @@ impl SparseStateTrie { pub fn from_state(state: SparseTrie) -> Self { Self { state, ..Default::default() } } +} +impl SparseStateTrie { /// Set the retention of branch node updates and deletions. pub const fn with_updates(mut self, retain_updates: bool) -> Self { self.retain_updates = retain_updates; @@ -64,7 +70,10 @@ impl SparseStateTrie { } /// Returns mutable reference to storage sparse trie if it was revealed. - pub fn storage_trie_mut(&mut self, account: &B256) -> Option<&mut RevealedSparseTrie> { + pub fn storage_trie_mut( + &mut self, + account: &B256, + ) -> Option<&mut RevealedSparseTrie> { self.storages.get_mut(account).and_then(|e| e.as_revealed_mut()) } @@ -84,7 +93,11 @@ impl SparseStateTrie { let Some(root_node) = self.validate_root_node(&mut proof)? else { return Ok(()) }; // Reveal root node if it wasn't already. - let trie = self.state.reveal_root(root_node, self.retain_updates)?; + let trie = self.state.reveal_root_with_provider( + self.provider_factory.account_node_provider(), + root_node, + self.retain_updates, + )?; // Reveal the remaining proof nodes. for (path, bytes) in proof { @@ -115,11 +128,11 @@ impl SparseStateTrie { let Some(root_node) = self.validate_root_node(&mut proof)? else { return Ok(()) }; // Reveal root node if it wasn't already. - let trie = self - .storages - .entry(account) - .or_default() - .reveal_root(root_node, self.retain_updates)?; + let trie = self.storages.entry(account).or_default().reveal_root_with_provider( + self.provider_factory.storage_node_provider(), + root_node, + self.retain_updates, + )?; // Reveal the remaining proof nodes. for (path, bytes) in proof { @@ -145,7 +158,11 @@ impl SparseStateTrie { if let Some(root_node) = self.validate_root_node(&mut account_nodes)? { // Reveal root node if it wasn't already. - let trie = self.state.reveal_root(root_node, self.retain_updates)?; + let trie = self.state.reveal_root_with_provider( + self.provider_factory.account_node_provider(), + root_node, + self.retain_updates, + )?; // Reveal the remaining proof nodes. for (path, bytes) in account_nodes { @@ -161,11 +178,11 @@ impl SparseStateTrie { if let Some(root_node) = self.validate_root_node(&mut storage_nodes)? { // Reveal root node if it wasn't already. - let trie = self - .storages - .entry(account) - .or_default() - .reveal_root(root_node, self.retain_updates)?; + let trie = self.storages.entry(account).or_default().reveal_root_with_provider( + self.provider_factory.storage_node_provider(), + root_node, + self.retain_updates, + )?; // Reveal the remaining proof nodes. for (path, bytes) in storage_nodes { @@ -205,41 +222,6 @@ impl SparseStateTrie { Ok(Some(root_node)) } - /// Update or remove trie account based on new account info. This method will either recompute - /// the storage root based on update storage trie or look it up from existing leaf value. - /// - /// If the new account info and storage trie are empty, the account leaf will be removed. - pub fn update_account(&mut self, address: B256, account: Account) -> SparseStateTrieResult<()> { - let nibbles = Nibbles::unpack(address); - let storage_root = if let Some(storage_trie) = self.storages.get_mut(&address) { - trace!(target: "trie::sparse", ?address, "Calculating storage root to update account"); - storage_trie.root().ok_or(SparseTrieError::Blind)? - } else if self.revealed.contains_key(&address) { - trace!(target: "trie::sparse", ?address, "Retrieving storage root from account leaf to update account"); - let state = self.state.as_revealed_mut().ok_or(SparseTrieError::Blind)?; - // The account was revealed, either... - if let Some(value) = state.get_leaf_value(&nibbles) { - // ..it exists and we should take it's current storage root or... - TrieAccount::decode(&mut &value[..])?.storage_root - } else { - // ...the account is newly created and the storage trie is empty. - EMPTY_ROOT_HASH - } - } else { - return Err(SparseTrieError::Blind.into()) - }; - - if account.is_empty() && storage_root == EMPTY_ROOT_HASH { - trace!(target: "trie::sparse", ?address, "Removing account"); - self.remove_account_leaf(&nibbles) - } else { - trace!(target: "trie::sparse", ?address, "Updating account"); - self.account_rlp_buf.clear(); - TrieAccount::from((account, storage_root)).encode(&mut self.account_rlp_buf); - self.update_account_leaf(nibbles, self.account_rlp_buf.clone()) - } - } - /// Update the account leaf node. pub fn update_account_leaf( &mut self, @@ -250,12 +232,6 @@ impl SparseStateTrie { Ok(()) } - /// Remove the account leaf node. - pub fn remove_account_leaf(&mut self, path: &Nibbles) -> SparseStateTrieResult<()> { - self.state.remove_leaf(path)?; - Ok(()) - } - /// Update the leaf node of a storage trie at the provided address. pub fn update_storage_leaf( &mut self, @@ -263,18 +239,11 @@ impl SparseStateTrie { slot: Nibbles, value: Vec, ) -> SparseStateTrieResult<()> { - self.storages.entry(address).or_default().update_leaf(slot, value)?; - Ok(()) - } - - /// Update the leaf node of a storage trie at the provided address. - pub fn remove_storage_leaf( - &mut self, - address: B256, - slot: &Nibbles, - ) -> SparseStateTrieResult<()> { - self.storages.entry(address).or_default().remove_leaf(slot)?; - Ok(()) + if let Some(storage_trie) = self.storages.get_mut(&address) { + Ok(storage_trie.update_leaf(slot, value)?) + } else { + Err(SparseStateTrieError::Sparse(SparseTrieError::Blind)) + } } /// Wipe the storage trie at the provided address. @@ -329,6 +298,67 @@ impl SparseStateTrie { } } +impl SparseStateTrie +where + F: BlindedProviderFactory, + SparseTrieError: From<::Error> + + From<::Error>, +{ + /// Update or remove trie account based on new account info. This method will either recompute + /// the storage root based on update storage trie or look it up from existing leaf value. + /// + /// If the new account info and storage trie are empty, the account leaf will be removed. + pub fn update_account(&mut self, address: B256, account: Account) -> SparseStateTrieResult<()> { + let nibbles = Nibbles::unpack(address); + let storage_root = if let Some(storage_trie) = self.storages.get_mut(&address) { + trace!(target: "trie::sparse", ?address, "Calculating storage root to update account"); + storage_trie.root().ok_or(SparseTrieError::Blind)? + } else if self.revealed.contains_key(&address) { + trace!(target: "trie::sparse", ?address, "Retrieving storage root from account leaf to update account"); + let state = self.state.as_revealed_mut().ok_or(SparseTrieError::Blind)?; + // The account was revealed, either... + if let Some(value) = state.get_leaf_value(&nibbles) { + // ..it exists and we should take it's current storage root or... + TrieAccount::decode(&mut &value[..])?.storage_root + } else { + // ...the account is newly created and the storage trie is empty. + EMPTY_ROOT_HASH + } + } else { + return Err(SparseTrieError::Blind.into()) + }; + + if account.is_empty() && storage_root == EMPTY_ROOT_HASH { + trace!(target: "trie::sparse", ?address, "Removing account"); + self.remove_account_leaf(&nibbles) + } else { + trace!(target: "trie::sparse", ?address, "Updating account"); + self.account_rlp_buf.clear(); + TrieAccount::from((account, storage_root)).encode(&mut self.account_rlp_buf); + self.update_account_leaf(nibbles, self.account_rlp_buf.clone()) + } + } + + /// Remove the account leaf node. + pub fn remove_account_leaf(&mut self, path: &Nibbles) -> SparseStateTrieResult<()> { + self.state.remove_leaf(path)?; + Ok(()) + } + + /// Update the leaf node of a storage trie at the provided address. + pub fn remove_storage_leaf( + &mut self, + address: B256, + slot: &Nibbles, + ) -> SparseStateTrieResult<()> { + if let Some(storage_trie) = self.storages.get_mut(&address) { + Ok(storage_trie.remove_leaf(slot)?) + } else { + Err(SparseStateTrieError::Sparse(SparseTrieError::Blind)) + } + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/crates/trie/sparse/src/trie.rs b/crates/trie/sparse/src/trie.rs index 12a0f87e1292..0dd6dc989c14 100644 --- a/crates/trie/sparse/src/trie.rs +++ b/crates/trie/sparse/src/trie.rs @@ -1,4 +1,7 @@ -use crate::{SparseTrieError, SparseTrieResult}; +use crate::{ + blinded::{BlindedProvider, DefaultBlindedProvider}, + SparseTrieError, SparseTrieResult, +}; use alloy_primitives::{ hex, keccak256, map::{HashMap, HashSet}, @@ -16,28 +19,53 @@ use std::{borrow::Cow, fmt}; /// Inner representation of the sparse trie. /// Sparse trie is blind by default until nodes are revealed. -#[derive(PartialEq, Eq, Default, Debug)] -pub enum SparseTrie { +#[derive(PartialEq, Eq, Debug)] +pub enum SparseTrie

{ /// None of the trie nodes are known. - #[default] Blind, /// The trie nodes have been revealed. - Revealed(Box), + Revealed(Box>), +} + +impl

Default for SparseTrie

{ + fn default() -> Self { + Self::Blind + } } impl SparseTrie { + /// Creates new blind trie. + pub const fn blind() -> Self { + Self::Blind + } + /// Creates new revealed empty trie. pub fn revealed_empty() -> Self { Self::Revealed(Box::default()) } + /// Reveals the root node if the trie is blinded. + /// + /// # Returns + /// + /// Mutable reference to [`RevealedSparseTrie`]. + pub fn reveal_root( + &mut self, + root: TrieNode, + retain_updates: bool, + ) -> SparseTrieResult<&mut RevealedSparseTrie> { + self.reveal_root_with_provider(Default::default(), root, retain_updates) + } +} + +impl

SparseTrie

{ /// Returns `true` if the sparse trie has no revealed nodes. pub const fn is_blind(&self) -> bool { matches!(self, Self::Blind) } /// Returns mutable reference to revealed sparse trie if the trie is not blind. - pub fn as_revealed_mut(&mut self) -> Option<&mut RevealedSparseTrie> { + pub fn as_revealed_mut(&mut self) -> Option<&mut RevealedSparseTrie

> { if let Self::Revealed(revealed) = self { Some(revealed) } else { @@ -50,13 +78,18 @@ impl SparseTrie { /// # Returns /// /// Mutable reference to [`RevealedSparseTrie`]. - pub fn reveal_root( + pub fn reveal_root_with_provider( &mut self, + provider: P, root: TrieNode, retain_updates: bool, - ) -> SparseTrieResult<&mut RevealedSparseTrie> { + ) -> SparseTrieResult<&mut RevealedSparseTrie

> { if self.is_blind() { - *self = Self::Revealed(Box::new(RevealedSparseTrie::from_root(root, retain_updates)?)) + *self = Self::Revealed(Box::new(RevealedSparseTrie::from_provider_and_root( + provider, + root, + retain_updates, + )?)) } Ok(self.as_revealed_mut().unwrap()) } @@ -68,13 +101,6 @@ impl SparseTrie { Ok(()) } - /// Remove the leaf node. - pub fn remove_leaf(&mut self, path: &Nibbles) -> SparseTrieResult<()> { - let revealed = self.as_revealed_mut().ok_or(SparseTrieError::Blind)?; - revealed.remove_leaf(path)?; - Ok(()) - } - /// Wipe the trie, removing all values and nodes, and replacing the root with an empty node. pub fn wipe(&mut self) -> SparseTrieResult<()> { let revealed = self.as_revealed_mut().ok_or(SparseTrieError::Blind)?; @@ -93,6 +119,19 @@ impl SparseTrie { } } +impl

SparseTrie

+where + P: BlindedProvider, + SparseTrieError: From, +{ + /// Remove the leaf node. + pub fn remove_leaf(&mut self, path: &Nibbles) -> SparseTrieResult<()> { + let revealed = self.as_revealed_mut().ok_or(SparseTrieError::Blind)?; + revealed.remove_leaf(path)?; + Ok(()) + } +} + /// The representation of revealed sparse trie. /// /// ## Invariants @@ -102,27 +141,29 @@ impl SparseTrie { /// The opposite is also true. /// - All keys in `values` collection are full leaf paths. #[derive(Clone, PartialEq, Eq)] -pub struct RevealedSparseTrie { +pub struct RevealedSparseTrie

{ + /// Blinded node provider. + provider: P, /// All trie nodes. nodes: HashMap, /// All leaf values. values: HashMap>, /// Prefix set. prefix_set: PrefixSetMut, - /// Reusable buffer for RLP encoding of nodes. - rlp_buf: Vec, /// Retained trie updates. updates: Option, + /// Reusable buffer for RLP encoding of nodes. + rlp_buf: Vec, } -impl fmt::Debug for RevealedSparseTrie { +impl

fmt::Debug for RevealedSparseTrie

{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("RevealedSparseTrie") .field("nodes", &self.nodes) .field("values", &self.values) .field("prefix_set", &self.prefix_set) - .field("rlp_buf", &hex::encode(&self.rlp_buf)) .field("updates", &self.updates) + .field("rlp_buf", &hex::encode(&self.rlp_buf)) .finish() } } @@ -130,11 +171,12 @@ impl fmt::Debug for RevealedSparseTrie { impl Default for RevealedSparseTrie { fn default() -> Self { Self { + provider: Default::default(), nodes: HashMap::from_iter([(Nibbles::default(), SparseNode::Empty)]), values: HashMap::default(), prefix_set: PrefixSetMut::default(), - rlp_buf: Vec::new(), updates: None, + rlp_buf: Vec::new(), } } } @@ -143,6 +185,28 @@ impl RevealedSparseTrie { /// Create new revealed sparse trie from the given root node. pub fn from_root(node: TrieNode, retain_updates: bool) -> SparseTrieResult { let mut this = Self { + provider: Default::default(), + nodes: HashMap::default(), + values: HashMap::default(), + prefix_set: PrefixSetMut::default(), + rlp_buf: Vec::new(), + updates: None, + } + .with_updates(retain_updates); + this.reveal_node(Nibbles::default(), node)?; + Ok(this) + } +} + +impl

RevealedSparseTrie

{ + /// Create new revealed sparse trie from the given root node. + pub fn from_provider_and_root( + provider: P, + node: TrieNode, + retain_updates: bool, + ) -> SparseTrieResult { + let mut this = Self { + provider, nodes: HashMap::default(), values: HashMap::default(), prefix_set: PrefixSetMut::default(), @@ -154,6 +218,18 @@ impl RevealedSparseTrie { Ok(this) } + /// Set new blinded node provider on sparse trie. + pub fn with_provider(self, provider: BP) -> RevealedSparseTrie { + RevealedSparseTrie { + provider, + nodes: self.nodes, + values: self.values, + prefix_set: self.prefix_set, + updates: self.updates, + rlp_buf: self.rlp_buf, + } + } + /// Set the retention of branch node updates and deletions. pub fn with_updates(mut self, retain_updates: bool) -> Self { if retain_updates { @@ -357,176 +433,6 @@ impl RevealedSparseTrie { Ok(()) } - /// Remove leaf node from the trie. - pub fn remove_leaf(&mut self, path: &Nibbles) -> SparseTrieResult<()> { - self.prefix_set.insert(path.clone()); - self.values.remove(path); - - // If the path wasn't present in `values`, we still need to walk the trie and ensure that - // there is no node at the path. When a leaf node is a blinded `Hash`, it will have an entry - // in `nodes`, but not in the `values`. - - // If the path wasn't present in `values`, we still need to walk the trie and ensure that - // there is no node at the path. When a leaf node is a blinded `Hash`, it will have an entry - // in `nodes`, but not in the `values`. - - let mut removed_nodes = self.take_nodes_for_path(path)?; - trace!(target: "trie::sparse", ?path, ?removed_nodes, "Removed nodes for path"); - // Pop the first node from the stack which is the leaf node we want to remove. - let mut child = removed_nodes.pop().expect("leaf exists"); - #[cfg(debug_assertions)] - { - let mut child_path = child.path.clone(); - let SparseNode::Leaf { key, .. } = &child.node else { panic!("expected leaf node") }; - child_path.extend_from_slice_unchecked(key); - assert_eq!(&child_path, path); - } - - // If we don't have any other removed nodes, insert an empty node at the root. - if removed_nodes.is_empty() { - debug_assert!(self.nodes.is_empty()); - self.nodes.insert(Nibbles::default(), SparseNode::Empty); - - return Ok(()) - } - - // Walk the stack of removed nodes from the back and re-insert them back into the trie, - // adjusting the node type as needed. - while let Some(removed_node) = removed_nodes.pop() { - let removed_path = removed_node.path; - - let new_node = match &removed_node.node { - SparseNode::Empty => return Err(SparseTrieError::Blind), - SparseNode::Hash(hash) => { - return Err(SparseTrieError::BlindedNode { path: removed_path, hash: *hash }) - } - SparseNode::Leaf { .. } => { - unreachable!("we already popped the leaf node") - } - SparseNode::Extension { key, .. } => { - // If the node is an extension node, we need to look at its child to see if we - // need to merge them. - match &child.node { - SparseNode::Empty => return Err(SparseTrieError::Blind), - SparseNode::Hash(hash) => { - return Err(SparseTrieError::BlindedNode { - path: child.path, - hash: *hash, - }) - } - // For a leaf node, we collapse the extension node into a leaf node, - // extending the key. While it's impossible to encounter an extension node - // followed by a leaf node in a complete trie, it's possible here because we - // could have downgraded the extension node's child into a leaf node from - // another node type. - SparseNode::Leaf { key: leaf_key, .. } => { - self.nodes.remove(&child.path); - - let mut new_key = key.clone(); - new_key.extend_from_slice_unchecked(leaf_key); - SparseNode::new_leaf(new_key) - } - // For an extension node, we collapse them into one extension node, - // extending the key - SparseNode::Extension { key: extension_key, .. } => { - self.nodes.remove(&child.path); - - let mut new_key = key.clone(); - new_key.extend_from_slice_unchecked(extension_key); - SparseNode::new_ext(new_key) - } - // For a branch node, we just leave the extension node as-is. - SparseNode::Branch { .. } => removed_node.node, - } - } - SparseNode::Branch { mut state_mask, hash: _, store_in_db_trie: _ } => { - // If the node is a branch node, we need to check the number of children left - // after deleting the child at the given nibble. - - if let Some(removed_nibble) = removed_node.unset_branch_nibble { - state_mask.unset_bit(removed_nibble); - } - - // If only one child is left set in the branch node, we need to collapse it. - if state_mask.count_bits() == 1 { - let child_nibble = - state_mask.first_set_bit_index().expect("state mask is not empty"); - - // Get full path of the only child node left. - let mut child_path = removed_path.clone(); - child_path.push_unchecked(child_nibble); - - // Remove the only child node. - let child = self.nodes.get(&child_path).unwrap(); - - trace!(target: "trie::sparse", ?removed_path, ?child_path, ?child, "Branch node has only one child"); - - let mut delete_child = false; - let new_node = match child { - SparseNode::Empty => return Err(SparseTrieError::Blind), - SparseNode::Hash(hash) => { - return Err(SparseTrieError::BlindedNode { - path: child_path, - hash: *hash, - }) - } - // If the only child is a leaf node, we downgrade the branch node into a - // leaf node, prepending the nibble to the key, and delete the old - // child. - SparseNode::Leaf { key, .. } => { - delete_child = true; - - let mut new_key = Nibbles::from_nibbles_unchecked([child_nibble]); - new_key.extend_from_slice_unchecked(key); - SparseNode::new_leaf(new_key) - } - // If the only child node is an extension node, we downgrade the branch - // node into an even longer extension node, prepending the nibble to the - // key, and delete the old child. - SparseNode::Extension { key, .. } => { - delete_child = true; - - let mut new_key = Nibbles::from_nibbles_unchecked([child_nibble]); - new_key.extend_from_slice_unchecked(key); - SparseNode::new_ext(new_key) - } - // If the only child is a branch node, we downgrade the current branch - // node into a one-nibble extension node. - SparseNode::Branch { .. } => { - SparseNode::new_ext(Nibbles::from_nibbles_unchecked([child_nibble])) - } - }; - - if delete_child { - self.nodes.remove(&child_path); - } - - if let Some(updates) = self.updates.as_mut() { - updates.removed_nodes.insert(removed_path.clone()); - } - - new_node - } - // If more than one child is left set in the branch, we just re-insert it - // as-is. - else { - SparseNode::new_branch(state_mask) - } - } - }; - - child = RemovedSparseNode { - path: removed_path.clone(), - node: new_node.clone(), - unset_branch_nibble: None, - }; - trace!(target: "trie::sparse", ?removed_path, ?new_node, "Re-inserting the node"); - self.nodes.insert(removed_path, new_node); - } - - Ok(()) - } - /// Traverse trie nodes down to the leaf node and collect all nodes along the path. fn take_nodes_for_path(&mut self, path: &Nibbles) -> SparseTrieResult> { let mut current = Nibbles::default(); // Start traversal from the root @@ -621,10 +527,10 @@ impl RevealedSparseTrie { /// Wipe the trie, removing all values and nodes, and replacing the root with an empty node. pub fn wipe(&mut self) { - let updates_retained = self.updates.is_some(); - *self = Self::default(); + self.nodes = HashMap::from_iter([(Nibbles::default(), SparseNode::Empty)]); + self.values = HashMap::default(); self.prefix_set = PrefixSetMut::all(); - self.updates = updates_retained.then(SparseTrieUpdates::wiped); + self.updates = self.updates.is_some().then(SparseTrieUpdates::wiped); } /// Return the root of the sparse trie. @@ -901,6 +807,191 @@ impl RevealedSparseTrie { } } +impl

RevealedSparseTrie

+where + P: BlindedProvider, + SparseTrieError: From, +{ + /// Remove leaf node from the trie. + pub fn remove_leaf(&mut self, path: &Nibbles) -> SparseTrieResult<()> { + self.prefix_set.insert(path.clone()); + self.values.remove(path); + + // If the path wasn't present in `values`, we still need to walk the trie and ensure that + // there is no node at the path. When a leaf node is a blinded `Hash`, it will have an entry + // in `nodes`, but not in the `values`. + + // If the path wasn't present in `values`, we still need to walk the trie and ensure that + // there is no node at the path. When a leaf node is a blinded `Hash`, it will have an entry + // in `nodes`, but not in the `values`. + + let mut removed_nodes = self.take_nodes_for_path(path)?; + trace!(target: "trie::sparse", ?path, ?removed_nodes, "Removed nodes for path"); + // Pop the first node from the stack which is the leaf node we want to remove. + let mut child = removed_nodes.pop().expect("leaf exists"); + #[cfg(debug_assertions)] + { + let mut child_path = child.path.clone(); + let SparseNode::Leaf { key, .. } = &child.node else { panic!("expected leaf node") }; + child_path.extend_from_slice_unchecked(key); + assert_eq!(&child_path, path); + } + + // If we don't have any other removed nodes, insert an empty node at the root. + if removed_nodes.is_empty() { + debug_assert!(self.nodes.is_empty()); + self.nodes.insert(Nibbles::default(), SparseNode::Empty); + + return Ok(()) + } + + // Walk the stack of removed nodes from the back and re-insert them back into the trie, + // adjusting the node type as needed. + while let Some(removed_node) = removed_nodes.pop() { + let removed_path = removed_node.path; + + let new_node = match &removed_node.node { + SparseNode::Empty => return Err(SparseTrieError::Blind), + SparseNode::Hash(hash) => { + return Err(SparseTrieError::BlindedNode { path: removed_path, hash: *hash }) + } + SparseNode::Leaf { .. } => { + unreachable!("we already popped the leaf node") + } + SparseNode::Extension { key, .. } => { + // If the node is an extension node, we need to look at its child to see if we + // need to merge them. + match &child.node { + SparseNode::Empty => return Err(SparseTrieError::Blind), + SparseNode::Hash(hash) => { + return Err(SparseTrieError::BlindedNode { + path: child.path, + hash: *hash, + }) + } + // For a leaf node, we collapse the extension node into a leaf node, + // extending the key. While it's impossible to encounter an extension node + // followed by a leaf node in a complete trie, it's possible here because we + // could have downgraded the extension node's child into a leaf node from + // another node type. + SparseNode::Leaf { key: leaf_key, .. } => { + self.nodes.remove(&child.path); + + let mut new_key = key.clone(); + new_key.extend_from_slice_unchecked(leaf_key); + SparseNode::new_leaf(new_key) + } + // For an extension node, we collapse them into one extension node, + // extending the key + SparseNode::Extension { key: extension_key, .. } => { + self.nodes.remove(&child.path); + + let mut new_key = key.clone(); + new_key.extend_from_slice_unchecked(extension_key); + SparseNode::new_ext(new_key) + } + // For a branch node, we just leave the extension node as-is. + SparseNode::Branch { .. } => removed_node.node, + } + } + SparseNode::Branch { mut state_mask, hash: _, store_in_db_trie: _ } => { + // If the node is a branch node, we need to check the number of children left + // after deleting the child at the given nibble. + + if let Some(removed_nibble) = removed_node.unset_branch_nibble { + state_mask.unset_bit(removed_nibble); + } + + // If only one child is left set in the branch node, we need to collapse it. + if state_mask.count_bits() == 1 { + let child_nibble = + state_mask.first_set_bit_index().expect("state mask is not empty"); + + // Get full path of the only child node left. + let mut child_path = removed_path.clone(); + child_path.push_unchecked(child_nibble); + + trace!(target: "trie::sparse", ?removed_path, ?child_path, ?child, "Branch node has only one child"); + + if self.nodes.get(&child_path).unwrap().is_hash() { + trace!(target: "trie::sparse", ?child_path, "Retrieving remaining blinded branch child"); + if let Some(node) = self.provider.blinded_node(child_path.clone())? { + let decoded = TrieNode::decode(&mut &node[..])?; + trace!(target: "trie::sparse", ?child_path, ?decoded, "Revealing remaining blinded branch child"); + self.reveal_node(child_path.clone(), decoded)?; + } + } + + // Get the only child node. + let child = self.nodes.get(&child_path).unwrap(); + + let mut delete_child = false; + let new_node = match child { + SparseNode::Empty => return Err(SparseTrieError::Blind), + SparseNode::Hash(hash) => { + return Err(SparseTrieError::BlindedNode { + path: child_path, + hash: *hash, + }) + } + // If the only child is a leaf node, we downgrade the branch node into a + // leaf node, prepending the nibble to the key, and delete the old + // child. + SparseNode::Leaf { key, .. } => { + delete_child = true; + + let mut new_key = Nibbles::from_nibbles_unchecked([child_nibble]); + new_key.extend_from_slice_unchecked(key); + SparseNode::new_leaf(new_key) + } + // If the only child node is an extension node, we downgrade the branch + // node into an even longer extension node, prepending the nibble to the + // key, and delete the old child. + SparseNode::Extension { key, .. } => { + delete_child = true; + + let mut new_key = Nibbles::from_nibbles_unchecked([child_nibble]); + new_key.extend_from_slice_unchecked(key); + SparseNode::new_ext(new_key) + } + // If the only child is a branch node, we downgrade the current branch + // node into a one-nibble extension node. + SparseNode::Branch { .. } => { + SparseNode::new_ext(Nibbles::from_nibbles_unchecked([child_nibble])) + } + }; + + if delete_child { + self.nodes.remove(&child_path); + } + + if let Some(updates) = self.updates.as_mut() { + updates.removed_nodes.insert(removed_path.clone()); + } + + new_node + } + // If more than one child is left set in the branch, we just re-insert it + // as-is. + else { + SparseNode::new_branch(state_mask) + } + } + }; + + child = RemovedSparseNode { + path: removed_path.clone(), + node: new_node.clone(), + unset_branch_nibble: None, + }; + trace!(target: "trie::sparse", ?removed_path, ?new_node, "Re-inserting the node"); + self.nodes.insert(removed_path, new_node); + } + + Ok(()) + } +} + /// Enum representing sparse trie node type. #[derive(Debug, Clone, Copy, PartialEq, Eq)] enum SparseNodeType { @@ -1007,6 +1098,11 @@ impl SparseNode { pub const fn new_leaf(key: Nibbles) -> Self { Self::Leaf { key, hash: None } } + + /// Returns `true` if the node is a hash node. + pub const fn is_hash(&self) -> bool { + matches!(self, Self::Hash(_)) + } } #[derive(Debug)] @@ -1190,7 +1286,7 @@ mod tests { #[test] fn sparse_trie_is_blind() { - assert!(SparseTrie::default().is_blind()); + assert!(SparseTrie::blind().is_blind()); assert!(!SparseTrie::revealed_empty().is_blind()); } From 1134c5d61ac4e8d596b2eaa41b5d569eb39d0ee3 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Mon, 2 Dec 2024 11:12:31 +0100 Subject: [PATCH 07/68] chore: mark ethereum-forks as rv32imac (#13053) --- .github/assets/check_rv32imac.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/assets/check_rv32imac.sh b/.github/assets/check_rv32imac.sh index 0112e5cec175..9a66da9fe3b3 100755 --- a/.github/assets/check_rv32imac.sh +++ b/.github/assets/check_rv32imac.sh @@ -4,6 +4,7 @@ set +e # Disable immediate exit on error # Array of crates to check crates_to_check=( reth-codecs-derive + reth-ethereum-forks # reth-evm # reth-primitives # reth-primitives-traits From 4f19fc67b13abe7c4823a806392ef380c5efb357 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 10:15:55 +0000 Subject: [PATCH 08/68] chore(deps): weekly `cargo update` (#13043) Co-authored-by: github-merge-queue <118344674+github-merge-queue@users.noreply.github.com> Co-authored-by: Roman Krasiuk --- Cargo.lock | 349 +++++++++++++++++++------------------- crates/tracing/Cargo.toml | 2 +- 2 files changed, 176 insertions(+), 175 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8f68f71bffb8..0116e251cca5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -166,9 +166,9 @@ dependencies = [ [[package]] name = "alloy-dyn-abi" -version = "0.8.12" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2364c782a245cf8725ea6dbfca5f530162702b5d685992ea03ce64529136cc" +checksum = "80759b3f57b3b20fa7cd8fef6479930fc95461b58ff8adea6e87e618449c8a1d" dependencies = [ "alloy-json-abi", "alloy-primitives", @@ -197,9 +197,9 @@ dependencies = [ [[package]] name = "alloy-eip7702" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6cee6a35793f3db8a5ffe60e86c695f321d081a567211245f503e8c498fce8" +checksum = "4c986539255fb839d1533c128e190e557e52ff652c9ef62939e233a81dd93f7e" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -245,9 +245,9 @@ dependencies = [ [[package]] name = "alloy-json-abi" -version = "0.8.12" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b84c506bf264110fa7e90d9924f742f40ef53c6572ea56a0b0bd714a567ed389" +checksum = "ac4b22b3e51cac09fd2adfcc73b55f447b4df669f983c13f7894ec82b607c63f" dependencies = [ "alloy-primitives", "alloy-sol-type-parser", @@ -326,9 +326,9 @@ dependencies = [ [[package]] name = "alloy-primitives" -version = "0.8.12" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fce5dbd6a4f118eecc4719eaa9c7ffc31c315e6c5ccde3642db927802312425" +checksum = "9db948902dfbae96a73c2fbf1f7abec62af034ab883e4c777c3fd29702bd6e2c" dependencies = [ "alloy-rlp", "arbitrary", @@ -339,7 +339,7 @@ dependencies = [ "derive_more 1.0.0", "foldhash", "getrandom 0.2.15", - "hashbrown 0.15.1", + "hashbrown 0.15.2", "hex-literal", "indexmap 2.6.0", "itoa", @@ -350,7 +350,7 @@ dependencies = [ "proptest-derive", "rand 0.8.5", "ruint", - "rustc-hash 2.0.0", + "rustc-hash 2.1.0", "serde", "sha3", "tiny-keccak", @@ -435,7 +435,7 @@ checksum = "2b09cae092c27b6f1bde952653a22708691802e57bfef4a2973b80bea21efd3f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -665,23 +665,23 @@ dependencies = [ [[package]] name = "alloy-sol-macro" -version = "0.8.12" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9343289b4a7461ed8bab8618504c995c049c082b70c7332efd7b32125633dc05" +checksum = "3bfd7853b65a2b4f49629ec975fee274faf6dff15ab8894c620943398ef283c0" dependencies = [ "alloy-sol-macro-expander", "alloy-sol-macro-input", "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] name = "alloy-sol-macro-expander" -version = "0.8.12" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4222d70bec485ceccc5d8fd4f2909edd65b5d5e43d4aca0b5dcee65d519ae98f" +checksum = "82ec42f342d9a9261699f8078e57a7a4fda8aaa73c1a212ed3987080e6a9cd13" dependencies = [ "alloy-sol-macro-input", "const-hex", @@ -690,31 +690,31 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "syn-solidity", "tiny-keccak", ] [[package]] name = "alloy-sol-macro-input" -version = "0.8.12" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e17f2677369571b976e51ea1430eb41c3690d344fef567b840bfc0b01b6f83a" +checksum = "ed2c50e6a62ee2b4f7ab3c6d0366e5770a21cad426e109c2f40335a1b3aff3df" dependencies = [ "const-hex", "dunce", "heck", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "syn-solidity", ] [[package]] name = "alloy-sol-type-parser" -version = "0.8.12" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa64d80ae58ffaafdff9d5d84f58d03775f66c84433916dc9a64ed16af5755da" +checksum = "ac17c6e89a50fb4a758012e4b409d9a0ba575228e69b539fe37d7a1bd507ca4a" dependencies = [ "serde", "winnow", @@ -722,9 +722,9 @@ dependencies = [ [[package]] name = "alloy-sol-types" -version = "0.8.12" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6520d427d4a8eb7aa803d852d7a52ceb0c519e784c292f64bb339e636918cf27" +checksum = "c9dc0fffe397aa17628160e16b89f704098bf3c9d74d5d369ebc239575936de5" dependencies = [ "alloy-json-abi", "alloy-primitives", @@ -912,7 +912,7 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -1135,7 +1135,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -1146,7 +1146,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -1184,7 +1184,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -1290,7 +1290,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -1387,7 +1387,7 @@ dependencies = [ "boa_macros", "indexmap 2.6.0", "num-bigint", - "rustc-hash 2.0.0", + "rustc-hash 2.1.0", ] [[package]] @@ -1423,7 +1423,7 @@ dependencies = [ "portable-atomic", "rand 0.8.5", "regress", - "rustc-hash 2.0.0", + "rustc-hash 2.1.0", "ryu-js", "serde", "serde_json", @@ -1460,7 +1460,7 @@ dependencies = [ "indexmap 2.6.0", "once_cell", "phf", - "rustc-hash 2.0.0", + "rustc-hash 2.1.0", "static_assertions", ] @@ -1472,7 +1472,7 @@ checksum = "240f4126219a83519bad05c9a40bfc0303921eeb571fc2d7e44c17ffac99d3f1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "synstructure", ] @@ -1492,7 +1492,7 @@ dependencies = [ "num-bigint", "num-traits", "regress", - "rustc-hash 2.0.0", + "rustc-hash 2.1.0", ] [[package]] @@ -1509,7 +1509,7 @@ checksum = "ae85205289bab1f2c7c8a30ddf0541cf89ba2ff7dbd144feef50bbfa664288d4" dependencies = [ "fast-float", "paste", - "rustc-hash 2.0.0", + "rustc-hash 2.1.0", "sptr", "static_assertions", ] @@ -1594,7 +1594,7 @@ checksum = "bcfcc3cd946cb52f0bbfdbbcfa2f4e24f75ebb6c0e1002f7c25904fada18b9ec" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -1605,9 +1605,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" +checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" dependencies = [ "serde", ] @@ -1638,9 +1638,9 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" +checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" dependencies = [ "serde", ] @@ -1682,9 +1682,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47" +checksum = "f34d93e62b03caf570cccc334cbc6c2fceca82f39211051345108adcba3eebdc" dependencies = [ "jobserver", "libc", @@ -1812,7 +1812,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -1946,9 +1946,9 @@ dependencies = [ [[package]] name = "const-hex" -version = "1.13.2" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "487981fa1af147182687064d0a2c336586d337a606595ced9ffb0c685c250c73" +checksum = "4b0485bab839b018a8f1723fc5391819fea5f8f0f32288ef8a735fd096b6160c" dependencies = [ "cfg-if", "cpufeatures", @@ -2156,7 +2156,7 @@ checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" dependencies = [ "bitflags 2.6.0", "crossterm_winapi", - "mio 1.0.2", + "mio 1.0.3", "parking_lot", "rustix", "signal-hook", @@ -2266,7 +2266,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -2290,7 +2290,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -2301,7 +2301,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -2423,7 +2423,7 @@ checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -2434,7 +2434,7 @@ checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -2455,7 +2455,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "unicode-xid", ] @@ -2569,7 +2569,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -2719,7 +2719,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -2730,7 +2730,7 @@ checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -2741,12 +2741,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -2787,7 +2787,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -3348,7 +3348,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -3584,9 +3584,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.1" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" dependencies = [ "allocator-api2", "equivalent", @@ -3732,9 +3732,9 @@ dependencies = [ [[package]] name = "http-range-header" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08a397c49fec283e3d6211adbe480be95aae5f304cfb923e9970e08956d5168a" +checksum = "9171a2ea8a68358193d15dd5d70c1c10a2afc3e7e4c5bc92bc9f025cebd7359c" [[package]] name = "http-types" @@ -3874,7 +3874,7 @@ dependencies = [ "quote", "serde", "serde_json", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -4024,7 +4024,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -4091,7 +4091,7 @@ checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -4138,7 +4138,7 @@ checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "arbitrary", "equivalent", - "hashbrown 0.15.1", + "hashbrown 0.15.2", "serde", ] @@ -4213,7 +4213,7 @@ dependencies = [ "pretty_assertions", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -4314,9 +4314,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "540654e97a3f4470a492cd30ff187bc95d89557a903a2bbf112e2fae98104ef2" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "jni" @@ -4349,10 +4349,11 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.72" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +checksum = "a865e038f7f6ed956f788f0d7d60c541fff74c7bd74272c5d4cf15c63743e705" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -4416,7 +4417,7 @@ dependencies = [ "parking_lot", "pin-project", "rand 0.8.5", - "rustc-hash 2.0.0", + "rustc-hash 2.1.0", "serde", "serde_json", "thiserror 1.0.69", @@ -4461,7 +4462,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -4621,15 +4622,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.165" +version = "0.2.167" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb4d3d38eab6c5239a362fa8bae48c03baf980a6e7079f063942d563ef3533e" +checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc" [[package]] name = "libloading" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", "windows-targets 0.52.6", @@ -4794,7 +4795,7 @@ version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" dependencies = [ - "hashbrown 0.15.1", + "hashbrown 0.15.2", ] [[package]] @@ -4862,9 +4863,9 @@ dependencies = [ [[package]] name = "metrics" -version = "0.24.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae428771d17306715c5091d446327d1cfdedc82185c65ba8423ab404e45bf10" +checksum = "7a7deb012b3b2767169ff203fadb4c6b0b82b947512e5eb9e0b78c2e186ad9e3" dependencies = [ "ahash", "portable-atomic", @@ -4879,7 +4880,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -4898,9 +4899,9 @@ dependencies = [ [[package]] name = "metrics-process" -version = "2.3.1" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57ca8ecd85575fbb143b2678cb123bb818779391ec0f745b1c4a9dbabadde407" +checksum = "4a82c8add4382f29a122fa64fff1891453ed0f6b2867d971e7d60cb8dfa322ff" dependencies = [ "libc", "libproc", @@ -4920,7 +4921,7 @@ checksum = "15b482df36c13dd1869d73d14d28cd4855fbd6cfc32294bee109908a9f4a4ed7" dependencies = [ "crossbeam-epoch", "crossbeam-utils", - "hashbrown 0.15.1", + "hashbrown 0.15.2", "indexmap 2.6.0", "metrics", "ordered-float", @@ -4993,11 +4994,10 @@ dependencies = [ [[package]] name = "mio" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ - "hermit-abi 0.3.9", "libc", "log", "wasi 0.11.0+wasi-snapshot-preview1", @@ -5027,7 +5027,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -5275,7 +5275,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -5537,7 +5537,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -5652,7 +5652,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -5681,7 +5681,7 @@ checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -5853,7 +5853,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" dependencies = [ "proc-macro2", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -5904,7 +5904,7 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -6002,7 +6002,7 @@ checksum = "6ff7ff745a347b87471d859a377a9a404361e7efc2a971d73424a6d183c0fc77" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -6054,7 +6054,7 @@ dependencies = [ "pin-project-lite", "quinn-proto", "quinn-udp", - "rustc-hash 2.0.0", + "rustc-hash 2.1.0", "rustls", "socket2", "thiserror 2.0.3", @@ -6072,7 +6072,7 @@ dependencies = [ "getrandom 0.2.15", "rand 0.8.5", "ring", - "rustc-hash 2.0.0", + "rustc-hash 2.1.0", "rustls", "rustls-pki-types", "slab", @@ -6815,7 +6815,7 @@ dependencies = [ "proc-macro2", "quote", "similar-asserts", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -6918,7 +6918,7 @@ dependencies = [ "reth-storage-errors", "reth-tracing", "reth-trie-common", - "rustc-hash 2.0.0", + "rustc-hash 2.1.0", "serde", "serde_json", "strum", @@ -7498,7 +7498,7 @@ dependencies = [ "once_cell", "proptest", "proptest-derive", - "rustc-hash 2.0.0", + "rustc-hash 2.1.0", "serde", "thiserror 2.0.3", ] @@ -7884,7 +7884,7 @@ dependencies = [ "reth-tokio-util", "reth-tracing", "reth-transaction-pool", - "rustc-hash 2.0.0", + "rustc-hash 2.1.0", "schnellru", "secp256k1", "serde", @@ -8751,7 +8751,7 @@ dependencies = [ "reth-testing-utils", "reth-tokio-util", "reth-tracing", - "rustc-hash 2.0.0", + "rustc-hash 2.1.0", "thiserror 2.0.3", "tokio", "tracing", @@ -9388,7 +9388,7 @@ dependencies = [ "reth-tasks", "reth-tracing", "revm", - "rustc-hash 2.0.0", + "rustc-hash 2.1.0", "schnellru", "serde", "serde_json", @@ -9712,9 +9712,9 @@ dependencies = [ [[package]] name = "roaring" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f4b84ba6e838ceb47b41de5194a60244fac43d9fe03b71dbe8c5a201081d6d1" +checksum = "f81dc953b2244ddd5e7860cb0bb2a790494b898ef321d4aff8e260efab60cc88" dependencies = [ "bytemuck", "byteorder", @@ -9762,7 +9762,7 @@ dependencies = [ "regex", "relative-path", "rustc_version 0.4.1", - "syn 2.0.89", + "syn 2.0.90", "unicode-ident", ] @@ -9811,9 +9811,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustc-hash" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" +checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497" dependencies = [ "rand 0.8.5", ] @@ -9857,9 +9857,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.18" +version = "0.23.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9cc1d47e243d655ace55ed38201c19ae02c148ae56412ab8750e8f0166ab7f" +checksum = "934b404430bb06b3fae2cba809eb45a1ab1aecd64491213d7c3301b88393f8d1" dependencies = [ "log", "once_cell", @@ -10164,7 +10164,7 @@ checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -10199,7 +10199,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -10250,7 +10250,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -10273,7 +10273,7 @@ checksum = "5d69265a08751de7844521fd15003ae0a888e035773ba05695c5c759a6f89eef" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -10372,7 +10372,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" dependencies = [ "libc", - "mio 1.0.2", + "mio 1.0.3", "signal-hook", ] @@ -10467,9 +10467,9 @@ checksum = "1b6b67fb9a61334225b5b790716f609cd58395f895b3fe8b328786812a40bc3b" [[package]] name = "socket2" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" dependencies = [ "libc", "windows-sys 0.52.0", @@ -10556,7 +10556,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -10580,9 +10580,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "symbolic-common" -version = "12.12.1" +version = "12.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d4d73159efebfb389d819fd479afb2dbd57dcb3e3f4b7fcfa0e675f5a46c1cb" +checksum = "e5ba5365997a4e375660bed52f5b42766475d5bc8ceb1bb13fea09c469ea0f49" dependencies = [ "debugid", "memmap2", @@ -10592,9 +10592,9 @@ dependencies = [ [[package]] name = "symbolic-demangle" -version = "12.12.1" +version = "12.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a767859f6549c665011970874c3f541838b4835d5aaaa493d3ee383918be9f10" +checksum = "beff338b2788519120f38c59ff4bb15174f52a183e547bac3d6072c2c0aa48aa" dependencies = [ "cpp_demangle", "rustc-demangle", @@ -10614,9 +10614,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.89" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ "proc-macro2", "quote", @@ -10625,14 +10625,14 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "0.8.12" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f76fe0a3e1476bdaa0775b9aec5b869ed9520c2b2fedfe9c6df3618f8ea6290b" +checksum = "da0523f59468a2696391f2a772edc089342aacd53c3caa2ac3264e598edf119b" dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -10658,7 +10658,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -10735,7 +10735,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -10783,7 +10783,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -10794,7 +10794,7 @@ checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -10934,7 +10934,7 @@ dependencies = [ "backtrace", "bytes", "libc", - "mio 1.0.2", + "mio 1.0.3", "parking_lot", "pin-project-lite", "signal-hook-registry", @@ -10951,7 +10951,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -11122,9 +11122,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "log", "pin-project-lite", @@ -11146,20 +11146,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", "valuable", @@ -11177,9 +11177,9 @@ dependencies = [ [[package]] name = "tracing-journald" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba316a74e8fc3c3896a850dba2375928a9fa171b085ecddfc7c054d39970f3fd" +checksum = "fc0b4143302cf1022dac868d521e36e8b27691f72c84b3311750d5188ebba657" dependencies = [ "libc", "tracing-core", @@ -11211,9 +11211,9 @@ dependencies = [ [[package]] name = "tracing-serde" -version = "0.1.3" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" +checksum = "704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1" dependencies = [ "serde", "tracing-core", @@ -11221,9 +11221,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" dependencies = [ "matchers", "nu-ansi-term", @@ -11550,7 +11550,7 @@ checksum = "d674d135b4a8c1d7e813e2f8d1c9a58308aee4a680323066025e53132218bd91" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -11601,9 +11601,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +checksum = "d15e63b4482863c109d70a7b8706c1e364eb6ea449b201a76c5b89cedcec2d5c" dependencies = [ "cfg-if", "once_cell", @@ -11612,36 +11612,37 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +checksum = "8d36ef12e3aaca16ddd3f67922bc63e48e953f126de60bd33ccc0101ef9998cd" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.45" +version = "0.4.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" +checksum = "9dfaf8f50e5f293737ee323940c7d8b08a66a95a419223d9f41610ca08b0833d" dependencies = [ "cfg-if", "js-sys", + "once_cell", "wasm-bindgen", "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +checksum = "705440e08b42d3e4b36de7d66c944be628d579796b8090bfa3471478a2260051" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -11649,22 +11650,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +checksum = "98c9ae5a76e46f4deecd0f0255cc223cfa18dc9b261213b8aa0c7b36f61b3f1d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" +checksum = "6ee99da9c5ba11bd675621338ef6fa52296b76b83305e9b6e5c77d4c286d6d49" [[package]] name = "wasm-streams" @@ -11695,9 +11696,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.72" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" +checksum = "a98bc3c33f0fe7e59ad7cd041b89034fa82a7c2d4365ca538dda6cdaf513863c" dependencies = [ "js-sys", "wasm-bindgen", @@ -11821,7 +11822,7 @@ checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -11832,7 +11833,7 @@ checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -11843,7 +11844,7 @@ checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -11854,7 +11855,7 @@ checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -12129,7 +12130,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "synstructure", ] @@ -12151,7 +12152,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -12171,7 +12172,7 @@ checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "synstructure", ] @@ -12192,7 +12193,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -12214,7 +12215,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] diff --git a/crates/tracing/Cargo.toml b/crates/tracing/Cargo.toml index 59631365d603..d944b5eeeb61 100644 --- a/crates/tracing/Cargo.toml +++ b/crates/tracing/Cargo.toml @@ -13,7 +13,7 @@ workspace = true [dependencies] tracing.workspace = true -tracing-subscriber = { version = "0.3", default-features = false, features = ["env-filter", "fmt", "json"] } +tracing-subscriber = { version = "0.3", default-features = false, features = ["env-filter", "fmt", "ansi", "json"] } tracing-appender.workspace = true tracing-journald = "0.3" tracing-logfmt = "0.3.3" From cccbd90e7b09163a14971a26ced9bba179267eed Mon Sep 17 00:00:00 2001 From: Alexey Shekhirin Date: Mon, 2 Dec 2024 11:09:03 +0000 Subject: [PATCH 09/68] docs(trie): duplicate comment in sparse trie (#13056) --- crates/trie/sparse/src/trie.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/crates/trie/sparse/src/trie.rs b/crates/trie/sparse/src/trie.rs index 0dd6dc989c14..dd609a77c99c 100644 --- a/crates/trie/sparse/src/trie.rs +++ b/crates/trie/sparse/src/trie.rs @@ -821,10 +821,6 @@ where // there is no node at the path. When a leaf node is a blinded `Hash`, it will have an entry // in `nodes`, but not in the `values`. - // If the path wasn't present in `values`, we still need to walk the trie and ensure that - // there is no node at the path. When a leaf node is a blinded `Hash`, it will have an entry - // in `nodes`, but not in the `values`. - let mut removed_nodes = self.take_nodes_for_path(path)?; trace!(target: "trie::sparse", ?path, ?removed_nodes, "Removed nodes for path"); // Pop the first node from the stack which is the leaf node we want to remove. From 3855519a5083c4cb3631e4dcc7505e79cda2aba0 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Mon, 2 Dec 2024 12:19:20 +0100 Subject: [PATCH 10/68] chore: disable revm primitives workspace default features (#13055) --- Cargo.toml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d0f32114944b..001a66bc4f89 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -424,9 +424,7 @@ reth-trie-sparse = { path = "crates/trie/sparse" } # revm revm = { version = "18.0.0", features = ["std"], default-features = false } revm-inspectors = "0.12.0" -revm-primitives = { version = "14.0.0", features = [ - "std", -], default-features = false } +revm-primitives = { version = "14.0.0", default-features = false } # eth alloy-chains = { version = "0.1.32", default-features = false } From 1b34f3e78d5fcd01a3701645b4a8364c7f2c5a2f Mon Sep 17 00:00:00 2001 From: Querty <98064975+Quertyy@users.noreply.github.com> Date: Mon, 2 Dec 2024 20:19:34 +0900 Subject: [PATCH 11/68] feat(rpc): enhance `eth_getLogs` error handling with block range feedback (#12790) Co-authored-by: Matthias Seitz --- crates/rpc/rpc/src/eth/filter.rs | 38 +++++++++++++++++++------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/crates/rpc/rpc/src/eth/filter.rs b/crates/rpc/rpc/src/eth/filter.rs index 132d99a5c1a3..200afadaa2e9 100644 --- a/crates/rpc/rpc/src/eth/filter.rs +++ b/crates/rpc/rpc/src/eth/filter.rs @@ -1,14 +1,5 @@ //! `eth_` `Filter` RPC handler implementation -use std::{ - collections::HashMap, - fmt, - iter::StepBy, - ops::RangeInclusive, - sync::Arc, - time::{Duration, Instant}, -}; - use alloy_primitives::TxHash; use alloy_rpc_types_eth::{ BlockNumHash, Filter, FilterBlockOption, FilterChanges, FilterId, FilteredParams, Log, @@ -30,6 +21,14 @@ use reth_rpc_server_types::{result::rpc_error_with_code, ToRpcResult}; use reth_rpc_types_compat::transaction::from_recovered; use reth_tasks::TaskSpawner; use reth_transaction_pool::{NewSubpoolTransactionStream, PoolTransaction, TransactionPool}; +use std::{ + collections::HashMap, + fmt, + iter::StepBy, + ops::RangeInclusive, + sync::Arc, + time::{Duration, Instant}, +}; use tokio::{ sync::{mpsc::Receiver, Mutex}, time::MissedTickBehavior, @@ -517,9 +516,11 @@ where // logs of a single block let is_multi_block_range = from_block != to_block; if is_multi_block_range && all_logs.len() > self.max_logs_per_response { - return Err(EthFilterError::QueryExceedsMaxResults( - self.max_logs_per_response, - )) + return Err(EthFilterError::QueryExceedsMaxResults { + max_logs: self.max_logs_per_response, + from_block, + to_block: num_hash.number.saturating_sub(1), + }); } } } @@ -724,8 +725,15 @@ pub enum EthFilterError { #[error("query exceeds max block range {0}")] QueryExceedsMaxBlocks(u64), /// Query result is too large. - #[error("query exceeds max results {0}")] - QueryExceedsMaxResults(usize), + #[error("query exceeds max results {max_logs}, retry with the range {from_block}-{to_block}")] + QueryExceedsMaxResults { + /// Maximum number of logs allowed per response + max_logs: usize, + /// Start block of the suggested retry range + from_block: u64, + /// End block of the suggested retry range (last successfully processed block) + to_block: u64, + }, /// Error serving request in `eth_` namespace. #[error(transparent)] EthAPIError(#[from] EthApiError), @@ -747,7 +755,7 @@ impl From for jsonrpsee::types::error::ErrorObject<'static> { EthFilterError::EthAPIError(err) => err.into(), err @ (EthFilterError::InvalidBlockRangeParams | EthFilterError::QueryExceedsMaxBlocks(_) | - EthFilterError::QueryExceedsMaxResults(_)) => { + EthFilterError::QueryExceedsMaxResults { .. }) => { rpc_error_with_code(jsonrpsee::types::error::INVALID_PARAMS_CODE, err.to_string()) } } From 088461166831ee87083d2b82f58bda9595ea55b8 Mon Sep 17 00:00:00 2001 From: Roman Krasiuk Date: Mon, 2 Dec 2024 12:25:40 +0100 Subject: [PATCH 12/68] chore(trie): remove infallible variant (#13057) --- crates/trie/sparse/src/blinded.rs | 3 +-- crates/trie/sparse/src/errors.rs | 8 +------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/crates/trie/sparse/src/blinded.rs b/crates/trie/sparse/src/blinded.rs index 3875e819da63..592f5e7bcd06 100644 --- a/crates/trie/sparse/src/blinded.rs +++ b/crates/trie/sparse/src/blinded.rs @@ -3,7 +3,6 @@ use crate::SparseTrieError; use alloy_primitives::Bytes; use reth_trie_common::Nibbles; -use std::convert::Infallible; /// Factory for instantiating blinded node providers. pub trait BlindedProviderFactory { @@ -50,7 +49,7 @@ impl BlindedProviderFactory for DefaultBlindedProviderFactory { pub struct DefaultBlindedProvider; impl BlindedProvider for DefaultBlindedProvider { - type Error = Infallible; + type Error = SparseTrieError; fn blinded_node(&mut self, _path: Nibbles) -> Result, Self::Error> { Ok(None) diff --git a/crates/trie/sparse/src/errors.rs b/crates/trie/sparse/src/errors.rs index ca3b279ce421..20545957e1cd 100644 --- a/crates/trie/sparse/src/errors.rs +++ b/crates/trie/sparse/src/errors.rs @@ -1,13 +1,10 @@ //! Errors for sparse trie. -use std::convert::Infallible; - +use crate::SparseNode; use alloy_primitives::{Bytes, B256}; use reth_trie_common::Nibbles; use thiserror::Error; -use crate::SparseNode; - /// Result type with [`SparseStateTrieError`] as error. pub type SparseStateTrieResult = Result; @@ -58,7 +55,4 @@ pub enum SparseTrieError { /// RLP error. #[error(transparent)] Rlp(#[from] alloy_rlp::Error), - /// Infallible. - #[error(transparent)] - Infallible(#[from] Infallible), } From 8d5668a23ac9b4ec828f8b78e518b6d4858d9499 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Mon, 2 Dec 2024 12:29:54 +0100 Subject: [PATCH 13/68] chore: disable reth-ethereum-forks default features in workspace (#13054) --- Cargo.lock | 1 + Cargo.toml | 2 +- crates/chainspec/Cargo.toml | 3 +- crates/ethereum/evm/Cargo.toml | 3 +- crates/evm/Cargo.toml | 23 ++++++++------- crates/net/discv4/Cargo.toml | 3 +- crates/net/dns/Cargo.toml | 3 +- crates/net/eth-wire-types/Cargo.toml | 39 +++++++++++++------------ crates/net/eth-wire-types/src/status.rs | 2 +- crates/net/eth-wire/Cargo.toml | 1 + crates/net/network-api/Cargo.toml | 3 +- crates/net/network-types/Cargo.toml | 6 +++- crates/net/network/Cargo.toml | 1 + crates/optimism/evm/Cargo.toml | 3 +- crates/optimism/hardforks/Cargo.toml | 6 ++-- crates/primitives/Cargo.toml | 3 +- crates/revm/Cargo.toml | 26 +++++++++-------- 17 files changed, 75 insertions(+), 53 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0116e251cca5..9a3521dccb2a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7431,6 +7431,7 @@ dependencies = [ "rand 0.8.5", "reth-chainspec", "reth-codecs-derive", + "reth-ethereum-forks", "reth-primitives", "reth-primitives-traits", "serde", diff --git a/Cargo.toml b/Cargo.toml index 001a66bc4f89..521cfd88f8a9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -339,7 +339,7 @@ reth-eth-wire-types = { path = "crates/net/eth-wire-types" } reth-ethereum-cli = { path = "crates/ethereum/cli" } reth-ethereum-consensus = { path = "crates/ethereum/consensus" } reth-ethereum-engine-primitives = { path = "crates/ethereum/engine-primitives" } -reth-ethereum-forks = { path = "crates/ethereum-forks" } +reth-ethereum-forks = { path = "crates/ethereum-forks", default-features = false } reth-ethereum-payload-builder = { path = "crates/ethereum/payload" } reth-etl = { path = "crates/etl" } reth-evm = { path = "crates/evm" } diff --git a/crates/chainspec/Cargo.toml b/crates/chainspec/Cargo.toml index 58b2f62b1a6e..e5f6c058c622 100644 --- a/crates/chainspec/Cargo.toml +++ b/crates/chainspec/Cargo.toml @@ -48,7 +48,8 @@ std = [ "reth-primitives-traits/std", "alloy-consensus/std", "once_cell/std", - "alloy-rlp/std" + "alloy-rlp/std", + "reth-ethereum-forks/std" ] arbitrary = [ "alloy-chains/arbitrary", diff --git a/crates/ethereum/evm/Cargo.toml b/crates/ethereum/evm/Cargo.toml index 17e870e61113..4ee072599188 100644 --- a/crates/ethereum/evm/Cargo.toml +++ b/crates/ethereum/evm/Cargo.toml @@ -50,5 +50,6 @@ std = [ "alloy-genesis/std", "alloy-primitives/std", "revm-primitives/std", - "secp256k1/std" + "secp256k1/std", + "reth-ethereum-forks/std" ] diff --git a/crates/evm/Cargo.toml b/crates/evm/Cargo.toml index 9d6a616af983..fe5505b52bd0 100644 --- a/crates/evm/Cargo.toml +++ b/crates/evm/Cargo.toml @@ -46,17 +46,18 @@ metrics-util = { workspace = true, features = ["debugging"] } [features] default = ["std"] std = [ - "dep:metrics", - "dep:reth-metrics", - "reth-consensus/std", - "reth-primitives/std", - "reth-primitives-traits/std", - "reth-revm/std", - "alloy-eips/std", - "alloy-primitives/std", - "alloy-consensus/std", - "revm-primitives/std", - "revm/std", + "dep:metrics", + "dep:reth-metrics", + "reth-consensus/std", + "reth-primitives/std", + "reth-primitives-traits/std", + "reth-revm/std", + "alloy-eips/std", + "alloy-primitives/std", + "alloy-consensus/std", + "revm-primitives/std", + "revm/std", + "reth-ethereum-forks/std" ] test-utils = [ "dep:parking_lot", diff --git a/crates/net/discv4/Cargo.toml b/crates/net/discv4/Cargo.toml index 1030825a91da..70946c6dce87 100644 --- a/crates/net/discv4/Cargo.toml +++ b/crates/net/discv4/Cargo.toml @@ -60,6 +60,7 @@ serde = [ "generic-array/serde", "parking_lot/serde", "rand?/serde", - "secp256k1/serde" + "secp256k1/serde", + "reth-ethereum-forks/serde" ] test-utils = ["dep:rand"] diff --git a/crates/net/dns/Cargo.toml b/crates/net/dns/Cargo.toml index a52f65057443..2f71354a7dd8 100644 --- a/crates/net/dns/Cargo.toml +++ b/crates/net/dns/Cargo.toml @@ -58,5 +58,6 @@ serde = [ "parking_lot/serde", "rand/serde", "secp256k1/serde", - "trust-dns-resolver/serde" + "trust-dns-resolver/serde", + "reth-ethereum-forks/serde" ] diff --git a/crates/net/eth-wire-types/Cargo.toml b/crates/net/eth-wire-types/Cargo.toml index 8b89603167d4..1fe97f236dea 100644 --- a/crates/net/eth-wire-types/Cargo.toml +++ b/crates/net/eth-wire-types/Cargo.toml @@ -17,6 +17,7 @@ reth-chainspec.workspace = true reth-codecs-derive.workspace = true reth-primitives.workspace = true reth-primitives-traits.workspace = true +reth-ethereum-forks.workspace = true # ethereum alloy-chains = { workspace = true, features = ["rlp"] } @@ -46,24 +47,26 @@ rand.workspace = true [features] arbitrary = [ - "reth-primitives/arbitrary", - "alloy-chains/arbitrary", - "dep:arbitrary", - "dep:proptest", - "dep:proptest-arbitrary-interop", - "reth-chainspec/arbitrary", - "alloy-consensus/arbitrary", - "alloy-eips/arbitrary", - "alloy-primitives/arbitrary", - "reth-primitives-traits/arbitrary", + "reth-primitives/arbitrary", + "alloy-chains/arbitrary", + "dep:arbitrary", + "dep:proptest", + "dep:proptest-arbitrary-interop", + "reth-chainspec/arbitrary", + "alloy-consensus/arbitrary", + "alloy-eips/arbitrary", + "alloy-primitives/arbitrary", + "reth-primitives-traits/arbitrary", + "reth-ethereum-forks/arbitrary" ] serde = [ - "dep:serde", - "alloy-chains/serde", - "alloy-consensus/serde", - "alloy-eips/serde", - "alloy-primitives/serde", - "bytes/serde", - "rand/serde", - "reth-primitives-traits/serde", + "dep:serde", + "alloy-chains/serde", + "alloy-consensus/serde", + "alloy-eips/serde", + "alloy-primitives/serde", + "bytes/serde", + "rand/serde", + "reth-primitives-traits/serde", + "reth-ethereum-forks/serde" ] diff --git a/crates/net/eth-wire-types/src/status.rs b/crates/net/eth-wire-types/src/status.rs index fa73d0907feb..e19912481e4e 100644 --- a/crates/net/eth-wire-types/src/status.rs +++ b/crates/net/eth-wire-types/src/status.rs @@ -4,7 +4,7 @@ use alloy_primitives::{hex, B256, U256}; use alloy_rlp::{RlpDecodable, RlpEncodable}; use reth_chainspec::{EthChainSpec, Hardforks, MAINNET}; use reth_codecs_derive::add_arbitrary_tests; -use reth_primitives::{EthereumHardfork, ForkId, Head}; +use reth_ethereum_forks::{EthereumHardfork, ForkId, Head}; use std::fmt::{Debug, Display}; /// The status message is used in the eth protocol handshake to ensure that peers are on the same diff --git a/crates/net/eth-wire/Cargo.toml b/crates/net/eth-wire/Cargo.toml index ffbd3017fa62..3dd632de5c05 100644 --- a/crates/net/eth-wire/Cargo.toml +++ b/crates/net/eth-wire/Cargo.toml @@ -89,6 +89,7 @@ serde = [ "reth-codecs/serde", "alloy-chains/serde", "reth-primitives-traits/serde", + "reth-ethereum-forks/serde" ] [[test]] diff --git a/crates/net/network-api/Cargo.toml b/crates/net/network-api/Cargo.toml index 6d410e9db23b..efb0257fc8e0 100644 --- a/crates/net/network-api/Cargo.toml +++ b/crates/net/network-api/Cargo.toml @@ -45,5 +45,6 @@ serde = [ "reth-eth-wire-types/serde", "reth-network-types/serde", "alloy-primitives/serde", - "enr/serde" + "enr/serde", + "reth-ethereum-forks/serde" ] diff --git a/crates/net/network-types/Cargo.toml b/crates/net/network-types/Cargo.toml index c9b8fdd5bf20..932527b91c65 100644 --- a/crates/net/network-types/Cargo.toml +++ b/crates/net/network-types/Cargo.toml @@ -26,5 +26,9 @@ serde_json = { workspace = true } tracing.workspace = true [features] -serde = ["dep:serde", "dep:humantime-serde"] +serde = [ + "dep:serde", + "dep:humantime-serde", + "reth-ethereum-forks/serde" +] test-utils = [] diff --git a/crates/net/network/Cargo.toml b/crates/net/network/Cargo.toml index ab9e89c2ca84..a4eff9d3a90c 100644 --- a/crates/net/network/Cargo.toml +++ b/crates/net/network/Cargo.toml @@ -123,6 +123,7 @@ serde = [ "smallvec/serde", "url/serde", "reth-primitives-traits/serde", + "reth-ethereum-forks/serde" ] test-utils = [ "dep:reth-provider", diff --git a/crates/optimism/evm/Cargo.toml b/crates/optimism/evm/Cargo.toml index d03a1c6490cb..149aa2e953bf 100644 --- a/crates/optimism/evm/Cargo.toml +++ b/crates/optimism/evm/Cargo.toml @@ -63,7 +63,8 @@ std = [ "alloy-genesis/std", "alloy-primitives/std", "revm-primitives/std", - "revm/std" + "revm/std", + "reth-ethereum-forks/std" ] optimism = [ "reth-primitives/optimism", diff --git a/crates/optimism/hardforks/Cargo.toml b/crates/optimism/hardforks/Cargo.toml index 67a04a8aa5f8..1ea23069a685 100644 --- a/crates/optimism/hardforks/Cargo.toml +++ b/crates/optimism/hardforks/Cargo.toml @@ -31,10 +31,12 @@ std = [ "alloy-primitives/std", "once_cell/std", "serde?/std", - "alloy-chains/std" + "alloy-chains/std", + "reth-ethereum-forks/std" ] serde = [ "dep:serde", "alloy-chains/serde", - "alloy-primitives/serde" + "alloy-primitives/serde", + "reth-ethereum-forks/serde" ] diff --git a/crates/primitives/Cargo.toml b/crates/primitives/Cargo.toml index 7a38e79b1c16..80299a06db60 100644 --- a/crates/primitives/Cargo.toml +++ b/crates/primitives/Cargo.toml @@ -105,7 +105,8 @@ std = [ "serde/std", "alloy-trie/std", "serde_with?/std", - "alloy-rlp/std" + "alloy-rlp/std", + "reth-ethereum-forks/std" ] reth-codec = [ "dep:reth-codecs", diff --git a/crates/revm/Cargo.toml b/crates/revm/Cargo.toml index 95def23a4432..cc1c8edcb8db 100644 --- a/crates/revm/Cargo.toml +++ b/crates/revm/Cargo.toml @@ -37,12 +37,13 @@ alloy-consensus.workspace = true [features] default = ["std"] std = [ - "reth-primitives/std", - "alloy-primitives/std", - "revm/std", - "alloy-eips/std", - "alloy-consensus/std", - "reth-primitives-traits/std", + "reth-primitives/std", + "alloy-primitives/std", + "revm/std", + "alloy-eips/std", + "alloy-consensus/std", + "reth-primitives-traits/std", + "reth-ethereum-forks/std" ] witness = ["dep:reth-trie"] test-utils = [ @@ -54,10 +55,11 @@ test-utils = [ "reth-primitives-traits/test-utils", ] serde = [ - "revm/serde", - "alloy-eips/serde", - "alloy-primitives/serde", - "alloy-consensus/serde", - "reth-primitives-traits/serde", - "reth-trie?/serde", + "revm/serde", + "alloy-eips/serde", + "alloy-primitives/serde", + "alloy-consensus/serde", + "reth-primitives-traits/serde", + "reth-trie?/serde", + "reth-ethereum-forks/serde" ] From df4673ef80dff722666f4597c8c8548afea6a365 Mon Sep 17 00:00:00 2001 From: Roman Krasiuk Date: Mon, 2 Dec 2024 13:09:39 +0100 Subject: [PATCH 14/68] trie: init storage blinded provider with account (#13058) --- crates/trie/sparse/src/blinded.rs | 6 +++--- crates/trie/sparse/src/state.rs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/trie/sparse/src/blinded.rs b/crates/trie/sparse/src/blinded.rs index 592f5e7bcd06..f82bdcd95bbd 100644 --- a/crates/trie/sparse/src/blinded.rs +++ b/crates/trie/sparse/src/blinded.rs @@ -1,7 +1,7 @@ //! Traits and default implementations related to retrieval of blinded trie nodes. use crate::SparseTrieError; -use alloy_primitives::Bytes; +use alloy_primitives::{Bytes, B256}; use reth_trie_common::Nibbles; /// Factory for instantiating blinded node providers. @@ -15,7 +15,7 @@ pub trait BlindedProviderFactory { fn account_node_provider(&self) -> Self::AccountNodeProvider; /// Returns blinded storage node provider. - fn storage_node_provider(&self) -> Self::StorageNodeProvider; + fn storage_node_provider(&self, account: B256) -> Self::StorageNodeProvider; } /// Trie node provider for retrieving blinded nodes. @@ -39,7 +39,7 @@ impl BlindedProviderFactory for DefaultBlindedProviderFactory { DefaultBlindedProvider } - fn storage_node_provider(&self) -> Self::StorageNodeProvider { + fn storage_node_provider(&self, _account: B256) -> Self::StorageNodeProvider { DefaultBlindedProvider } } diff --git a/crates/trie/sparse/src/state.rs b/crates/trie/sparse/src/state.rs index 877744954ae1..0ca290e2d0cb 100644 --- a/crates/trie/sparse/src/state.rs +++ b/crates/trie/sparse/src/state.rs @@ -129,7 +129,7 @@ impl SparseStateTrie { // Reveal root node if it wasn't already. let trie = self.storages.entry(account).or_default().reveal_root_with_provider( - self.provider_factory.storage_node_provider(), + self.provider_factory.storage_node_provider(account), root_node, self.retain_updates, )?; @@ -179,7 +179,7 @@ impl SparseStateTrie { if let Some(root_node) = self.validate_root_node(&mut storage_nodes)? { // Reveal root node if it wasn't already. let trie = self.storages.entry(account).or_default().reveal_root_with_provider( - self.provider_factory.storage_node_provider(), + self.provider_factory.storage_node_provider(account), root_node, self.retain_updates, )?; From dd055a4615c2e8fc42f63103bb3c3d369349a85d Mon Sep 17 00:00:00 2001 From: Federico Gimenez Date: Mon, 2 Dec 2024 13:11:08 +0100 Subject: [PATCH 15/68] feat(executor): call hook with state changes after post block balance increments (#13050) --- crates/ethereum/evm/src/execute.rs | 78 +++++++++++++++-- crates/evm/src/execute.rs | 131 ++++++++++++++++++++++++++++- crates/optimism/evm/src/execute.rs | 10 ++- 3 files changed, 208 insertions(+), 11 deletions(-) diff --git a/crates/ethereum/evm/src/execute.rs b/crates/ethereum/evm/src/execute.rs index 3bfc3cb2ed65..65fbbdd25682 100644 --- a/crates/ethereum/evm/src/execute.rs +++ b/crates/ethereum/evm/src/execute.rs @@ -13,8 +13,9 @@ use reth_consensus::ConsensusError; use reth_ethereum_consensus::validate_block_post_execution; use reth_evm::{ execute::{ - BasicBlockExecutorProvider, BlockExecutionError, BlockExecutionStrategy, - BlockExecutionStrategyFactory, BlockValidationError, ExecuteOutput, ProviderError, + balance_increment_state, BasicBlockExecutorProvider, BlockExecutionError, + BlockExecutionStrategy, BlockExecutionStrategyFactory, BlockValidationError, ExecuteOutput, + ProviderError, }, state_change::post_block_balance_increments, system_calls::{OnStateHook, SystemCaller}, @@ -263,8 +264,11 @@ where } // increment balances self.state - .increment_balances(balance_increments) + .increment_balances(balance_increments.clone()) .map_err(|_| BlockValidationError::IncrementBalanceFailed)?; + // call state hook with changes due to balance increments. + let balance_state = balance_increment_state(&balance_increments, &mut self.state)?; + self.system_caller.on_state(&balance_state); Ok(requests) } @@ -317,6 +321,7 @@ mod tests { use alloy_eips::{ eip2935::{HISTORY_STORAGE_ADDRESS, HISTORY_STORAGE_CODE}, eip4788::{BEACON_ROOTS_ADDRESS, BEACON_ROOTS_CODE, SYSTEM_ADDRESS}, + eip4895::Withdrawal, eip7002::{WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS, WITHDRAWAL_REQUEST_PREDEPLOY_CODE}, eip7685::EMPTY_REQUESTS_HASH, }; @@ -333,9 +338,9 @@ mod tests { database::StateProviderDatabase, test_utils::StateProviderTest, TransitionState, }; use reth_testing_utils::generators::{self, sign_tx_with_key_pair}; - use revm_primitives::BLOCKHASH_SERVE_WINDOW; + use revm_primitives::{address, EvmState, BLOCKHASH_SERVE_WINDOW}; use secp256k1::{Keypair, Secp256k1}; - use std::collections::HashMap; + use std::{collections::HashMap, sync::mpsc}; fn create_state_provider_with_beacon_root_contract() -> StateProviderTest { let mut db = StateProviderTest::default(); @@ -1220,4 +1225,67 @@ mod tests { ), } } + + #[test] + fn test_balance_increment_not_duplicated() { + let chain_spec = Arc::new( + ChainSpecBuilder::from(&*MAINNET) + .shanghai_activated() + .with_fork(EthereumHardfork::Prague, ForkCondition::Timestamp(0)) + .build(), + ); + + let withdrawal_recipient = address!("1000000000000000000000000000000000000000"); + + let mut db = StateProviderTest::default(); + let initial_balance = 100; + db.insert_account( + withdrawal_recipient, + Account { balance: U256::from(initial_balance), nonce: 1, bytecode_hash: None }, + None, + HashMap::default(), + ); + + let withdrawal = + Withdrawal { index: 0, validator_index: 0, address: withdrawal_recipient, amount: 1 }; + + let header = Header { timestamp: 1, number: 1, ..Header::default() }; + + let block = BlockWithSenders { + block: Block { + header, + body: BlockBody { + transactions: vec![], + ommers: vec![], + withdrawals: Some(vec![withdrawal].into()), + }, + }, + senders: vec![], + }; + + let provider = executor_provider(chain_spec); + let executor = provider.executor(StateProviderDatabase::new(&db)); + + let (tx, rx) = mpsc::channel(); + let tx_clone = tx.clone(); + + let _output = executor + .execute_with_state_hook((&block, U256::ZERO).into(), move |state: &EvmState| { + if let Some(account) = state.get(&withdrawal_recipient) { + let _ = tx_clone.send(account.info.balance); + } + }) + .expect("Block execution should succeed"); + + drop(tx); + let balance_changes: Vec = rx.try_iter().collect(); + + if let Some(final_balance) = balance_changes.last() { + let expected_final_balance = U256::from(initial_balance) + U256::from(1_000_000_000); // initial + 1 Gwei in Wei + assert_eq!( + *final_balance, expected_final_balance, + "Final balance should match expected value after withdrawal" + ); + } + } } diff --git a/crates/evm/src/execute.rs b/crates/evm/src/execute.rs index 7d477d2195aa..8c3e0108fcc3 100644 --- a/crates/evm/src/execute.rs +++ b/crates/evm/src/execute.rs @@ -12,7 +12,10 @@ pub use reth_storage_errors::provider::ProviderError; use crate::{system_calls::OnStateHook, TxEnvOverrides}; use alloc::{boxed::Box, vec::Vec}; use alloy_eips::eip7685::Requests; -use alloy_primitives::BlockNumber; +use alloy_primitives::{ + map::{DefaultHashBuilder, HashMap}, + Address, BlockNumber, +}; use core::fmt::Display; use reth_consensus::ConsensusError; use reth_primitives::{BlockWithSenders, NodePrimitives, Receipt}; @@ -22,7 +25,7 @@ use revm::{ db::{states::bundle_state::BundleRetention, BundleState}, State, }; -use revm_primitives::{db::Database, U256}; +use revm_primitives::{db::Database, Account, AccountStatus, EvmState, U256}; /// A general purpose executor trait that executes an input (e.g. block) and produces an output /// (e.g. state changes and receipts). @@ -499,6 +502,42 @@ where } } +/// Creates an `EvmState` from a map of balance increments and the current state +/// to load accounts from. No balance increment is done in the function. +/// Zero balance increments are ignored and won't create state entries. +pub fn balance_increment_state( + balance_increments: &HashMap, + state: &mut State, +) -> Result +where + DB: Database, +{ + let mut load_account = |address: &Address| -> Result<(Address, Account), BlockExecutionError> { + let cache_account = state.load_cache_account(*address).map_err(|_| { + BlockExecutionError::msg("could not load account for balance increment") + })?; + + let account = cache_account.account.as_ref().ok_or_else(|| { + BlockExecutionError::msg("could not load account for balance increment") + })?; + + Ok(( + *address, + Account { + info: account.info.clone(), + storage: Default::default(), + status: AccountStatus::Touched, + }, + )) + }; + + balance_increments + .iter() + .filter(|(_, &balance)| balance != 0) + .map(|(addr, _)| load_account(addr)) + .collect::>() +} + #[cfg(test)] mod tests { use super::*; @@ -507,7 +546,7 @@ mod tests { use reth_chainspec::{ChainSpec, MAINNET}; use reth_primitives::EthPrimitives; use revm::db::{CacheDB, EmptyDBTyped}; - use revm_primitives::{bytes, TxEnv}; + use revm_primitives::{address, bytes, AccountInfo, TxEnv, KECCAK_EMPTY}; use std::sync::Arc; #[derive(Clone, Default)] @@ -760,4 +799,90 @@ mod tests { let result = executor.execute(BlockExecutionInput::new(&Default::default(), U256::ZERO)); assert!(result.is_ok()); } + + fn setup_state_with_account( + addr: Address, + balance: u128, + nonce: u64, + ) -> State>> { + let db = CacheDB::>::default(); + let mut state = State::builder().with_database(db).with_bundle_update().build(); + + let account_info = AccountInfo { + balance: U256::from(balance), + nonce, + code_hash: KECCAK_EMPTY, + code: None, + }; + state.insert_account(addr, account_info); + state + } + + #[test] + fn test_balance_increment_state_zero() { + let addr = address!("1000000000000000000000000000000000000000"); + let mut state = setup_state_with_account(addr, 100, 1); + + let mut increments = HashMap::::default(); + increments.insert(addr, 0); + + let result = balance_increment_state(&increments, &mut state).unwrap(); + assert!(result.is_empty(), "Zero increments should be ignored"); + } + + #[test] + fn test_balance_increment_state_empty_increments_map() { + let mut state = State::builder() + .with_database(CacheDB::>::default()) + .with_bundle_update() + .build(); + + let increments = HashMap::::default(); + let result = balance_increment_state(&increments, &mut state).unwrap(); + assert!(result.is_empty(), "Empty increments map should return empty state"); + } + + #[test] + fn test_balance_increment_state_multiple_valid_increments() { + let addr1 = address!("1000000000000000000000000000000000000000"); + let addr2 = address!("2000000000000000000000000000000000000000"); + + 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 }; + state.insert_account(addr2, account2); + + let mut increments = HashMap::::default(); + increments.insert(addr1, 50); + increments.insert(addr2, 100); + + let result = balance_increment_state(&increments, &mut state).unwrap(); + + assert_eq!(result.len(), 2); + assert_eq!(result.get(&addr1).unwrap().info.balance, U256::from(100)); + assert_eq!(result.get(&addr2).unwrap().info.balance, U256::from(200)); + } + + #[test] + fn test_balance_increment_state_mixed_zero_and_nonzero_increments() { + let addr1 = address!("1000000000000000000000000000000000000000"); + let addr2 = address!("2000000000000000000000000000000000000000"); + + 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 }; + state.insert_account(addr2, account2); + + let mut increments = HashMap::::default(); + increments.insert(addr1, 0); + increments.insert(addr2, 100); + + let result = balance_increment_state(&increments, &mut state).unwrap(); + + assert_eq!(result.len(), 1, "Only non-zero increments should be included"); + assert!(!result.contains_key(&addr1), "Zero increment account should not be included"); + assert_eq!(result.get(&addr2).unwrap().info.balance, U256::from(200)); + } } diff --git a/crates/optimism/evm/src/execute.rs b/crates/optimism/evm/src/execute.rs index a333978f096f..549f52c89def 100644 --- a/crates/optimism/evm/src/execute.rs +++ b/crates/optimism/evm/src/execute.rs @@ -10,8 +10,9 @@ use reth_chainspec::EthereumHardforks; use reth_consensus::ConsensusError; use reth_evm::{ execute::{ - BasicBlockExecutorProvider, BlockExecutionError, BlockExecutionStrategy, - BlockExecutionStrategyFactory, BlockValidationError, ExecuteOutput, ProviderError, + balance_increment_state, BasicBlockExecutorProvider, BlockExecutionError, + BlockExecutionStrategy, BlockExecutionStrategyFactory, BlockValidationError, ExecuteOutput, + ProviderError, }, state_change::post_block_balance_increments, system_calls::{OnStateHook, SystemCaller}, @@ -260,8 +261,11 @@ where post_block_balance_increments(&self.chain_spec.clone(), block, total_difficulty); // increment balances self.state - .increment_balances(balance_increments) + .increment_balances(balance_increments.clone()) .map_err(|_| BlockValidationError::IncrementBalanceFailed)?; + // call state hook with changes due to balance increments. + let balance_state = balance_increment_state(&balance_increments, &mut self.state)?; + self.system_caller.on_state(&balance_state); Ok(Requests::default()) } From 519a10ae99338f58a4f443dea295057469f807c1 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Mon, 2 Dec 2024 14:24:21 +0100 Subject: [PATCH 16/68] chore: remove OpTxType new type (#12715) --- Cargo.lock | 2 +- crates/optimism/primitives/Cargo.toml | 8 +- .../primitives/src/transaction/tx_type.rs | 289 +----------------- crates/primitives-traits/Cargo.toml | 27 +- crates/primitives-traits/src/size.rs | 7 + .../src/transaction/tx_type.rs | 29 +- .../codecs/src/alloy/transaction/optimism.rs | 52 +++- 7 files changed, 118 insertions(+), 296 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9a3521dccb2a..cf011d0f639f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8461,7 +8461,6 @@ dependencies = [ "alloy-consensus", "alloy-eips", "alloy-primitives", - "alloy-rlp", "arbitrary", "bytes", "derive_more 1.0.0", @@ -8664,6 +8663,7 @@ dependencies = [ "bytes", "derive_more 1.0.0", "modular-bitfield", + "op-alloy-consensus", "proptest", "proptest-arbitrary-interop", "rand 0.8.5", diff --git a/crates/optimism/primitives/Cargo.toml b/crates/optimism/primitives/Cargo.toml index 92e02f1d2dd4..075cd0d13f4f 100644 --- a/crates/optimism/primitives/Cargo.toml +++ b/crates/optimism/primitives/Cargo.toml @@ -14,14 +14,13 @@ workspace = true [dependencies] # reth reth-primitives.workspace = true -reth-primitives-traits.workspace = true +reth-primitives-traits = { workspace = true, features = ["op"] } reth-codecs = { workspace = true, optional = true, features = ["optimism"] } # ethereum alloy-primitives.workspace = true alloy-consensus.workspace = true alloy-eips.workspace = true -alloy-rlp.workspace = true # op op-alloy-consensus.workspace = true @@ -37,7 +36,7 @@ derive_more.workspace = true arbitrary = { workspace = true, features = ["derive"], optional = true } [dev-dependencies] -reth-codecs = { workspace = true, features = ["test-utils"] } +reth-codecs = { workspace = true, features = ["test-utils", "optimism"] } rstest.workspace = true arbitrary.workspace = true @@ -51,12 +50,13 @@ std = [ "alloy-eips/std", "alloy-primitives/std", "serde/std", - "alloy-rlp/std" ] reth-codec = [ "dep:reth-codecs", "reth-primitives/reth-codec", "reth-primitives-traits/reth-codec", + "reth-codecs?/optimism", + "reth-primitives/reth-codec" ] serde = [ "dep:serde", diff --git a/crates/optimism/primitives/src/transaction/tx_type.rs b/crates/optimism/primitives/src/transaction/tx_type.rs index 9976221b4240..8be5f3a3d5e5 100644 --- a/crates/optimism/primitives/src/transaction/tx_type.rs +++ b/crates/optimism/primitives/src/transaction/tx_type.rs @@ -1,286 +1,21 @@ -//! newtype pattern on `op_alloy_consensus::OpTxType`. -//! `OpTxType` implements `reth_primitives_traits::TxType`. -//! This type is required because a `Compact` impl is needed on the deposit tx type. +//! Optimism transaction type. -use core::fmt::Debug; - -use alloy_primitives::{U64, U8}; -use alloy_rlp::{Decodable, Encodable, Error}; -use bytes::BufMut; -use derive_more::{ - derive::{From, Into}, - Display, -}; -use op_alloy_consensus::OpTxType as AlloyOpTxType; -use reth_primitives_traits::{InMemorySize, TxType}; - -/// Wrapper type for [`op_alloy_consensus::OpTxType`] to implement -/// [`TxType`] trait. -#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Display, Ord, Hash, From, Into)] -#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] -#[into(u8)] -pub struct OpTxType(AlloyOpTxType); - -impl TxType for OpTxType { - #[inline] - fn is_legacy(&self) -> bool { - matches!(self.0, AlloyOpTxType::Legacy) - } - - #[inline] - fn is_eip2930(&self) -> bool { - matches!(self.0, AlloyOpTxType::Eip2930) - } - - #[inline] - fn is_eip1559(&self) -> bool { - matches!(self.0, AlloyOpTxType::Eip1559) - } - - #[inline] - fn is_eip4844(&self) -> bool { - false - } - - #[inline] - fn is_eip7702(&self) -> bool { - matches!(self.0, AlloyOpTxType::Eip7702) - } -} - -impl InMemorySize for OpTxType { - /// Calculates a heuristic for the in-memory size of the [`OpTxType`]. - #[inline] - fn size(&self) -> usize { - core::mem::size_of::() - } -} - -impl From for U8 { - fn from(tx_type: OpTxType) -> Self { - Self::from(u8::from(tx_type)) - } -} - -impl TryFrom for OpTxType { - type Error = Error; - - fn try_from(value: u8) -> Result { - AlloyOpTxType::try_from(value) - .map(OpTxType) - .map_err(|_| Error::Custom("Invalid transaction type")) - } -} - -impl Default for OpTxType { - fn default() -> Self { - Self(AlloyOpTxType::Legacy) - } -} - -impl PartialEq for OpTxType { - fn eq(&self, other: &u8) -> bool { - let self_as_u8: u8 = (*self).into(); - &self_as_u8 == other - } -} - -impl TryFrom for OpTxType { - type Error = Error; - - fn try_from(value: u64) -> Result { - if value > u8::MAX as u64 { - return Err(Error::Custom("value out of range")); - } - Self::try_from(value as u8) - } -} - -impl TryFrom for OpTxType { - type Error = Error; - - fn try_from(value: U64) -> Result { - let u64_value: u64 = value.try_into().map_err(|_| Error::Custom("value out of range"))?; - Self::try_from(u64_value) - } -} - -impl Encodable for OpTxType { - fn length(&self) -> usize { - let value: u8 = (*self).into(); - value.length() - } - - fn encode(&self, out: &mut dyn BufMut) { - let value: u8 = (*self).into(); - value.encode(out); - } -} - -impl Decodable for OpTxType { - fn decode(buf: &mut &[u8]) -> Result { - // Decode the u8 value from RLP - let value = if buf.is_empty() { - return Err(alloy_rlp::Error::InputTooShort); - } else if buf[0] == 0x80 { - 0 // Special case: RLP encoding for integer 0 is `b"\x80"` - } else { - u8::decode(buf)? - }; - - Self::try_from(value).map_err(|_| alloy_rlp::Error::Custom("Invalid transaction type")) - } -} - -#[cfg(any(test, feature = "reth-codec"))] -impl reth_codecs::Compact for OpTxType { - fn to_compact(&self, buf: &mut B) -> usize - where - B: bytes::BufMut + AsMut<[u8]>, - { - use reth_codecs::txtype::*; - match self.0 { - AlloyOpTxType::Legacy => COMPACT_IDENTIFIER_LEGACY, - AlloyOpTxType::Eip2930 => COMPACT_IDENTIFIER_EIP2930, - AlloyOpTxType::Eip1559 => COMPACT_IDENTIFIER_EIP1559, - AlloyOpTxType::Eip7702 => { - buf.put_u8(alloy_consensus::constants::EIP7702_TX_TYPE_ID); - COMPACT_EXTENDED_IDENTIFIER_FLAG - } - AlloyOpTxType::Deposit => { - buf.put_u8(op_alloy_consensus::DEPOSIT_TX_TYPE_ID); - COMPACT_EXTENDED_IDENTIFIER_FLAG - } - } - } - - fn from_compact(mut buf: &[u8], identifier: usize) -> (Self, &[u8]) { - use bytes::Buf; - ( - match identifier { - reth_codecs::txtype::COMPACT_IDENTIFIER_LEGACY => Self(AlloyOpTxType::Legacy), - reth_codecs::txtype::COMPACT_IDENTIFIER_EIP2930 => Self(AlloyOpTxType::Eip2930), - reth_codecs::txtype::COMPACT_IDENTIFIER_EIP1559 => Self(AlloyOpTxType::Eip1559), - reth_codecs::txtype::COMPACT_EXTENDED_IDENTIFIER_FLAG => { - let extended_identifier = buf.get_u8(); - match extended_identifier { - alloy_consensus::constants::EIP7702_TX_TYPE_ID => { - Self(AlloyOpTxType::Eip7702) - } - op_alloy_consensus::DEPOSIT_TX_TYPE_ID => Self(AlloyOpTxType::Deposit), - _ => panic!("Unsupported OpTxType identifier: {extended_identifier}"), - } - } - _ => panic!("Unknown identifier for OpTxType: {identifier}"), - }, - buf, - ) - } -} +pub use op_alloy_consensus::OpTxType; #[cfg(test)] mod tests { use super::*; use alloy_consensus::constants::EIP7702_TX_TYPE_ID; - use bytes::BytesMut; use op_alloy_consensus::DEPOSIT_TX_TYPE_ID; use reth_codecs::{txtype::*, Compact}; use rstest::rstest; - #[test] - fn test_from_alloy_op_tx_type() { - let alloy_tx = AlloyOpTxType::Legacy; - let op_tx: OpTxType = OpTxType::from(alloy_tx); - assert_eq!(op_tx, OpTxType(AlloyOpTxType::Legacy)); - } - - #[test] - fn test_from_op_tx_type_to_u8() { - let op_tx = OpTxType(AlloyOpTxType::Legacy); - let tx_type_u8: u8 = op_tx.into(); - assert_eq!(tx_type_u8, AlloyOpTxType::Legacy as u8); - } - - #[test] - fn test_from_op_tx_type_to_u8_u8() { - let op_tx = OpTxType(AlloyOpTxType::Legacy); - let tx_type_u8: U8 = op_tx.into(); - assert_eq!(tx_type_u8, U8::from(AlloyOpTxType::Legacy as u8)); - } - - #[test] - fn test_try_from_u8() { - let op_tx = OpTxType::try_from(AlloyOpTxType::Legacy as u8).unwrap(); - assert_eq!(op_tx, OpTxType(AlloyOpTxType::Legacy)); - } - - #[test] - fn test_try_from_invalid_u8() { - let invalid_value: u8 = 255; - let result = OpTxType::try_from(invalid_value); - assert_eq!(result, Err(Error::Custom("Invalid transaction type"))); - } - - #[test] - fn test_try_from_u64() { - let op_tx = OpTxType::try_from(AlloyOpTxType::Legacy as u64).unwrap(); - assert_eq!(op_tx, OpTxType(AlloyOpTxType::Legacy)); - } - - #[test] - fn test_try_from_u64_out_of_range() { - let result = OpTxType::try_from(u64::MAX); - assert_eq!(result, Err(Error::Custom("value out of range"))); - } - - #[test] - fn test_try_from_u64_within_range() { - let valid_value: U64 = U64::from(AlloyOpTxType::Legacy as u64); - let op_tx = OpTxType::try_from(valid_value).unwrap(); - assert_eq!(op_tx, OpTxType(AlloyOpTxType::Legacy)); - } - - #[test] - fn test_default() { - let default_tx = OpTxType::default(); - assert_eq!(default_tx, OpTxType(AlloyOpTxType::Legacy)); - } - - #[test] - fn test_partial_eq_u8() { - let op_tx = OpTxType(AlloyOpTxType::Legacy); - assert_eq!(op_tx, AlloyOpTxType::Legacy as u8); - } - - #[test] - fn test_encodable() { - let op_tx = OpTxType(AlloyOpTxType::Legacy); - let mut buf = BytesMut::new(); - op_tx.encode(&mut buf); - assert_eq!(buf, BytesMut::from(&[0x80][..])); - } - - #[test] - fn test_decodable_success() { - // Using the RLP-encoded form of 0, which is `b"\x80"` - let mut buf: &[u8] = &[0x80]; - let decoded_tx = OpTxType::decode(&mut buf).unwrap(); - assert_eq!(decoded_tx, OpTxType(AlloyOpTxType::Legacy)); - } - - #[test] - fn test_decodable_invalid() { - let mut buf: &[u8] = &[255]; - let result = OpTxType::decode(&mut buf); - assert!(result.is_err()); - } - #[rstest] - #[case(OpTxType(AlloyOpTxType::Legacy), COMPACT_IDENTIFIER_LEGACY, vec![])] - #[case(OpTxType(AlloyOpTxType::Eip2930), COMPACT_IDENTIFIER_EIP2930, vec![])] - #[case(OpTxType(AlloyOpTxType::Eip1559), COMPACT_IDENTIFIER_EIP1559, vec![])] - #[case(OpTxType(AlloyOpTxType::Eip7702), COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![EIP7702_TX_TYPE_ID])] - #[case(OpTxType(AlloyOpTxType::Deposit), COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![DEPOSIT_TX_TYPE_ID])] + #[case(OpTxType::Legacy, COMPACT_IDENTIFIER_LEGACY, vec![])] + #[case(OpTxType::Eip2930, COMPACT_IDENTIFIER_EIP2930, vec![])] + #[case(OpTxType::Eip1559, COMPACT_IDENTIFIER_EIP1559, vec![])] + #[case(OpTxType::Eip7702, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![EIP7702_TX_TYPE_ID])] + #[case(OpTxType::Deposit, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![DEPOSIT_TX_TYPE_ID])] fn test_txtype_to_compact( #[case] tx_type: OpTxType, #[case] expected_identifier: usize, @@ -297,11 +32,11 @@ mod tests { } #[rstest] - #[case(OpTxType(AlloyOpTxType::Legacy), COMPACT_IDENTIFIER_LEGACY, vec![])] - #[case(OpTxType(AlloyOpTxType::Eip2930), COMPACT_IDENTIFIER_EIP2930, vec![])] - #[case(OpTxType(AlloyOpTxType::Eip1559), COMPACT_IDENTIFIER_EIP1559, vec![])] - #[case(OpTxType(AlloyOpTxType::Eip7702), COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![EIP7702_TX_TYPE_ID])] - #[case(OpTxType(AlloyOpTxType::Deposit), COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![DEPOSIT_TX_TYPE_ID])] + #[case(OpTxType::Legacy, COMPACT_IDENTIFIER_LEGACY, vec![])] + #[case(OpTxType::Eip2930, COMPACT_IDENTIFIER_EIP2930, vec![])] + #[case(OpTxType::Eip1559, COMPACT_IDENTIFIER_EIP1559, vec![])] + #[case(OpTxType::Eip7702, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![EIP7702_TX_TYPE_ID])] + #[case(OpTxType::Deposit, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![DEPOSIT_TX_TYPE_ID])] fn test_txtype_from_compact( #[case] expected_type: OpTxType, #[case] identifier: usize, diff --git a/crates/primitives-traits/Cargo.toml b/crates/primitives-traits/Cargo.toml index d56fd5bc0f29..ceee1e26cecd 100644 --- a/crates/primitives-traits/Cargo.toml +++ b/crates/primitives-traits/Cargo.toml @@ -23,6 +23,9 @@ alloy-primitives.workspace = true alloy-rlp.workspace = true revm-primitives.workspace = true +# op +op-alloy-consensus = { workspace = true, optional = true } + # misc byteorder = { workspace = true, optional = true } bytes.workspace = true @@ -78,28 +81,34 @@ arbitrary = [ "dep:proptest-arbitrary-interop", "alloy-eips/arbitrary", "revm-primitives/arbitrary", - "reth-codecs?/arbitrary" + "reth-codecs?/arbitrary", + "op-alloy-consensus?/arbitrary" ] serde-bincode-compat = [ "serde", "serde_with", "alloy-consensus/serde-bincode-compat", - "alloy-eips/serde-bincode-compat" + "alloy-eips/serde-bincode-compat", + "op-alloy-consensus?/serde-bincode-compat" ] serde = [ "dep:serde", "alloy-consensus/serde", - "alloy-eips/serde", - "alloy-primitives/serde", - "bytes/serde", - "rand/serde", - "reth-codecs?/serde", - "revm-primitives/serde", - "roaring/serde", + "alloy-eips/serde", + "alloy-primitives/serde", + "bytes/serde", + "rand/serde", + "reth-codecs?/serde", + "revm-primitives/serde", + "roaring/serde", "revm-primitives/serde", + "op-alloy-consensus?/serde" ] reth-codec = [ "dep:reth-codecs", "dep:modular-bitfield", "dep:byteorder", ] +op = [ + "dep:op-alloy-consensus", +] diff --git a/crates/primitives-traits/src/size.rs b/crates/primitives-traits/src/size.rs index 4d721dd00b30..f9065cda24aa 100644 --- a/crates/primitives-traits/src/size.rs +++ b/crates/primitives-traits/src/size.rs @@ -46,6 +46,13 @@ macro_rules! impl_in_mem_size { impl_in_mem_size!(Header, TxLegacy, TxEip2930, TxEip1559, TxEip7702, TxEip4844); +#[cfg(feature = "op")] +impl InMemorySize for op_alloy_consensus::OpTxType { + fn size(&self) -> usize { + 1 + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/crates/primitives-traits/src/transaction/tx_type.rs b/crates/primitives-traits/src/transaction/tx_type.rs index d2caebe4c9f1..c2f2e04899df 100644 --- a/crates/primitives-traits/src/transaction/tx_type.rs +++ b/crates/primitives-traits/src/transaction/tx_type.rs @@ -1,10 +1,8 @@ //! Abstraction of transaction envelope type ID. -use core::fmt; - -use alloy_primitives::{U64, U8}; - use crate::{InMemorySize, MaybeArbitrary, MaybeCompact}; +use alloy_primitives::{U64, U8}; +use core::fmt; /// Helper trait that unifies all behaviour required by transaction type ID to support full node /// operations. @@ -60,3 +58,26 @@ pub trait TxType: !self.is_eip4844() } } + +#[cfg(feature = "op")] +impl TxType for op_alloy_consensus::OpTxType { + fn is_legacy(&self) -> bool { + matches!(self, Self::Legacy) + } + + fn is_eip2930(&self) -> bool { + matches!(self, Self::Eip2930) + } + + fn is_eip1559(&self) -> bool { + matches!(self, Self::Eip1559) + } + + fn is_eip4844(&self) -> bool { + false + } + + fn is_eip7702(&self) -> bool { + matches!(self, Self::Eip7702) + } +} diff --git a/crates/storage/codecs/src/alloy/transaction/optimism.rs b/crates/storage/codecs/src/alloy/transaction/optimism.rs index bb970b581775..631f5c406eeb 100644 --- a/crates/storage/codecs/src/alloy/transaction/optimism.rs +++ b/crates/storage/codecs/src/alloy/transaction/optimism.rs @@ -1,9 +1,11 @@ //! Compact implementation for [`AlloyTxDeposit`] +use alloy_consensus::constants::EIP7702_TX_TYPE_ID; use crate::Compact; use alloy_primitives::{Address, Bytes, TxKind, B256, U256}; -use op_alloy_consensus::TxDeposit as AlloyTxDeposit; +use op_alloy_consensus::{OpTxType, TxDeposit as AlloyTxDeposit}; use reth_codecs_derive::add_arbitrary_tests; +use crate::txtype::{COMPACT_EXTENDED_IDENTIFIER_FLAG, COMPACT_IDENTIFIER_EIP1559, COMPACT_IDENTIFIER_EIP2930, COMPACT_IDENTIFIER_LEGACY}; /// Deposit transactions, also known as deposits are initiated on L1, and executed on L2. /// @@ -65,3 +67,51 @@ impl Compact for AlloyTxDeposit { (alloy_tx, buf) } } + + +impl crate::Compact for OpTxType { + fn to_compact(&self, buf: &mut B) -> usize + where + B: bytes::BufMut + AsMut<[u8]>, + { + use crate::txtype::*; + + match self { + Self::Legacy => COMPACT_IDENTIFIER_LEGACY, + Self::Eip2930 => COMPACT_IDENTIFIER_EIP2930, + Self::Eip1559 => COMPACT_IDENTIFIER_EIP1559, + Self::Eip7702 => { + buf.put_u8(EIP7702_TX_TYPE_ID); + COMPACT_EXTENDED_IDENTIFIER_FLAG + } + Self::Deposit => { + buf.put_u8(op_alloy_consensus::DEPOSIT_TX_TYPE_ID); + COMPACT_EXTENDED_IDENTIFIER_FLAG + } + } + } + + // For backwards compatibility purposes only 2 bits of the type are encoded in the identifier + // parameter. In the case of a [`COMPACT_EXTENDED_IDENTIFIER_FLAG`], the full transaction type + // is read from the buffer as a single byte. + fn from_compact(mut buf: &[u8], identifier: usize) -> (Self, &[u8]) { + use bytes::Buf; + ( + match identifier { + COMPACT_IDENTIFIER_LEGACY => Self::Legacy, + COMPACT_IDENTIFIER_EIP2930 => Self::Eip2930, + COMPACT_IDENTIFIER_EIP1559 => Self::Eip1559, + COMPACT_EXTENDED_IDENTIFIER_FLAG => { + let extended_identifier = buf.get_u8(); + match extended_identifier { + EIP7702_TX_TYPE_ID => Self::Eip7702, + op_alloy_consensus::DEPOSIT_TX_TYPE_ID => Self::Deposit, + _ => panic!("Unsupported TxType identifier: {extended_identifier}"), + } + } + _ => panic!("Unknown identifier for TxType: {identifier}"), + }, + buf, + ) + } +} \ No newline at end of file From 332cce1f9b193e9fe52d4903a3f6858d7fc96130 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Mon, 2 Dec 2024 14:24:48 +0100 Subject: [PATCH 17/68] feat: add header AT to provider (#13030) Co-authored-by: Arsenii Kulikov --- Cargo.lock | 2 + .../commands/debug_cmd/in_memory_merkle.rs | 1 + bin/reth/src/commands/debug_cmd/merkle.rs | 1 + .../src/commands/debug_cmd/replay_engine.rs | 1 + crates/blockchain-tree/src/blockchain_tree.rs | 7 +- crates/chain-state/src/notifications.rs | 11 +- crates/cli/commands/Cargo.toml | 4 +- .../commands/src/init_state/without_evm.rs | 25 ++-- .../cli/commands/src/stage/dump/execution.rs | 3 + crates/cli/commands/src/stage/dump/merkle.rs | 28 +++-- .../beacon/src/engine/hooks/static_file.rs | 4 +- crates/consensus/beacon/src/engine/mod.rs | 17 ++- crates/consensus/common/src/validation.rs | 2 + crates/engine/local/Cargo.toml | 1 + crates/engine/local/src/miner.rs | 3 +- crates/engine/tree/src/tree/mod.rs | 12 +- crates/evm/src/provider.rs | 19 ++- crates/exex/exex/src/manager.rs | 6 +- crates/net/downloaders/src/bodies/bodies.rs | 13 +- crates/net/downloaders/src/bodies/task.rs | 4 +- crates/net/network/src/config.rs | 7 +- crates/net/network/src/eth_requests.rs | 14 +-- crates/net/network/src/test_utils/testnet.rs | 21 +++- crates/node/builder/src/builder/mod.rs | 14 ++- crates/node/builder/src/launch/common.rs | 2 + crates/node/builder/src/setup.rs | 4 +- crates/node/core/src/node_config.rs | 6 +- crates/node/events/src/cl.rs | 9 +- crates/optimism/rpc/src/eth/pending_block.rs | 1 + crates/optimism/rpc/src/witness.rs | 4 +- crates/payload/basic/src/lib.rs | 6 +- crates/primitives-traits/src/block/header.rs | 26 ++-- crates/rpc/rpc-builder/src/eth.rs | 7 +- crates/rpc/rpc-builder/src/lib.rs | 27 +++- crates/rpc/rpc-eth-api/src/helpers/fee.rs | 18 ++- .../rpc-eth-api/src/helpers/pending_block.rs | 5 +- crates/rpc/rpc-eth-types/src/cache/mod.rs | 21 +++- crates/rpc/rpc-eth-types/src/gas_oracle.rs | 6 +- crates/rpc/rpc/src/eth/core.rs | 10 +- crates/rpc/rpc/src/eth/filter.rs | 19 +-- .../rpc/rpc/src/eth/helpers/pending_block.rs | 1 + crates/rpc/rpc/src/validation.rs | 4 +- crates/stages/stages/src/stages/bodies.rs | 6 +- crates/stages/stages/src/stages/execution.rs | 11 +- .../stages/src/stages/hashing_account.rs | 6 +- crates/stages/stages/src/stages/headers.rs | 40 +++--- crates/stages/stages/src/stages/merkle.rs | 5 +- .../stages/src/stages/sender_recovery.rs | 5 +- crates/stages/stages/src/stages/utils.rs | 2 +- .../static-file/src/segments/headers.rs | 15 ++- .../static-file/src/static_file_producer.rs | 2 +- crates/storage/db-common/Cargo.toml | 1 + crates/storage/db-common/src/init.rs | 21 ++-- .../src/providers/blockchain_provider.rs | 80 +++++++----- .../provider/src/providers/consistent.rs | 67 +++++----- .../provider/src/providers/database/mod.rs | 44 ++++--- .../src/providers/database/provider.rs | 118 ++++++++++-------- crates/storage/provider/src/providers/mod.rs | 63 +++++----- .../provider/src/providers/static_file/jar.rs | 35 +++--- .../src/providers/static_file/manager.rs | 38 +++--- .../src/providers/static_file/writer.rs | 11 +- .../storage/provider/src/test_utils/mock.rs | 2 + .../storage/provider/src/test_utils/noop.rs | 4 + crates/storage/provider/src/traits/full.rs | 22 ++-- .../provider/src/traits/header_sync_gap.rs | 14 ++- crates/storage/storage-api/src/block.rs | 37 +++--- crates/storage/storage-api/src/chain_info.rs | 9 +- crates/storage/storage-api/src/header.rs | 32 +++-- crates/transaction-pool/src/maintain.rs | 9 +- examples/db-access/Cargo.toml | 1 + examples/db-access/src/main.rs | 3 +- 71 files changed, 667 insertions(+), 432 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cf011d0f639f..2a9d5222025d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2987,6 +2987,7 @@ dependencies = [ name = "example-db-access" version = "0.0.0" dependencies = [ + "alloy-consensus", "alloy-primitives", "alloy-rpc-types-eth", "eyre", @@ -7202,6 +7203,7 @@ dependencies = [ name = "reth-engine-local" version = "1.1.2" dependencies = [ + "alloy-consensus", "alloy-primitives", "alloy-rpc-types-engine", "eyre", diff --git a/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs b/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs index 870dc1ddf233..6fbfa33b891d 100644 --- a/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs +++ b/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs @@ -63,6 +63,7 @@ impl> Command { Primitives: NodePrimitives< Block = reth_primitives::Block, Receipt = reth_primitives::Receipt, + BlockHeader = reth_primitives::Header, >, >, >( diff --git a/bin/reth/src/commands/debug_cmd/merkle.rs b/bin/reth/src/commands/debug_cmd/merkle.rs index 78e32df52664..16a1f1112726 100644 --- a/bin/reth/src/commands/debug_cmd/merkle.rs +++ b/bin/reth/src/commands/debug_cmd/merkle.rs @@ -62,6 +62,7 @@ impl> Command { Primitives: NodePrimitives< Block = reth_primitives::Block, Receipt = reth_primitives::Receipt, + BlockHeader = reth_primitives::Header, >, >, >( diff --git a/bin/reth/src/commands/debug_cmd/replay_engine.rs b/bin/reth/src/commands/debug_cmd/replay_engine.rs index f0016a129bde..4b98fc85d0b2 100644 --- a/bin/reth/src/commands/debug_cmd/replay_engine.rs +++ b/bin/reth/src/commands/debug_cmd/replay_engine.rs @@ -61,6 +61,7 @@ impl> Command { Primitives: NodePrimitives< Block = reth_primitives::Block, Receipt = reth_primitives::Receipt, + BlockHeader = reth_primitives::Header, >, >, >( diff --git a/crates/blockchain-tree/src/blockchain_tree.rs b/crates/blockchain-tree/src/blockchain_tree.rs index ec9beb20a076..757729d5416d 100644 --- a/crates/blockchain-tree/src/blockchain_tree.rs +++ b/crates/blockchain-tree/src/blockchain_tree.rs @@ -1424,7 +1424,12 @@ mod tests { } fn setup_genesis< - N: ProviderNodeTypes>, + N: ProviderNodeTypes< + Primitives: FullNodePrimitives< + BlockBody = reth_primitives::BlockBody, + BlockHeader = reth_primitives::Header, + >, + >, >( factory: &ProviderFactory, mut genesis: SealedBlock, diff --git a/crates/chain-state/src/notifications.rs b/crates/chain-state/src/notifications.rs index c4e0415436a5..498528813d66 100644 --- a/crates/chain-state/src/notifications.rs +++ b/crates/chain-state/src/notifications.rs @@ -162,19 +162,22 @@ pub struct ForkChoiceNotifications( /// A trait that allows to register to fork choice related events /// and get notified when a new fork choice is available. pub trait ForkChoiceSubscriptions: Send + Sync { + /// Block Header type. + type Header: Clone + Send + Sync + 'static; + /// Get notified when a new safe block of the chain is selected. - fn subscribe_safe_block(&self) -> ForkChoiceNotifications; + fn subscribe_safe_block(&self) -> ForkChoiceNotifications; /// Get notified when a new finalized block of the chain is selected. - fn subscribe_finalized_block(&self) -> ForkChoiceNotifications; + fn subscribe_finalized_block(&self) -> ForkChoiceNotifications; /// Convenience method to get a stream of the new safe blocks of the chain. - fn safe_block_stream(&self) -> ForkChoiceStream { + fn safe_block_stream(&self) -> ForkChoiceStream> { ForkChoiceStream::new(self.subscribe_safe_block().0) } /// Convenience method to get a stream of the new finalized blocks of the chain. - fn finalized_block_stream(&self) -> ForkChoiceStream { + fn finalized_block_stream(&self) -> ForkChoiceStream> { ForkChoiceStream::new(self.subscribe_finalized_block().0) } } diff --git a/crates/cli/commands/Cargo.toml b/crates/cli/commands/Cargo.toml index 90acb82d71d7..2220efda5c6e 100644 --- a/crates/cli/commands/Cargo.toml +++ b/crates/cli/commands/Cargo.toml @@ -17,7 +17,7 @@ reth-cli.workspace = true reth-ethereum-cli.workspace = true reth-cli-runner.workspace = true reth-cli-util.workspace = true -reth-codecs = { workspace = true, optional = true } +reth-codecs.workspace = true reth-config.workspace = true reth-consensus.workspace = true reth-db = { workspace = true, features = ["mdbx"] } @@ -110,7 +110,7 @@ arbitrary = [ "reth-prune-types/test-utils", "reth-stages-types/test-utils", "reth-trie-common/test-utils", - "reth-codecs?/arbitrary", + "reth-codecs/arbitrary", "reth-prune-types?/arbitrary", "reth-stages-types?/arbitrary", "reth-trie-common?/arbitrary", diff --git a/crates/cli/commands/src/init_state/without_evm.rs b/crates/cli/commands/src/init_state/without_evm.rs index 22236d14c76b..f8f72709a7e1 100644 --- a/crates/cli/commands/src/init_state/without_evm.rs +++ b/crates/cli/commands/src/init_state/without_evm.rs @@ -1,7 +1,8 @@ use alloy_primitives::{BlockNumber, B256, U256}; use alloy_rlp::Decodable; -use alloy_consensus::Header; +use alloy_consensus::{BlockHeader, Header}; +use reth_codecs::Compact; use reth_node_builder::NodePrimitives; use reth_primitives::{SealedBlock, SealedBlockWithSenders, SealedHeader, StaticFileSegment}; use reth_provider::{ @@ -27,26 +28,26 @@ pub(crate) fn read_header_from_file(path: PathBuf) -> Result( provider_rw: &Provider, - header: SealedHeader, + header: SealedHeader<::BlockHeader>, total_difficulty: U256, ) -> Result<(), eyre::Error> where - Provider: StaticFileProviderFactory + Provider: StaticFileProviderFactory> + StageCheckpointWriter - + BlockWriter>, + + BlockWriter::Block>, { info!(target: "reth::cli", "Setting up dummy EVM chain before importing state."); let static_file_provider = provider_rw.static_file_provider(); // Write EVM dummy data up to `header - 1` block - append_dummy_chain(&static_file_provider, header.number - 1)?; + append_dummy_chain(&static_file_provider, header.number() - 1)?; info!(target: "reth::cli", "Appending first valid block."); append_first_block(provider_rw, &header, total_difficulty)?; for stage in StageId::ALL { - provider_rw.save_stage_checkpoint(stage, StageCheckpoint::new(header.number))?; + provider_rw.save_stage_checkpoint(stage, StageCheckpoint::new(header.number()))?; } info!(target: "reth::cli", "Set up finished."); @@ -60,12 +61,12 @@ where /// height. fn append_first_block( provider_rw: &Provider, - header: &SealedHeader, + header: &SealedHeader<::BlockHeader>, total_difficulty: U256, ) -> Result<(), eyre::Error> where - Provider: BlockWriter> - + StaticFileProviderFactory, + Provider: BlockWriter::Block> + + StaticFileProviderFactory>, { provider_rw.insert_block( SealedBlockWithSenders::new(SealedBlock::new(header.clone(), Default::default()), vec![]) @@ -81,9 +82,9 @@ where &header.hash(), )?; - sf_provider.latest_writer(StaticFileSegment::Receipts)?.increment_block(header.number)?; + sf_provider.latest_writer(StaticFileSegment::Receipts)?.increment_block(header.number())?; - sf_provider.latest_writer(StaticFileSegment::Transactions)?.increment_block(header.number)?; + sf_provider.latest_writer(StaticFileSegment::Transactions)?.increment_block(header.number())?; Ok(()) } @@ -93,7 +94,7 @@ where /// * Headers: It will push an empty block. /// * Transactions: It will not push any tx, only increments the end block range. /// * Receipts: It will not push any receipt, only increments the end block range. -fn append_dummy_chain( +fn append_dummy_chain>( sf_provider: &StaticFileProvider, target_height: BlockNumber, ) -> Result<(), eyre::Error> { diff --git a/crates/cli/commands/src/stage/dump/execution.rs b/crates/cli/commands/src/stage/dump/execution.rs index 70fd23f9847c..73d2e8a9f8f0 100644 --- a/crates/cli/commands/src/stage/dump/execution.rs +++ b/crates/cli/commands/src/stage/dump/execution.rs @@ -31,6 +31,7 @@ where Primitives: NodePrimitives< Block = reth_primitives::Block, Receipt = reth_primitives::Receipt, + BlockHeader = reth_primitives::Header, >, >, E: BlockExecutorProvider, @@ -143,6 +144,7 @@ fn unwind_and_copy< Primitives: NodePrimitives< Block = reth_primitives::Block, Receipt = reth_primitives::Receipt, + BlockHeader = reth_primitives::Header, >, >, >( @@ -186,6 +188,7 @@ where Primitives: NodePrimitives< Block = reth_primitives::Block, Receipt = reth_primitives::Receipt, + BlockHeader = reth_primitives::Header, >, >, E: BlockExecutorProvider, diff --git a/crates/cli/commands/src/stage/dump/merkle.rs b/crates/cli/commands/src/stage/dump/merkle.rs index ce187437218a..59a25c492aa8 100644 --- a/crates/cli/commands/src/stage/dump/merkle.rs +++ b/crates/cli/commands/src/stage/dump/merkle.rs @@ -25,21 +25,23 @@ use reth_stages::{ }; use tracing::info; -pub(crate) async fn dump_merkle_stage< +pub(crate) async fn dump_merkle_stage( + db_tool: &DbTool, + from: BlockNumber, + to: BlockNumber, + output_datadir: ChainPath, + should_run: bool, +) -> Result<()> +where N: ProviderNodeTypes< DB = Arc, Primitives: NodePrimitives< Block = reth_primitives::Block, Receipt = reth_primitives::Receipt, + BlockHeader = reth_primitives::Header, >, >, ->( - db_tool: &DbTool, - from: BlockNumber, - to: BlockNumber, - output_datadir: ChainPath, - should_run: bool, -) -> Result<()> { +{ let (output_db, tip_block_number) = setup(from, to, &output_datadir.db(), db_tool)?; output_db.update(|tx| { @@ -81,6 +83,7 @@ fn unwind_and_copy< Primitives: NodePrimitives< Block = reth_primitives::Block, Receipt = reth_primitives::Receipt, + BlockHeader = reth_primitives::Header, >, >, >( @@ -161,11 +164,10 @@ fn unwind_and_copy< } /// Try to re-execute the stage straight away -fn dry_run( - output_provider_factory: ProviderFactory, - to: u64, - from: u64, -) -> eyre::Result<()> { +fn dry_run(output_provider_factory: ProviderFactory, to: u64, from: u64) -> eyre::Result<()> +where + N: ProviderNodeTypes>, +{ info!(target: "reth::cli", "Executing stage."); let provider = output_provider_factory.database_provider_rw()?; diff --git a/crates/consensus/beacon/src/engine/hooks/static_file.rs b/crates/consensus/beacon/src/engine/hooks/static_file.rs index 7cd286f659c3..b4b38239a03f 100644 --- a/crates/consensus/beacon/src/engine/hooks/static_file.rs +++ b/crates/consensus/beacon/src/engine/hooks/static_file.rs @@ -36,7 +36,7 @@ where Provider: StaticFileProviderFactory + DatabaseProviderFactory< Provider: StaticFileProviderFactory< - Primitives: NodePrimitives, + Primitives: NodePrimitives, > + StageCheckpointReader + BlockReader + ChainStateBlockReader, @@ -152,7 +152,7 @@ where Provider: StaticFileProviderFactory + DatabaseProviderFactory< Provider: StaticFileProviderFactory< - Primitives: NodePrimitives, + Primitives: NodePrimitives, > + StageCheckpointReader + BlockReader + ChainStateBlockReader, diff --git a/crates/consensus/beacon/src/engine/mod.rs b/crates/consensus/beacon/src/engine/mod.rs index 7a894f08e1c7..f188e495be4e 100644 --- a/crates/consensus/beacon/src/engine/mod.rs +++ b/crates/consensus/beacon/src/engine/mod.rs @@ -21,7 +21,7 @@ use reth_network_p2p::{ sync::{NetworkSyncUpdater, SyncState}, EthBlockClient, }; -use reth_node_types::{Block, BlockTy, NodeTypesWithEngine}; +use reth_node_types::{Block, BlockTy, HeaderTy, NodeTypesWithEngine}; use reth_payload_builder::PayloadBuilderHandle; use reth_payload_builder_primitives::PayloadBuilder; use reth_payload_primitives::{PayloadAttributes, PayloadBuilderAttributes}; @@ -234,9 +234,9 @@ impl BeaconConsensusEngine where N: EngineNodeTypes, BT: BlockchainTreeEngine - + BlockReader> + + BlockReader, Header = HeaderTy> + BlockIdReader - + CanonChainTracker + + CanonChainTracker

> + StageCheckpointReader + ChainSpecProvider + 'static, @@ -1804,9 +1804,9 @@ where N: EngineNodeTypes, Client: EthBlockClient + 'static, BT: BlockchainTreeEngine - + BlockReader> + + BlockReader, Header = HeaderTy> + BlockIdReader - + CanonChainTracker + + CanonChainTracker
> + StageCheckpointReader + ChainSpecProvider + Unpin @@ -2179,7 +2179,12 @@ mod tests { fn insert_blocks< 'a, - N: ProviderNodeTypes>, + N: ProviderNodeTypes< + Primitives: FullNodePrimitives< + BlockBody = reth_primitives::BlockBody, + BlockHeader = reth_primitives::Header, + >, + >, >( provider_factory: ProviderFactory, mut blocks: impl Iterator, diff --git a/crates/consensus/common/src/validation.rs b/crates/consensus/common/src/validation.rs index dce7d2579540..2d681be449a5 100644 --- a/crates/consensus/common/src/validation.rs +++ b/crates/consensus/common/src/validation.rs @@ -391,6 +391,8 @@ mod tests { } impl HeaderProvider for Provider { + type Header = Header; + fn is_known(&self, _block_hash: &BlockHash) -> ProviderResult { Ok(self.is_known) } diff --git a/crates/engine/local/Cargo.toml b/crates/engine/local/Cargo.toml index d8a66e65e04c..b3ad169e3189 100644 --- a/crates/engine/local/Cargo.toml +++ b/crates/engine/local/Cargo.toml @@ -29,6 +29,7 @@ reth-transaction-pool.workspace = true reth-stages-api.workspace = true # alloy +alloy-consensus.workspace = true alloy-primitives.workspace = true alloy-rpc-types-engine.workspace = true diff --git a/crates/engine/local/src/miner.rs b/crates/engine/local/src/miner.rs index a5c7cf4d4c60..29418c0b714c 100644 --- a/crates/engine/local/src/miner.rs +++ b/crates/engine/local/src/miner.rs @@ -1,5 +1,6 @@ //! Contains the implementation of the mining mode for the local engine. +use alloy_consensus::BlockHeader; use alloy_primitives::{TxHash, B256}; use alloy_rpc_types_engine::{CancunPayloadFields, ExecutionPayloadSidecar, ForkchoiceState}; use eyre::OptionExt; @@ -114,7 +115,7 @@ where to_engine, mode, payload_builder, - last_timestamp: latest_header.timestamp, + last_timestamp: latest_header.timestamp(), last_block_hashes: vec![latest_header.hash()], }; diff --git a/crates/engine/tree/src/tree/mod.rs b/crates/engine/tree/src/tree/mod.rs index cdd066cdc243..16e07e518443 100644 --- a/crates/engine/tree/src/tree/mod.rs +++ b/crates/engine/tree/src/tree/mod.rs @@ -540,9 +540,13 @@ impl std::fmt::Debug impl EngineApiTreeHandler where - N: NodePrimitives, + N: NodePrimitives< + Block = reth_primitives::Block, + BlockHeader = reth_primitives::Header, + Receipt = reth_primitives::Receipt, + >, P: DatabaseProviderFactory - + BlockReader + + BlockReader + StateProviderFactory + StateReader + Clone @@ -1357,7 +1361,7 @@ where // update the tracked chain height, after backfill sync both the canonical height and // persisted height are the same self.state.tree_state.set_canonical_head(new_head.num_hash()); - self.persistence_state.finish(new_head.hash(), new_head.number); + self.persistence_state.finish(new_head.hash(), new_head.number()); // update the tracked canonical head self.canonical_in_memory_state.set_canonical_head(new_head); @@ -1622,7 +1626,7 @@ where // the hash could belong to an unknown block or a persisted block if let Some(header) = self.provider.header(&hash)? { - debug!(target: "engine::tree", %hash, number = %header.number, "found canonical state for block in database"); + debug!(target: "engine::tree", %hash, number = %header.number(), "found canonical state for block in database"); // the block is known and persisted let historical = self.provider.state_by_block_hash(hash)?; return Ok(Some(historical)) diff --git a/crates/evm/src/provider.rs b/crates/evm/src/provider.rs index 5f86eb74dd46..ec2f1803da01 100644 --- a/crates/evm/src/provider.rs +++ b/crates/evm/src/provider.rs @@ -3,7 +3,6 @@ use crate::ConfigureEvmEnv; use alloy_consensus::Header; use alloy_eips::BlockHashOrNumber; -use reth_primitives::NodePrimitives; use reth_storage_errors::provider::ProviderResult; use revm::primitives::{BlockEnv, CfgEnv, CfgEnvWithHandlerCfg, SpecId}; @@ -13,7 +12,7 @@ use revm::primitives::{BlockEnv, CfgEnv, CfgEnvWithHandlerCfg, SpecId}; /// This type is mainly used to provide required data to configure the EVM environment that is /// usually stored on disk. #[auto_impl::auto_impl(&, Arc)] -pub trait EvmEnvProvider: Send + Sync { +pub trait EvmEnvProvider: Send + Sync { /// Fills the [`CfgEnvWithHandlerCfg`] and [BlockEnv] fields with values specific to the given /// [BlockHashOrNumber]. fn fill_env_at( @@ -24,17 +23,17 @@ pub trait EvmEnvProvider: Se evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
; + EvmConfig: ConfigureEvmEnv
; /// Fills the default [`CfgEnvWithHandlerCfg`] and [BlockEnv] fields with values specific to the /// given block header. fn env_with_header( &self, - header: &N::BlockHeader, + header: &H, evm_config: EvmConfig, ) -> ProviderResult<(CfgEnvWithHandlerCfg, BlockEnv)> where - EvmConfig: ConfigureEvmEnv
, + EvmConfig: ConfigureEvmEnv
, { let mut cfg = CfgEnvWithHandlerCfg::new_with_spec_id(CfgEnv::default(), SpecId::LATEST); let mut block_env = BlockEnv::default(); @@ -48,11 +47,11 @@ pub trait EvmEnvProvider: Se &self, cfg: &mut CfgEnvWithHandlerCfg, block_env: &mut BlockEnv, - header: &N::BlockHeader, + header: &H, evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
; + EvmConfig: ConfigureEvmEnv
; /// Fills the [`CfgEnvWithHandlerCfg`] fields with values specific to the given /// [BlockHashOrNumber]. @@ -63,15 +62,15 @@ pub trait EvmEnvProvider: Se evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
; + EvmConfig: ConfigureEvmEnv
; /// Fills the [`CfgEnvWithHandlerCfg`] fields with values specific to the given block header. fn fill_cfg_env_with_header( &self, cfg: &mut CfgEnvWithHandlerCfg, - header: &N::BlockHeader, + header: &H, evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
; + EvmConfig: ConfigureEvmEnv
; } diff --git a/crates/exex/exex/src/manager.rs b/crates/exex/exex/src/manager.rs index a3b92e9f17ab..16a930526141 100644 --- a/crates/exex/exex/src/manager.rs +++ b/crates/exex/exex/src/manager.rs @@ -246,7 +246,7 @@ pub struct ExExManager { /// Write-Ahead Log for the [`ExExNotification`]s. wal: Wal, /// A stream of finalized headers. - finalized_header_stream: ForkChoiceStream, + finalized_header_stream: ForkChoiceStream>, /// A handle to the `ExEx` manager. handle: ExExManagerHandle, @@ -270,7 +270,7 @@ where handles: Vec>, max_capacity: usize, wal: Wal, - finalized_header_stream: ForkChoiceStream, + finalized_header_stream: ForkChoiceStream>, ) -> Self { let num_exexs = handles.len(); @@ -355,7 +355,7 @@ where /// /// This function checks if all ExExes are on the canonical chain and finalizes the WAL if /// necessary. - fn finalize_wal(&self, finalized_header: SealedHeader) -> eyre::Result<()> { + fn finalize_wal(&self, finalized_header: SealedHeader) -> eyre::Result<()> { debug!(target: "exex::manager", header = ?finalized_header.num_hash(), "Received finalized header"); // Check if all ExExes are on the canonical chain diff --git a/crates/net/downloaders/src/bodies/bodies.rs b/crates/net/downloaders/src/bodies/bodies.rs index 82f45dd23bfe..682995e7eb3a 100644 --- a/crates/net/downloaders/src/bodies/bodies.rs +++ b/crates/net/downloaders/src/bodies/bodies.rs @@ -1,5 +1,6 @@ use super::queue::BodiesRequestQueue; use crate::{bodies::task::TaskDownloader, metrics::BodyDownloaderMetrics}; +use alloy_consensus::BlockHeader; use alloy_primitives::BlockNumber; use futures::Stream; use futures_util::StreamExt; @@ -14,7 +15,7 @@ use reth_network_p2p::{ error::{DownloadError, DownloadResult}, }; use reth_primitives::SealedHeader; -use reth_primitives_traits::size::InMemorySize; +use reth_primitives_traits::{size::InMemorySize, BlockHeader as _}; use reth_storage_api::HeaderProvider; use reth_tasks::{TaskSpawner, TokioTaskExecutor}; use std::{ @@ -71,7 +72,7 @@ where Provider: HeaderProvider + Unpin + 'static, { /// Returns the next contiguous request. - fn next_headers_request(&self) -> DownloadResult>> { + fn next_headers_request(&self) -> DownloadResult>>> { let start_at = match self.in_progress_queue.last_requested_block_number { Some(num) => num + 1, None => *self.download_range.start(), @@ -96,7 +97,7 @@ where &self, range: RangeInclusive, max_non_empty: u64, - ) -> DownloadResult>> { + ) -> DownloadResult>>> { if range.is_empty() || max_non_empty == 0 { return Ok(None) } @@ -109,7 +110,7 @@ where let mut collected = 0; let mut non_empty_headers = 0; let headers = self.provider.sealed_headers_while(range.clone(), |header| { - let should_take = range.contains(&header.number) && + let should_take = range.contains(&header.number()) && non_empty_headers < max_non_empty && collected < self.stream_batch_size; @@ -300,7 +301,7 @@ where impl BodyDownloader for BodiesDownloader where B: BodiesClient + 'static, - Provider: HeaderProvider + Unpin + 'static, + Provider: HeaderProvider
+ Unpin + 'static, { type Body = B::Body; @@ -350,7 +351,7 @@ where impl Stream for BodiesDownloader where B: BodiesClient + 'static, - Provider: HeaderProvider + Unpin + 'static, + Provider: HeaderProvider
+ Unpin + 'static, { type Item = BodyDownloaderResult; diff --git a/crates/net/downloaders/src/bodies/task.rs b/crates/net/downloaders/src/bodies/task.rs index a2b63c8ed186..89af9813e3cc 100644 --- a/crates/net/downloaders/src/bodies/task.rs +++ b/crates/net/downloaders/src/bodies/task.rs @@ -52,10 +52,10 @@ impl TaskDownloader { /// /// fn t< /// B: BodiesClient + 'static, - /// Provider: HeaderProvider + Unpin + 'static, + /// Provider: HeaderProvider
+ Unpin + 'static, /// >( /// client: Arc, - /// consensus: Arc>, + /// consensus: Arc>, /// provider: Provider, /// ) { /// let downloader = BodiesDownloaderBuilder::default().build(client, consensus, provider); diff --git a/crates/net/network/src/config.rs b/crates/net/network/src/config.rs index a7d8a98fae6d..bde2cf78d979 100644 --- a/crates/net/network/src/config.rs +++ b/crates/net/network/src/config.rs @@ -147,8 +147,11 @@ where impl NetworkConfig where - C: BlockReader - + HeaderProvider + C: BlockReader< + Block = reth_primitives::Block, + Receipt = reth_primitives::Receipt, + Header = reth_primitives::Header, + > + HeaderProvider + Clone + Unpin + 'static, diff --git a/crates/net/network/src/eth_requests.rs b/crates/net/network/src/eth_requests.rs index bb45507bdbdb..ee8640daaa9a 100644 --- a/crates/net/network/src/eth_requests.rs +++ b/crates/net/network/src/eth_requests.rs @@ -4,7 +4,7 @@ use crate::{ budget::DEFAULT_BUDGET_TRY_DRAIN_DOWNLOADERS, metered_poll_nested_stream_with_budget, metrics::EthRequestHandlerMetrics, }; -use alloy_consensus::Header; +use alloy_consensus::BlockHeader; use alloy_eips::BlockHashOrNumber; use alloy_rlp::Encodable; use futures::StreamExt; @@ -83,7 +83,7 @@ where C: BlockReader + HeaderProvider + ReceiptProvider, { /// Returns the list of requested headers - fn get_headers_response(&self, request: GetBlockHeaders) -> Vec
{ + fn get_headers_response(&self, request: GetBlockHeaders) -> Vec { let GetBlockHeaders { start_block, limit, skip, direction } = request; let mut headers = Vec::new(); @@ -105,7 +105,7 @@ where if let Some(header) = self.client.header_by_hash_or_number(block).unwrap_or_default() { match direction { HeadersDirection::Rising => { - if let Some(next) = (header.number + 1).checked_add(skip) { + if let Some(next) = (header.number() + 1).checked_add(skip) { block = next.into() } else { break @@ -116,14 +116,14 @@ where // prevent under flows for block.number == 0 and `block.number - skip < // 0` if let Some(next) = - header.number.checked_sub(1).and_then(|num| num.checked_sub(skip)) + header.number().checked_sub(1).and_then(|num| num.checked_sub(skip)) { block = next.into() } else { break } } else { - block = header.parent_hash.into() + block = header.parent_hash().into() } } } @@ -146,7 +146,7 @@ where &self, _peer_id: PeerId, request: GetBlockHeaders, - response: oneshot::Sender>>, + response: oneshot::Sender>>, ) { self.metrics.eth_headers_requests_received_total.increment(1); let headers = self.get_headers_response(request); @@ -225,7 +225,7 @@ where impl Future for EthRequestHandler where C: BlockReader - + HeaderProvider + + HeaderProvider
+ Unpin, { type Output = (); diff --git a/crates/net/network/src/test_utils/testnet.rs b/crates/net/network/src/test_utils/testnet.rs index 9801ecf9293a..bdd02118352b 100644 --- a/crates/net/network/src/test_utils/testnet.rs +++ b/crates/net/network/src/test_utils/testnet.rs @@ -194,8 +194,11 @@ where impl Testnet where - C: BlockReader - + HeaderProvider + C: BlockReader< + Block = reth_primitives::Block, + Receipt = reth_primitives::Receipt, + Header = reth_primitives::Header, + > + HeaderProvider + Clone + Unpin + 'static, @@ -257,8 +260,11 @@ impl fmt::Debug for Testnet { impl Future for Testnet where - C: BlockReader - + HeaderProvider + C: BlockReader< + Block = reth_primitives::Block, + Receipt = reth_primitives::Receipt, + Header = reth_primitives::Header, + > + HeaderProvider + Unpin + 'static, Pool: TransactionPool + Unpin + 'static, @@ -455,8 +461,11 @@ where impl Future for Peer where - C: BlockReader - + HeaderProvider + C: BlockReader< + Block = reth_primitives::Block, + Receipt = reth_primitives::Receipt, + Header = reth_primitives::Header, + > + HeaderProvider + Unpin + 'static, Pool: TransactionPool + Unpin + 'static, diff --git a/crates/node/builder/src/builder/mod.rs b/crates/node/builder/src/builder/mod.rs index 06d5294d800a..b311cc4e2a0f 100644 --- a/crates/node/builder/src/builder/mod.rs +++ b/crates/node/builder/src/builder/mod.rs @@ -651,8 +651,11 @@ impl BuilderContext { pub fn start_network(&self, builder: NetworkBuilder<(), ()>, pool: Pool) -> NetworkHandle where Pool: TransactionPool + Unpin + 'static, - Node::Provider: - BlockReader, + Node::Provider: BlockReader< + Block = reth_primitives::Block, + Receipt = reth_primitives::Receipt, + Header = reth_primitives::Header, + >, { self.start_network_with(builder, pool, Default::default()) } @@ -671,8 +674,11 @@ impl BuilderContext { ) -> NetworkHandle where Pool: TransactionPool + Unpin + 'static, - Node::Provider: - BlockReader, + Node::Provider: BlockReader< + Block = reth_primitives::Block, + Receipt = reth_primitives::Receipt, + Header = reth_primitives::Header, + >, { let (handle, network, txpool, eth) = builder .transactions(pool, tx_config) diff --git a/crates/node/builder/src/launch/common.rs b/crates/node/builder/src/launch/common.rs index 2d126266a25c..25c81a8d5cf0 100644 --- a/crates/node/builder/src/launch/common.rs +++ b/crates/node/builder/src/launch/common.rs @@ -385,6 +385,7 @@ where Block = reth_primitives::Block, BlockBody = reth_primitives::BlockBody, Receipt = reth_primitives::Receipt, + BlockHeader = reth_primitives::Header, >, { let factory = ProviderFactory::new( @@ -456,6 +457,7 @@ where Block = reth_primitives::Block, BlockBody = reth_primitives::BlockBody, Receipt = reth_primitives::Receipt, + BlockHeader = reth_primitives::Header, >, { let factory = self.create_provider_factory().await?; diff --git a/crates/node/builder/src/setup.rs b/crates/node/builder/src/setup.rs index ec4ee4956dd2..0a0e4f10dbc9 100644 --- a/crates/node/builder/src/setup.rs +++ b/crates/node/builder/src/setup.rs @@ -14,7 +14,7 @@ use reth_exex::ExExManagerHandle; use reth_network_p2p::{ bodies::downloader::BodyDownloader, headers::downloader::HeaderDownloader, BlockClient, }; -use reth_node_api::{BodyTy, HeaderTy}; +use reth_node_api::{BodyTy, HeaderTy, NodePrimitives}; use reth_provider::{providers::ProviderNodeTypes, ProviderFactory}; use reth_stages::{prelude::DefaultStages, stages::ExecutionStage, Pipeline, StageSet}; use reth_static_file::StaticFileProducer; @@ -41,6 +41,7 @@ where N: ProviderNodeTypes, Client: BlockClient
, Body = BodyTy> + 'static, Executor: BlockExecutorProvider, + N::Primitives: NodePrimitives, { // building network downloaders using the fetch client let header_downloader = ReverseHeadersDownloaderBuilder::new(config.headers) @@ -88,6 +89,7 @@ where H: HeaderDownloader
> + 'static, B: BodyDownloader> + 'static, Executor: BlockExecutorProvider, + N::Primitives: NodePrimitives, { let mut builder = Pipeline::::builder(); diff --git a/crates/node/core/src/node_config.rs b/crates/node/core/src/node_config.rs index 2fd39bde82f2..861e47fc3cf1 100644 --- a/crates/node/core/src/node_config.rs +++ b/crates/node/core/src/node_config.rs @@ -319,9 +319,9 @@ impl NodeConfig { Ok(Head { number: head, hash, - difficulty: header.difficulty, + difficulty: header.difficulty(), total_difficulty, - timestamp: header.timestamp, + timestamp: header.timestamp(), }) } @@ -344,7 +344,7 @@ impl NodeConfig { // try to look up the header in the database if let Some(header) = header { info!(target: "reth::cli", ?tip, "Successfully looked up tip block in the database"); - return Ok(header.number) + return Ok(header.number()) } Ok(self.fetch_tip_from_network(client, tip.into()).await.number()) diff --git a/crates/node/events/src/cl.rs b/crates/node/events/src/cl.rs index bf0d4a59b213..dac13fe07631 100644 --- a/crates/node/events/src/cl.rs +++ b/crates/node/events/src/cl.rs @@ -1,5 +1,6 @@ //! Events related to Consensus Layer health. +use alloy_consensus::Header; use futures::Stream; use reth_storage_api::CanonChainTracker; use std::{ @@ -20,9 +21,9 @@ const NO_TRANSITION_CONFIG_EXCHANGED_PERIOD: Duration = Duration::from_secs(120) const NO_FORKCHOICE_UPDATE_RECEIVED_PERIOD: Duration = Duration::from_secs(120); /// A Stream of [`ConsensusLayerHealthEvent`]. -pub struct ConsensusLayerHealthEvents { +pub struct ConsensusLayerHealthEvents { interval: Interval, - canon_chain: Box, + canon_chain: Box>, } impl fmt::Debug for ConsensusLayerHealthEvents { @@ -31,9 +32,9 @@ impl fmt::Debug for ConsensusLayerHealthEvents { } } -impl ConsensusLayerHealthEvents { +impl ConsensusLayerHealthEvents { /// Creates a new [`ConsensusLayerHealthEvents`] with the given canonical chain tracker. - pub fn new(canon_chain: Box) -> Self { + pub fn new(canon_chain: Box>) -> Self { // Skip the first tick to prevent the false `ConsensusLayerHealthEvent::NeverSeen` event. let interval = tokio::time::interval_at(Instant::now() + CHECK_INTERVAL, CHECK_INTERVAL); Self { interval, canon_chain } diff --git a/crates/optimism/rpc/src/eth/pending_block.rs b/crates/optimism/rpc/src/eth/pending_block.rs index 98ea65778d8d..852c4454f060 100644 --- a/crates/optimism/rpc/src/eth/pending_block.rs +++ b/crates/optimism/rpc/src/eth/pending_block.rs @@ -27,6 +27,7 @@ where Provider: BlockReaderIdExt< Block = reth_primitives::Block, Receipt = reth_primitives::Receipt, + Header = reth_primitives::Header, > + EvmEnvProvider + ChainSpecProvider + StateProviderFactory, diff --git a/crates/optimism/rpc/src/witness.rs b/crates/optimism/rpc/src/witness.rs index ed9d77e73e84..278c785cbe9a 100644 --- a/crates/optimism/rpc/src/witness.rs +++ b/crates/optimism/rpc/src/witness.rs @@ -31,7 +31,7 @@ impl OpDebugWitnessApi { impl OpDebugWitnessApi where - Provider: BlockReaderIdExt, + Provider: BlockReaderIdExt
, { /// Fetches the parent header by hash. fn parent_header(&self, parent_block_hash: B256) -> ProviderResult { @@ -45,7 +45,7 @@ where impl DebugExecutionWitnessApiServer for OpDebugWitnessApi where - Provider: BlockReaderIdExt + Provider: BlockReaderIdExt
+ StateProviderFactory + ChainSpecProvider + 'static, diff --git a/crates/payload/basic/src/lib.rs b/crates/payload/basic/src/lib.rs index 0ab411d3e600..8e9c06865d03 100644 --- a/crates/payload/basic/src/lib.rs +++ b/crates/payload/basic/src/lib.rs @@ -132,7 +132,11 @@ impl BasicPayloadJobGenerator PayloadJobGenerator for BasicPayloadJobGenerator where - Client: StateProviderFactory + BlockReaderIdExt + Clone + Unpin + 'static, + Client: StateProviderFactory + + BlockReaderIdExt
+ + Clone + + Unpin + + 'static, Pool: TransactionPool + Unpin + 'static, Tasks: TaskSpawner + Clone + Unpin + 'static, Builder: PayloadBuilder + Unpin + 'static, diff --git a/crates/primitives-traits/src/block/header.rs b/crates/primitives-traits/src/block/header.rs index 6ac85d82caa4..47d50a45bb54 100644 --- a/crates/primitives-traits/src/block/header.rs +++ b/crates/primitives-traits/src/block/header.rs @@ -30,27 +30,15 @@ pub trait BlockHeader: + MaybeSerde + MaybeArbitrary + MaybeSerdeBincodeCompat + + AsRef + 'static { + /// Returns whether this header corresponds to an empty block. + fn is_empty(&self) -> bool; } -impl BlockHeader for T where - T: Send - + Sync - + Unpin - + Clone - + Default - + fmt::Debug - + PartialEq - + Eq - + alloy_rlp::Encodable - + alloy_rlp::Decodable - + alloy_consensus::BlockHeader - + Sealable - + InMemorySize - + MaybeSerde - + MaybeArbitrary - + MaybeSerdeBincodeCompat - + 'static -{ +impl BlockHeader for alloy_consensus::Header { + fn is_empty(&self) -> bool { + self.is_empty() + } } diff --git a/crates/rpc/rpc-builder/src/eth.rs b/crates/rpc/rpc-builder/src/eth.rs index 2a781fc0859b..283fba6e957f 100644 --- a/crates/rpc/rpc-builder/src/eth.rs +++ b/crates/rpc/rpc-builder/src/eth.rs @@ -29,8 +29,11 @@ pub struct EthHandlers { impl EthHandlers where Provider: StateProviderFactory - + BlockReader - + EvmEnvProvider + + BlockReader< + Block = reth_primitives::Block, + Receipt = reth_primitives::Receipt, + Header = reth_primitives::Header, + > + EvmEnvProvider + Clone + Unpin + 'static, diff --git a/crates/rpc/rpc-builder/src/lib.rs b/crates/rpc/rpc-builder/src/lib.rs index 3817c4d3b378..e2141dcf1cee 100644 --- a/crates/rpc/rpc-builder/src/lib.rs +++ b/crates/rpc/rpc-builder/src/lib.rs @@ -41,6 +41,7 @@ //! Transaction = TransactionSigned, //! Block = reth_primitives::Block, //! Receipt = reth_primitives::Receipt, +//! Header = reth_primitives::Header, //! > + AccountReader //! + ChangeSetReader, //! Pool: TransactionPool + Unpin + 'static, @@ -121,6 +122,7 @@ //! Transaction = TransactionSigned, //! Block = reth_primitives::Block, //! Receipt = reth_primitives::Receipt, +//! Header = reth_primitives::Header, //! > + AccountReader //! + ChangeSetReader, //! Pool: TransactionPool + Unpin + 'static, @@ -201,7 +203,7 @@ use reth_network_api::{noop::NoopNetwork, NetworkInfo, Peers}; use reth_primitives::{EthPrimitives, NodePrimitives}; use reth_provider::{ AccountReader, BlockReader, CanonStateSubscriptions, ChainSpecProvider, ChangeSetReader, - EvmEnvProvider, FullRpcProvider, ReceiptProvider, StateProviderFactory, + EvmEnvProvider, FullRpcProvider, HeaderProvider, ReceiptProvider, StateProviderFactory, }; use reth_rpc::{ AdminApi, DebugApi, EngineEthApi, EthBundle, NetApi, OtterscanApi, RPCApi, RethApi, TraceApi, @@ -269,8 +271,11 @@ pub async fn launch, ) -> Result where - Provider: FullRpcProvider - + AccountReader + Provider: FullRpcProvider< + Block = reth_primitives::Block, + Receipt = reth_primitives::Receipt, + Header = reth_primitives::Header, + > + AccountReader + ChangeSetReader, Pool: TransactionPool + 'static, Network: NetworkInfo + Peers + Clone + 'static, @@ -667,6 +672,7 @@ where Provider: BlockReader< Block = ::Block, Receipt = ::Receipt, + Header = ::Header, >, { let Self { @@ -743,7 +749,11 @@ where ) -> RpcRegistryInner where EthApi: EthApiTypes + 'static, - Provider: BlockReader, + Provider: BlockReader< + Block = reth_primitives::Block, + Receipt = reth_primitives::Receipt, + Header = reth_primitives::Header, + >, { let Self { provider, @@ -781,6 +791,7 @@ where Provider: BlockReader< Block = ::Block, Receipt = ::Receipt, + Header = ::Header, >, { let mut modules = TransportRpcModules::default(); @@ -940,8 +951,11 @@ impl RpcRegistryInner where Provider: StateProviderFactory - + BlockReader - + EvmEnvProvider + + BlockReader< + Block = reth_primitives::Block, + Receipt = reth_primitives::Receipt, + Header = reth_primitives::Header, + > + EvmEnvProvider + Clone + Unpin + 'static, @@ -1311,6 +1325,7 @@ where Provider: FullRpcProvider< Block = ::Block, Receipt = ::Receipt, + Header = ::Header, > + AccountReader + ChangeSetReader, Pool: TransactionPool + 'static, diff --git a/crates/rpc/rpc-eth-api/src/helpers/fee.rs b/crates/rpc/rpc-eth-api/src/helpers/fee.rs index 0099e0f6b160..5843e945b8c3 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/fee.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/fee.rs @@ -163,11 +163,11 @@ pub trait EthFees: LoadFee { for header in &headers { - base_fee_per_gas.push(header.base_fee_per_gas.unwrap_or_default() as u128); - gas_used_ratio.push(header.gas_used as f64 / header.gas_limit as f64); + base_fee_per_gas.push(header.base_fee_per_gas().unwrap_or_default() as u128); + gas_used_ratio.push(header.gas_used() as f64 / header.gas_limit() as f64); base_fee_per_blob_gas.push(header.blob_fee().unwrap_or_default()); blob_gas_used_ratio.push( - header.blob_gas_used.unwrap_or_default() as f64 + header.blob_gas_used().unwrap_or_default() as f64 / alloy_eips::eip4844::MAX_DATA_GAS_PER_BLOCK as f64, ); @@ -181,8 +181,8 @@ pub trait EthFees: LoadFee { rewards.push( calculate_reward_percentiles_for_block( percentiles, - header.gas_used, - header.base_fee_per_gas.unwrap_or_default(), + header.gas_used(), + header.base_fee_per_gas().unwrap_or_default(), &block.body.transactions, &receipts, ) @@ -198,14 +198,10 @@ pub trait EthFees: LoadFee { // The unwrap is safe since we checked earlier that we got at least 1 header. let last_header = headers.last().expect("is present"); base_fee_per_gas.push( + last_header.next_block_base_fee( self.provider() .chain_spec() - .base_fee_params_at_timestamp(last_header.timestamp) - .next_block_base_fee( - last_header.gas_used , - last_header.gas_limit, - last_header.base_fee_per_gas.unwrap_or_default() , - ) as u128, + .base_fee_params_at_timestamp(last_header.timestamp())).unwrap_or_default() as u128 ); // Same goes for the `base_fee_per_blob_gas`: diff --git a/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs b/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs index e3ef6621bcba..4394feb28341 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs @@ -3,7 +3,7 @@ use super::SpawnBlocking; use crate::{EthApiTypes, FromEthApiError, FromEvmError, RpcNodeCore}; -use alloy_consensus::{Header, EMPTY_OMMER_ROOT_HASH}; +use alloy_consensus::{BlockHeader, Header, EMPTY_OMMER_ROOT_HASH}; use alloy_eips::{ eip4844::MAX_DATA_GAS_PER_BLOCK, eip7685::EMPTY_REQUESTS_HASH, merge::BEACON_NONCE, }; @@ -50,6 +50,7 @@ pub trait LoadPendingBlock: Provider: BlockReaderIdExt< Block = reth_primitives::Block, Receipt = reth_primitives::Receipt, + Header = reth_primitives::Header, > + EvmEnvProvider + ChainSpecProvider + StateProviderFactory, @@ -88,7 +89,7 @@ pub trait LoadPendingBlock: let chain_spec = self.provider().chain_spec(); latest_header.base_fee_per_gas = latest_header.next_block_base_fee( - chain_spec.base_fee_params_at_timestamp(latest_header.timestamp), + chain_spec.base_fee_params_at_timestamp(latest_header.timestamp()), ); // update excess blob gas consumed above target diff --git a/crates/rpc/rpc-eth-types/src/cache/mod.rs b/crates/rpc/rpc-eth-types/src/cache/mod.rs index 2dcabc0d1841..7a0d9dfa0f01 100644 --- a/crates/rpc/rpc-eth-types/src/cache/mod.rs +++ b/crates/rpc/rpc-eth-types/src/cache/mod.rs @@ -96,8 +96,11 @@ impl EthStateCache { pub fn spawn(provider: Provider, config: EthStateCacheConfig) -> Self where Provider: StateProviderFactory - + BlockReader - + Clone + + BlockReader< + Block = reth_primitives::Block, + Receipt = reth_primitives::Receipt, + Header = reth_primitives::Header, + > + Clone + Unpin + 'static, { @@ -115,8 +118,11 @@ impl EthStateCache { ) -> Self where Provider: StateProviderFactory - + BlockReader - + Clone + + BlockReader< + Block = reth_primitives::Block, + Receipt = reth_primitives::Receipt, + Header = reth_primitives::Header, + > + Clone + Unpin + 'static, Tasks: TaskSpawner + Clone + 'static, @@ -331,8 +337,11 @@ where impl Future for EthStateCacheService where Provider: StateProviderFactory - + BlockReader - + Clone + + BlockReader< + Block = reth_primitives::Block, + Receipt = reth_primitives::Receipt, + Header = reth_primitives::Header, + > + Clone + Unpin + 'static, Tasks: TaskSpawner + Clone + 'static, diff --git a/crates/rpc/rpc-eth-types/src/gas_oracle.rs b/crates/rpc/rpc-eth-types/src/gas_oracle.rs index 3f8186ae1502..73cab209fd54 100644 --- a/crates/rpc/rpc-eth-types/src/gas_oracle.rs +++ b/crates/rpc/rpc-eth-types/src/gas_oracle.rs @@ -1,7 +1,7 @@ //! An implementation of the eth gas price oracle, used for providing gas price estimates based on //! previous blocks. -use alloy_consensus::constants::GWEI_TO_WEI; +use alloy_consensus::{constants::GWEI_TO_WEI, BlockHeader}; use alloy_eips::BlockNumberOrTag; use alloy_primitives::{B256, U256}; use alloy_rpc_types_eth::BlockId; @@ -142,8 +142,8 @@ where let mut populated_blocks = 0; // we only check a maximum of 2 * max_block_history, or the number of blocks in the chain - let max_blocks = if self.oracle_config.max_block_history * 2 > header.number { - header.number + let max_blocks = if self.oracle_config.max_block_history * 2 > header.number() { + header.number() } else { self.oracle_config.max_block_history * 2 }; diff --git a/crates/rpc/rpc/src/eth/core.rs b/crates/rpc/rpc/src/eth/core.rs index 86e0f9f383cd..092d94851622 100644 --- a/crates/rpc/rpc/src/eth/core.rs +++ b/crates/rpc/rpc/src/eth/core.rs @@ -3,6 +3,7 @@ use std::sync::Arc; +use alloy_consensus::BlockHeader; use alloy_eips::BlockNumberOrTag; use alloy_network::Ethereum; use alloy_primitives::U256; @@ -286,7 +287,7 @@ where .header_by_number_or_tag(BlockNumberOrTag::Latest) .ok() .flatten() - .map(|header| header.number) + .map(|header| header.number()) .unwrap_or_default(), ); @@ -438,8 +439,11 @@ mod tests { use crate::EthApi; fn build_test_eth_api< - P: BlockReaderIdExt - + BlockReader + P: BlockReaderIdExt< + Block = reth_primitives::Block, + Receipt = reth_primitives::Receipt, + Header = reth_primitives::Header, + > + BlockReader + ChainSpecProvider + EvmEnvProvider + StateProviderFactory diff --git a/crates/rpc/rpc/src/eth/filter.rs b/crates/rpc/rpc/src/eth/filter.rs index 200afadaa2e9..b16b370b2c02 100644 --- a/crates/rpc/rpc/src/eth/filter.rs +++ b/crates/rpc/rpc/src/eth/filter.rs @@ -1,5 +1,6 @@ //! `eth_` `Filter` RPC handler implementation +use alloy_consensus::BlockHeader; use alloy_primitives::TxHash; use alloy_rpc_types_eth::{ BlockNumHash, Filter, FilterBlockOption, FilterChanges, FilterId, FilteredParams, Log, @@ -380,7 +381,7 @@ where .header_by_hash_or_number(block_hash.into())? .ok_or_else(|| ProviderError::HeaderNotFound(block_hash.into()))?; - let block_num_hash = BlockNumHash::new(header.number, block_hash); + let block_num_hash = BlockNumHash::new(header.number(), block_hash); // we also need to ensure that the receipts are available and return an error if // not, in case the block hash been reorged @@ -402,7 +403,7 @@ where block_num_hash, &receipts, false, - header.timestamp, + header.timestamp(), )?; Ok(all_logs) @@ -483,20 +484,20 @@ where for (idx, header) in headers.iter().enumerate() { // only if filter matches - if FilteredParams::matches_address(header.logs_bloom, &address_filter) && - FilteredParams::matches_topics(header.logs_bloom, &topics_filter) + if FilteredParams::matches_address(header.logs_bloom(), &address_filter) && + FilteredParams::matches_topics(header.logs_bloom(), &topics_filter) { // these are consecutive headers, so we can use the parent hash of the next // block to get the current header's hash let block_hash = match headers.get(idx + 1) { - Some(parent) => parent.parent_hash, + Some(parent) => parent.parent_hash(), None => self .provider - .block_hash(header.number)? - .ok_or_else(|| ProviderError::HeaderNotFound(header.number.into()))?, + .block_hash(header.number())? + .ok_or_else(|| ProviderError::HeaderNotFound(header.number().into()))?, }; - let num_hash = BlockNumHash::new(header.number, block_hash); + let num_hash = BlockNumHash::new(header.number(), block_hash); if let Some((receipts, maybe_block)) = self.receipts_and_maybe_block(&num_hash, chain_info.best_number).await? { @@ -509,7 +510,7 @@ where num_hash, &receipts, false, - header.timestamp, + header.timestamp(), )?; // size check but only if range is multiple blocks, so we always return all diff --git a/crates/rpc/rpc/src/eth/helpers/pending_block.rs b/crates/rpc/rpc/src/eth/helpers/pending_block.rs index a67522ce0326..794b9dde82f4 100644 --- a/crates/rpc/rpc/src/eth/helpers/pending_block.rs +++ b/crates/rpc/rpc/src/eth/helpers/pending_block.rs @@ -21,6 +21,7 @@ where Provider: BlockReaderIdExt< Block = reth_primitives::Block, Receipt = reth_primitives::Receipt, + Header = reth_primitives::Header, > + EvmEnvProvider + ChainSpecProvider + StateProviderFactory, diff --git a/crates/rpc/rpc/src/validation.rs b/crates/rpc/rpc/src/validation.rs index 91a3dae2ce7c..d862bc5f30dd 100644 --- a/crates/rpc/rpc/src/validation.rs +++ b/crates/rpc/rpc/src/validation.rs @@ -89,7 +89,7 @@ where impl ValidationApi where - Provider: BlockReaderIdExt + Provider: BlockReaderIdExt
+ ChainSpecProvider + StateProviderFactory + HeaderProvider @@ -410,7 +410,7 @@ where #[async_trait] impl BlockSubmissionValidationApiServer for ValidationApi where - Provider: BlockReaderIdExt + Provider: BlockReaderIdExt
+ ChainSpecProvider + StateProviderFactory + HeaderProvider diff --git a/crates/stages/stages/src/stages/bodies.rs b/crates/stages/stages/src/stages/bodies.rs index c1fde11c2354..0f90ff69e46f 100644 --- a/crates/stages/stages/src/stages/bodies.rs +++ b/crates/stages/stages/src/stages/bodies.rs @@ -75,7 +75,9 @@ impl BodyStage { unwind_block: Option, ) -> Result<(), StageError> where - Provider: DBProvider + BlockReader + StaticFileProviderFactory, + Provider: DBProvider + + BlockReader
+ + StaticFileProviderFactory, { // Get id for the next tx_num of zero if there are no transactions. let next_tx_num = provider @@ -152,7 +154,7 @@ where Provider: DBProvider + StaticFileProviderFactory + StatsReader - + BlockReader + + BlockReader
+ BlockWriter>, D: BodyDownloader>, { diff --git a/crates/stages/stages/src/stages/execution.rs b/crates/stages/stages/src/stages/execution.rs index f7832dd788ee..c8cc89080867 100644 --- a/crates/stages/stages/src/stages/execution.rs +++ b/crates/stages/stages/src/stages/execution.rs @@ -193,7 +193,10 @@ where unwind_to: Option, ) -> Result<(), StageError> where - Provider: StaticFileProviderFactory + DBProvider + BlockReader + HeaderProvider, + Provider: StaticFileProviderFactory + + DBProvider + + BlockReader + + HeaderProvider
, { // If thre's any receipts pruning configured, receipts are written directly to database and // inconsistencies are expected. @@ -265,8 +268,10 @@ impl Stage for ExecutionStage where E: BlockExecutorProvider>, Provider: DBProvider - + BlockReader::Block> - + StaticFileProviderFactory + + BlockReader< + Block = ::Block, + Header = ::BlockHeader, + > + StaticFileProviderFactory + StatsReader + BlockHashReader + StateWriter::Receipt> diff --git a/crates/stages/stages/src/stages/hashing_account.rs b/crates/stages/stages/src/stages/hashing_account.rs index e6b1e548455f..551c10d7711f 100644 --- a/crates/stages/stages/src/stages/hashing_account.rs +++ b/crates/stages/stages/src/stages/hashing_account.rs @@ -63,8 +63,10 @@ impl AccountHashingStage { opts: SeedOpts, ) -> Result, StageError> where - N::Primitives: - reth_primitives_traits::FullNodePrimitives, + N::Primitives: reth_primitives_traits::FullNodePrimitives< + BlockBody = reth_primitives::BlockBody, + BlockHeader = reth_primitives::Header, + >, { use alloy_primitives::U256; use reth_db_api::models::AccountBeforeTx; diff --git a/crates/stages/stages/src/stages/headers.rs b/crates/stages/stages/src/stages/headers.rs index 100fe4e979a7..7b9b394b5615 100644 --- a/crates/stages/stages/src/stages/headers.rs +++ b/crates/stages/stages/src/stages/headers.rs @@ -1,3 +1,4 @@ +use alloy_consensus::BlockHeader; use alloy_primitives::{BlockHash, BlockNumber, Bytes, B256}; use futures_util::StreamExt; use reth_config::config::EtlConfig; @@ -10,7 +11,7 @@ use reth_db_api::{ }; use reth_etl::Collector; use reth_network_p2p::headers::{downloader::HeaderDownloader, error::HeadersDownloaderError}; -use reth_primitives::{SealedHeader, StaticFileSegment}; +use reth_primitives::{NodePrimitives, SealedHeader, StaticFileSegment}; use reth_primitives_traits::serde_bincode_compat; use reth_provider::{ providers::StaticFileWriter, BlockHashReader, DBProvider, HeaderProvider, HeaderSyncGap, @@ -50,7 +51,7 @@ pub struct HeaderStage { /// Consensus client implementation consensus: Arc>, /// Current sync gap. - sync_gap: Option, + sync_gap: Option>, /// ETL collector with `HeaderHash` -> `BlockNumber` hash_collector: Collector, /// ETL collector with `BlockNumber` -> `BincodeSealedHeader` @@ -63,7 +64,7 @@ pub struct HeaderStage { impl HeaderStage where - Downloader: HeaderDownloader
, + Downloader: HeaderDownloader, { /// Create a new header stage pub fn new( @@ -89,10 +90,14 @@ where /// /// Writes to static files ( `Header | HeaderTD | HeaderHash` ) and [`tables::HeaderNumbers`] /// database table. - fn write_headers + StaticFileProviderFactory>( - &mut self, - provider: &P, - ) -> Result { + fn write_headers

(&mut self, provider: &P) -> Result + where + P: DBProvider + + StaticFileProviderFactory< + Primitives: NodePrimitives, + >, + Downloader: HeaderDownloader

::BlockHeader>, + { let total_headers = self.header_collector.len(); info!(target: "sync::stages::headers", total = total_headers, "Writing headers"); @@ -121,19 +126,19 @@ where info!(target: "sync::stages::headers", progress = %format!("{:.2}%", (index as f64 / total_headers as f64) * 100.0), "Writing headers"); } - let sealed_header: SealedHeader = - bincode::deserialize::>(&header_buf) + let sealed_header: SealedHeader = + bincode::deserialize::>(&header_buf) .map_err(|err| StageError::Fatal(Box::new(err)))? .into(); let (header, header_hash) = sealed_header.split(); - if header.number == 0 { + if header.number() == 0 { continue } - last_header_number = header.number; + last_header_number = header.number(); // Increase total difficulty - td += header.difficulty; + td += header.difficulty(); // Header validation self.consensus.validate_header_with_total_difficulty(&header, td).map_err(|error| { @@ -193,9 +198,10 @@ where impl Stage for HeaderStage where - P: HeaderSyncGapProvider, - D: HeaderDownloader
, Provider: DBProvider + StaticFileProviderFactory, + Provider::Primitives: NodePrimitives, + P: HeaderSyncGapProvider
::BlockHeader>, + D: HeaderDownloader
::BlockHeader>, { /// Return the id of the stage fn id(&self) -> StageId { @@ -232,7 +238,7 @@ where } debug!(target: "sync::stages::headers", ?tip, head = ?gap.local_head.hash(), "Commencing sync"); - let local_head_number = gap.local_head.number; + let local_head_number = gap.local_head.number(); // let the downloader know what to sync self.downloader.update_sync_gap(gap.local_head, gap.target); @@ -241,9 +247,9 @@ where loop { match ready!(self.downloader.poll_next_unpin(cx)) { Some(Ok(headers)) => { - info!(target: "sync::stages::headers", total = headers.len(), from_block = headers.first().map(|h| h.number), to_block = headers.last().map(|h| h.number), "Received headers"); + info!(target: "sync::stages::headers", total = headers.len(), from_block = headers.first().map(|h| h.number()), to_block = headers.last().map(|h| h.number()), "Received headers"); for header in headers { - let header_number = header.number; + let header_number = header.number(); self.hash_collector.insert(header.hash(), header_number)?; self.header_collector.insert( diff --git a/crates/stages/stages/src/stages/merkle.rs b/crates/stages/stages/src/stages/merkle.rs index 2d2503b53919..8095dfed9048 100644 --- a/crates/stages/stages/src/stages/merkle.rs +++ b/crates/stages/stages/src/stages/merkle.rs @@ -1,3 +1,4 @@ +use alloy_consensus::BlockHeader; use alloy_primitives::{BlockNumber, B256}; use reth_codecs::Compact; use reth_consensus::ConsensusError; @@ -135,7 +136,7 @@ where Provider: DBProvider + TrieWriter + StatsReader - + HeaderProvider + + HeaderProvider
+ StageCheckpointReader + StageCheckpointWriter, { @@ -168,7 +169,7 @@ where let target_block = provider .header_by_number(to_block)? .ok_or_else(|| ProviderError::HeaderNotFound(to_block.into()))?; - let target_block_root = target_block.state_root; + let target_block_root = target_block.state_root(); let mut checkpoint = self.get_execution_checkpoint(provider)?; let (trie_root, entities_checkpoint) = if range.is_empty() { diff --git a/crates/stages/stages/src/stages/sender_recovery.rs b/crates/stages/stages/src/stages/sender_recovery.rs index 674d035021d6..d34a4b07921a 100644 --- a/crates/stages/stages/src/stages/sender_recovery.rs +++ b/crates/stages/stages/src/stages/sender_recovery.rs @@ -59,7 +59,7 @@ impl Default for SenderRecoveryStage { impl Stage for SenderRecoveryStage where Provider: DBProvider - + BlockReader + + BlockReader
+ StaticFileProviderFactory> + StatsReader + PruneCheckpointReader, @@ -146,7 +146,8 @@ fn recover_range( senders_cursor: &mut CURSOR, ) -> Result<(), StageError> where - Provider: DBProvider + HeaderProvider + StaticFileProviderFactory, + Provider: + DBProvider + HeaderProvider
+ StaticFileProviderFactory, CURSOR: DbCursorRW, { debug!(target: "sync::stages::sender_recovery", ?tx_range, "Sending batch for processing"); diff --git a/crates/stages/stages/src/stages/utils.rs b/crates/stages/stages/src/stages/utils.rs index 5aa1f3f880c3..34aaeee44beb 100644 --- a/crates/stages/stages/src/stages/utils.rs +++ b/crates/stages/stages/src/stages/utils.rs @@ -258,7 +258,7 @@ pub(crate) fn missing_static_data_error( segment: StaticFileSegment, ) -> Result where - Provider: BlockReader + StaticFileProviderFactory, + Provider: BlockReader
+ StaticFileProviderFactory, { let mut last_block = static_file_provider.get_highest_static_file_block(segment).unwrap_or_default(); diff --git a/crates/static-file/static-file/src/segments/headers.rs b/crates/static-file/static-file/src/segments/headers.rs index e06e1f09a177..dff80a23f83b 100644 --- a/crates/static-file/static-file/src/segments/headers.rs +++ b/crates/static-file/static-file/src/segments/headers.rs @@ -1,7 +1,9 @@ use crate::segments::Segment; use alloy_primitives::BlockNumber; -use reth_db::tables; +use reth_codecs::Compact; +use reth_db::{table::Value, tables}; use reth_db_api::{cursor::DbCursorRO, transaction::DbTx}; +use reth_primitives_traits::NodePrimitives; use reth_provider::{providers::StaticFileWriter, DBProvider, StaticFileProviderFactory}; use reth_static_file_types::StaticFileSegment; use reth_storage_errors::provider::ProviderResult; @@ -11,7 +13,11 @@ use std::ops::RangeInclusive; #[derive(Debug, Default)] pub struct Headers; -impl Segment for Headers { +impl Segment for Headers +where + Provider: StaticFileProviderFactory> + + DBProvider, +{ fn segment(&self) -> StaticFileSegment { StaticFileSegment::Headers } @@ -25,7 +31,10 @@ impl Segment for Hea let mut static_file_writer = static_file_provider.get_writer(*block_range.start(), StaticFileSegment::Headers)?; - let mut headers_cursor = provider.tx_ref().cursor_read::()?; + let mut headers_cursor = provider + .tx_ref() + .cursor_read::::BlockHeader>>( + )?; let headers_walker = headers_cursor.walk_range(block_range.clone())?; let mut header_td_cursor = diff --git a/crates/static-file/static-file/src/static_file_producer.rs b/crates/static-file/static-file/src/static_file_producer.rs index 371a344d8727..30a72561b235 100644 --- a/crates/static-file/static-file/src/static_file_producer.rs +++ b/crates/static-file/static-file/src/static_file_producer.rs @@ -90,7 +90,7 @@ where Provider: StaticFileProviderFactory + DatabaseProviderFactory< Provider: StaticFileProviderFactory< - Primitives: NodePrimitives, + Primitives: NodePrimitives, > + StageCheckpointReader + BlockReader, >, diff --git a/crates/storage/db-common/Cargo.toml b/crates/storage/db-common/Cargo.toml index 9e4954357f84..28dbc33e90dc 100644 --- a/crates/storage/db-common/Cargo.toml +++ b/crates/storage/db-common/Cargo.toml @@ -24,6 +24,7 @@ reth-fs-util.workspace = true reth-node-types.workspace = true # eth +alloy-consensus.workspace = true alloy-genesis.workspace = true alloy-primitives.workspace = true diff --git a/crates/storage/db-common/src/init.rs b/crates/storage/db-common/src/init.rs index 9d4fb4ff02c5..d738aaec4399 100644 --- a/crates/storage/db-common/src/init.rs +++ b/crates/storage/db-common/src/init.rs @@ -1,5 +1,6 @@ //! Reth genesis initialization utility functions. +use alloy_consensus::BlockHeader; use alloy_genesis::GenesisAccount; use alloy_primitives::{Address, B256, U256}; use reth_chainspec::EthChainSpec; @@ -8,7 +9,9 @@ use reth_config::config::EtlConfig; use reth_db::tables; use reth_db_api::{transaction::DbTxMut, DatabaseError}; use reth_etl::Collector; -use reth_primitives::{Account, Bytecode, GotExpected, Receipts, StaticFileSegment, StorageEntry}; +use reth_primitives::{ + Account, Bytecode, GotExpected, NodePrimitives, Receipts, StaticFileSegment, StorageEntry, +}; use reth_provider::{ errors::provider::ProviderResult, providers::StaticFileWriter, writer::UnifiedStorageWriter, BlockHashReader, BlockNumReader, BundleStateInit, ChainSpecProvider, DBProvider, @@ -69,7 +72,10 @@ impl From for InitDatabaseError { /// Write the genesis block if it has not already been written pub fn init_genesis(factory: &PF) -> Result where - PF: DatabaseProviderFactory + StaticFileProviderFactory + ChainSpecProvider + BlockHashReader, + PF: DatabaseProviderFactory + + StaticFileProviderFactory> + + ChainSpecProvider + + BlockHashReader, PF::ProviderRW: StaticFileProviderFactory + StageCheckpointWriter + HistoryWriter @@ -78,7 +84,7 @@ where + StateWriter + StateWriter + AsRef, - PF::ChainSpec: EthChainSpec
, + PF::ChainSpec: EthChainSpec
::BlockHeader>, { let chain = factory.chain_spec(); @@ -307,15 +313,16 @@ pub fn insert_genesis_header( chain: &Spec, ) -> ProviderResult<()> where - Provider: StaticFileProviderFactory + DBProvider, - Spec: EthChainSpec
, + Provider: StaticFileProviderFactory> + + DBProvider, + Spec: EthChainSpec
::BlockHeader>, { let (header, block_hash) = (chain.genesis_header(), chain.genesis_hash()); let static_file_provider = provider.static_file_provider(); match static_file_provider.block_hash(0) { Ok(None) | Err(ProviderError::MissingStaticFileBlock(StaticFileSegment::Headers, 0)) => { - let (difficulty, hash) = (header.difficulty, block_hash); + let (difficulty, hash) = (header.difficulty(), block_hash); let mut writer = static_file_provider.latest_writer(StaticFileSegment::Headers)?; writer.append_header(header, difficulty, &hash)?; } @@ -359,7 +366,7 @@ where let expected_state_root = provider_rw .header_by_number(block)? .ok_or_else(|| ProviderError::HeaderNotFound(block.into()))? - .state_root; + .state_root(); // first line can be state root let dump_state_root = parse_state_root(&mut reader)?; diff --git a/crates/storage/provider/src/providers/blockchain_provider.rs b/crates/storage/provider/src/providers/blockchain_provider.rs index 08f5e4680a2b..1bb65a6e4fb4 100644 --- a/crates/storage/provider/src/providers/blockchain_provider.rs +++ b/crates/storage/provider/src/providers/blockchain_provider.rs @@ -25,7 +25,7 @@ use reth_db::{models::BlockNumberAddress, transaction::DbTx, Database}; use reth_db_api::models::{AccountBeforeTx, StoredBlockBodyIndices}; use reth_evm::ConfigureEvmEnv; use reth_execution_types::ExecutionOutcome; -use reth_node_types::{BlockTy, NodeTypesWithDB, ReceiptTy, TxTy}; +use reth_node_types::{BlockTy, HeaderTy, NodeTypesWithDB, ReceiptTy, TxTy}; use reth_primitives::{ Account, Block, BlockWithSenders, EthPrimitives, NodePrimitives, Receipt, SealedBlock, SealedBlockFor, SealedBlockWithSenders, SealedHeader, StorageEntry, TransactionMeta, @@ -89,7 +89,10 @@ impl BlockchainProvider2 { /// /// This returns a `ProviderResult` since it tries the retrieve the last finalized header from /// `database`. - pub fn with_latest(storage: ProviderFactory, latest: SealedHeader) -> ProviderResult { + pub fn with_latest( + storage: ProviderFactory, + latest: SealedHeader>, + ) -> ProviderResult { let provider = storage.provider()?; let finalized_header = provider .last_finalized_block_number()? @@ -175,11 +178,13 @@ impl StaticFileProviderFactory for BlockchainProvider2 } impl HeaderProvider for BlockchainProvider2 { - fn header(&self, block_hash: &BlockHash) -> ProviderResult> { + type Header = HeaderTy; + + fn header(&self, block_hash: &BlockHash) -> ProviderResult> { self.consistent_provider()?.header(block_hash) } - fn header_by_number(&self, num: BlockNumber) -> ProviderResult> { + fn header_by_number(&self, num: BlockNumber) -> ProviderResult> { self.consistent_provider()?.header_by_number(num) } @@ -191,26 +196,32 @@ impl HeaderProvider for BlockchainProvider2 { self.consistent_provider()?.header_td_by_number(number) } - fn headers_range(&self, range: impl RangeBounds) -> ProviderResult> { + fn headers_range( + &self, + range: impl RangeBounds, + ) -> ProviderResult> { self.consistent_provider()?.headers_range(range) } - fn sealed_header(&self, number: BlockNumber) -> ProviderResult> { + fn sealed_header( + &self, + number: BlockNumber, + ) -> ProviderResult>> { self.consistent_provider()?.sealed_header(number) } fn sealed_headers_range( &self, range: impl RangeBounds, - ) -> ProviderResult> { + ) -> ProviderResult>> { self.consistent_provider()?.sealed_headers_range(range) } fn sealed_headers_while( &self, range: impl RangeBounds, - predicate: impl FnMut(&SealedHeader) -> bool, - ) -> ProviderResult> { + predicate: impl FnMut(&SealedHeader) -> bool, + ) -> ProviderResult>> { self.consistent_provider()?.sealed_headers_while(range, predicate) } } @@ -292,7 +303,7 @@ impl BlockReader for BlockchainProvider2 { Ok(self.canonical_in_memory_state.pending_block_and_receipts()) } - fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult>> { + fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult>> { self.consistent_provider()?.ommers(id) } @@ -470,7 +481,7 @@ impl StageCheckpointReader for BlockchainProvider2 { } } -impl EvmEnvProvider for BlockchainProvider2 { +impl EvmEnvProvider> for BlockchainProvider2 { fn fill_env_at( &self, cfg: &mut CfgEnvWithHandlerCfg, @@ -479,7 +490,7 @@ impl EvmEnvProvider for BlockchainProvider2 { evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
, + EvmConfig: ConfigureEvmEnv
>, { self.consistent_provider()?.fill_env_at(cfg, block_env, at, evm_config) } @@ -488,11 +499,11 @@ impl EvmEnvProvider for BlockchainProvider2 { &self, cfg: &mut CfgEnvWithHandlerCfg, block_env: &mut BlockEnv, - header: &Header, + header: &HeaderTy, evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
, + EvmConfig: ConfigureEvmEnv
>, { self.consistent_provider()?.fill_env_with_header(cfg, block_env, header, evm_config) } @@ -504,7 +515,7 @@ impl EvmEnvProvider for BlockchainProvider2 { evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
, + EvmConfig: ConfigureEvmEnv
>, { self.consistent_provider()?.fill_cfg_env_at(cfg, at, evm_config) } @@ -512,11 +523,11 @@ impl EvmEnvProvider for BlockchainProvider2 { fn fill_cfg_env_with_header( &self, cfg: &mut CfgEnvWithHandlerCfg, - header: &Header, + header: &HeaderTy, evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
, + EvmConfig: ConfigureEvmEnv
>, { self.consistent_provider()?.fill_cfg_env_with_header(cfg, header, evm_config) } @@ -652,10 +663,9 @@ impl StateProviderFactory for BlockchainProvider2 { } } -impl CanonChainTracker for BlockchainProvider2 -where - Self: BlockReader, -{ +impl CanonChainTracker for BlockchainProvider2 { + type Header = HeaderTy; + fn on_forkchoice_update_received(&self, _update: &ForkchoiceState) { // update timestamp self.canonical_in_memory_state.on_forkchoice_update_received(); @@ -673,15 +683,15 @@ where self.canonical_in_memory_state.last_exchanged_transition_configuration_timestamp() } - fn set_canonical_head(&self, header: SealedHeader) { + fn set_canonical_head(&self, header: SealedHeader) { self.canonical_in_memory_state.set_canonical_head(header); } - fn set_safe(&self, header: SealedHeader) { + fn set_safe(&self, header: SealedHeader) { self.canonical_in_memory_state.set_safe(header); } - fn set_finalized(&self, header: SealedHeader) { + fn set_finalized(&self, header: SealedHeader) { self.canonical_in_memory_state.set_finalized(header); } } @@ -694,26 +704,32 @@ where self.consistent_provider()?.block_by_id(id) } - fn header_by_number_or_tag(&self, id: BlockNumberOrTag) -> ProviderResult> { + fn header_by_number_or_tag( + &self, + id: BlockNumberOrTag, + ) -> ProviderResult> { self.consistent_provider()?.header_by_number_or_tag(id) } fn sealed_header_by_number_or_tag( &self, id: BlockNumberOrTag, - ) -> ProviderResult> { + ) -> ProviderResult>> { self.consistent_provider()?.sealed_header_by_number_or_tag(id) } - fn sealed_header_by_id(&self, id: BlockId) -> ProviderResult> { + fn sealed_header_by_id( + &self, + id: BlockId, + ) -> ProviderResult>> { self.consistent_provider()?.sealed_header_by_id(id) } - fn header_by_id(&self, id: BlockId) -> ProviderResult> { + fn header_by_id(&self, id: BlockId) -> ProviderResult> { self.consistent_provider()?.header_by_id(id) } - fn ommers_by_id(&self, id: BlockId) -> ProviderResult>> { + fn ommers_by_id(&self, id: BlockId) -> ProviderResult>> { self.consistent_provider()?.ommers_by_id(id) } } @@ -727,12 +743,14 @@ impl> CanonStateSubscriptions } impl ForkChoiceSubscriptions for BlockchainProvider2 { - fn subscribe_safe_block(&self) -> ForkChoiceNotifications { + type Header = HeaderTy; + + fn subscribe_safe_block(&self) -> ForkChoiceNotifications { let receiver = self.canonical_in_memory_state.subscribe_safe_block(); ForkChoiceNotifications(receiver) } - fn subscribe_finalized_block(&self) -> ForkChoiceNotifications { + fn subscribe_finalized_block(&self) -> ForkChoiceNotifications { let receiver = self.canonical_in_memory_state.subscribe_finalized_block(); ForkChoiceNotifications(receiver) } diff --git a/crates/storage/provider/src/providers/consistent.rs b/crates/storage/provider/src/providers/consistent.rs index e70f4b4e5e1d..5aea5be27d45 100644 --- a/crates/storage/provider/src/providers/consistent.rs +++ b/crates/storage/provider/src/providers/consistent.rs @@ -6,7 +6,7 @@ use crate::{ StageCheckpointReader, StateReader, StaticFileProviderFactory, TransactionVariant, TransactionsProvider, WithdrawalsProvider, }; -use alloy_consensus::Header; +use alloy_consensus::BlockHeader; use alloy_eips::{ eip2718::Encodable2718, eip4895::{Withdrawal, Withdrawals}, @@ -19,7 +19,7 @@ use reth_db::models::BlockNumberAddress; use reth_db_api::models::{AccountBeforeTx, StoredBlockBodyIndices}; use reth_evm::ConfigureEvmEnv; use reth_execution_types::{BundleStateInit, ExecutionOutcome, RevertsInit}; -use reth_node_types::{BlockTy, ReceiptTy, TxTy}; +use reth_node_types::{BlockTy, HeaderTy, ReceiptTy, TxTy}; use reth_primitives::{ Account, BlockWithSenders, SealedBlockFor, SealedBlockWithSenders, SealedHeader, StorageEntry, TransactionMeta, @@ -628,7 +628,9 @@ impl StaticFileProviderFactory for ConsistentProvider { } impl HeaderProvider for ConsistentProvider { - fn header(&self, block_hash: &BlockHash) -> ProviderResult> { + type Header = HeaderTy; + + fn header(&self, block_hash: &BlockHash) -> ProviderResult> { self.get_in_memory_or_storage_by_block( (*block_hash).into(), |db_provider| db_provider.header(block_hash), @@ -636,7 +638,7 @@ impl HeaderProvider for ConsistentProvider { ) } - fn header_by_number(&self, num: BlockNumber) -> ProviderResult> { + fn header_by_number(&self, num: BlockNumber) -> ProviderResult> { self.get_in_memory_or_storage_by_block( num.into(), |db_provider| db_provider.header_by_number(num), @@ -675,7 +677,10 @@ impl HeaderProvider for ConsistentProvider { self.storage_provider.header_td_by_number(number) } - fn headers_range(&self, range: impl RangeBounds) -> ProviderResult> { + fn headers_range( + &self, + range: impl RangeBounds, + ) -> ProviderResult> { self.get_in_memory_or_storage_by_block_range_while( range, |db_provider, range, _| db_provider.headers_range(range), @@ -684,7 +689,10 @@ impl HeaderProvider for ConsistentProvider { ) } - fn sealed_header(&self, number: BlockNumber) -> ProviderResult> { + fn sealed_header( + &self, + number: BlockNumber, + ) -> ProviderResult>> { self.get_in_memory_or_storage_by_block( number.into(), |db_provider| db_provider.sealed_header(number), @@ -695,7 +703,7 @@ impl HeaderProvider for ConsistentProvider { fn sealed_headers_range( &self, range: impl RangeBounds, - ) -> ProviderResult> { + ) -> ProviderResult>> { self.get_in_memory_or_storage_by_block_range_while( range, |db_provider, range, _| db_provider.sealed_headers_range(range), @@ -707,8 +715,8 @@ impl HeaderProvider for ConsistentProvider { fn sealed_headers_while( &self, range: impl RangeBounds, - predicate: impl FnMut(&SealedHeader) -> bool, - ) -> ProviderResult> { + predicate: impl FnMut(&SealedHeader) -> bool, + ) -> ProviderResult>> { self.get_in_memory_or_storage_by_block_range_while( range, |db_provider, range, predicate| db_provider.sealed_headers_while(range, predicate), @@ -832,7 +840,7 @@ impl BlockReader for ConsistentProvider { Ok(self.canonical_in_memory_state.pending_block_and_receipts()) } - fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult>> { + fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult>>> { self.get_in_memory_or_storage_by_block( id, |db_provider| db_provider.ommers(id), @@ -868,7 +876,7 @@ impl BlockReader for ConsistentProvider { // Iterate from the lowest block in memory until our target block for state in block_state.chain().collect::>().into_iter().rev() { let block_tx_count = state.block_ref().block.body.transactions().len() as u64; - if state.block_ref().block().number == number { + if state.block_ref().block().number() == number { stored_indices.tx_count = block_tx_count; } else { stored_indices.first_tx_num += block_tx_count; @@ -1017,7 +1025,7 @@ impl TransactionsProvider for ConsistentProvider { self.get_in_memory_or_storage_by_tx( id.into(), |provider| provider.transaction_block(id), - |_, _, block_state| Ok(Some(block_state.block_ref().block().number)), + |_, _, block_state| Ok(Some(block_state.block_ref().block().number())), ) } @@ -1222,7 +1230,7 @@ impl StageCheckpointReader for ConsistentProvider { } } -impl EvmEnvProvider for ConsistentProvider { +impl EvmEnvProvider> for ConsistentProvider { fn fill_env_at( &self, cfg: &mut CfgEnvWithHandlerCfg, @@ -1231,7 +1239,7 @@ impl EvmEnvProvider for ConsistentProvider { evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
, + EvmConfig: ConfigureEvmEnv
>, { let hash = self.convert_number(at)?.ok_or(ProviderError::HeaderNotFound(at))?; let header = self.header(&hash)?.ok_or(ProviderError::HeaderNotFound(at))?; @@ -1242,15 +1250,15 @@ impl EvmEnvProvider for ConsistentProvider { &self, cfg: &mut CfgEnvWithHandlerCfg, block_env: &mut BlockEnv, - header: &Header, + header: &HeaderTy, evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
, + EvmConfig: ConfigureEvmEnv
>, { let total_difficulty = self - .header_td_by_number(header.number)? - .ok_or_else(|| ProviderError::HeaderNotFound(header.number.into()))?; + .header_td_by_number(header.number())? + .ok_or_else(|| ProviderError::HeaderNotFound(header.number().into()))?; evm_config.fill_cfg_and_block_env(cfg, block_env, header, total_difficulty); Ok(()) } @@ -1262,7 +1270,7 @@ impl EvmEnvProvider for ConsistentProvider { evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
, + EvmConfig: ConfigureEvmEnv
>, { let hash = self.convert_number(at)?.ok_or(ProviderError::HeaderNotFound(at))?; let header = self.header(&hash)?.ok_or(ProviderError::HeaderNotFound(at))?; @@ -1272,15 +1280,15 @@ impl EvmEnvProvider for ConsistentProvider { fn fill_cfg_env_with_header( &self, cfg: &mut CfgEnvWithHandlerCfg, - header: &Header, + header: &HeaderTy, evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
, + EvmConfig: ConfigureEvmEnv
>, { let total_difficulty = self - .header_td_by_number(header.number)? - .ok_or_else(|| ProviderError::HeaderNotFound(header.number.into()))?; + .header_td_by_number(header.number())? + .ok_or_else(|| ProviderError::HeaderNotFound(header.number().into()))?; evm_config.fill_cfg_env(cfg, header, total_difficulty); Ok(()) } @@ -1326,7 +1334,7 @@ impl BlockReaderIdExt for ConsistentProvider { } } - fn header_by_number_or_tag(&self, id: BlockNumberOrTag) -> ProviderResult> { + fn header_by_number_or_tag(&self, id: BlockNumberOrTag) -> ProviderResult>> { Ok(match id { BlockNumberOrTag::Latest => { Some(self.canonical_in_memory_state.get_canonical_head().unseal()) @@ -1347,7 +1355,7 @@ impl BlockReaderIdExt for ConsistentProvider { fn sealed_header_by_number_or_tag( &self, id: BlockNumberOrTag, - ) -> ProviderResult> { + ) -> ProviderResult>>> { match id { BlockNumberOrTag::Latest => { Ok(Some(self.canonical_in_memory_state.get_canonical_head())) @@ -1366,21 +1374,24 @@ impl BlockReaderIdExt for ConsistentProvider { } } - fn sealed_header_by_id(&self, id: BlockId) -> ProviderResult> { + fn sealed_header_by_id( + &self, + id: BlockId, + ) -> ProviderResult>>> { Ok(match id { BlockId::Number(num) => self.sealed_header_by_number_or_tag(num)?, BlockId::Hash(hash) => self.header(&hash.block_hash)?.map(SealedHeader::seal), }) } - fn header_by_id(&self, id: BlockId) -> ProviderResult> { + fn header_by_id(&self, id: BlockId) -> ProviderResult>> { Ok(match id { BlockId::Number(num) => self.header_by_number_or_tag(num)?, BlockId::Hash(hash) => self.header(&hash.block_hash)?, }) } - fn ommers_by_id(&self, id: BlockId) -> ProviderResult>> { + fn ommers_by_id(&self, id: BlockId) -> ProviderResult>>> { match id { BlockId::Number(num) => self.ommers_by_number_or_tag(num), BlockId::Hash(hash) => { diff --git a/crates/storage/provider/src/providers/database/mod.rs b/crates/storage/provider/src/providers/database/mod.rs index 3c22a1a73a23..d34d67d9dc86 100644 --- a/crates/storage/provider/src/providers/database/mod.rs +++ b/crates/storage/provider/src/providers/database/mod.rs @@ -7,7 +7,6 @@ use crate::{ PruneCheckpointReader, StageCheckpointReader, StateProviderBox, StaticFileProviderFactory, TransactionVariant, TransactionsProvider, WithdrawalsProvider, }; -use alloy_consensus::Header; use alloy_eips::{ eip4895::{Withdrawal, Withdrawals}, BlockHashOrNumber, @@ -19,7 +18,7 @@ use reth_db::{init_db, mdbx::DatabaseArguments, DatabaseEnv}; use reth_db_api::{database::Database, models::StoredBlockBodyIndices}; use reth_errors::{RethError, RethResult}; use reth_evm::ConfigureEvmEnv; -use reth_node_types::{BlockTy, NodeTypesWithDB, ReceiptTy, TxTy}; +use reth_node_types::{BlockTy, HeaderTy, NodeTypesWithDB, ReceiptTy, TxTy}; use reth_primitives::{ BlockWithSenders, SealedBlockFor, SealedBlockWithSenders, SealedHeader, StaticFileSegment, TransactionMeta, @@ -228,21 +227,24 @@ impl StaticFileProviderFactory for ProviderFactory { } impl HeaderSyncGapProvider for ProviderFactory { + type Header = HeaderTy; fn sync_gap( &self, tip: watch::Receiver, highest_uninterrupted_block: BlockNumber, - ) -> ProviderResult { + ) -> ProviderResult> { self.provider()?.sync_gap(tip, highest_uninterrupted_block) } } impl HeaderProvider for ProviderFactory { - fn header(&self, block_hash: &BlockHash) -> ProviderResult> { + type Header = HeaderTy; + + fn header(&self, block_hash: &BlockHash) -> ProviderResult> { self.provider()?.header(block_hash) } - fn header_by_number(&self, num: BlockNumber) -> ProviderResult> { + fn header_by_number(&self, num: BlockNumber) -> ProviderResult> { self.static_file_provider.get_with_static_file_or_database( StaticFileSegment::Headers, num, @@ -270,7 +272,10 @@ impl HeaderProvider for ProviderFactory { ) } - fn headers_range(&self, range: impl RangeBounds) -> ProviderResult> { + fn headers_range( + &self, + range: impl RangeBounds, + ) -> ProviderResult> { self.static_file_provider.get_range_with_static_file_or_database( StaticFileSegment::Headers, to_range(range), @@ -280,7 +285,10 @@ impl HeaderProvider for ProviderFactory { ) } - fn sealed_header(&self, number: BlockNumber) -> ProviderResult> { + fn sealed_header( + &self, + number: BlockNumber, + ) -> ProviderResult>> { self.static_file_provider.get_with_static_file_or_database( StaticFileSegment::Headers, number, @@ -292,15 +300,15 @@ impl HeaderProvider for ProviderFactory { fn sealed_headers_range( &self, range: impl RangeBounds, - ) -> ProviderResult> { + ) -> ProviderResult>> { self.sealed_headers_while(range, |_| true) } fn sealed_headers_while( &self, range: impl RangeBounds, - predicate: impl FnMut(&SealedHeader) -> bool, - ) -> ProviderResult> { + predicate: impl FnMut(&SealedHeader) -> bool, + ) -> ProviderResult>> { self.static_file_provider.get_range_with_static_file_or_database( StaticFileSegment::Headers, to_range(range), @@ -385,7 +393,7 @@ impl BlockReader for ProviderFactory { self.provider()?.pending_block_and_receipts() } - fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult>> { + fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult>> { self.provider()?.ommers(id) } @@ -570,7 +578,7 @@ impl StageCheckpointReader for ProviderFactory { } } -impl EvmEnvProvider for ProviderFactory { +impl EvmEnvProvider> for ProviderFactory { fn fill_env_at( &self, cfg: &mut CfgEnvWithHandlerCfg, @@ -579,7 +587,7 @@ impl EvmEnvProvider for ProviderFactory { evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
, + EvmConfig: ConfigureEvmEnv
>, { self.provider()?.fill_env_at(cfg, block_env, at, evm_config) } @@ -588,11 +596,11 @@ impl EvmEnvProvider for ProviderFactory { &self, cfg: &mut CfgEnvWithHandlerCfg, block_env: &mut BlockEnv, - header: &Header, + header: &HeaderTy, evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
, + EvmConfig: ConfigureEvmEnv
>, { self.provider()?.fill_env_with_header(cfg, block_env, header, evm_config) } @@ -604,7 +612,7 @@ impl EvmEnvProvider for ProviderFactory { evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
, + EvmConfig: ConfigureEvmEnv
>, { self.provider()?.fill_cfg_env_at(cfg, at, evm_config) } @@ -612,11 +620,11 @@ impl EvmEnvProvider for ProviderFactory { fn fill_cfg_env_with_header( &self, cfg: &mut CfgEnvWithHandlerCfg, - header: &Header, + header: &HeaderTy, evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
, + EvmConfig: ConfigureEvmEnv
>, { self.provider()?.fill_cfg_env_with_header(cfg, header, evm_config) } diff --git a/crates/storage/provider/src/providers/database/provider.rs b/crates/storage/provider/src/providers/database/provider.rs index cfbe20cf4b44..9dddbb9c0a7c 100644 --- a/crates/storage/provider/src/providers/database/provider.rs +++ b/crates/storage/provider/src/providers/database/provider.rs @@ -19,7 +19,7 @@ use crate::{ StorageLocation, StorageReader, StorageTrieWriter, TransactionVariant, TransactionsProvider, TransactionsProviderExt, TrieWriter, WithdrawalsProvider, }; -use alloy_consensus::Header; +use alloy_consensus::{BlockHeader, Header}; use alloy_eips::{ eip2718::Encodable2718, eip4895::{Withdrawal, Withdrawals}, @@ -50,10 +50,11 @@ use reth_db_api::{ use reth_evm::ConfigureEvmEnv; use reth_execution_types::{Chain, ExecutionOutcome}; use reth_network_p2p::headers::downloader::SyncTarget; -use reth_node_types::{BlockTy, BodyTy, NodeTypes, ReceiptTy, TxTy}; +use reth_node_types::{BlockTy, BodyTy, HeaderTy, NodeTypes, ReceiptTy, TxTy}; use reth_primitives::{ - Account, BlockExt, BlockWithSenders, Bytecode, GotExpected, SealedBlock, SealedBlockFor, - SealedBlockWithSenders, SealedHeader, StaticFileSegment, StorageEntry, TransactionMeta, + Account, BlockExt, BlockWithSenders, Bytecode, GotExpected, NodePrimitives, SealedBlock, + SealedBlockFor, SealedBlockWithSenders, SealedHeader, StaticFileSegment, StorageEntry, + TransactionMeta, }; use reth_primitives_traits::{Block as _, BlockBody as _, SignedTransaction}; use reth_prune_types::{PruneCheckpoint, PruneModes, PruneSegment}; @@ -326,7 +327,7 @@ impl DatabaseProvider StateCommitmentProvider for DatabaseProvi type StateCommitment = N::StateCommitment; } -impl DatabaseProvider { +impl< + Tx: DbTx + DbTxMut + 'static, + N: NodeTypesForProvider>, + > DatabaseProvider +{ // TODO: uncomment below, once `reth debug_cmd` has been feature gated with dev. // #[cfg(any(test, feature = "test-utils"))] /// Inserts an historical block. **Used for setting up test environments** @@ -560,8 +565,7 @@ impl DatabaseProvider { construct_block: BF, ) -> ProviderResult> where - N::ChainSpec: EthereumHardforks, - H: AsRef
, + H: AsRef>, HF: FnOnce(BlockNumber) -> ProviderResult>, BF: FnOnce(H, BodyTy, Vec
) -> ProviderResult>, { @@ -610,8 +614,7 @@ impl DatabaseProvider { mut assemble_block: F, ) -> ProviderResult> where - N::ChainSpec: EthereumHardforks, - H: AsRef
, + H: AsRef>, HF: FnOnce(RangeInclusive) -> ProviderResult>, F: FnMut(H, BodyTy, Range) -> ProviderResult, { @@ -634,7 +637,7 @@ impl DatabaseProvider { // have enough information to return the block anyways, so // we skip the block. if let Some((_, block_body_indices)) = - block_body_cursor.seek_exact(header.as_ref().number)? + block_body_cursor.seek_exact(header.as_ref().number())? { let tx_range = block_body_indices.tx_num_range(); present_headers.push((header, tx_range)); @@ -678,8 +681,7 @@ impl DatabaseProvider { assemble_block: BF, ) -> ProviderResult> where - N::ChainSpec: EthereumHardforks, - H: AsRef
, + H: AsRef>, HF: Fn(RangeInclusive) -> ProviderResult>, BF: Fn(H, BodyTy, Vec
) -> ProviderResult, { @@ -943,12 +945,16 @@ impl ChangeSetReader for DatabaseProvider { } } -impl HeaderSyncGapProvider for DatabaseProvider { +impl HeaderSyncGapProvider + for DatabaseProvider +{ + type Header = HeaderTy; + fn sync_gap( &self, tip: watch::Receiver, highest_uninterrupted_block: BlockNumber, - ) -> ProviderResult { + ) -> ProviderResult> { let static_file_provider = self.static_file_provider(); // Make sure Headers static file is at the same height. If it's further, this @@ -987,10 +993,10 @@ impl HeaderSyncGapProvider for DatabaseProvide } } -impl> HeaderProvider - for DatabaseProvider -{ - fn header(&self, block_hash: &BlockHash) -> ProviderResult> { +impl HeaderProvider for DatabaseProvider { + type Header = HeaderTy; + + fn header(&self, block_hash: &BlockHash) -> ProviderResult> { if let Some(num) = self.block_number(*block_hash)? { Ok(self.header_by_number(num)?) } else { @@ -998,12 +1004,12 @@ impl> HeaderProvi } } - fn header_by_number(&self, num: BlockNumber) -> ProviderResult> { + fn header_by_number(&self, num: BlockNumber) -> ProviderResult> { self.static_file_provider.get_with_static_file_or_database( StaticFileSegment::Headers, num, |static_file| static_file.header_by_number(num), - || Ok(self.tx.get::(num)?), + || Ok(self.tx.get::>(num)?), ) } @@ -1030,17 +1036,25 @@ impl> HeaderProvi ) } - fn headers_range(&self, range: impl RangeBounds) -> ProviderResult> { + fn headers_range( + &self, + range: impl RangeBounds, + ) -> ProviderResult> { self.static_file_provider.get_range_with_static_file_or_database( StaticFileSegment::Headers, to_range(range), |static_file, range, _| static_file.headers_range(range), - |range, _| self.cursor_read_collect::(range).map_err(Into::into), + |range, _| { + self.cursor_read_collect::>(range).map_err(Into::into) + }, |_| true, ) } - fn sealed_header(&self, number: BlockNumber) -> ProviderResult> { + fn sealed_header( + &self, + number: BlockNumber, + ) -> ProviderResult>> { self.static_file_provider.get_with_static_file_or_database( StaticFileSegment::Headers, number, @@ -1061,15 +1075,17 @@ impl> HeaderProvi fn sealed_headers_while( &self, range: impl RangeBounds, - predicate: impl FnMut(&SealedHeader) -> bool, - ) -> ProviderResult> { + predicate: impl FnMut(&SealedHeader) -> bool, + ) -> ProviderResult>> { self.static_file_provider.get_range_with_static_file_or_database( StaticFileSegment::Headers, to_range(range), |static_file, range, predicate| static_file.sealed_headers_while(range, predicate), |range, mut predicate| { let mut headers = vec![]; - for entry in self.tx.cursor_read::()?.walk_range(range)? { + for entry in + self.tx.cursor_read::>()?.walk_range(range)? + { let (number, header) = entry?; let hash = self .block_hash(number)? @@ -1210,7 +1226,7 @@ impl BlockReader for DatabaseProvid /// /// If the block is not found, this returns `None`. /// If the block exists, but doesn't contain ommers, this returns `None`. - fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult>> { + fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult>> { if let Some(number) = self.convert_hash_or_number(id)? { // If the Paris (Merge) hardfork block is known and block is after it, return empty // ommers. @@ -1218,7 +1234,8 @@ impl BlockReader for DatabaseProvid return Ok(Some(Vec::new())) } - let ommers = self.tx.get::(number)?.map(|o| o.ommers); + let ommers = + self.tx.get::>(number)?.map(|o| o.ommers); return Ok(ommers) } @@ -1450,9 +1467,9 @@ impl TransactionsProvider for Datab index, block_hash, block_number, - base_fee: header.base_fee_per_gas, - excess_blob_gas: header.excess_blob_gas, - timestamp: header.timestamp, + base_fee: header.base_fee_per_gas(), + excess_blob_gas: header.excess_blob_gas(), + timestamp: header.timestamp(), }; return Ok(Some((transaction, meta))) @@ -1618,7 +1635,7 @@ impl> Withdrawals } } -impl> EvmEnvProvider +impl EvmEnvProvider> for DatabaseProvider { fn fill_env_at( @@ -1629,7 +1646,7 @@ impl> EvmEnvProvi evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
, + EvmConfig: ConfigureEvmEnv
>, { let hash = self.convert_number(at)?.ok_or(ProviderError::HeaderNotFound(at))?; let header = self.header(&hash)?.ok_or(ProviderError::HeaderNotFound(at))?; @@ -1640,15 +1657,15 @@ impl> EvmEnvProvi &self, cfg: &mut CfgEnvWithHandlerCfg, block_env: &mut BlockEnv, - header: &Header, + header: &HeaderTy, evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
, + EvmConfig: ConfigureEvmEnv
>, { let total_difficulty = self - .header_td_by_number(header.number)? - .ok_or_else(|| ProviderError::HeaderNotFound(header.number.into()))?; + .header_td_by_number(header.number())? + .ok_or_else(|| ProviderError::HeaderNotFound(header.number().into()))?; evm_config.fill_cfg_and_block_env(cfg, block_env, header, total_difficulty); Ok(()) } @@ -1660,7 +1677,7 @@ impl> EvmEnvProvi evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
, + EvmConfig: ConfigureEvmEnv
>, { let hash = self.convert_number(at)?.ok_or(ProviderError::HeaderNotFound(at))?; let header = self.header(&hash)?.ok_or(ProviderError::HeaderNotFound(at))?; @@ -1670,15 +1687,15 @@ impl> EvmEnvProvi fn fill_cfg_env_with_header( &self, cfg: &mut CfgEnvWithHandlerCfg, - header: &Header, + header: &HeaderTy, evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
, + EvmConfig: ConfigureEvmEnv
>, { let total_difficulty = self - .header_td_by_number(header.number)? - .ok_or_else(|| ProviderError::HeaderNotFound(header.number.into()))?; + .header_td_by_number(header.number())? + .ok_or_else(|| ProviderError::HeaderNotFound(header.number().into()))?; evm_config.fill_cfg_env(cfg, header, total_difficulty); Ok(()) } @@ -2813,18 +2830,18 @@ impl BlockWrite block: SealedBlockWithSenders, write_to: StorageLocation, ) -> ProviderResult { - let block_number = block.number; + let block_number = block.number(); let mut durations_recorder = metrics::DurationsRecorder::default(); // total difficulty let ttd = if block_number == 0 { - block.difficulty + block.difficulty() } else { let parent_block_number = block_number - 1; let parent_ttd = self.header_td_by_number(parent_block_number)?.unwrap_or_default(); durations_recorder.record_relative(metrics::Action::GetParentTD); - parent_ttd + block.difficulty + parent_ttd + block.difficulty() }; if write_to.database() { @@ -2832,7 +2849,8 @@ impl BlockWrite durations_recorder.record_relative(metrics::Action::InsertCanonicalHeaders); // Put header with canonical hashes. - self.tx.put::(block_number, block.header.as_ref().clone())?; + self.tx + .put::>>(block_number, block.header.as_ref().clone())?; durations_recorder.record_relative(metrics::Action::InsertHeaders); self.tx.put::(block_number, ttd.into())?; @@ -2979,7 +2997,7 @@ impl BlockWrite self.tx.delete::(hash, None)?; rev_headers.delete_current()?; } - self.remove::(block + 1..)?; + self.remove::>>(block + 1..)?; self.remove::(block + 1..)?; // First transaction to be removed @@ -3063,10 +3081,10 @@ impl BlockWrite return Ok(()) } - let first_number = blocks.first().unwrap().number; + let first_number = blocks.first().unwrap().number(); let last = blocks.last().unwrap(); - let last_block_number = last.number; + let last_block_number = last.number(); let mut durations_recorder = metrics::DurationsRecorder::default(); diff --git a/crates/storage/provider/src/providers/mod.rs b/crates/storage/provider/src/providers/mod.rs index 6631b5b1b31a..44cd5554bee6 100644 --- a/crates/storage/provider/src/providers/mod.rs +++ b/crates/storage/provider/src/providers/mod.rs @@ -1,6 +1,6 @@ use crate::{ AccountReader, BlockHashReader, BlockIdReader, BlockNumReader, BlockReader, BlockReaderIdExt, - BlockSource, BlockchainTreePendingStateProvider, CanonChainTracker, CanonStateNotifications, + BlockSource, BlockchainTreePendingStateProvider, CanonStateNotifications, CanonStateSubscriptions, ChainSpecProvider, ChainStateBlockReader, ChangeSetReader, DatabaseProviderFactory, EvmEnvProvider, FullExecutionDataProvider, HeaderProvider, NodePrimitivesProvider, ProviderError, PruneCheckpointReader, ReceiptProvider, @@ -14,6 +14,7 @@ use alloy_eips::{ BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag, }; use alloy_primitives::{Address, BlockHash, BlockNumber, TxHash, TxNumber, B256, U256}; +use alloy_rpc_types_engine::ForkchoiceState; use reth_blockchain_tree_api::{ error::{CanonicalError, InsertBlockError}, BlockValidationKind, BlockchainTreeEngine, BlockchainTreeViewer, CanonicalOutcome, @@ -24,13 +25,16 @@ use reth_chainspec::{ChainInfo, EthereumHardforks}; use reth_db::table::Value; use reth_db_api::models::{AccountBeforeTx, StoredBlockBodyIndices}; use reth_evm::ConfigureEvmEnv; -use reth_node_types::{BlockTy, FullNodePrimitives, NodeTypes, NodeTypesWithDB, ReceiptTy, TxTy}; +use reth_node_types::{ + BlockTy, FullNodePrimitives, HeaderTy, NodeTypes, NodeTypesWithDB, ReceiptTy, TxTy, +}; use reth_primitives::{ Account, BlockWithSenders, EthPrimitives, Receipt, SealedBlock, SealedBlockFor, SealedBlockWithSenders, SealedHeader, TransactionMeta, }; use reth_prune_types::{PruneCheckpoint, PruneSegment}; use reth_stages_types::{StageCheckpoint, StageId}; +use reth_storage_api::CanonChainTracker; use reth_storage_errors::provider::ProviderResult; use revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg}; use std::{ @@ -61,7 +65,6 @@ mod bundle_state_provider; pub use bundle_state_provider::BundleStateProvider; mod consistent_view; -use alloy_rpc_types_engine::ForkchoiceState; pub use consistent_view::{ConsistentDbView, ConsistentViewError}; mod blockchain_provider; @@ -77,11 +80,7 @@ where Self: NodeTypes< ChainSpec: EthereumHardforks, Storage: ChainStorage, - Primitives: FullNodePrimitives< - SignedTx: Value, - Receipt: Value, - BlockHeader = alloy_consensus::Header, - >, + Primitives: FullNodePrimitives, >, { } @@ -90,11 +89,7 @@ impl NodeTypesForProvider for T where T: NodeTypes< ChainSpec: EthereumHardforks, Storage: ChainStorage, - Primitives: FullNodePrimitives< - SignedTx: Value, - Receipt: Value, - BlockHeader = alloy_consensus::Header, - >, + Primitives: FullNodePrimitives, > { } @@ -151,7 +146,7 @@ impl BlockchainProvider { } } -impl BlockchainProvider { +impl BlockchainProvider { /// Create new provider instance that wraps the database and the blockchain tree, using the /// provided latest header to initialize the chain info tracker, alongside the finalized header /// if it exists. @@ -261,7 +256,9 @@ impl StaticFileProviderFactory for BlockchainProvider { } } -impl HeaderProvider for BlockchainProvider { +impl HeaderProvider for BlockchainProvider { + type Header = Header; + fn header(&self, block_hash: &BlockHash) -> ProviderResult> { self.database.header(block_hash) } @@ -593,7 +590,7 @@ impl StageCheckpointReader for BlockchainProvider { } } -impl EvmEnvProvider for BlockchainProvider { +impl EvmEnvProvider for BlockchainProvider { fn fill_env_at( &self, cfg: &mut CfgEnvWithHandlerCfg, @@ -666,7 +663,7 @@ impl ChainSpecProvider for BlockchainProvider { } } -impl StateProviderFactory for BlockchainProvider { +impl StateProviderFactory for BlockchainProvider { /// Storage provider for latest block fn latest(&self) -> ProviderResult { trace!(target: "providers::blockchain", "Getting latest block state provider"); @@ -840,10 +837,9 @@ impl BlockchainTreeViewer for BlockchainProvider { } } -impl CanonChainTracker for BlockchainProvider -where - Self: BlockReader, -{ +impl CanonChainTracker for BlockchainProvider { + type Header = HeaderTy; + fn on_forkchoice_update_received(&self, _update: &ForkchoiceState) { // update timestamp self.chain_info.on_forkchoice_update_received(); @@ -874,10 +870,7 @@ where } } -impl BlockReaderIdExt for BlockchainProvider -where - Self: BlockReader + ReceiptProviderIdExt, -{ +impl BlockReaderIdExt for BlockchainProvider { fn block_by_id(&self, id: BlockId) -> ProviderResult> { match id { BlockId::Number(num) => self.block_by_number_or_tag(num), @@ -896,7 +889,10 @@ where } } - fn header_by_number_or_tag(&self, id: BlockNumberOrTag) -> ProviderResult> { + fn header_by_number_or_tag( + &self, + id: BlockNumberOrTag, + ) -> ProviderResult> { Ok(match id { BlockNumberOrTag::Latest => Some(self.chain_info.get_canonical_head().unseal()), BlockNumberOrTag::Finalized => { @@ -912,7 +908,7 @@ where fn sealed_header_by_number_or_tag( &self, id: BlockNumberOrTag, - ) -> ProviderResult> { + ) -> ProviderResult>> { match id { BlockNumberOrTag::Latest => Ok(Some(self.chain_info.get_canonical_head())), BlockNumberOrTag::Finalized => Ok(self.chain_info.get_finalized_header()), @@ -927,21 +923,24 @@ where } } - fn sealed_header_by_id(&self, id: BlockId) -> ProviderResult> { + fn sealed_header_by_id( + &self, + id: BlockId, + ) -> ProviderResult>> { Ok(match id { BlockId::Number(num) => self.sealed_header_by_number_or_tag(num)?, BlockId::Hash(hash) => self.header(&hash.block_hash)?.map(SealedHeader::seal), }) } - fn header_by_id(&self, id: BlockId) -> ProviderResult> { + fn header_by_id(&self, id: BlockId) -> ProviderResult> { Ok(match id { BlockId::Number(num) => self.header_by_number_or_tag(num)?, BlockId::Hash(hash) => self.header(&hash.block_hash)?, }) } - fn ommers_by_id(&self, id: BlockId) -> ProviderResult>> { + fn ommers_by_id(&self, id: BlockId) -> ProviderResult>> { match id { BlockId::Number(num) => self.ommers_by_number_or_tag(num), BlockId::Hash(hash) => { @@ -968,7 +967,9 @@ impl CanonStateSubscriptions for BlockchainProvider { } } -impl ForkChoiceSubscriptions for BlockchainProvider { +impl ForkChoiceSubscriptions for BlockchainProvider { + type Header = HeaderTy; + fn subscribe_safe_block(&self) -> ForkChoiceNotifications { let receiver = self.chain_info.subscribe_safe_block(); ForkChoiceNotifications(receiver) diff --git a/crates/storage/provider/src/providers/static_file/jar.rs b/crates/storage/provider/src/providers/static_file/jar.rs index 659b093d9d6a..8f2d002ab898 100644 --- a/crates/storage/provider/src/providers/static_file/jar.rs +++ b/crates/storage/provider/src/providers/static_file/jar.rs @@ -6,7 +6,6 @@ use crate::{ to_range, BlockHashReader, BlockNumReader, HeaderProvider, ReceiptProvider, TransactionsProvider, }; -use alloy_consensus::Header; use alloy_eips::{eip2718::Encodable2718, BlockHashOrNumber}; use alloy_primitives::{Address, BlockHash, BlockNumber, TxHash, TxNumber, B256, U256}; use reth_chainspec::ChainInfo; @@ -15,7 +14,7 @@ use reth_db::{ BlockHashMask, HeaderMask, HeaderWithHashMask, ReceiptMask, StaticFileCursor, TDWithHashMask, TotalDifficultyMask, TransactionMask, }, - table::Decompress, + table::{Decompress, Value}, }; use reth_node_types::NodePrimitives; use reth_primitives::{transaction::recover_signers, SealedHeader, TransactionMeta}; @@ -90,17 +89,19 @@ impl<'a, N: NodePrimitives> StaticFileJarProvider<'a, N> { } } -impl HeaderProvider for StaticFileJarProvider<'_, N> { - fn header(&self, block_hash: &BlockHash) -> ProviderResult> { +impl> HeaderProvider for StaticFileJarProvider<'_, N> { + type Header = N::BlockHeader; + + fn header(&self, block_hash: &BlockHash) -> ProviderResult> { Ok(self .cursor()? - .get_two::>(block_hash.into())? + .get_two::>(block_hash.into())? .filter(|(_, hash)| hash == block_hash) .map(|(header, _)| header)) } - fn header_by_number(&self, num: BlockNumber) -> ProviderResult> { - self.cursor()?.get_one::>(num.into()) + fn header_by_number(&self, num: BlockNumber) -> ProviderResult> { + self.cursor()?.get_one::>(num.into()) } fn header_td(&self, block_hash: &BlockHash) -> ProviderResult> { @@ -115,14 +116,17 @@ impl HeaderProvider for StaticFileJarProvider<'_, N> { Ok(self.cursor()?.get_one::(num.into())?.map(Into::into)) } - fn headers_range(&self, range: impl RangeBounds) -> ProviderResult> { + fn headers_range( + &self, + range: impl RangeBounds, + ) -> ProviderResult> { let range = to_range(range); let mut cursor = self.cursor()?; let mut headers = Vec::with_capacity((range.end - range.start) as usize); for num in range { - if let Some(header) = cursor.get_one::>(num.into())? { + if let Some(header) = cursor.get_one::>(num.into())? { headers.push(header); } } @@ -130,18 +134,21 @@ impl HeaderProvider for StaticFileJarProvider<'_, N> { Ok(headers) } - fn sealed_header(&self, number: BlockNumber) -> ProviderResult> { + fn sealed_header( + &self, + number: BlockNumber, + ) -> ProviderResult>> { Ok(self .cursor()? - .get_two::>(number.into())? + .get_two::>(number.into())? .map(|(header, hash)| SealedHeader::new(header, hash))) } fn sealed_headers_while( &self, range: impl RangeBounds, - mut predicate: impl FnMut(&SealedHeader) -> bool, - ) -> ProviderResult> { + mut predicate: impl FnMut(&SealedHeader) -> bool, + ) -> ProviderResult>> { let range = to_range(range); let mut cursor = self.cursor()?; @@ -149,7 +156,7 @@ impl HeaderProvider for StaticFileJarProvider<'_, N> { for number in range { if let Some((header, hash)) = - cursor.get_two::>(number.into())? + cursor.get_two::>(number.into())? { let sealed = SealedHeader::new(header, hash); if !predicate(&sealed) { diff --git a/crates/storage/provider/src/providers/static_file/manager.rs b/crates/storage/provider/src/providers/static_file/manager.rs index 3b49f8d401f9..eca382af76c7 100644 --- a/crates/storage/provider/src/providers/static_file/manager.rs +++ b/crates/storage/provider/src/providers/static_file/manager.rs @@ -1235,12 +1235,14 @@ impl StaticFileWriter for StaticFileProvider { } } -impl HeaderProvider for StaticFileProvider { - fn header(&self, block_hash: &BlockHash) -> ProviderResult> { +impl> HeaderProvider for StaticFileProvider { + type Header = N::BlockHeader; + + fn header(&self, block_hash: &BlockHash) -> ProviderResult> { self.find_static_file(StaticFileSegment::Headers, |jar_provider| { Ok(jar_provider .cursor()? - .get_two::>(block_hash.into())? + .get_two::>(block_hash.into())? .and_then(|(header, hash)| { if &hash == block_hash { return Some(header) @@ -1250,7 +1252,7 @@ impl HeaderProvider for StaticFileProvider { }) } - fn header_by_number(&self, num: BlockNumber) -> ProviderResult> { + fn header_by_number(&self, num: BlockNumber) -> ProviderResult> { self.get_segment_provider_from_block(StaticFileSegment::Headers, num, None) .and_then(|provider| provider.header_by_number(num)) .or_else(|err| { @@ -1283,16 +1285,22 @@ impl HeaderProvider for StaticFileProvider { }) } - fn headers_range(&self, range: impl RangeBounds) -> ProviderResult> { + fn headers_range( + &self, + range: impl RangeBounds, + ) -> ProviderResult> { self.fetch_range_with_predicate( StaticFileSegment::Headers, to_range(range), - |cursor, number| cursor.get_one::>(number.into()), + |cursor, number| cursor.get_one::>(number.into()), |_| true, ) } - fn sealed_header(&self, num: BlockNumber) -> ProviderResult> { + fn sealed_header( + &self, + num: BlockNumber, + ) -> ProviderResult>> { self.get_segment_provider_from_block(StaticFileSegment::Headers, num, None) .and_then(|provider| provider.sealed_header(num)) .or_else(|err| { @@ -1307,14 +1315,14 @@ impl HeaderProvider for StaticFileProvider { fn sealed_headers_while( &self, range: impl RangeBounds, - predicate: impl FnMut(&SealedHeader) -> bool, - ) -> ProviderResult> { + predicate: impl FnMut(&SealedHeader) -> bool, + ) -> ProviderResult>> { self.fetch_range_with_predicate( StaticFileSegment::Headers, to_range(range), |cursor, number| { Ok(cursor - .get_two::>(number.into())? + .get_two::>(number.into())? .map(|(header, hash)| SealedHeader::new(header, hash))) }, predicate, @@ -1385,8 +1393,8 @@ impl> Rec } } -impl> TransactionsProviderExt - for StaticFileProvider +impl> + TransactionsProviderExt for StaticFileProvider { fn transaction_hashes_by_range( &self, @@ -1582,7 +1590,9 @@ impl BlockNumReader for StaticFileProvider { } } -impl> BlockReader for StaticFileProvider { +impl> BlockReader + for StaticFileProvider +{ type Block = N::Block; fn find_block_by_hash( @@ -1618,7 +1628,7 @@ impl> BlockReader for Sta Err(ProviderError::UnsupportedProvider) } - fn ommers(&self, _id: BlockHashOrNumber) -> ProviderResult>> { + fn ommers(&self, _id: BlockHashOrNumber) -> ProviderResult>> { // Required data not present in static_files Err(ProviderError::UnsupportedProvider) } diff --git a/crates/storage/provider/src/providers/static_file/writer.rs b/crates/storage/provider/src/providers/static_file/writer.rs index 6f5335ec6657..b7f60c164423 100644 --- a/crates/storage/provider/src/providers/static_file/writer.rs +++ b/crates/storage/provider/src/providers/static_file/writer.rs @@ -2,7 +2,7 @@ use super::{ manager::StaticFileProviderInner, metrics::StaticFileProviderMetrics, StaticFileProvider, }; use crate::providers::static_file::metrics::StaticFileProviderOperation; -use alloy_consensus::Header; +use alloy_consensus::BlockHeader; use alloy_primitives::{BlockHash, BlockNumber, TxNumber, U256}; use parking_lot::{lock_api::RwLockWriteGuard, RawRwLock, RwLock}; use reth_codecs::Compact; @@ -526,16 +526,19 @@ impl StaticFileProviderRW { /// Returns the current [`BlockNumber`] as seen in the static file. pub fn append_header( &mut self, - header: &Header, + header: &N::BlockHeader, total_difficulty: U256, hash: &BlockHash, - ) -> ProviderResult<()> { + ) -> ProviderResult<()> + where + N::BlockHeader: Compact, + { let start = Instant::now(); self.ensure_no_queued_prune()?; debug_assert!(self.writer.user_header().segment() == StaticFileSegment::Headers); - self.increment_block(header.number)?; + self.increment_block(header.number())?; self.append_column(header)?; self.append_column(CompactU256::from(total_difficulty))?; diff --git a/crates/storage/provider/src/test_utils/mock.rs b/crates/storage/provider/src/test_utils/mock.rs index 12c0330ac0e0..385e5e8205df 100644 --- a/crates/storage/provider/src/test_utils/mock.rs +++ b/crates/storage/provider/src/test_utils/mock.rs @@ -179,6 +179,8 @@ impl DatabaseProviderFactory for MockEthProvider { } impl HeaderProvider for MockEthProvider { + type Header = Header; + fn header(&self, block_hash: &BlockHash) -> ProviderResult> { let lock = self.headers.lock(); Ok(lock.get(block_hash).cloned()) diff --git a/crates/storage/provider/src/test_utils/noop.rs b/crates/storage/provider/src/test_utils/noop.rs index ff6b3fccbe10..5120afffa857 100644 --- a/crates/storage/provider/src/test_utils/noop.rs +++ b/crates/storage/provider/src/test_utils/noop.rs @@ -284,6 +284,8 @@ impl ReceiptProvider for NoopProvider { impl ReceiptProviderIdExt for NoopProvider {} impl HeaderProvider for NoopProvider { + type Header = Header; + fn header(&self, _block_hash: &BlockHash) -> ProviderResult> { Ok(None) } @@ -586,6 +588,8 @@ impl CanonStateSubscriptions for NoopProvider { } impl ForkChoiceSubscriptions for NoopProvider { + type Header = Header; + fn subscribe_safe_block(&self) -> ForkChoiceNotifications { let (_, rx) = watch::channel(None); ForkChoiceNotifications(rx) diff --git a/crates/storage/provider/src/traits/full.rs b/crates/storage/provider/src/traits/full.rs index 0d28f83739b0..be485839f00b 100644 --- a/crates/storage/provider/src/traits/full.rs +++ b/crates/storage/provider/src/traits/full.rs @@ -7,7 +7,7 @@ use crate::{ }; use reth_chain_state::{CanonStateSubscriptions, ForkChoiceSubscriptions}; use reth_chainspec::EthereumHardforks; -use reth_node_types::{BlockTy, NodeTypesWithDB, ReceiptTy, TxTy}; +use reth_node_types::{BlockTy, HeaderTy, NodeTypesWithDB, ReceiptTy, TxTy}; use reth_storage_api::NodePrimitivesProvider; /// Helper trait to unify all provider traits for simplicity. @@ -15,14 +15,18 @@ pub trait FullProvider: DatabaseProviderFactory + NodePrimitivesProvider + StaticFileProviderFactory - + BlockReaderIdExt, Block = BlockTy, Receipt = ReceiptTy> - + AccountReader + + BlockReaderIdExt< + Transaction = TxTy, + Block = BlockTy, + Receipt = ReceiptTy, + Header = HeaderTy, + > + AccountReader + StateProviderFactory + EvmEnvProvider + ChainSpecProvider + ChangeSetReader + CanonStateSubscriptions - + ForkChoiceSubscriptions + + ForkChoiceSubscriptions
> + StageCheckpointReader + Clone + Unpin @@ -34,14 +38,18 @@ impl FullProvider for T where T: DatabaseProviderFactory + NodePrimitivesProvider + StaticFileProviderFactory - + BlockReaderIdExt, Block = BlockTy, Receipt = ReceiptTy> - + AccountReader + + BlockReaderIdExt< + Transaction = TxTy, + Block = BlockTy, + Receipt = ReceiptTy, + Header = HeaderTy, + > + AccountReader + StateProviderFactory + EvmEnvProvider + ChainSpecProvider + ChangeSetReader + CanonStateSubscriptions - + ForkChoiceSubscriptions + + ForkChoiceSubscriptions
> + StageCheckpointReader + Clone + Unpin diff --git a/crates/storage/provider/src/traits/header_sync_gap.rs b/crates/storage/provider/src/traits/header_sync_gap.rs index 5ce7e1197300..b572750d4a23 100644 --- a/crates/storage/provider/src/traits/header_sync_gap.rs +++ b/crates/storage/provider/src/traits/header_sync_gap.rs @@ -1,3 +1,4 @@ +use alloy_consensus::{BlockHeader, Header}; use alloy_eips::BlockHashOrNumber; use alloy_primitives::{BlockNumber, B256}; use reth_network_p2p::headers::downloader::SyncTarget; @@ -7,21 +8,21 @@ use tokio::sync::watch; /// Represents a gap to sync: from `local_head` to `target` #[derive(Clone, Debug)] -pub struct HeaderSyncGap { +pub struct HeaderSyncGap { /// The local head block. Represents lower bound of sync range. - pub local_head: SealedHeader, + pub local_head: SealedHeader, /// The sync target. Represents upper bound of sync range. pub target: SyncTarget, } -impl HeaderSyncGap { +impl HeaderSyncGap { /// Returns `true` if the gap from the head to the target was closed #[inline] pub fn is_closed(&self) -> bool { match self.target.tip() { BlockHashOrNumber::Hash(hash) => self.local_head.hash() == hash, - BlockHashOrNumber::Number(num) => self.local_head.number == num, + BlockHashOrNumber::Number(num) => self.local_head.number() == num, } } } @@ -29,6 +30,9 @@ impl HeaderSyncGap { /// Client trait for determining the current headers sync gap. #[auto_impl::auto_impl(&, Arc)] pub trait HeaderSyncGapProvider: Send + Sync { + /// The header type. + type Header: Send + Sync; + /// Find a current sync gap for the headers depending on the last /// uninterrupted block number. Last uninterrupted block represents the block number before /// which there are no gaps. It's up to the caller to ensure that last uninterrupted block is @@ -37,5 +41,5 @@ pub trait HeaderSyncGapProvider: Send + Sync { &self, tip: watch::Receiver, highest_uninterrupted_block: BlockNumber, - ) -> ProviderResult; + ) -> ProviderResult>; } diff --git a/crates/storage/storage-api/src/block.rs b/crates/storage/storage-api/src/block.rs index 204e9027da28..917796038e9d 100644 --- a/crates/storage/storage-api/src/block.rs +++ b/crates/storage/storage-api/src/block.rs @@ -2,7 +2,6 @@ use crate::{ BlockNumReader, HeaderProvider, ReceiptProvider, ReceiptProviderIdExt, TransactionVariant, TransactionsProvider, WithdrawalsProvider, }; -use alloy_consensus::Header; use alloy_eips::{BlockHashOrNumber, BlockId, BlockNumberOrTag}; use alloy_primitives::{BlockNumber, B256}; use reth_db_models::StoredBlockBodyIndices; @@ -57,6 +56,7 @@ pub trait BlockReader: /// The block type this provider reads. type Block: reth_primitives_traits::Block< Body: reth_primitives_traits::BlockBody, + Header = Self::Header, >; /// Tries to find in the given block source. @@ -98,7 +98,7 @@ pub trait BlockReader: /// Returns the ommers/uncle headers of the given block from the database. /// /// Returns `None` if block is not found. - fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult>>; + fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult>>; /// Returns the block with matching hash from the database. /// @@ -187,7 +187,7 @@ impl BlockReader for std::sync::Arc { ) -> ProviderResult, Vec)>> { T::pending_block_and_receipts(self) } - fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult>> { + fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult>> { T::ommers(self, id) } fn block_by_hash(&self, hash: B256) -> ProviderResult> { @@ -256,7 +256,7 @@ impl BlockReader for &T { ) -> ProviderResult, Vec)>> { T::pending_block_and_receipts(self) } - fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult>> { + fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult>> { T::ommers(self, id) } fn block_by_hash(&self, hash: B256) -> ProviderResult> { @@ -321,7 +321,7 @@ pub trait BlockReaderIdExt: BlockReader + ReceiptProviderIdExt { /// /// Note: This returns a [`SealedHeader`] because it's expected that this is sealed by the /// provider and the caller does not know the hash. - fn pending_header(&self) -> ProviderResult> { + fn pending_header(&self) -> ProviderResult>> { self.sealed_header_by_id(BlockNumberOrTag::Pending.into()) } @@ -329,7 +329,7 @@ pub trait BlockReaderIdExt: BlockReader + ReceiptProviderIdExt { /// /// Note: This returns a [`SealedHeader`] because it's expected that this is sealed by the /// provider and the caller does not know the hash. - fn latest_header(&self) -> ProviderResult> { + fn latest_header(&self) -> ProviderResult>> { self.sealed_header_by_id(BlockNumberOrTag::Latest.into()) } @@ -337,7 +337,7 @@ pub trait BlockReaderIdExt: BlockReader + ReceiptProviderIdExt { /// /// Note: This returns a [`SealedHeader`] because it's expected that this is sealed by the /// provider and the caller does not know the hash. - fn safe_header(&self) -> ProviderResult> { + fn safe_header(&self) -> ProviderResult>> { self.sealed_header_by_id(BlockNumberOrTag::Safe.into()) } @@ -345,7 +345,7 @@ pub trait BlockReaderIdExt: BlockReader + ReceiptProviderIdExt { /// /// Note: This returns a [`SealedHeader`] because it's expected that this is sealed by the /// provider and the caller does not know the hash. - fn finalized_header(&self) -> ProviderResult> { + fn finalized_header(&self) -> ProviderResult>> { self.sealed_header_by_id(BlockNumberOrTag::Finalized.into()) } @@ -378,7 +378,10 @@ pub trait BlockReaderIdExt: BlockReader + ReceiptProviderIdExt { /// Returns the header with matching tag from the database /// /// Returns `None` if header is not found. - fn header_by_number_or_tag(&self, id: BlockNumberOrTag) -> ProviderResult> { + fn header_by_number_or_tag( + &self, + id: BlockNumberOrTag, + ) -> ProviderResult> { self.convert_block_number(id)? .map_or_else(|| Ok(None), |num| self.header_by_hash_or_number(num.into())) } @@ -389,7 +392,7 @@ pub trait BlockReaderIdExt: BlockReader + ReceiptProviderIdExt { fn sealed_header_by_number_or_tag( &self, id: BlockNumberOrTag, - ) -> ProviderResult> { + ) -> ProviderResult>> { self.convert_block_number(id)? .map_or_else(|| Ok(None), |num| self.header_by_hash_or_number(num.into()))? .map_or_else(|| Ok(None), |h| Ok(Some(SealedHeader::seal(h)))) @@ -398,22 +401,28 @@ pub trait BlockReaderIdExt: BlockReader + ReceiptProviderIdExt { /// Returns the sealed header with the matching `BlockId` from the database. /// /// Returns `None` if header is not found. - fn sealed_header_by_id(&self, id: BlockId) -> ProviderResult>; + fn sealed_header_by_id( + &self, + id: BlockId, + ) -> ProviderResult>>; /// Returns the header with the matching `BlockId` from the database. /// /// Returns `None` if header is not found. - fn header_by_id(&self, id: BlockId) -> ProviderResult>; + fn header_by_id(&self, id: BlockId) -> ProviderResult>; /// Returns the ommers with the matching tag from the database. - fn ommers_by_number_or_tag(&self, id: BlockNumberOrTag) -> ProviderResult>> { + fn ommers_by_number_or_tag( + &self, + id: BlockNumberOrTag, + ) -> ProviderResult>> { self.convert_block_number(id)?.map_or_else(|| Ok(None), |num| self.ommers(num.into())) } /// Returns the ommers with the matching `BlockId` from the database. /// /// Returns `None` if block is not found. - fn ommers_by_id(&self, id: BlockId) -> ProviderResult>>; + fn ommers_by_id(&self, id: BlockId) -> ProviderResult>>; } /// Functionality to read the last known chain blocks from the database. diff --git a/crates/storage/storage-api/src/chain_info.rs b/crates/storage/storage-api/src/chain_info.rs index 39f8639dd274..b6f58b7e73f0 100644 --- a/crates/storage/storage-api/src/chain_info.rs +++ b/crates/storage/storage-api/src/chain_info.rs @@ -4,6 +4,9 @@ use std::time::Instant; /// A type that can track updates related to fork choice updates. pub trait CanonChainTracker: Send + Sync { + /// The header type. + type Header: Send + Sync; + /// Notify the tracker about a received fork choice update. fn on_forkchoice_update_received(&self, update: &ForkchoiceState); @@ -19,11 +22,11 @@ pub trait CanonChainTracker: Send + Sync { fn last_exchanged_transition_configuration_timestamp(&self) -> Option; /// Sets the canonical head of the chain. - fn set_canonical_head(&self, header: SealedHeader); + fn set_canonical_head(&self, header: SealedHeader); /// Sets the safe block of the chain. - fn set_safe(&self, header: SealedHeader); + fn set_safe(&self, header: SealedHeader); /// Sets the finalized block of the chain. - fn set_finalized(&self, header: SealedHeader); + fn set_finalized(&self, header: SealedHeader); } diff --git a/crates/storage/storage-api/src/header.rs b/crates/storage/storage-api/src/header.rs index c068f7c1d295..2f1c9750edb1 100644 --- a/crates/storage/storage-api/src/header.rs +++ b/crates/storage/storage-api/src/header.rs @@ -1,34 +1,40 @@ -use alloy_consensus::Header; use alloy_eips::BlockHashOrNumber; use alloy_primitives::{BlockHash, BlockNumber, U256}; use reth_primitives::SealedHeader; +use reth_primitives_traits::BlockHeader; use reth_storage_errors::provider::ProviderResult; use std::ops::RangeBounds; /// Client trait for fetching `Header` related data. #[auto_impl::auto_impl(&, Arc)] pub trait HeaderProvider: Send + Sync { + /// The header type this provider supports. + type Header: BlockHeader; + /// Check if block is known fn is_known(&self, block_hash: &BlockHash) -> ProviderResult { self.header(block_hash).map(|header| header.is_some()) } /// Get header by block hash - fn header(&self, block_hash: &BlockHash) -> ProviderResult>; + fn header(&self, block_hash: &BlockHash) -> ProviderResult>; /// Retrieves the header sealed by the given block hash. - fn sealed_header_by_hash(&self, block_hash: BlockHash) -> ProviderResult> { + fn sealed_header_by_hash( + &self, + block_hash: BlockHash, + ) -> ProviderResult>> { Ok(self.header(&block_hash)?.map(|header| SealedHeader::new(header, block_hash))) } /// Get header by block number - fn header_by_number(&self, num: u64) -> ProviderResult>; + fn header_by_number(&self, num: u64) -> ProviderResult>; /// Get header by block number or hash fn header_by_hash_or_number( &self, hash_or_num: BlockHashOrNumber, - ) -> ProviderResult> { + ) -> ProviderResult> { match hash_or_num { BlockHashOrNumber::Hash(hash) => self.header(&hash), BlockHashOrNumber::Number(num) => self.header_by_number(num), @@ -42,16 +48,22 @@ pub trait HeaderProvider: Send + Sync { fn header_td_by_number(&self, number: BlockNumber) -> ProviderResult>; /// Get headers in range of block numbers - fn headers_range(&self, range: impl RangeBounds) -> ProviderResult>; + fn headers_range( + &self, + range: impl RangeBounds, + ) -> ProviderResult>; /// Get a single sealed header by block number. - fn sealed_header(&self, number: BlockNumber) -> ProviderResult>; + fn sealed_header( + &self, + number: BlockNumber, + ) -> ProviderResult>>; /// Get headers in range of block numbers. fn sealed_headers_range( &self, range: impl RangeBounds, - ) -> ProviderResult> { + ) -> ProviderResult>> { self.sealed_headers_while(range, |_| true) } @@ -59,6 +71,6 @@ pub trait HeaderProvider: Send + Sync { fn sealed_headers_while( &self, range: impl RangeBounds, - predicate: impl FnMut(&SealedHeader) -> bool, - ) -> ProviderResult>; + predicate: impl FnMut(&SealedHeader) -> bool, + ) -> ProviderResult>>; } diff --git a/crates/transaction-pool/src/maintain.rs b/crates/transaction-pool/src/maintain.rs index cb75af7db178..1a5fd8399266 100644 --- a/crates/transaction-pool/src/maintain.rs +++ b/crates/transaction-pool/src/maintain.rs @@ -7,6 +7,7 @@ use crate::{ traits::{CanonicalStateUpdate, TransactionPool, TransactionPoolExt}, BlockInfo, PoolTransaction, PoolUpdateKind, }; +use alloy_consensus::BlockHeader; use alloy_eips::BlockNumberOrTag; use alloy_primitives::{Address, BlockHash, BlockNumber}; use futures_util::{ @@ -110,11 +111,13 @@ pub async fn maintain_transaction_pool( let latest = SealedHeader::seal(latest); let chain_spec = client.chain_spec(); let info = BlockInfo { - block_gas_limit: latest.gas_limit, + block_gas_limit: latest.gas_limit(), last_seen_block_hash: latest.hash(), - last_seen_block_number: latest.number, + last_seen_block_number: latest.number(), pending_basefee: latest - .next_block_base_fee(chain_spec.base_fee_params_at_timestamp(latest.timestamp + 12)) + .next_block_base_fee( + chain_spec.base_fee_params_at_timestamp(latest.timestamp() + 12), + ) .unwrap_or_default(), pending_blob_fee: latest.next_block_blob_fee(), }; diff --git a/examples/db-access/Cargo.toml b/examples/db-access/Cargo.toml index 3310d1cbd676..ec278ac1cc14 100644 --- a/examples/db-access/Cargo.toml +++ b/examples/db-access/Cargo.toml @@ -14,6 +14,7 @@ reth-provider.workspace = true reth-node-ethereum.workspace = true reth-node-types.workspace = true +alloy-consensus.workspace = true alloy-rpc-types-eth.workspace = true alloy-primitives.workspace = true diff --git a/examples/db-access/src/main.rs b/examples/db-access/src/main.rs index 9f95fb51d91a..727bd1bfff3c 100644 --- a/examples/db-access/src/main.rs +++ b/examples/db-access/src/main.rs @@ -1,3 +1,4 @@ +use alloy_consensus::BlockHeader; use alloy_primitives::{Address, B256}; use alloy_rpc_types_eth::{Filter, FilteredParams}; use reth_chainspec::ChainSpecBuilder; @@ -193,7 +194,7 @@ fn receipts_provider_example< // receipts and do something with the data // 1. get the bloom from the header let header = provider.header_by_number(header_num)?.unwrap(); - let bloom = header.logs_bloom; + let bloom = header.logs_bloom(); // 2. Construct the address/topics filters // For a hypothetical address, we'll want to filter down for a specific indexed topic (e.g. From 6789ff4a1ecbf8d92f076817abdc0f48b00b794b Mon Sep 17 00:00:00 2001 From: joshieDo <93316087+joshieDo@users.noreply.github.com> Date: Mon, 2 Dec 2024 14:56:55 +0000 Subject: [PATCH 18/68] chore: add `OpEthApiBuilder` and `OpEthApiInner` (#13009) --- Cargo.lock | 1 - crates/optimism/bin/src/main.rs | 9 +- crates/optimism/node/src/node.rs | 47 +++++-- crates/optimism/node/tests/it/builder.rs | 9 +- crates/optimism/rpc/Cargo.toml | 1 - crates/optimism/rpc/src/eth/block.rs | 2 +- crates/optimism/rpc/src/eth/call.rs | 4 +- crates/optimism/rpc/src/eth/mod.rs | 130 +++++++++++++------ crates/optimism/rpc/src/eth/pending_block.rs | 2 +- crates/optimism/rpc/src/eth/receipt.rs | 4 +- crates/optimism/rpc/src/eth/transaction.rs | 5 +- 11 files changed, 145 insertions(+), 69 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2a9d5222025d..2b02dc2e3e25 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8483,7 +8483,6 @@ dependencies = [ "alloy-primitives", "alloy-rpc-types-debug", "alloy-rpc-types-eth", - "derive_more 1.0.0", "jsonrpsee-core", "jsonrpsee-types", "op-alloy-consensus", diff --git a/crates/optimism/bin/src/main.rs b/crates/optimism/bin/src/main.rs index 6494298ba393..82fb3c241954 100644 --- a/crates/optimism/bin/src/main.rs +++ b/crates/optimism/bin/src/main.rs @@ -3,9 +3,9 @@ #![cfg(feature = "optimism")] use clap::Parser; -use reth_node_builder::{engine_tree_config::TreeConfig, EngineNodeLauncher}; +use reth_node_builder::{engine_tree_config::TreeConfig, EngineNodeLauncher, Node}; use reth_optimism_cli::{chainspec::OpChainSpecParser, Cli}; -use reth_optimism_node::{args::RollupArgs, node::OpAddOns, OpNode}; +use reth_optimism_node::{args::RollupArgs, OpNode}; use reth_provider::providers::BlockchainProvider2; use tracing as _; @@ -27,7 +27,6 @@ fn main() { tracing::warn!(target: "reth::cli", "Experimental engine is default now, and the --engine.experimental flag is deprecated. To enable the legacy functionality, use --engine.legacy."); } let use_legacy_engine = rollup_args.legacy; - let sequencer_http_arg = rollup_args.sequencer_http.clone(); match use_legacy_engine { false => { let engine_tree_config = TreeConfig::default() @@ -35,8 +34,8 @@ fn main() { .with_memory_block_buffer_target(rollup_args.memory_block_buffer_target); let handle = builder .with_types_and_provider::>() - .with_components(OpNode::components(rollup_args)) - .with_add_ons(OpAddOns::new(sequencer_http_arg)) + .with_components(OpNode::components(rollup_args.clone())) + .with_add_ons(OpNode::new(rollup_args).add_ons()) .launch_with_fn(|builder| { let launcher = EngineNodeLauncher::new( builder.task_executor().clone(), diff --git a/crates/optimism/node/src/node.rs b/crates/optimism/node/src/node.rs index bdf8c3f58eed..73adcb43f18a 100644 --- a/crates/optimism/node/src/node.rs +++ b/crates/optimism/node/src/node.rs @@ -31,7 +31,7 @@ use reth_optimism_payload_builder::builder::OpPayloadTransactions; use reth_optimism_primitives::OpPrimitives; use reth_optimism_rpc::{ witness::{DebugExecutionWitnessApiServer, OpDebugWitnessApi}, - OpEthApi, + OpEthApi, SequencerClient, }; use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService}; use reth_primitives::BlockBody; @@ -178,12 +178,11 @@ where OpAddOns>::Components>>; fn components_builder(&self) -> Self::ComponentsBuilder { - let Self { args } = self; - Self::components(args.clone()) + Self::components(self.args.clone()) } fn add_ons(&self) -> Self::AddOns { - OpAddOns::new(self.args.sequencer_http.clone()) + Self::AddOns::builder().with_sequencer(self.args.sequencer_http.clone()).build() } } @@ -204,14 +203,14 @@ pub struct OpAddOns(pub RpcAddOns, OpEngin impl>> Default for OpAddOns { fn default() -> Self { - Self::new(None) + Self::builder().build() } } impl>> OpAddOns { - /// Create a new instance with the given `sequencer_http` URL. - pub fn new(sequencer_http: Option) -> Self { - Self(RpcAddOns::new(move |ctx| OpEthApi::new(ctx, sequencer_http), Default::default())) + /// Build a [`OpAddOns`] using [`OpAddOnsBuilder`]. + pub fn builder() -> OpAddOnsBuilder { + OpAddOnsBuilder::default() } } @@ -270,6 +269,38 @@ where } } +/// A regular optimism evm and executor builder. +#[derive(Debug, Default, Clone)] +#[non_exhaustive] +pub struct OpAddOnsBuilder { + /// Sequencer client, configured to forward submitted transactions to sequencer of given OP + /// network. + sequencer_client: Option, +} + +impl OpAddOnsBuilder { + /// With a [`SequencerClient`]. + pub fn with_sequencer(mut self, sequencer_client: Option) -> Self { + self.sequencer_client = sequencer_client.map(SequencerClient::new); + self + } +} + +impl OpAddOnsBuilder { + /// Builds an instance of [`OpAddOns`]. + pub fn build(self) -> OpAddOns + where + N: FullNodeComponents>, + { + let Self { sequencer_client, .. } = self; + + OpAddOns(RpcAddOns::new( + move |ctx| OpEthApi::::builder().with_sequencer(sequencer_client).build(ctx), + Default::default(), + )) + } +} + /// A regular optimism evm and executor builder. #[derive(Debug, Default, Clone, Copy)] #[non_exhaustive] diff --git a/crates/optimism/node/tests/it/builder.rs b/crates/optimism/node/tests/it/builder.rs index 67cac17d3987..875b282e0ad0 100644 --- a/crates/optimism/node/tests/it/builder.rs +++ b/crates/optimism/node/tests/it/builder.rs @@ -2,20 +2,21 @@ use reth_db::test_utils::create_test_rw_db; use reth_node_api::FullNodeComponents; -use reth_node_builder::{NodeBuilder, NodeConfig}; +use reth_node_builder::{Node, NodeBuilder, NodeConfig}; use reth_optimism_chainspec::BASE_MAINNET; -use reth_optimism_node::{node::OpAddOns, OpNode}; +use reth_optimism_node::{args::RollupArgs, OpNode}; #[test] fn test_basic_setup() { // parse CLI -> config let config = NodeConfig::new(BASE_MAINNET.clone()); let db = create_test_rw_db(); + let args = RollupArgs::default(); let _builder = NodeBuilder::new(config) .with_database(db) .with_types::() - .with_components(OpNode::components(Default::default())) - .with_add_ons(OpAddOns::new(None)) + .with_components(OpNode::components(args.clone())) + .with_add_ons(OpNode::new(args).add_ons()) .on_component_initialized(move |ctx| { let _provider = ctx.provider(); Ok(()) diff --git a/crates/optimism/rpc/Cargo.toml b/crates/optimism/rpc/Cargo.toml index 50194f39aa3c..4b25066d6759 100644 --- a/crates/optimism/rpc/Cargo.toml +++ b/crates/optimism/rpc/Cargo.toml @@ -61,7 +61,6 @@ serde_json.workspace = true # misc thiserror.workspace = true tracing.workspace = true -derive_more = { workspace = true, features = ["constructor", "deref"] } [dev-dependencies] reth-optimism-chainspec.workspace = true diff --git a/crates/optimism/rpc/src/eth/block.rs b/crates/optimism/rpc/src/eth/block.rs index 64a55496993d..92b4353ec9e4 100644 --- a/crates/optimism/rpc/src/eth/block.rs +++ b/crates/optimism/rpc/src/eth/block.rs @@ -57,7 +57,7 @@ where }; Ok(OpReceiptBuilder::new( - &self.inner.provider().chain_spec(), + &self.inner.eth_api.provider().chain_spec(), tx, meta, receipt, diff --git a/crates/optimism/rpc/src/eth/call.rs b/crates/optimism/rpc/src/eth/call.rs index 9495a359e329..c5e96bb87d17 100644 --- a/crates/optimism/rpc/src/eth/call.rs +++ b/crates/optimism/rpc/src/eth/call.rs @@ -33,12 +33,12 @@ where { #[inline] fn call_gas_limit(&self) -> u64 { - self.inner.gas_cap() + self.inner.eth_api.gas_cap() } #[inline] fn max_simulate_blocks(&self) -> u64 { - self.inner.max_simulate_blocks() + self.inner.eth_api.max_simulate_blocks() } fn create_txn_env( diff --git a/crates/optimism/rpc/src/eth/mod.rs b/crates/optimism/rpc/src/eth/mod.rs index 6b909f012c55..27672804839b 100644 --- a/crates/optimism/rpc/src/eth/mod.rs +++ b/crates/optimism/rpc/src/eth/mod.rs @@ -14,7 +14,6 @@ use std::{fmt, sync::Arc}; use alloy_consensus::Header; use alloy_primitives::U256; -use derive_more::Deref; use op_alloy_network::Optimism; use reth_chainspec::{EthChainSpec, EthereumHardforks}; use reth_evm::ConfigureEvm; @@ -59,14 +58,10 @@ pub type EthApiNodeBackend = EthApiInner< /// /// This type implements the [`FullEthApi`](reth_rpc_eth_api::helpers::FullEthApi) by implemented /// all the `Eth` helper traits and prerequisite traits. -#[derive(Deref, Clone)] +#[derive(Clone)] pub struct OpEthApi { /// Gateway to node's core components. - #[deref] - inner: Arc>, - /// Sequencer client, configured to forward submitted transactions to sequencer of given OP - /// network. - sequencer_client: Option, + inner: Arc>, } impl OpEthApi @@ -79,28 +74,9 @@ where + 'static, >, { - /// Creates a new instance for given context. - pub fn new(ctx: &EthApiBuilderCtx, sequencer_http: Option) -> Self { - let blocking_task_pool = - BlockingTaskPool::build().expect("failed to build blocking task pool"); - - let inner = EthApiInner::new( - ctx.provider.clone(), - ctx.pool.clone(), - ctx.network.clone(), - ctx.cache.clone(), - ctx.new_gas_price_oracle(), - ctx.config.rpc_gas_cap, - ctx.config.rpc_max_simulate_blocks, - ctx.config.eth_proof_window, - blocking_task_pool, - ctx.new_fee_history_cache(), - ctx.evm_config.clone(), - ctx.executor.clone(), - ctx.config.proof_permits, - ); - - Self { inner: Arc::new(inner), sequencer_client: sequencer_http.map(SequencerClient::new) } + /// Build a [`OpEthApi`] using [`OpEthApiBuilder`]. + pub const fn builder() -> OpEthApiBuilder { + OpEthApiBuilder::new() } } @@ -130,17 +106,17 @@ where #[inline] fn pool(&self) -> &Self::Pool { - self.inner.pool() + self.inner.eth_api.pool() } #[inline] fn evm_config(&self) -> &Self::Evm { - self.inner.evm_config() + self.inner.eth_api.evm_config() } #[inline] fn network(&self) -> &Self::Network { - self.inner.network() + self.inner.eth_api.network() } #[inline] @@ -150,7 +126,7 @@ where #[inline] fn provider(&self) -> &Self::Provider { - self.inner.provider() + self.inner.eth_api.provider() } } @@ -160,7 +136,7 @@ where { #[inline] fn cache(&self) -> &EthStateCache { - self.inner.cache() + self.inner.eth_api.cache() } } @@ -175,12 +151,12 @@ where { #[inline] fn starting_block(&self) -> U256 { - self.inner.starting_block() + self.inner.eth_api.starting_block() } #[inline] fn signers(&self) -> &parking_lot::RwLock>> { - self.inner.signers() + self.inner.eth_api.signers() } } @@ -191,17 +167,17 @@ where { #[inline] fn io_task_spawner(&self) -> impl TaskSpawner { - self.inner.task_spawner() + self.inner.eth_api.task_spawner() } #[inline] fn tracing_task_pool(&self) -> &BlockingTaskPool { - self.inner.blocking_task_pool() + self.inner.eth_api.blocking_task_pool() } #[inline] fn tracing_task_guard(&self) -> &BlockingTaskGuard { - self.inner.blocking_task_guard() + self.inner.eth_api.blocking_task_guard() } } @@ -217,12 +193,12 @@ where { #[inline] fn gas_oracle(&self) -> &GasPriceOracle { - self.inner.gas_oracle() + self.inner.eth_api.gas_oracle() } #[inline] fn fee_history_cache(&self) -> &FeeHistoryCache { - self.inner.fee_history_cache() + self.inner.eth_api.fee_history_cache() } } @@ -241,7 +217,7 @@ where { #[inline] fn max_proof_window(&self) -> u64 { - self.inner.eth_proof_window() + self.inner.eth_api.eth_proof_window() } } @@ -264,7 +240,7 @@ where N: RpcNodeCore, { fn with_dev_accounts(&self) { - *self.inner.signers().write() = DevSigner::random_signers(20) + *self.inner.eth_api.signers().write() = DevSigner::random_signers(20) } } @@ -273,3 +249,71 @@ impl fmt::Debug for OpEthApi { f.debug_struct("OpEthApi").finish_non_exhaustive() } } + +/// Container type `OpEthApi` +#[allow(missing_debug_implementations)] +struct OpEthApiInner { + /// Gateway to node's core components. + eth_api: EthApiNodeBackend, + /// Sequencer client, configured to forward submitted transactions to sequencer of given OP + /// network. + sequencer_client: Option, +} + +/// A type that knows how to build a [`OpEthApi`]. +#[derive(Debug, Default)] +pub struct OpEthApiBuilder { + /// Sequencer client, configured to forward submitted transactions to sequencer of given OP + /// network. + sequencer_client: Option, +} + +impl OpEthApiBuilder { + /// Creates a [`OpEthApiBuilder`] instance from [`EthApiBuilderCtx`]. + pub const fn new() -> Self { + Self { sequencer_client: None } + } + + /// With a [`SequencerClient`]. + pub fn with_sequencer(mut self, sequencer_client: Option) -> Self { + self.sequencer_client = sequencer_client; + self + } +} + +impl OpEthApiBuilder { + /// Builds an instance of [`OpEthApi`] + pub fn build(self, ctx: &EthApiBuilderCtx) -> OpEthApi + where + N: RpcNodeCore< + Provider: BlockReaderIdExt + + ChainSpecProvider + + CanonStateSubscriptions + + Clone + + 'static, + >, + { + let blocking_task_pool = + BlockingTaskPool::build().expect("failed to build blocking task pool"); + + let eth_api = EthApiInner::new( + ctx.provider.clone(), + ctx.pool.clone(), + ctx.network.clone(), + ctx.cache.clone(), + ctx.new_gas_price_oracle(), + ctx.config.rpc_gas_cap, + ctx.config.rpc_max_simulate_blocks, + ctx.config.eth_proof_window, + blocking_task_pool, + ctx.new_fee_history_cache(), + ctx.evm_config.clone(), + ctx.executor.clone(), + ctx.config.proof_permits, + ); + + OpEthApi { + inner: Arc::new(OpEthApiInner { eth_api, sequencer_client: self.sequencer_client }), + } + } +} diff --git a/crates/optimism/rpc/src/eth/pending_block.rs b/crates/optimism/rpc/src/eth/pending_block.rs index 852c4454f060..fec610bb1e93 100644 --- a/crates/optimism/rpc/src/eth/pending_block.rs +++ b/crates/optimism/rpc/src/eth/pending_block.rs @@ -37,7 +37,7 @@ where { #[inline] fn pending_block(&self) -> &tokio::sync::Mutex> { - self.inner.pending_block() + self.inner.eth_api.pending_block() } /// Returns the locally built pending block diff --git a/crates/optimism/rpc/src/eth/receipt.rs b/crates/optimism/rpc/src/eth/receipt.rs index e803ea210197..2a4df1ada49d 100644 --- a/crates/optimism/rpc/src/eth/receipt.rs +++ b/crates/optimism/rpc/src/eth/receipt.rs @@ -31,6 +31,8 @@ where receipt: Receipt, ) -> Result, Self::Error> { let (block, receipts) = self + .inner + .eth_api .cache() .get_block_and_receipts(meta.block_hash) .await @@ -43,7 +45,7 @@ where reth_optimism_evm::extract_l1_info(&block.body).map_err(OpEthApiError::from)?; Ok(OpReceiptBuilder::new( - &self.inner.provider().chain_spec(), + &self.inner.eth_api.provider().chain_spec(), &tx, meta, &receipt, diff --git a/crates/optimism/rpc/src/eth/transaction.rs b/crates/optimism/rpc/src/eth/transaction.rs index 3202dc46ad1b..2b92927f6495 100644 --- a/crates/optimism/rpc/src/eth/transaction.rs +++ b/crates/optimism/rpc/src/eth/transaction.rs @@ -23,7 +23,7 @@ where N: RpcNodeCore, { fn signers(&self) -> &parking_lot::RwLock>> { - self.inner.signers() + self.inner.eth_api.signers() } /// Decodes and recovers the transaction and submits it to the pool. @@ -68,7 +68,7 @@ where { /// Returns the [`SequencerClient`] if one is set. pub fn raw_tx_forwarder(&self) -> Option { - self.sequencer_client.clone() + self.inner.sequencer_client.clone() } } @@ -106,6 +106,7 @@ where } reth_primitives::Transaction::Deposit(tx) => { self.inner + .eth_api .provider() .receipt_by_hash(hash) .map_err(Self::Error::from_eth_err)? From 8a047ed6e437a87454c3d6ab5f19f5029b6af9de Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Mon, 2 Dec 2024 17:02:19 +0100 Subject: [PATCH 19/68] chore: move Integerlist to db-api (#13062) --- Cargo.lock | 3 +- crates/net/ecies/Cargo.toml | 2 +- crates/primitives-traits/Cargo.toml | 2 - crates/primitives-traits/src/integer_list.rs | 196 ------------------ crates/primitives-traits/src/lib.rs | 3 - crates/storage/db-api/Cargo.toml | 1 + .../storage/db-api/src/models/integer_list.rs | 181 +++++++++++++++- crates/storage/db-api/src/models/mod.rs | 6 +- crates/storage/db-common/src/init.rs | 3 +- .../storage/db/src/implementation/mdbx/mod.rs | 5 +- .../db/src/tables/codecs/fuzz/inputs.rs | 2 +- .../storage/db/src/tables/codecs/fuzz/mod.rs | 3 - crates/storage/db/src/tables/mod.rs | 8 +- crates/storage/libmdbx-rs/Cargo.toml | 2 +- 14 files changed, 195 insertions(+), 222 deletions(-) delete mode 100644 crates/primitives-traits/src/integer_list.rs diff --git a/Cargo.lock b/Cargo.lock index 2b02dc2e3e25..b39cd76e09be 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6953,6 +6953,7 @@ dependencies = [ "reth-stages-types", "reth-storage-errors", "reth-trie-common", + "roaring", "serde", "test-fuzz", ] @@ -8670,7 +8671,6 @@ dependencies = [ "rand 0.8.5", "reth-codecs", "revm-primitives", - "roaring", "serde", "serde_json", "serde_with", @@ -9720,7 +9720,6 @@ checksum = "f81dc953b2244ddd5e7860cb0bb2a790494b898ef321d4aff8e260efab60cc88" dependencies = [ "bytemuck", "byteorder", - "serde", ] [[package]] diff --git a/crates/net/ecies/Cargo.toml b/crates/net/ecies/Cargo.toml index eb2a0b023b3f..ec34e3e7a323 100644 --- a/crates/net/ecies/Cargo.toml +++ b/crates/net/ecies/Cargo.toml @@ -28,7 +28,7 @@ tracing.workspace = true # HeaderBytes generic-array.workspace = true typenum = "1.15.0" -byteorder = "1.4.3" +byteorder.workspace = true # crypto rand.workspace = true diff --git a/crates/primitives-traits/Cargo.toml b/crates/primitives-traits/Cargo.toml index ceee1e26cecd..9265c878d6cb 100644 --- a/crates/primitives-traits/Cargo.toml +++ b/crates/primitives-traits/Cargo.toml @@ -30,7 +30,6 @@ op-alloy-consensus = { workspace = true, optional = true } byteorder = { workspace = true, optional = true } bytes.workspace = true derive_more.workspace = true -roaring = "0.10.2" serde_with = { workspace = true, optional = true } auto_impl.workspace = true @@ -100,7 +99,6 @@ serde = [ "rand/serde", "reth-codecs?/serde", "revm-primitives/serde", - "roaring/serde", "revm-primitives/serde", "op-alloy-consensus?/serde" ] diff --git a/crates/primitives-traits/src/integer_list.rs b/crates/primitives-traits/src/integer_list.rs deleted file mode 100644 index 6fc6d75899ce..000000000000 --- a/crates/primitives-traits/src/integer_list.rs +++ /dev/null @@ -1,196 +0,0 @@ -use alloc::vec::Vec; -use core::fmt; - -use bytes::BufMut; -use derive_more::Deref; -use roaring::RoaringTreemap; - -/// A data structure that uses Roaring Bitmaps to efficiently store a list of integers. -/// -/// This structure provides excellent compression while allowing direct access to individual -/// elements without the need for full decompression. -/// -/// Key features: -/// - Efficient compression: the underlying Roaring Bitmaps significantly reduce memory usage. -/// - Direct access: elements can be accessed or queried without needing to decode the entire list. -/// - [`RoaringTreemap`] backing: internally backed by [`RoaringTreemap`], which supports 64-bit -/// integers. -#[derive(Clone, PartialEq, Default, Deref)] -pub struct IntegerList(pub RoaringTreemap); - -impl fmt::Debug for IntegerList { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str("IntegerList")?; - f.debug_list().entries(self.0.iter()).finish() - } -} - -impl IntegerList { - /// Creates a new empty [`IntegerList`]. - pub fn empty() -> Self { - Self(RoaringTreemap::new()) - } - - /// Creates an [`IntegerList`] from a list of integers. - /// - /// Returns an error if the list is not pre-sorted. - pub fn new(list: impl IntoIterator) -> Result { - RoaringTreemap::from_sorted_iter(list) - .map(Self) - .map_err(|_| IntegerListError::UnsortedInput) - } - - /// Creates an [`IntegerList`] from a pre-sorted list of integers. - /// - /// # Panics - /// - /// Panics if the list is not pre-sorted. - #[inline] - #[track_caller] - pub fn new_pre_sorted(list: impl IntoIterator) -> Self { - Self::new(list).expect("IntegerList must be pre-sorted and non-empty") - } - - /// Appends a list of integers to the current list. - pub fn append(&mut self, list: impl IntoIterator) -> Result { - self.0.append(list).map_err(|_| IntegerListError::UnsortedInput) - } - - /// Pushes a new integer to the list. - pub fn push(&mut self, value: u64) -> Result<(), IntegerListError> { - self.0.push(value).then_some(()).ok_or(IntegerListError::UnsortedInput) - } - - /// Clears the list. - pub fn clear(&mut self) { - self.0.clear(); - } - - /// Serializes a [`IntegerList`] into a sequence of bytes. - pub fn to_bytes(&self) -> Vec { - let mut vec = Vec::with_capacity(self.0.serialized_size()); - self.0.serialize_into(&mut vec).expect("not able to encode IntegerList"); - vec - } - - /// Serializes a [`IntegerList`] into a sequence of bytes. - pub fn to_mut_bytes(&self, buf: &mut B) { - self.0.serialize_into(buf.writer()).unwrap(); - } - - /// Deserializes a sequence of bytes into a proper [`IntegerList`]. - pub fn from_bytes(data: &[u8]) -> Result { - RoaringTreemap::deserialize_from(data) - .map(Self) - .map_err(|_| IntegerListError::FailedToDeserialize) - } -} - -#[cfg(feature = "serde")] -impl serde::Serialize for IntegerList { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - use serde::ser::SerializeSeq; - - let mut seq = serializer.serialize_seq(Some(self.len() as usize))?; - for e in &self.0 { - seq.serialize_element(&e)?; - } - seq.end() - } -} - -#[cfg(feature = "serde")] -struct IntegerListVisitor; - -#[cfg(feature = "serde")] -impl<'de> serde::de::Visitor<'de> for IntegerListVisitor { - type Value = IntegerList; - - fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str("a usize array") - } - - fn visit_seq(self, mut seq: E) -> Result - where - E: serde::de::SeqAccess<'de>, - { - let mut list = IntegerList::empty(); - while let Some(item) = seq.next_element()? { - list.push(item).map_err(serde::de::Error::custom)?; - } - Ok(list) - } -} - -#[cfg(feature = "serde")] -impl<'de> serde::Deserialize<'de> for IntegerList { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - deserializer.deserialize_byte_buf(IntegerListVisitor) - } -} - -#[cfg(any(test, feature = "arbitrary"))] -use arbitrary::{Arbitrary, Unstructured}; - -#[cfg(any(test, feature = "arbitrary"))] -impl<'a> Arbitrary<'a> for IntegerList { - fn arbitrary(u: &mut Unstructured<'a>) -> Result { - let mut nums: Vec = Vec::arbitrary(u)?; - nums.sort_unstable(); - Self::new(nums).map_err(|_| arbitrary::Error::IncorrectFormat) - } -} - -/// Primitives error type. -#[derive(Debug, derive_more::Display, derive_more::Error)] -pub enum IntegerListError { - /// The provided input is unsorted. - #[display("the provided input is unsorted")] - UnsortedInput, - /// Failed to deserialize data into type. - #[display("failed to deserialize data into type")] - FailedToDeserialize, -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn empty_list() { - assert_eq!(IntegerList::empty().len(), 0); - assert_eq!(IntegerList::new_pre_sorted(std::iter::empty()).len(), 0); - } - - #[test] - fn test_integer_list() { - let original_list = [1, 2, 3]; - let ef_list = IntegerList::new(original_list).unwrap(); - assert_eq!(ef_list.iter().collect::>(), original_list); - } - - #[test] - fn test_integer_list_serialization() { - let original_list = [1, 2, 3]; - let ef_list = IntegerList::new(original_list).unwrap(); - - let blist = ef_list.to_bytes(); - assert_eq!(IntegerList::from_bytes(&blist).unwrap(), ef_list) - } - - #[test] - fn serde_serialize_deserialize() { - let original_list = [1, 2, 3]; - let ef_list = IntegerList::new(original_list).unwrap(); - - let serde_out = serde_json::to_string(&ef_list).unwrap(); - let serde_ef_list = serde_json::from_str::(&serde_out).unwrap(); - assert_eq!(serde_ef_list, ef_list); - } -} diff --git a/crates/primitives-traits/src/lib.rs b/crates/primitives-traits/src/lib.rs index c88da5ad7a7b..04d02be0b7dd 100644 --- a/crates/primitives-traits/src/lib.rs +++ b/crates/primitives-traits/src/lib.rs @@ -31,9 +31,6 @@ pub use transaction::{ FullTransaction, Transaction, }; -mod integer_list; -pub use integer_list::{IntegerList, IntegerListError}; - pub mod block; pub use block::{ body::{BlockBody, FullBlockBody}, diff --git a/crates/storage/db-api/Cargo.toml b/crates/storage/db-api/Cargo.toml index 3aa908a60093..05581b9725d7 100644 --- a/crates/storage/db-api/Cargo.toml +++ b/crates/storage/db-api/Cargo.toml @@ -29,6 +29,7 @@ alloy-consensus.workspace = true # codecs modular-bitfield.workspace = true +roaring = "0.10.2" parity-scale-codec = { version = "3.2.1", features = ["bytes"] } serde = { workspace = true, default-features = false } diff --git a/crates/storage/db-api/src/models/integer_list.rs b/crates/storage/db-api/src/models/integer_list.rs index 480b52a9e2c0..5301ec303e50 100644 --- a/crates/storage/db-api/src/models/integer_list.rs +++ b/crates/storage/db-api/src/models/integer_list.rs @@ -4,7 +4,159 @@ use crate::{ table::{Compress, Decompress}, DatabaseError, }; -use reth_primitives_traits::IntegerList; +use bytes::BufMut; +use core::fmt; +use derive_more::Deref; +use roaring::RoaringTreemap; + +/// A data structure that uses Roaring Bitmaps to efficiently store a list of integers. +/// +/// This structure provides excellent compression while allowing direct access to individual +/// elements without the need for full decompression. +/// +/// Key features: +/// - Efficient compression: the underlying Roaring Bitmaps significantly reduce memory usage. +/// - Direct access: elements can be accessed or queried without needing to decode the entire list. +/// - [`RoaringTreemap`] backing: internally backed by [`RoaringTreemap`], which supports 64-bit +/// integers. +#[derive(Clone, PartialEq, Default, Deref)] +pub struct IntegerList(pub RoaringTreemap); + +impl fmt::Debug for IntegerList { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("IntegerList")?; + f.debug_list().entries(self.0.iter()).finish() + } +} + +impl IntegerList { + /// Creates a new empty [`IntegerList`]. + pub fn empty() -> Self { + Self(RoaringTreemap::new()) + } + + /// Creates an [`IntegerList`] from a list of integers. + /// + /// Returns an error if the list is not pre-sorted. + pub fn new(list: impl IntoIterator) -> Result { + RoaringTreemap::from_sorted_iter(list) + .map(Self) + .map_err(|_| IntegerListError::UnsortedInput) + } + + /// Creates an [`IntegerList`] from a pre-sorted list of integers. + /// + /// # Panics + /// + /// Panics if the list is not pre-sorted. + #[inline] + #[track_caller] + pub fn new_pre_sorted(list: impl IntoIterator) -> Self { + Self::new(list).expect("IntegerList must be pre-sorted and non-empty") + } + + /// Appends a list of integers to the current list. + pub fn append(&mut self, list: impl IntoIterator) -> Result { + self.0.append(list).map_err(|_| IntegerListError::UnsortedInput) + } + + /// Pushes a new integer to the list. + pub fn push(&mut self, value: u64) -> Result<(), IntegerListError> { + self.0.push(value).then_some(()).ok_or(IntegerListError::UnsortedInput) + } + + /// Clears the list. + pub fn clear(&mut self) { + self.0.clear(); + } + + /// Serializes a [`IntegerList`] into a sequence of bytes. + pub fn to_bytes(&self) -> Vec { + let mut vec = Vec::with_capacity(self.0.serialized_size()); + self.0.serialize_into(&mut vec).expect("not able to encode IntegerList"); + vec + } + + /// Serializes a [`IntegerList`] into a sequence of bytes. + pub fn to_mut_bytes(&self, buf: &mut B) { + self.0.serialize_into(buf.writer()).unwrap(); + } + + /// Deserializes a sequence of bytes into a proper [`IntegerList`]. + pub fn from_bytes(data: &[u8]) -> Result { + RoaringTreemap::deserialize_from(data) + .map(Self) + .map_err(|_| IntegerListError::FailedToDeserialize) + } +} + +impl serde::Serialize for IntegerList { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + use serde::ser::SerializeSeq; + + let mut seq = serializer.serialize_seq(Some(self.len() as usize))?; + for e in &self.0 { + seq.serialize_element(&e)?; + } + seq.end() + } +} + +struct IntegerListVisitor; + +impl<'de> serde::de::Visitor<'de> for IntegerListVisitor { + type Value = IntegerList; + + fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("a usize array") + } + + fn visit_seq(self, mut seq: E) -> Result + where + E: serde::de::SeqAccess<'de>, + { + let mut list = IntegerList::empty(); + while let Some(item) = seq.next_element()? { + list.push(item).map_err(serde::de::Error::custom)?; + } + Ok(list) + } +} + +impl<'de> serde::Deserialize<'de> for IntegerList { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + deserializer.deserialize_byte_buf(IntegerListVisitor) + } +} + +#[cfg(any(test, feature = "arbitrary"))] +use arbitrary::{Arbitrary, Unstructured}; + +#[cfg(any(test, feature = "arbitrary"))] +impl<'a> Arbitrary<'a> for IntegerList { + fn arbitrary(u: &mut Unstructured<'a>) -> Result { + let mut nums: Vec = Vec::arbitrary(u)?; + nums.sort_unstable(); + Self::new(nums).map_err(|_| arbitrary::Error::IncorrectFormat) + } +} + +/// Primitives error type. +#[derive(Debug, derive_more::Display, derive_more::Error)] +pub enum IntegerListError { + /// The provided input is unsorted. + #[display("the provided input is unsorted")] + UnsortedInput, + /// Failed to deserialize data into type. + #[display("failed to deserialize data into type")] + FailedToDeserialize, +} impl Compress for IntegerList { type Compressed = Vec; @@ -23,3 +175,30 @@ impl Decompress for IntegerList { Self::from_bytes(value).map_err(|_| DatabaseError::Decode) } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn empty_list() { + assert_eq!(IntegerList::empty().len(), 0); + assert_eq!(IntegerList::new_pre_sorted(std::iter::empty()).len(), 0); + } + + #[test] + fn test_integer_list() { + let original_list = [1, 2, 3]; + let ef_list = IntegerList::new(original_list).unwrap(); + assert_eq!(ef_list.iter().collect::>(), original_list); + } + + #[test] + fn test_integer_list_serialization() { + let original_list = [1, 2, 3]; + let ef_list = IntegerList::new(original_list).unwrap(); + + let blist = ef_list.to_bytes(); + assert_eq!(IntegerList::from_bytes(&blist).unwrap(), ef_list) + } +} diff --git a/crates/storage/db-api/src/models/mod.rs b/crates/storage/db-api/src/models/mod.rs index 614dc598bdb7..0a008bb88a5f 100644 --- a/crates/storage/db-api/src/models/mod.rs +++ b/crates/storage/db-api/src/models/mod.rs @@ -8,9 +8,8 @@ use alloy_consensus::Header; use alloy_genesis::GenesisAccount; use alloy_primitives::{Address, Bytes, Log, B256, U256}; use reth_codecs::{add_arbitrary_tests, Compact}; -use reth_primitives::{ - Account, Bytecode, Receipt, StorageEntry, TransactionSigned, TransactionSignedNoHash, TxType, -}; +use reth_primitives::{Receipt, StorageEntry, TransactionSigned, TransactionSignedNoHash, TxType}; +use reth_primitives_traits::{Account, Bytecode}; use reth_prune_types::{PruneCheckpoint, PruneSegment}; use reth_stages_types::StageCheckpoint; use reth_trie_common::{StoredNibbles, StoredNibblesSubKey, *}; @@ -24,6 +23,7 @@ pub mod storage_sharded_key; pub use accounts::*; pub use blocks::*; +pub use integer_list::IntegerList; pub use reth_db_models::{ AccountBeforeTx, ClientVersion, StoredBlockBodyIndices, StoredBlockWithdrawals, }; diff --git a/crates/storage/db-common/src/init.rs b/crates/storage/db-common/src/init.rs index d738aaec4399..493b27be7808 100644 --- a/crates/storage/db-common/src/init.rs +++ b/crates/storage/db-common/src/init.rs @@ -609,12 +609,11 @@ mod tests { use reth_db::DatabaseEnv; use reth_db_api::{ cursor::DbCursorRO, - models::{storage_sharded_key::StorageShardedKey, ShardedKey}, + models::{storage_sharded_key::StorageShardedKey, IntegerList, ShardedKey}, table::{Table, TableRow}, transaction::DbTx, Database, }; - use reth_primitives_traits::IntegerList; use reth_provider::{ test_utils::{create_test_provider_factory_with_chain_spec, MockNodeTypesWithDB}, ProviderFactory, diff --git a/crates/storage/db/src/implementation/mdbx/mod.rs b/crates/storage/db/src/implementation/mdbx/mod.rs index 006213e4cb91..8a6811b15391 100644 --- a/crates/storage/db/src/implementation/mdbx/mod.rs +++ b/crates/storage/db/src/implementation/mdbx/mod.rs @@ -507,12 +507,11 @@ mod tests { use alloy_primitives::{Address, B256, U256}; use reth_db_api::{ cursor::{DbDupCursorRO, DbDupCursorRW, ReverseWalker, Walker}, - models::{AccountBeforeTx, ShardedKey}, + models::{AccountBeforeTx, IntegerList, ShardedKey}, table::{Encode, Table}, }; use reth_libmdbx::Error; - use reth_primitives::{Account, StorageEntry}; - use reth_primitives_traits::IntegerList; + use reth_primitives_traits::{Account, StorageEntry}; use reth_storage_errors::db::{DatabaseWriteError, DatabaseWriteOperation}; use std::str::FromStr; use tempfile::TempDir; diff --git a/crates/storage/db/src/tables/codecs/fuzz/inputs.rs b/crates/storage/db/src/tables/codecs/fuzz/inputs.rs index bb26e8b9e217..da15c112e628 100644 --- a/crates/storage/db/src/tables/codecs/fuzz/inputs.rs +++ b/crates/storage/db/src/tables/codecs/fuzz/inputs.rs @@ -1,6 +1,6 @@ //! Curates the input coming from the fuzzer for certain types. -use reth_primitives_traits::IntegerList; +use reth_db_api::models::IntegerList; use serde::{Deserialize, Serialize}; /// Makes sure that the list provided by the fuzzer is not empty and pre-sorted diff --git a/crates/storage/db/src/tables/codecs/fuzz/mod.rs b/crates/storage/db/src/tables/codecs/fuzz/mod.rs index e64a3841df49..f6b68897e349 100644 --- a/crates/storage/db/src/tables/codecs/fuzz/mod.rs +++ b/crates/storage/db/src/tables/codecs/fuzz/mod.rs @@ -16,9 +16,6 @@ macro_rules! impl_fuzzer_with_input { pub mod $name { use reth_db_api::table; - #[allow(unused_imports)] - - #[allow(unused_imports)] use reth_primitives_traits::*; diff --git a/crates/storage/db/src/tables/mod.rs b/crates/storage/db/src/tables/mod.rs index 940bb3aa2596..9ff21261eee5 100644 --- a/crates/storage/db/src/tables/mod.rs +++ b/crates/storage/db/src/tables/mod.rs @@ -26,13 +26,13 @@ use reth_db_api::{ accounts::BlockNumberAddress, blocks::{HeaderHash, StoredBlockOmmers}, storage_sharded_key::StorageShardedKey, - AccountBeforeTx, ClientVersion, CompactU256, ShardedKey, StoredBlockBodyIndices, - StoredBlockWithdrawals, + AccountBeforeTx, ClientVersion, CompactU256, IntegerList, ShardedKey, + StoredBlockBodyIndices, StoredBlockWithdrawals, }, table::{Decode, DupSort, Encode, Table}, }; -use reth_primitives::{Account, Bytecode, Receipt, StorageEntry, TransactionSignedNoHash}; -use reth_primitives_traits::IntegerList; +use reth_primitives::{Receipt, StorageEntry, TransactionSignedNoHash}; +use reth_primitives_traits::{Account, Bytecode}; use reth_prune_types::{PruneCheckpoint, PruneSegment}; use reth_stages_types::StageCheckpoint; use reth_trie_common::{BranchNodeCompact, StorageTrieEntry, StoredNibbles, StoredNibblesSubKey}; diff --git a/crates/storage/libmdbx-rs/Cargo.toml b/crates/storage/libmdbx-rs/Cargo.toml index fa10a73cb330..4679f4fe9149 100644 --- a/crates/storage/libmdbx-rs/Cargo.toml +++ b/crates/storage/libmdbx-rs/Cargo.toml @@ -15,7 +15,7 @@ workspace = true reth-mdbx-sys.workspace = true bitflags.workspace = true -byteorder = "1" +byteorder.workspace = true derive_more.workspace = true indexmap = "2" parking_lot.workspace = true From 30800af6ec81521625db40cd6d3881f0e2d3f9e6 Mon Sep 17 00:00:00 2001 From: Hai | RISE <150876604+hai-rise@users.noreply.github.com> Date: Mon, 2 Dec 2024 23:28:47 +0700 Subject: [PATCH 20/68] perf(validate-tx-pool): fast non-allocating `is_create` (#13063) --- crates/transaction-pool/src/test_utils/mock.rs | 10 ++++++++++ crates/transaction-pool/src/traits.rs | 12 +++++++++++- crates/transaction-pool/src/validate/eth.rs | 2 +- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/crates/transaction-pool/src/test_utils/mock.rs b/crates/transaction-pool/src/test_utils/mock.rs index afa1638c8516..78982cb46575 100644 --- a/crates/transaction-pool/src/test_utils/mock.rs +++ b/crates/transaction-pool/src/test_utils/mock.rs @@ -719,6 +719,16 @@ impl PoolTransaction for MockTransaction { } } + /// Returns true if the transaction is a contract creation. + fn is_create(&self) -> bool { + match self { + Self::Legacy { to, .. } | Self::Eip1559 { to, .. } | Self::Eip2930 { to, .. } => { + to.is_create() + } + Self::Eip4844 { .. } => false, + } + } + /// Returns the input data associated with the transaction. fn input(&self) -> &[u8] { self.get_input() diff --git a/crates/transaction-pool/src/traits.rs b/crates/transaction-pool/src/traits.rs index 6adb81729e17..11c8db225b0a 100644 --- a/crates/transaction-pool/src/traits.rs +++ b/crates/transaction-pool/src/traits.rs @@ -1061,6 +1061,11 @@ pub trait PoolTransaction: fmt::Debug + Send + Sync + Clone { /// [`TxKind::Create`] if the transaction is a contract creation. fn kind(&self) -> TxKind; + /// Returns true if the transaction is a contract creation. + /// We don't provide a default implementation via `kind` as it copies the 21-byte + /// [`TxKind`] for this simple check. A proper implementation shouldn't allocate. + fn is_create(&self) -> bool; + /// Returns the recipient of the transaction if it is not a [`TxKind::Create`] /// transaction. fn to(&self) -> Option
{ @@ -1109,7 +1114,7 @@ pub trait PoolTransaction: fmt::Debug + Send + Sync + Clone { &self, max_init_code_size: usize, ) -> Result<(), InvalidPoolTransactionError> { - if self.kind().is_create() && self.input().len() > max_init_code_size { + if self.is_create() && self.input().len() > max_init_code_size { Err(InvalidPoolTransactionError::ExceedsMaxInitCodeSize( self.size(), max_init_code_size, @@ -1328,6 +1333,11 @@ impl PoolTransaction for EthPooledTransaction { self.transaction.kind() } + /// Returns true if the transaction is a contract creation. + fn is_create(&self) -> bool { + self.transaction.is_create() + } + fn input(&self) -> &[u8] { self.transaction.input() } diff --git a/crates/transaction-pool/src/validate/eth.rs b/crates/transaction-pool/src/validate/eth.rs index ca7452225755..5249c1befa2c 100644 --- a/crates/transaction-pool/src/validate/eth.rs +++ b/crates/transaction-pool/src/validate/eth.rs @@ -815,7 +815,7 @@ pub fn ensure_intrinsic_gas( let gas_after_merge = validate_initial_tx_gas( spec_id, transaction.input(), - transaction.kind().is_create(), + transaction.is_create(), transaction.access_list().map(|list| list.0.as_slice()).unwrap_or(&[]), transaction.authorization_count() as u64, ); From aacf5d13d29d32fef3163f93763c686efbcabbad Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Mon, 2 Dec 2024 18:03:33 +0100 Subject: [PATCH 21/68] chore: disable more default features (#13065) --- .github/assets/check_rv32imac.sh | 2 +- Cargo.toml | 4 ++-- crates/chainspec/Cargo.toml | 3 ++- crates/consensus/consensus/Cargo.toml | 3 ++- crates/evm/execution-errors/Cargo.toml | 3 ++- crates/net/p2p/Cargo.toml | 3 ++- crates/optimism/chainspec/Cargo.toml | 23 ++++++++++++----------- crates/optimism/evm/Cargo.toml | 3 ++- crates/optimism/primitives/Cargo.toml | 2 ++ crates/primitives-traits/Cargo.toml | 4 +++- crates/primitives/Cargo.toml | 4 +++- crates/storage/errors/Cargo.toml | 3 ++- 12 files changed, 35 insertions(+), 22 deletions(-) diff --git a/.github/assets/check_rv32imac.sh b/.github/assets/check_rv32imac.sh index 9a66da9fe3b3..9032c05b9d6f 100755 --- a/.github/assets/check_rv32imac.sh +++ b/.github/assets/check_rv32imac.sh @@ -5,9 +5,9 @@ set +e # Disable immediate exit on error crates_to_check=( reth-codecs-derive reth-ethereum-forks + reth-primitives-traits # reth-evm # reth-primitives - # reth-primitives-traits # reth-optimism-forks # reth-optimism-chainspec ) diff --git a/Cargo.toml b/Cargo.toml index 521cfd88f8a9..dcb5510e79f8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -485,12 +485,12 @@ backon = { version = "1.2", default-features = false, features = [ bincode = "1.3" bitflags = "2.4" boyer-moore-magiclen = "0.2.16" -bytes = "1.5" +bytes = { version = "1.5", default-features = false } cfg-if = "1.0" clap = "4" const_format = { version = "0.2.32", features = ["rust_1_64"] } dashmap = "6.0" -derive_more = { version = "1", features = ["full"] } +derive_more = { version = "1", default-features = false, features = ["full"] } dyn-clone = "1.0.17" eyre = "0.6" fdlimit = "0.3.0" diff --git a/crates/chainspec/Cargo.toml b/crates/chainspec/Cargo.toml index e5f6c058c622..67968ee0a88c 100644 --- a/crates/chainspec/Cargo.toml +++ b/crates/chainspec/Cargo.toml @@ -49,7 +49,8 @@ std = [ "alloy-consensus/std", "once_cell/std", "alloy-rlp/std", - "reth-ethereum-forks/std" + "reth-ethereum-forks/std", + "derive_more/std" ] arbitrary = [ "alloy-chains/arbitrary", diff --git a/crates/consensus/consensus/Cargo.toml b/crates/consensus/consensus/Cargo.toml index 55188dd8472b..36356a4de369 100644 --- a/crates/consensus/consensus/Cargo.toml +++ b/crates/consensus/consensus/Cargo.toml @@ -32,7 +32,8 @@ std = [ "alloy-primitives/std", "alloy-eips/std", "alloy-consensus/std", - "reth-primitives-traits/std" + "reth-primitives-traits/std", + "derive_more/std" ] test-utils = [ "reth-primitives/test-utils", diff --git a/crates/evm/execution-errors/Cargo.toml b/crates/evm/execution-errors/Cargo.toml index 3368eb065030..01727cd70b5c 100644 --- a/crates/evm/execution-errors/Cargo.toml +++ b/crates/evm/execution-errors/Cargo.toml @@ -31,5 +31,6 @@ std = [ "alloy-eips/std", "alloy-primitives/std", "revm-primitives/std", - "alloy-rlp/std" + "alloy-rlp/std", + "derive_more/std" ] diff --git a/crates/net/p2p/Cargo.toml b/crates/net/p2p/Cargo.toml index 9348bf2d0413..a72110647c46 100644 --- a/crates/net/p2p/Cargo.toml +++ b/crates/net/p2p/Cargo.toml @@ -57,5 +57,6 @@ std = [ "alloy-eips/std", "alloy-primitives/std", "reth-primitives-traits/std", - "alloy-consensus/std", + "alloy-consensus/std", + "derive_more/std" ] diff --git a/crates/optimism/chainspec/Cargo.toml b/crates/optimism/chainspec/Cargo.toml index 4e573ce29946..7f74156b885c 100644 --- a/crates/optimism/chainspec/Cargo.toml +++ b/crates/optimism/chainspec/Cargo.toml @@ -46,15 +46,16 @@ op-alloy-rpc-types.workspace = true [features] default = ["std"] std = [ - "alloy-chains/std", - "alloy-genesis/std", - "alloy-primitives/std", - "alloy-eips/std", - "op-alloy-rpc-types/std", - "reth-chainspec/std", - "reth-ethereum-forks/std", - "reth-primitives-traits/std", - "reth-optimism-forks/std", - "alloy-consensus/std", - "once_cell/std", + "alloy-chains/std", + "alloy-genesis/std", + "alloy-primitives/std", + "alloy-eips/std", + "op-alloy-rpc-types/std", + "reth-chainspec/std", + "reth-ethereum-forks/std", + "reth-primitives-traits/std", + "reth-optimism-forks/std", + "alloy-consensus/std", + "once_cell/std", + "derive_more/std" ] diff --git a/crates/optimism/evm/Cargo.toml b/crates/optimism/evm/Cargo.toml index 149aa2e953bf..c640b130841e 100644 --- a/crates/optimism/evm/Cargo.toml +++ b/crates/optimism/evm/Cargo.toml @@ -64,7 +64,8 @@ std = [ "alloy-primitives/std", "revm-primitives/std", "revm/std", - "reth-ethereum-forks/std" + "reth-ethereum-forks/std", + "derive_more/std" ] optimism = [ "reth-primitives/optimism", diff --git a/crates/optimism/primitives/Cargo.toml b/crates/optimism/primitives/Cargo.toml index 075cd0d13f4f..9f370511d491 100644 --- a/crates/optimism/primitives/Cargo.toml +++ b/crates/optimism/primitives/Cargo.toml @@ -50,6 +50,8 @@ std = [ "alloy-eips/std", "alloy-primitives/std", "serde/std", + "bytes/std", + "derive_more/std" ] reth-codec = [ "dep:reth-codecs", diff --git a/crates/primitives-traits/Cargo.toml b/crates/primitives-traits/Cargo.toml index 9265c878d6cb..459fdbde1a70 100644 --- a/crates/primitives-traits/Cargo.toml +++ b/crates/primitives-traits/Cargo.toml @@ -65,7 +65,9 @@ std = [ "revm-primitives/std", "serde?/std", "serde_with?/std", - "alloy-rlp/std" + "alloy-rlp/std", + "bytes/std", + "derive_more/std" ] test-utils = [ "arbitrary", diff --git a/crates/primitives/Cargo.toml b/crates/primitives/Cargo.toml index 80299a06db60..3bfaefb39ede 100644 --- a/crates/primitives/Cargo.toml +++ b/crates/primitives/Cargo.toml @@ -106,7 +106,9 @@ std = [ "alloy-trie/std", "serde_with?/std", "alloy-rlp/std", - "reth-ethereum-forks/std" + "reth-ethereum-forks/std", + "bytes/std", + "derive_more/std" ] reth-codec = [ "dep:reth-codecs", diff --git a/crates/storage/errors/Cargo.toml b/crates/storage/errors/Cargo.toml index 9a31177662f7..0f2cf03f6521 100644 --- a/crates/storage/errors/Cargo.toml +++ b/crates/storage/errors/Cargo.toml @@ -29,5 +29,6 @@ std = [ "reth-primitives/std", "alloy-eips/std", "alloy-primitives/std", - "alloy-rlp/std" + "alloy-rlp/std", + "derive_more/std" ] From 675410def1b85e1938e62d088d6952d4e647389d Mon Sep 17 00:00:00 2001 From: Darshan Kathiriya <8559992+lakshya-sky@users.noreply.github.com> Date: Mon, 2 Dec 2024 12:10:27 -0500 Subject: [PATCH 22/68] add replace and remove methods (#13059) Co-authored-by: dkathiriya --- crates/rpc/rpc-builder/src/auth.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/crates/rpc/rpc-builder/src/auth.rs b/crates/rpc/rpc-builder/src/auth.rs index 25626e4f12d3..f22fd554ca6d 100644 --- a/crates/rpc/rpc-builder/src/auth.rs +++ b/crates/rpc/rpc-builder/src/auth.rs @@ -221,6 +221,30 @@ impl AuthRpcModule { self.module_mut().merge(other.into()).map(|_| true) } + /// Removes the method with the given name from the configured authenticated methods. + /// + /// Returns `true` if the method was found and removed, `false` otherwise. + pub fn remove_auth_method(&mut self, method_name: &'static str) -> bool { + self.module_mut().remove_method(method_name).is_some() + } + + /// Removes the given methods from the configured authenticated methods. + pub fn remove_auth_methods(&mut self, methods: impl IntoIterator) { + for name in methods { + self.remove_auth_method(name); + } + } + + /// Replace the given [Methods] in the configured authenticated methods. + pub fn replace_auth_methods( + &mut self, + other: impl Into, + ) -> Result { + let other = other.into(); + self.remove_auth_methods(other.method_names()); + self.merge_auth_methods(other) + } + /// Convenience function for starting a server pub async fn start_server( self, From c61a0713b44c9566c4e8157ea1e27d98756d79fb Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Mon, 2 Dec 2024 22:34:13 +0400 Subject: [PATCH 23/68] feat: bump alloy (#13070) --- Cargo.lock | 166 +++++++++++++++---------------- Cargo.toml | 64 ++++++------ crates/rpc/rpc/src/eth/bundle.rs | 1 + 3 files changed, 116 insertions(+), 115 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b39cd76e09be..66cd14d1e2a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -112,9 +112,9 @@ dependencies = [ [[package]] name = "alloy-consensus" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a1ff8439834ab71a4b0ecd1a8ff80b3921c87615f158940c3364f399c732786" +checksum = "73dd0ab7003dfa3efd252e423873cd3bc241d1456147e752f995cc8aabd1d1f6" dependencies = [ "alloy-eips", "alloy-primitives", @@ -132,9 +132,9 @@ dependencies = [ [[package]] name = "alloy-consensus-any" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "519a86faaa6729464365a90c04eba68539b6d3a30f426edb4b3dafd78920d42f" +checksum = "d08234c0eece0e08602db5095a16dc942cad91967cccfcfc2c6a42c25563964f" dependencies = [ "alloy-consensus", "alloy-eips", @@ -146,9 +146,9 @@ dependencies = [ [[package]] name = "alloy-contract" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cca2b353d8b7f160dc930dfa174557acefece6deab5ecd7e6230d38858579eea" +checksum = "6a01f5593f6878452c6dde102ece391b60cba79801c5f606f8fe898ff57cd5d7" dependencies = [ "alloy-dyn-abi", "alloy-json-abi", @@ -161,7 +161,7 @@ dependencies = [ "alloy-transport", "futures", "futures-util", - "thiserror 1.0.69", + "thiserror 2.0.3", ] [[package]] @@ -213,9 +213,9 @@ dependencies = [ [[package]] name = "alloy-eips" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dedb328c2114284f767e075589ca9de8d5e9c8a91333402f4804a584ed71a38" +checksum = "50c242de43a1869bcb2fbce3b377130959d10dfd562b87ac7aa2f04d98baac51" dependencies = [ "alloy-eip2930", "alloy-eip7702", @@ -234,9 +234,9 @@ dependencies = [ [[package]] name = "alloy-genesis" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4841e8dd4e0f53d76b501fd4c6bc21d95d688bc8ebf0ea359fc6c7ab65b48742" +checksum = "9dd39b72f860cb0c542fac925f91d1939c2b14a0970b39d0ae304b5b7574a0ac" dependencies = [ "alloy-primitives", "alloy-serde", @@ -257,23 +257,23 @@ dependencies = [ [[package]] name = "alloy-json-rpc" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "254f770918f96dc4ec88a15e6e2e243358e1719d66b40ef814428e7697079d25" +checksum = "6c15c11661571a19a06896663c93e804ccf013159275a89a98e892014df514d8" dependencies = [ "alloy-primitives", "alloy-sol-types", "serde", "serde_json", - "thiserror 1.0.69", + "thiserror 2.0.3", "tracing", ] [[package]] name = "alloy-network" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "931dd176c6e33355f3dc0170ec69cf5b951f4d73870b276e2c837ab35f9c5136" +checksum = "60dd0b99eaa5e715dd90d42021f7f08a0a70976ea84f41a0ad233770e0c1962b" dependencies = [ "alloy-consensus", "alloy-consensus-any", @@ -291,14 +291,14 @@ dependencies = [ "futures-utils-wasm", "serde", "serde_json", - "thiserror 1.0.69", + "thiserror 2.0.3", ] [[package]] name = "alloy-network-primitives" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa6ec0f23be233e851e31c5e4badfedfa9c7bc177bc37f4e03616072cd40a806" +checksum = "18abfc73ce48f074c8bc6e05c1f08ef0b1ddc9b04f191a821d0beb9470a42a29" dependencies = [ "alloy-consensus", "alloy-eips", @@ -309,9 +309,9 @@ dependencies = [ [[package]] name = "alloy-node-bindings" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bce85f0f67b2248c2eb42941bb75079ac53648569a668e8bfd7de5a831ec64" +checksum = "f9a04cf8f3a19b024b2bc71b5774d423cd2edda7f67df6029daa1368c5c02da5" dependencies = [ "alloy-genesis", "alloy-primitives", @@ -319,7 +319,7 @@ dependencies = [ "rand 0.8.5", "serde_json", "tempfile", - "thiserror 1.0.69", + "thiserror 2.0.3", "tracing", "url", ] @@ -358,9 +358,9 @@ dependencies = [ [[package]] name = "alloy-provider" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5545e2cbf2f8f24c68bb887ba0294fa12a2f816b9e72c4f226cd137b77d0e294" +checksum = "4933c761f10e44d5e901804b56efb2ce6e0945e6c57d2fa1e5ace303fae6f74a" dependencies = [ "alloy-chains", "alloy-consensus", @@ -390,7 +390,7 @@ dependencies = [ "schnellru", "serde", "serde_json", - "thiserror 1.0.69", + "thiserror 2.0.3", "tokio", "tracing", "url", @@ -399,9 +399,9 @@ dependencies = [ [[package]] name = "alloy-pubsub" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b633f7731a3df2f4f334001bf80436565113816c5aa5c136c1ded563051e049b" +checksum = "808719714bfb2aa24b0eb2a38411ce8e654ba11c0ebf2a6648fcbe9fabfe696d" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -440,9 +440,9 @@ dependencies = [ [[package]] name = "alloy-rpc-client" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aed9e40c2a73265ebf70f1e48303ee55920282e1ea5971e832873fb2d32cea74" +checksum = "6ce26c25efb8290b6ba559ae6c40bf6630d337e107ae242e5790501420dba7b7" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -465,9 +465,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42dea20fa715a6f39ec7adc735cfd9567342870737270ac67795d55896527772" +checksum = "41080ce2640928f0df45c41d2af629b88db3cb31af3abbe614964ae10001ddac" dependencies = [ "alloy-primitives", "alloy-rpc-types-engine", @@ -478,9 +478,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-admin" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9eab93eabf53697b4b9095c0f9203fca3702e78d083c77a5c677bdc02bebab8" +checksum = "db981579da4d597d9d35f56ad7641b929bf8f551ab696715132f554863c83540" dependencies = [ "alloy-genesis", "alloy-primitives", @@ -490,9 +490,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-anvil" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2750f4f694b27461915b9794df60177198bf733da38dde71aadfbe2946a3c0be" +checksum = "252b7433e731e5d24f7eb7a54a368bc813a1086aaf84643ab10e99599a6ff16c" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", @@ -502,11 +502,10 @@ dependencies = [ [[package]] name = "alloy-rpc-types-any" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79d7620e22d6ed7c58451dd303d0501ade5a8bec9dc8daef0fbc48ceffabbae1" +checksum = "abca110e59f760259e26d0c84912121468008aba48dd227af0f306cfd7bce9ae" dependencies = [ - "alloy-consensus", "alloy-consensus-any", "alloy-rpc-types-eth", "alloy-serde", @@ -514,9 +513,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-beacon" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdbfc1b5ee81b1ef6d5e770f3bd6018eab66c7ac2ee1e897f88973b327e2fc20" +checksum = "45c8db5fb70d2fece7bc1cd5adf42e72fc8a23547adeff8f558d9063f1e7788c" dependencies = [ "alloy-eips", "alloy-primitives", @@ -524,14 +523,14 @@ dependencies = [ "alloy-serde", "serde", "serde_with", - "thiserror 1.0.69", + "thiserror 2.0.3", ] [[package]] name = "alloy-rpc-types-debug" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d2d4a265fb1198272cc43d8d418c0423cdfc1aebcd283be9105464874a1dda" +checksum = "ea3a662ced0bfbe582d26ed85d6a0092310787331555c8f7a86f843c7ca272ef" dependencies = [ "alloy-primitives", "serde", @@ -539,9 +538,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-engine" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb843daa6feb011475f0db8c499fff5ac62e1e6012fc01d97477ddb3217a83f" +checksum = "d3b000c7f3469e7faa575ba70207294cf07e91dfd6ce4d04d5d5d8069f974a66" dependencies = [ "alloy-consensus", "alloy-eips", @@ -560,9 +559,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-eth" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df34b88df4deeac9ecfc80ad7cbb26a33e57437b9db8be5b952792feef6134bc" +checksum = "3468e7385fbb86b0fde5497d685c02f765ea09d36f7e07c5d1c9a52b077d38e2" dependencies = [ "alloy-consensus", "alloy-consensus-any", @@ -582,12 +581,13 @@ dependencies = [ [[package]] name = "alloy-rpc-types-mev" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be601847f0b13112249ed577eaa7501755e7dd3df7b037088f8b8236a4602d59" +checksum = "26988fb56d87414c96b8fd9b69ad6ce3768bc9acc953ed02c18a66f74ab98c66" dependencies = [ "alloy-eips", "alloy-primitives", + "alloy-rpc-types-eth", "alloy-serde", "serde", "serde_json", @@ -595,23 +595,23 @@ dependencies = [ [[package]] name = "alloy-rpc-types-trace" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db32f30a55ea4fa9d893127a84eef52fc54d23acb34c1a5a39bfe9bd95fbc149" +checksum = "7a90be1bc8e3659db1c9512191873a268a917efbc62b8bd39a92c12bf613b193" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", "alloy-serde", "serde", "serde_json", - "thiserror 1.0.69", + "thiserror 2.0.3", ] [[package]] name = "alloy-rpc-types-txpool" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af1588d8d799095a9bd55d9045b76add042ab725c37316a77da933683754aa4b" +checksum = "beade2858d292442f5be6fce452c923072a7ac4d3898d333abf42703945444d0" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", @@ -621,9 +621,9 @@ dependencies = [ [[package]] name = "alloy-serde" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a89fd4cc3f96b3c5c0dd1cebeb63323e4659bbdc837117fa3fd5ac168df7d9" +checksum = "42de6002e2154b50b3568aea27e26bd9caf7b754658f43065f2e9b6ee0a8c839" dependencies = [ "alloy-primitives", "arbitrary", @@ -633,23 +633,23 @@ dependencies = [ [[package]] name = "alloy-signer" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "532010243a96d1f8593c2246ec3971bc52303884fa1e43ca0a776798ba178910" +checksum = "f288a9a25e2578dab17845fd8d2be1d32de33565783ed185ded161a65f92381b" dependencies = [ "alloy-primitives", "async-trait", "auto_impl", "elliptic-curve", "k256", - "thiserror 1.0.69", + "thiserror 2.0.3", ] [[package]] name = "alloy-signer-local" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8080c0ab2dc729b0cbb183843d08e78d2a1629140c9fc16234d2272abb483bd" +checksum = "0d8081f589ddc11a959605e30c723d51cad2562d9072305f8e3ef311f077e5eb" dependencies = [ "alloy-consensus", "alloy-network", @@ -660,7 +660,7 @@ dependencies = [ "coins-bip39", "k256", "rand 0.8.5", - "thiserror 1.0.69", + "thiserror 2.0.3", ] [[package]] @@ -735,9 +735,9 @@ dependencies = [ [[package]] name = "alloy-transport" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6f295f4b745fb9e4e663d70bc57aed991288912c7aaaf25767def921050ee43" +checksum = "90352f4cf78017905c3244f48b38fadc345970bbc9095087c0f985a580550488" dependencies = [ "alloy-json-rpc", "base64 0.22.1", @@ -745,7 +745,7 @@ dependencies = [ "futures-utils-wasm", "serde", "serde_json", - "thiserror 1.0.69", + "thiserror 2.0.3", "tokio", "tower 0.5.1", "tracing", @@ -755,9 +755,9 @@ dependencies = [ [[package]] name = "alloy-transport-http" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39139015a5ec127d9c895b49b484608e27fe4538544f84cdf5eae0bd36339bc6" +checksum = "7d26c94d51fa8b1aee3d15db113dd0773776c02bb36dbaa2590b900dadd7e7d0" dependencies = [ "alloy-json-rpc", "alloy-transport", @@ -770,9 +770,9 @@ dependencies = [ [[package]] name = "alloy-transport-ipc" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b4f865b13bb8648e93f812b19b74838b9165212a2beb95fc386188c443a5e3" +checksum = "14c498fcdec50650be6b6a22ce7928a1b2738086b4f94f31b132e83498d45bbb" dependencies = [ "alloy-json-rpc", "alloy-pubsub", @@ -789,9 +789,9 @@ dependencies = [ [[package]] name = "alloy-transport-ws" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6af91e3521b8b3eac26809b1c6f9b86e3ed455dfab812f036836aabdf709b921" +checksum = "cd7b21335b55c9f715e2acca0228dc1d6880d961756916c13a9ce70f9f413e70" dependencies = [ "alloy-pubsub", "alloy-transport", @@ -5329,9 +5329,9 @@ checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" [[package]] name = "op-alloy-consensus" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75353c94e7515fac7d3c280bae56bff3375784a05cb44b317260606292ff6ba9" +checksum = "77284451ec70602f148f4f3bc6d1106fdfefd57c11ff459c4b2985e400ed1a18" dependencies = [ "alloy-consensus", "alloy-eips", @@ -5347,9 +5347,9 @@ dependencies = [ [[package]] name = "op-alloy-genesis" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f24feef0404861c836b8fc0a3eb0cf6f20507e63ab59a61eeb1491c0f57bc352" +checksum = "c912ec93ec839076e8bbaaf7bd3d80aeedbe38cd5e8e3e76dfc67d217637e651" dependencies = [ "alloy-consensus", "alloy-eips", @@ -5362,9 +5362,9 @@ dependencies = [ [[package]] name = "op-alloy-network" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dda5a5c4bc786f35f6c53ba611863a889790cc40a07c8160465072026795cba" +checksum = "bef4620ba6309ecc18e1aaa339836ca839b001a420ca245add040a3bde1ae9b1" dependencies = [ "alloy-consensus", "alloy-network", @@ -5377,9 +5377,9 @@ dependencies = [ [[package]] name = "op-alloy-protocol" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2ab185601941f4ed04418d71e42b220a9c59353c8fb98ba8993c42590c6742" +checksum = "9ab24c1b9c21cedd691938b5667c951b04ae8b89429d7cb7a88f30afb79cbbf1" dependencies = [ "alloc-no-stdlib", "alloy-consensus", @@ -5401,9 +5401,9 @@ dependencies = [ [[package]] name = "op-alloy-rpc-types" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "680a86b63fe4c45fbd5dbf1ac6779409565211c4b234d20af94cf1f79d11f23a" +checksum = "2bdc32eba4d43bbd23f1f16dece7afd991d41ab4ffc2494a72b048e9f38db622" dependencies = [ "alloy-consensus", "alloy-eips", @@ -5420,9 +5420,9 @@ dependencies = [ [[package]] name = "op-alloy-rpc-types-engine" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeff9cf6fcdf8ef7183f254f9ad59b6e87af5084f21dfa17ba00c4448a84ddf1" +checksum = "b07175fcfd9d03a587ece7ce79fc288331e6d9ae523464eb677c751d5737713b" dependencies = [ "alloy-eips", "alloy-primitives", diff --git a/Cargo.toml b/Cargo.toml index dcb5510e79f8..75feb6636c48 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -434,46 +434,46 @@ alloy-rlp = { version = "0.3.4", default-features = false } alloy-sol-types = "0.8.11" alloy-trie = { version = "0.7", default-features = false } -alloy-consensus = { version = "0.7.0", default-features = false } -alloy-contract = { version = "0.7.0", default-features = false } -alloy-eips = { version = "0.7.0", default-features = false } -alloy-genesis = { version = "0.7.0", default-features = false } -alloy-json-rpc = { version = "0.7.0", default-features = false } -alloy-network = { version = "0.7.0", default-features = false } -alloy-network-primitives = { version = "0.7.0", default-features = false } -alloy-node-bindings = { version = "0.7.0", default-features = false } -alloy-provider = { version = "0.7.0", features = [ +alloy-consensus = { version = "0.7.2", default-features = false } +alloy-contract = { version = "0.7.2", default-features = false } +alloy-eips = { version = "0.7.2", default-features = false } +alloy-genesis = { version = "0.7.2", default-features = false } +alloy-json-rpc = { version = "0.7.2", default-features = false } +alloy-network = { version = "0.7.2", default-features = false } +alloy-network-primitives = { version = "0.7.2", default-features = false } +alloy-node-bindings = { version = "0.7.2", default-features = false } +alloy-provider = { version = "0.7.2", features = [ "reqwest", ], default-features = false } -alloy-pubsub = { version = "0.7.0", default-features = false } -alloy-rpc-client = { version = "0.7.0", default-features = false } -alloy-rpc-types = { version = "0.7.0", features = [ +alloy-pubsub = { version = "0.7.2", default-features = false } +alloy-rpc-client = { version = "0.7.2", default-features = false } +alloy-rpc-types = { version = "0.7.2", features = [ "eth", ], default-features = false } -alloy-rpc-types-admin = { version = "0.7.0", default-features = false } -alloy-rpc-types-anvil = { version = "0.7.0", default-features = false } -alloy-rpc-types-beacon = { version = "0.7.0", default-features = false } -alloy-rpc-types-debug = { version = "0.7.0", default-features = false } -alloy-rpc-types-engine = { version = "0.7.0", default-features = false } -alloy-rpc-types-eth = { version = "0.7.0", default-features = false } -alloy-rpc-types-mev = { version = "0.7.0", default-features = false } -alloy-rpc-types-trace = { version = "0.7.0", default-features = false } -alloy-rpc-types-txpool = { version = "0.7.0", default-features = false } -alloy-serde = { version = "0.7.0", default-features = false } -alloy-signer = { version = "0.7.0", default-features = false } -alloy-signer-local = { version = "0.7.0", default-features = false } -alloy-transport = { version = "0.7.0" } -alloy-transport-http = { version = "0.7.0", features = [ +alloy-rpc-types-admin = { version = "0.7.2", default-features = false } +alloy-rpc-types-anvil = { version = "0.7.2", default-features = false } +alloy-rpc-types-beacon = { version = "0.7.2", default-features = false } +alloy-rpc-types-debug = { version = "0.7.2", default-features = false } +alloy-rpc-types-engine = { version = "0.7.2", default-features = false } +alloy-rpc-types-eth = { version = "0.7.2", default-features = false } +alloy-rpc-types-mev = { version = "0.7.2", default-features = false } +alloy-rpc-types-trace = { version = "0.7.2", default-features = false } +alloy-rpc-types-txpool = { version = "0.7.2", default-features = false } +alloy-serde = { version = "0.7.2", default-features = false } +alloy-signer = { version = "0.7.2", default-features = false } +alloy-signer-local = { version = "0.7.2", default-features = false } +alloy-transport = { version = "0.7.2" } +alloy-transport-http = { version = "0.7.2", features = [ "reqwest-rustls-tls", ], default-features = false } -alloy-transport-ipc = { version = "0.7.0", default-features = false } -alloy-transport-ws = { version = "0.7.0", default-features = false } +alloy-transport-ipc = { version = "0.7.2", default-features = false } +alloy-transport-ws = { version = "0.7.2", default-features = false } # op -op-alloy-rpc-types = "0.7.1" -op-alloy-rpc-types-engine = "0.7.1" -op-alloy-network = "0.7.1" -op-alloy-consensus = "0.7.1" +op-alloy-rpc-types = "0.7.2" +op-alloy-rpc-types-engine = "0.7.2" +op-alloy-network = "0.7.2" +op-alloy-consensus = "0.7.2" # misc aquamarine = "0.6" diff --git a/crates/rpc/rpc/src/eth/bundle.rs b/crates/rpc/rpc/src/eth/bundle.rs index a80060b3377c..3a748f529a0f 100644 --- a/crates/rpc/rpc/src/eth/bundle.rs +++ b/crates/rpc/rpc/src/eth/bundle.rs @@ -62,6 +62,7 @@ where gas_limit, difficulty, base_fee, + .. } = bundle; if txs.is_empty() { return Err(EthApiError::InvalidParams( From 6cea9955b6d510d830510c6331e1a076d70bb7e6 Mon Sep 17 00:00:00 2001 From: Minhyuk Kim Date: Mon, 2 Dec 2024 12:55:00 -0600 Subject: [PATCH 24/68] Check holocene activation based on the parent's timestamp (#13060) Co-authored-by: Matthias Seitz --- crates/optimism/chainspec/src/lib.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/crates/optimism/chainspec/src/lib.rs b/crates/optimism/chainspec/src/lib.rs index f3450e873241..a3dab80705e5 100644 --- a/crates/optimism/chainspec/src/lib.rs +++ b/crates/optimism/chainspec/src/lib.rs @@ -186,14 +186,20 @@ pub struct OpChainSpec { impl OpChainSpec { /// Read from parent to determine the base fee for the next block + /// + /// See also [Base fee computation](https://github.com/ethereum-optimism/specs/blob/main/specs/protocol/holocene/exec-engine.md#base-fee-computation) pub fn next_block_base_fee( &self, parent: &Header, timestamp: u64, ) -> Result { - let is_holocene_activated = self - .inner - .is_fork_active_at_timestamp(reth_optimism_forks::OpHardfork::Holocene, timestamp); + // > if Holocene is active in parent_header.timestamp, then the parameters from + // > parent_header.extraData are used. + let is_holocene_activated = self.inner.is_fork_active_at_timestamp( + reth_optimism_forks::OpHardfork::Holocene, + parent.timestamp, + ); + // If we are in the Holocene, we need to use the base fee params // from the parent block's extra data. // Else, use the base fee params (default values) from chainspec From 8d10b9329531bfd224000026eb4f9c3f2e990e8d Mon Sep 17 00:00:00 2001 From: Dan Cline <6798349+Rjected@users.noreply.github.com> Date: Mon, 2 Dec 2024 14:28:20 -0500 Subject: [PATCH 25/68] chore: rename codecs optimism feature to op (#13067) Co-authored-by: Matthias Seitz --- crates/consensus/beacon/Cargo.toml | 2 +- crates/optimism/primitives/Cargo.toml | 6 +++--- crates/optimism/storage/Cargo.toml | 2 +- crates/primitives/Cargo.toml | 2 +- crates/storage/codecs/Cargo.toml | 2 +- crates/storage/codecs/src/alloy/transaction/mod.rs | 10 +++++----- crates/storage/db-api/Cargo.toml | 2 +- crates/storage/provider/Cargo.toml | 2 +- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/crates/consensus/beacon/Cargo.toml b/crates/consensus/beacon/Cargo.toml index a7e326848391..b937eb2b4683 100644 --- a/crates/consensus/beacon/Cargo.toml +++ b/crates/consensus/beacon/Cargo.toml @@ -83,7 +83,7 @@ assert_matches.workspace = true [features] optimism = [ "reth-blockchain-tree/optimism", - "reth-codecs/optimism", + "reth-codecs/op", "reth-chainspec", "reth-db-api/optimism", "reth-db/optimism", diff --git a/crates/optimism/primitives/Cargo.toml b/crates/optimism/primitives/Cargo.toml index 9f370511d491..bdc423e14982 100644 --- a/crates/optimism/primitives/Cargo.toml +++ b/crates/optimism/primitives/Cargo.toml @@ -15,7 +15,7 @@ workspace = true # reth reth-primitives.workspace = true reth-primitives-traits = { workspace = true, features = ["op"] } -reth-codecs = { workspace = true, optional = true, features = ["optimism"] } +reth-codecs = { workspace = true, optional = true, features = ["op"] } # ethereum alloy-primitives.workspace = true @@ -36,7 +36,7 @@ derive_more.workspace = true arbitrary = { workspace = true, features = ["derive"], optional = true } [dev-dependencies] -reth-codecs = { workspace = true, features = ["test-utils", "optimism"] } +reth-codecs = { workspace = true, features = ["test-utils", "op"] } rstest.workspace = true arbitrary.workspace = true @@ -57,7 +57,7 @@ reth-codec = [ "dep:reth-codecs", "reth-primitives/reth-codec", "reth-primitives-traits/reth-codec", - "reth-codecs?/optimism", + "reth-codecs?/op", "reth-primitives/reth-codec" ] serde = [ diff --git a/crates/optimism/storage/Cargo.toml b/crates/optimism/storage/Cargo.toml index 2b18897d94a0..b72e9c287df3 100644 --- a/crates/optimism/storage/Cargo.toml +++ b/crates/optimism/storage/Cargo.toml @@ -22,6 +22,6 @@ reth-stages-types.workspace = true [features] optimism = [ "reth-primitives/optimism", - "reth-codecs/optimism", + "reth-codecs/op", "reth-db-api/optimism" ] diff --git a/crates/primitives/Cargo.toml b/crates/primitives/Cargo.toml index 3bfaefb39ede..2f8f37bcd356 100644 --- a/crates/primitives/Cargo.toml +++ b/crates/primitives/Cargo.toml @@ -146,7 +146,7 @@ c-kzg = [ ] optimism = [ "dep:op-alloy-consensus", - "reth-codecs?/optimism", + "reth-codecs?/op", "revm-primitives/optimism", ] alloy-compat = [ diff --git a/crates/storage/codecs/Cargo.toml b/crates/storage/codecs/Cargo.toml index 57fe9f726c7b..8fbf1632403a 100644 --- a/crates/storage/codecs/Cargo.toml +++ b/crates/storage/codecs/Cargo.toml @@ -67,7 +67,7 @@ alloy = [ "dep:modular-bitfield", "dep:alloy-trie", ] -optimism = ["alloy", "dep:op-alloy-consensus"] +op = ["alloy", "dep:op-alloy-consensus"] test-utils = [ "std", "alloy", diff --git a/crates/storage/codecs/src/alloy/transaction/mod.rs b/crates/storage/codecs/src/alloy/transaction/mod.rs index dc27eacfacc2..fe31293cd18f 100644 --- a/crates/storage/codecs/src/alloy/transaction/mod.rs +++ b/crates/storage/codecs/src/alloy/transaction/mod.rs @@ -9,9 +9,9 @@ cond_mod!( ); -#[cfg(all(feature = "test-utils", feature = "optimism"))] +#[cfg(all(feature = "test-utils", feature = "op"))] pub mod optimism; -#[cfg(all(not(feature = "test-utils"), feature = "optimism"))] +#[cfg(all(not(feature = "test-utils"), feature = "op"))] mod optimism; #[cfg(test)] @@ -41,7 +41,7 @@ mod tests { assert_eq!(TxEip7702::bitflag_encoded_bytes(), 4); } - #[cfg(feature = "optimism")] + #[cfg(feature = "op")] #[test] fn test_ensure_backwards_compatibility_optimism() { assert_eq!(crate::alloy::transaction::optimism::TxDeposit::bitflag_encoded_bytes(), 2); @@ -89,11 +89,11 @@ mod tests { )); } - #[cfg(feature = "optimism")] + #[cfg(feature = "op")] #[test] fn test_decode_deposit() { test_decode::(&hex!( "8108ac8f15983d59b6ae4911a00ff7bfcd2e53d2950926f8c82c12afad02861c46fcb293e776204052725e1c08ff2e9ff602ca916357601fa972a14094891fe3598b718758f22c46f163c18bcaa6296ce87e5267ef3fd932112842fbbf79011548cdf067d93ce6098dfc0aaf5a94531e439f30d6dfd0c6" - )); + )); } } diff --git a/crates/storage/db-api/Cargo.toml b/crates/storage/db-api/Cargo.toml index 05581b9725d7..4f9c2d76b3f4 100644 --- a/crates/storage/db-api/Cargo.toml +++ b/crates/storage/db-api/Cargo.toml @@ -82,4 +82,4 @@ arbitrary = [ "reth-stages-types/arbitrary", "alloy-consensus/arbitrary", ] -optimism = ["reth-primitives/optimism", "reth-codecs/optimism"] +optimism = ["reth-primitives/optimism", "reth-codecs/op"] diff --git a/crates/storage/provider/Cargo.toml b/crates/storage/provider/Cargo.toml index 2875b91149c5..5a9595794d94 100644 --- a/crates/storage/provider/Cargo.toml +++ b/crates/storage/provider/Cargo.toml @@ -92,7 +92,7 @@ optimism = [ "reth-primitives/optimism", "reth-execution-types/optimism", "reth-optimism-primitives", - "reth-codecs/optimism", + "reth-codecs/op", "reth-db/optimism", "reth-db-api/optimism", "revm/optimism", From d7f5846a37366a506c0192a4aeb571d22ae6ed5a Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Mon, 2 Dec 2024 20:53:41 +0100 Subject: [PATCH 26/68] chore: add tx trait bounds to primitives (#13075) --- crates/primitives-traits/src/node.rs | 27 ++++----------------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/crates/primitives-traits/src/node.rs b/crates/primitives-traits/src/node.rs index e610c094ba2d..5b3691d2fdf7 100644 --- a/crates/primitives-traits/src/node.rs +++ b/crates/primitives-traits/src/node.rs @@ -1,9 +1,8 @@ -use core::fmt; - use crate::{ Block, BlockBody, BlockHeader, FullBlock, FullBlockBody, FullBlockHeader, FullReceipt, - FullSignedTx, FullTxType, MaybeArbitrary, MaybeSerde, Receipt, + FullSignedTx, FullTxType, Receipt, SignedTransaction, TxType, }; +use core::fmt; /// Configures all the primitive types of the node. pub trait NodePrimitives: @@ -16,27 +15,9 @@ pub trait NodePrimitives: /// Block body primitive. type BlockBody: BlockBody; /// Signed version of the transaction type. - type SignedTx: Send - + Sync - + Unpin - + Clone - + fmt::Debug - + PartialEq - + Eq - + MaybeSerde - + MaybeArbitrary - + 'static; + type SignedTx: SignedTransaction + 'static; /// Transaction envelope type ID. - type TxType: Send - + Sync - + Unpin - + Clone - + Default - + fmt::Debug - + PartialEq - + Eq - + MaybeArbitrary - + 'static; + type TxType: TxType + 'static; /// A receipt. type Receipt: Receipt; } From 756eafa1aa05b98d393aadc1d01666814a33b372 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Mon, 2 Dec 2024 21:20:45 +0100 Subject: [PATCH 27/68] chore: disable default features op forks (#13073) --- .github/assets/check_rv32imac.sh | 2 +- Cargo.toml | 2 +- crates/optimism/evm/Cargo.toml | 3 ++- crates/optimism/hardforks/src/dev.rs | 1 + crates/optimism/hardforks/src/lib.rs | 1 + 5 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/assets/check_rv32imac.sh b/.github/assets/check_rv32imac.sh index 9032c05b9d6f..0556fa31deae 100755 --- a/.github/assets/check_rv32imac.sh +++ b/.github/assets/check_rv32imac.sh @@ -6,9 +6,9 @@ crates_to_check=( reth-codecs-derive reth-ethereum-forks reth-primitives-traits + reth-optimism-forks # reth-evm # reth-primitives - # reth-optimism-forks # reth-optimism-chainspec ) diff --git a/Cargo.toml b/Cargo.toml index 75feb6636c48..06f59719d61e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -375,7 +375,7 @@ reth-node-types = { path = "crates/node/types" } reth-optimism-chainspec = { path = "crates/optimism/chainspec" } reth-optimism-cli = { path = "crates/optimism/cli" } reth-optimism-consensus = { path = "crates/optimism/consensus" } -reth-optimism-forks = { path = "crates/optimism/hardforks" } +reth-optimism-forks = { path = "crates/optimism/hardforks", default-features = false } reth-optimism-payload-builder = { path = "crates/optimism/payload" } reth-optimism-primitives = { path = "crates/optimism/primitives" } reth-optimism-rpc = { path = "crates/optimism/rpc" } diff --git a/crates/optimism/evm/Cargo.toml b/crates/optimism/evm/Cargo.toml index c640b130841e..95657e0ff207 100644 --- a/crates/optimism/evm/Cargo.toml +++ b/crates/optimism/evm/Cargo.toml @@ -65,7 +65,8 @@ std = [ "revm-primitives/std", "revm/std", "reth-ethereum-forks/std", - "derive_more/std" + "derive_more/std", + "reth-optimism-forks/std" ] optimism = [ "reth-primitives/optimism", diff --git a/crates/optimism/hardforks/src/dev.rs b/crates/optimism/hardforks/src/dev.rs index 5fe77a314029..6dcd28c46c9e 100644 --- a/crates/optimism/hardforks/src/dev.rs +++ b/crates/optimism/hardforks/src/dev.rs @@ -1,3 +1,4 @@ +use alloc::vec; use alloy_primitives::U256; use reth_ethereum_forks::{ChainHardforks, EthereumHardfork, ForkCondition}; diff --git a/crates/optimism/hardforks/src/lib.rs b/crates/optimism/hardforks/src/lib.rs index 3915bcf6cbda..bf6ca98ce4e9 100644 --- a/crates/optimism/hardforks/src/lib.rs +++ b/crates/optimism/hardforks/src/lib.rs @@ -6,6 +6,7 @@ issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" )] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +#![cfg_attr(not(feature = "std"), no_std)] extern crate alloc; From 156984b377690ad651212fec3e769199b4434047 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Mon, 2 Dec 2024 21:36:30 +0100 Subject: [PATCH 28/68] chore: misc direct imports (#13079) --- .../evm/execution-types/src/execution_outcome.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/crates/evm/execution-types/src/execution_outcome.rs b/crates/evm/execution-types/src/execution_outcome.rs index 7acbfea33669..c9e85ae444fd 100644 --- a/crates/evm/execution-types/src/execution_outcome.rs +++ b/crates/evm/execution-types/src/execution_outcome.rs @@ -1,16 +1,14 @@ -use std::collections::HashMap; - +use crate::BlockExecutionOutput; use alloy_eips::eip7685::Requests; -use alloy_primitives::{Address, BlockNumber, Bloom, Log, B256, U256}; -use reth_primitives::{logs_bloom, Account, Bytecode, Receipts, StorageEntry}; -use reth_primitives_traits::{receipt::ReceiptExt, Receipt}; +use alloy_primitives::{logs_bloom, Address, BlockNumber, Bloom, Log, B256, U256}; +use reth_primitives::Receipts; +use reth_primitives_traits::{receipt::ReceiptExt, Account, Bytecode, Receipt, StorageEntry}; use reth_trie::HashedPostState; use revm::{ db::{states::BundleState, BundleAccount}, primitives::AccountInfo, }; - -use crate::BlockExecutionOutput; +use std::collections::HashMap; /// Represents a changed account #[derive(Clone, Copy, Debug, PartialEq, Eq)] @@ -376,10 +374,12 @@ mod tests { use super::*; #[cfg(not(feature = "optimism"))] use alloy_primitives::bytes; + #[cfg(not(feature = "optimism"))] + use alloy_primitives::LogData; use alloy_primitives::{Address, B256}; use reth_primitives::Receipts; #[cfg(not(feature = "optimism"))] - use reth_primitives::{LogData, TxType}; + use reth_primitives::TxType; #[test] #[cfg(not(feature = "optimism"))] From 65193bdaf34bf7b2c89a53a32798150b06579d01 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Mon, 2 Dec 2024 21:56:21 +0100 Subject: [PATCH 29/68] feat: add std feature to network-peers (#13078) --- .github/assets/check_wasm.sh | 1 + crates/chainspec/Cargo.toml | 3 ++- crates/net/p2p/Cargo.toml | 3 ++- crates/net/peers/Cargo.toml | 8 ++++++++ crates/net/peers/src/bootnodes/mod.rs | 1 + crates/net/peers/src/lib.rs | 17 ++++++++++++----- crates/net/peers/src/node_record.rs | 11 +++++++---- crates/net/peers/src/trusted_peer.rs | 25 ++++++++++++++----------- crates/optimism/chainspec/Cargo.toml | 3 ++- 9 files changed, 49 insertions(+), 23 deletions(-) diff --git a/.github/assets/check_wasm.sh b/.github/assets/check_wasm.sh index 11e5b5e00b9e..971327f0cb21 100755 --- a/.github/assets/check_wasm.sh +++ b/.github/assets/check_wasm.sh @@ -70,6 +70,7 @@ exclude_crates=( reth-transaction-pool # c-kzg reth-trie-parallel # tokio reth-testing-utils + reth-network-peers ) # Array to hold the results diff --git a/crates/chainspec/Cargo.toml b/crates/chainspec/Cargo.toml index 67968ee0a88c..0e56cf2d3d94 100644 --- a/crates/chainspec/Cargo.toml +++ b/crates/chainspec/Cargo.toml @@ -50,7 +50,8 @@ std = [ "once_cell/std", "alloy-rlp/std", "reth-ethereum-forks/std", - "derive_more/std" + "derive_more/std", + "reth-network-peers/std" ] arbitrary = [ "alloy-chains/arbitrary", diff --git a/crates/net/p2p/Cargo.toml b/crates/net/p2p/Cargo.toml index a72110647c46..2c61da751844 100644 --- a/crates/net/p2p/Cargo.toml +++ b/crates/net/p2p/Cargo.toml @@ -58,5 +58,6 @@ std = [ "alloy-primitives/std", "reth-primitives-traits/std", "alloy-consensus/std", - "derive_more/std" + "derive_more/std", + "reth-network-peers/std" ] diff --git a/crates/net/peers/Cargo.toml b/crates/net/peers/Cargo.toml index 5ac24edea759..8ca5faec93d5 100644 --- a/crates/net/peers/Cargo.toml +++ b/crates/net/peers/Cargo.toml @@ -35,5 +35,13 @@ serde_json.workspace = true tokio = { workspace = true, features = ["net", "macros", "rt"] } [features] +default = ["std"] +std = [ + "alloy-primitives/std", + "alloy-rlp/std", + "secp256k1?/std", + "serde_with/std", + "thiserror/std" +] secp256k1 = ["dep:secp256k1", "enr/secp256k1"] net = ["dep:tokio", "tokio?/net"] diff --git a/crates/net/peers/src/bootnodes/mod.rs b/crates/net/peers/src/bootnodes/mod.rs index 31c91e5d1cea..b149c108a969 100644 --- a/crates/net/peers/src/bootnodes/mod.rs +++ b/crates/net/peers/src/bootnodes/mod.rs @@ -1,6 +1,7 @@ //! Bootnodes for the network use crate::NodeRecord; +use alloc::vec::Vec; mod ethereum; pub use ethereum::*; diff --git a/crates/net/peers/src/lib.rs b/crates/net/peers/src/lib.rs index 1d60994d8e1b..3e2777c2df89 100644 --- a/crates/net/peers/src/lib.rs +++ b/crates/net/peers/src/lib.rs @@ -52,9 +52,16 @@ )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +#![cfg_attr(not(feature = "std"), no_std)] +extern crate alloc; + +use alloc::{ + format, + string::{String, ToString}, +}; use alloy_primitives::B512; -use std::str::FromStr; +use core::str::FromStr; // Re-export PeerId for ease of use. pub use enr::Enr; @@ -137,8 +144,8 @@ impl AnyNode { let node_record = NodeRecord { address: enr .ip4() - .map(std::net::IpAddr::from) - .or_else(|| enr.ip6().map(std::net::IpAddr::from))?, + .map(core::net::IpAddr::from) + .or_else(|| enr.ip6().map(core::net::IpAddr::from))?, tcp_port: enr.tcp4().or_else(|| enr.tcp6())?, udp_port: enr.udp4().or_else(|| enr.udp6())?, id: pk2id(&enr.public_key()), @@ -186,8 +193,8 @@ impl FromStr for AnyNode { } } -impl std::fmt::Display for AnyNode { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Display for AnyNode { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { Self::NodeRecord(record) => write!(f, "{record}"), #[cfg(feature = "secp256k1")] diff --git a/crates/net/peers/src/node_record.rs b/crates/net/peers/src/node_record.rs index ed48e242c1da..15ef5ad8522a 100644 --- a/crates/net/peers/src/node_record.rs +++ b/crates/net/peers/src/node_record.rs @@ -1,15 +1,18 @@ //! Commonly used `NodeRecord` type for peers. -use std::{ +use crate::PeerId; +use alloc::{ + format, + string::{String, ToString}, +}; +use alloy_rlp::{RlpDecodable, RlpEncodable}; +use core::{ fmt, fmt::Write, net::{IpAddr, Ipv4Addr, SocketAddr}, num::ParseIntError, str::FromStr, }; - -use crate::PeerId; -use alloy_rlp::{RlpDecodable, RlpEncodable}; use serde_with::{DeserializeFromStr, SerializeDisplay}; #[cfg(feature = "secp256k1")] diff --git a/crates/net/peers/src/trusted_peer.rs b/crates/net/peers/src/trusted_peer.rs index aa7e0a015336..b87c4d6da2f0 100644 --- a/crates/net/peers/src/trusted_peer.rs +++ b/crates/net/peers/src/trusted_peer.rs @@ -1,14 +1,14 @@ //! `NodeRecord` type that uses a domain instead of an IP. use crate::{NodeRecord, PeerId}; -use serde_with::{DeserializeFromStr, SerializeDisplay}; -use std::{ +use alloc::string::{String, ToString}; +use core::{ fmt::{self, Write}, - io::Error, net::IpAddr, num::ParseIntError, str::FromStr, }; +use serde_with::{DeserializeFromStr, SerializeDisplay}; use url::Host; /// Represents the node record of a trusted peer. The only difference between this and a @@ -45,11 +45,13 @@ impl TrustedPeer { Self { host, tcp_port: port, udp_port: port, id } } + #[cfg(any(test, feature = "std"))] const fn to_node_record(&self, ip: IpAddr) -> NodeRecord { NodeRecord { address: ip, id: self.id, tcp_port: self.tcp_port, udp_port: self.udp_port } } /// Tries to resolve directly to a [`NodeRecord`] if the host is an IP address. + #[cfg(any(test, feature = "std"))] fn try_node_record(&self) -> Result { match &self.host { Host::Ipv4(ip) => Ok(self.to_node_record((*ip).into())), @@ -61,23 +63,24 @@ impl TrustedPeer { /// Resolves the host in a [`TrustedPeer`] to an IP address, returning a [`NodeRecord`]. /// /// This use [`ToSocketAddr`](std::net::ToSocketAddrs) to resolve the host to an IP address. - pub fn resolve_blocking(&self) -> Result { + #[cfg(any(test, feature = "std"))] + pub fn resolve_blocking(&self) -> Result { let domain = match self.try_node_record() { Ok(record) => return Ok(record), Err(domain) => domain, }; // Resolve the domain to an IP address let mut ips = std::net::ToSocketAddrs::to_socket_addrs(&(domain, 0))?; - let ip = ips - .next() - .ok_or_else(|| Error::new(std::io::ErrorKind::AddrNotAvailable, "No IP found"))?; + let ip = ips.next().ok_or_else(|| { + std::io::Error::new(std::io::ErrorKind::AddrNotAvailable, "No IP found") + })?; Ok(self.to_node_record(ip.ip())) } /// Resolves the host in a [`TrustedPeer`] to an IP address, returning a [`NodeRecord`]. #[cfg(any(test, feature = "net"))] - pub async fn resolve(&self) -> Result { + pub async fn resolve(&self) -> Result { let domain = match self.try_node_record() { Ok(record) => return Ok(record), Err(domain) => domain, @@ -85,9 +88,9 @@ impl TrustedPeer { // Resolve the domain to an IP address let mut ips = tokio::net::lookup_host(format!("{domain}:0")).await?; - let ip = ips - .next() - .ok_or_else(|| Error::new(std::io::ErrorKind::AddrNotAvailable, "No IP found"))?; + let ip = ips.next().ok_or_else(|| { + std::io::Error::new(std::io::ErrorKind::AddrNotAvailable, "No IP found") + })?; Ok(self.to_node_record(ip.ip())) } diff --git a/crates/optimism/chainspec/Cargo.toml b/crates/optimism/chainspec/Cargo.toml index 7f74156b885c..5ccf26607094 100644 --- a/crates/optimism/chainspec/Cargo.toml +++ b/crates/optimism/chainspec/Cargo.toml @@ -57,5 +57,6 @@ std = [ "reth-optimism-forks/std", "alloy-consensus/std", "once_cell/std", - "derive_more/std" + "derive_more/std", + "reth-network-peers/std" ] From 80d0fb0cda4a999098e5189ae00c3b3e999c739a Mon Sep 17 00:00:00 2001 From: joshieDo <93316087+joshieDo@users.noreply.github.com> Date: Mon, 2 Dec 2024 21:03:00 +0000 Subject: [PATCH 30/68] chore: set event logs from `StaticFileProducer` and `Pruner` to `debug` (#13080) --- crates/node/events/src/node.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/node/events/src/node.rs b/crates/node/events/src/node.rs index edd85501ec0a..86f1ea507ac5 100644 --- a/crates/node/events/src/node.rs +++ b/crates/node/events/src/node.rs @@ -298,14 +298,14 @@ impl NodeState { fn handle_pruner_event(&self, event: PrunerEvent) { match event { PrunerEvent::Started { tip_block_number } => { - info!(tip_block_number, "Pruner started"); + debug!(tip_block_number, "Pruner started"); } PrunerEvent::Finished { tip_block_number, elapsed, stats } => { let stats = format!( "[{}]", stats.iter().map(|item| item.to_string()).collect::>().join(", ") ); - info!(tip_block_number, ?elapsed, %stats, "Pruner finished"); + debug!(tip_block_number, ?elapsed, pruned_segments = %stats, "Pruner finished"); } } } @@ -313,10 +313,10 @@ impl NodeState { fn handle_static_file_producer_event(&self, event: StaticFileProducerEvent) { match event { StaticFileProducerEvent::Started { targets } => { - info!(?targets, "Static File Producer started"); + debug!(?targets, "Static File Producer started"); } StaticFileProducerEvent::Finished { targets, elapsed } => { - info!(?targets, ?elapsed, "Static File Producer finished"); + debug!(?targets, ?elapsed, "Static File Producer finished"); } } } From bcfe9ebb25ff1318f64d3446ce3d971c9e5d15ed Mon Sep 17 00:00:00 2001 From: Roman Krasiuk Date: Mon, 2 Dec 2024 22:07:18 +0100 Subject: [PATCH 31/68] feat(trie): `SparseStateTrie::new` (#13068) --- crates/trie/sparse/src/state.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/crates/trie/sparse/src/state.rs b/crates/trie/sparse/src/state.rs index 0ca290e2d0cb..cf0bc20abe4f 100644 --- a/crates/trie/sparse/src/state.rs +++ b/crates/trie/sparse/src/state.rs @@ -53,6 +53,18 @@ impl SparseStateTrie { } impl SparseStateTrie { + /// Create new [`SparseStateTrie`] with blinded node provider factory. + pub fn new(provider_factory: F) -> Self { + Self { + provider_factory, + state: Default::default(), + storages: Default::default(), + revealed: Default::default(), + retain_updates: false, + account_rlp_buf: Vec::with_capacity(TRIE_ACCOUNT_RLP_MAX_SIZE), + } + } + /// Set the retention of branch node updates and deletions. pub const fn with_updates(mut self, retain_updates: bool) -> Self { self.retain_updates = retain_updates; From 2c5a1a743a43a2fd2cc194fd7df1825989bee35d Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Mon, 2 Dec 2024 22:17:54 +0100 Subject: [PATCH 32/68] chore: disable nybbles default feature (#13081) --- Cargo.toml | 2 +- crates/evm/execution-errors/Cargo.toml | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 06f59719d61e..550a71352061 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -503,7 +503,7 @@ modular-bitfield = "0.11.2" notify = { version = "6.1.1", default-features = false, features = [ "macos_fsevent", ] } -nybbles = "0.2.1" +nybbles = { version = "0.2.1", default-features = false } once_cell = { version = "1.19", default-features = false, features = [ "critical-section", ] } diff --git a/crates/evm/execution-errors/Cargo.toml b/crates/evm/execution-errors/Cargo.toml index 01727cd70b5c..5e1755c0c552 100644 --- a/crates/evm/execution-errors/Cargo.toml +++ b/crates/evm/execution-errors/Cargo.toml @@ -32,5 +32,6 @@ std = [ "alloy-primitives/std", "revm-primitives/std", "alloy-rlp/std", - "derive_more/std" + "derive_more/std", + "nybbles/std" ] From 039f1215d05b736f7ca23384cd12e566cd00d639 Mon Sep 17 00:00:00 2001 From: Dan Cline <6798349+Rjected@users.noreply.github.com> Date: Mon, 2 Dec 2024 16:46:54 -0500 Subject: [PATCH 33/68] chore: make `has_eip4844` generic over `SignedTransaction` (#13083) --- crates/net/eth-wire-types/src/broadcast.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/net/eth-wire-types/src/broadcast.rs b/crates/net/eth-wire-types/src/broadcast.rs index b54fd0df2db2..72a1116c3925 100644 --- a/crates/net/eth-wire-types/src/broadcast.rs +++ b/crates/net/eth-wire-types/src/broadcast.rs @@ -8,7 +8,7 @@ use alloy_rlp::{ use derive_more::{Constructor, Deref, DerefMut, From, IntoIterator}; use reth_codecs_derive::{add_arbitrary_tests, generate_tests}; use reth_primitives::TransactionSigned; -use reth_primitives_traits::SignedTransaction; +use reth_primitives_traits::{SignedTransaction, Transaction}; use std::{ collections::{HashMap, HashSet}, mem, @@ -94,7 +94,7 @@ pub struct Transactions( pub Vec, ); -impl Transactions { +impl Transactions { /// Returns `true` if the list of transactions contains any blob transactions. pub fn has_eip4844(&self) -> bool { self.0.iter().any(|tx| tx.is_eip4844()) From 98319537814fe689e487090d2b3083375684c581 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Mon, 2 Dec 2024 22:55:56 +0100 Subject: [PATCH 34/68] chore: flatten reth-primitives dep (#13082) --- Cargo.lock | 3 ++- crates/storage/errors/Cargo.toml | 7 ++++--- crates/storage/errors/src/provider.rs | 4 ++-- crates/storage/errors/src/writer.rs | 2 +- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 66cd14d1e2a0..8142bbc83875 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9298,7 +9298,8 @@ dependencies = [ "alloy-rlp", "derive_more 1.0.0", "reth-fs-util", - "reth-primitives", + "reth-primitives-traits", + "reth-static-file-types", ] [[package]] diff --git a/crates/storage/errors/Cargo.toml b/crates/storage/errors/Cargo.toml index 0f2cf03f6521..2e864e09d43a 100644 --- a/crates/storage/errors/Cargo.toml +++ b/crates/storage/errors/Cargo.toml @@ -12,8 +12,9 @@ workspace = true [dependencies] # reth -reth-primitives.workspace = true +reth-primitives-traits.workspace = true reth-fs-util.workspace = true +reth-static-file-types.workspace = true # ethereum alloy-eips.workspace = true @@ -26,9 +27,9 @@ derive_more.workspace = true [features] default = ["std"] std = [ - "reth-primitives/std", "alloy-eips/std", "alloy-primitives/std", "alloy-rlp/std", - "derive_more/std" + "derive_more/std", + "reth-primitives-traits/std" ] diff --git a/crates/storage/errors/src/provider.rs b/crates/storage/errors/src/provider.rs index e69c0343f564..d4b69cffb08e 100644 --- a/crates/storage/errors/src/provider.rs +++ b/crates/storage/errors/src/provider.rs @@ -3,7 +3,8 @@ use alloc::{boxed::Box, string::String}; use alloy_eips::{BlockHashOrNumber, HashOrNumber}; use alloy_primitives::{Address, BlockHash, BlockNumber, TxNumber, B256}; use derive_more::Display; -use reth_primitives::{GotExpected, StaticFileSegment}; +use reth_primitives_traits::GotExpected; +use reth_static_file_types::StaticFileSegment; /// Provider result type. pub type ProviderResult = Result; @@ -165,7 +166,6 @@ impl core::error::Error for ProviderError { fn source(&self) -> Option<&(dyn core::error::Error + 'static)> { match self { Self::Database(source) => core::error::Error::source(source), - Self::Rlp(source) => core::error::Error::source(source), Self::StorageLockError(source) => core::error::Error::source(source), Self::UnifiedStorageWriterError(source) => core::error::Error::source(source), _ => Option::None, diff --git a/crates/storage/errors/src/writer.rs b/crates/storage/errors/src/writer.rs index 10d4ad96ed3f..3e060d7005d4 100644 --- a/crates/storage/errors/src/writer.rs +++ b/crates/storage/errors/src/writer.rs @@ -1,5 +1,5 @@ use crate::db::DatabaseError; -use reth_primitives::StaticFileSegment; +use reth_static_file_types::StaticFileSegment; /// `UnifiedStorageWriter` related errors /// `StorageWriter` related errors From 9ed9fa241d66caadc9e6b6065cbbc5984b57b97a Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Tue, 3 Dec 2024 03:36:09 +0400 Subject: [PATCH 35/68] refactor: rename `TransactionSignedEcRecovered` to `RecoveredTx` (#13074) --- crates/blockchain-tree/src/blockchain_tree.rs | 6 +- crates/chain-state/src/test_utils.rs | 7 +- crates/evm/execution-types/src/chain.rs | 9 +- crates/optimism/node/src/txpool.rs | 5 +- crates/optimism/node/tests/it/priority.rs | 4 +- crates/optimism/payload/src/builder.rs | 2 +- crates/optimism/payload/src/error.rs | 4 +- crates/optimism/rpc/src/eth/transaction.rs | 4 +- crates/payload/util/src/traits.rs | 4 +- crates/payload/util/src/transaction.rs | 8 +- crates/primitives/src/block.rs | 14 +-- crates/primitives/src/lib.rs | 4 +- crates/primitives/src/transaction/error.rs | 2 +- crates/primitives/src/transaction/mod.rs | 92 +++++++++++-------- crates/primitives/src/transaction/pooled.rs | 92 +++++-------------- .../rpc-eth-api/src/helpers/pending_block.rs | 4 +- crates/rpc/rpc-eth-types/src/transaction.rs | 12 +-- .../rpc/rpc-types-compat/src/transaction.rs | 12 +-- crates/rpc/rpc/src/eth/bundle.rs | 2 +- crates/rpc/rpc/src/eth/filter.rs | 6 +- crates/rpc/rpc/src/eth/helpers/types.rs | 4 +- crates/rpc/rpc/src/eth/sim_bundle.rs | 2 +- crates/rpc/rpc/src/txpool.rs | 8 +- crates/transaction-pool/src/maintain.rs | 6 +- crates/transaction-pool/src/pool/best.rs | 10 +- .../transaction-pool/src/test_utils/mock.rs | 16 ++-- crates/transaction-pool/src/traits.rs | 46 ++++------ crates/transaction-pool/src/validate/mod.rs | 8 +- 28 files changed, 170 insertions(+), 223 deletions(-) diff --git a/crates/blockchain-tree/src/blockchain_tree.rs b/crates/blockchain-tree/src/blockchain_tree.rs index 757729d5416d..91ddd75f2a71 100644 --- a/crates/blockchain-tree/src/blockchain_tree.rs +++ b/crates/blockchain-tree/src/blockchain_tree.rs @@ -1390,7 +1390,7 @@ mod tests { use reth_node_types::FullNodePrimitives; use reth_primitives::{ proofs::{calculate_receipt_root, calculate_transaction_root}, - Account, BlockBody, Transaction, TransactionSigned, TransactionSignedEcRecovered, + Account, BlockBody, RecoveredTx, Transaction, TransactionSigned, }; use reth_provider::{ providers::ProviderNodeTypes, @@ -1574,7 +1574,7 @@ mod tests { } let single_tx_cost = U256::from(INITIAL_BASE_FEE * MIN_TRANSACTION_GAS); - let mock_tx = |nonce: u64| -> TransactionSignedEcRecovered { + let mock_tx = |nonce: u64| -> RecoveredTx { TransactionSigned::new_unhashed( Transaction::Eip1559(TxEip1559 { chain_id: chain_spec.chain.id(), @@ -1591,7 +1591,7 @@ mod tests { let mock_block = |number: u64, parent: Option, - body: Vec, + body: Vec, num_of_signer_txs: u64| -> SealedBlockWithSenders { let signed_body = diff --git a/crates/chain-state/src/test_utils.rs b/crates/chain-state/src/test_utils.rs index f6b0a4f17723..1cd9f2df96b9 100644 --- a/crates/chain-state/src/test_utils.rs +++ b/crates/chain-state/src/test_utils.rs @@ -14,9 +14,8 @@ use reth_chainspec::{ChainSpec, EthereumHardfork, MIN_TRANSACTION_GAS}; use reth_execution_types::{Chain, ExecutionOutcome}; use reth_primitives::{ proofs::{calculate_receipt_root, calculate_transaction_root, calculate_withdrawals_root}, - BlockBody, EthPrimitives, NodePrimitives, Receipt, Receipts, SealedBlock, + BlockBody, EthPrimitives, NodePrimitives, Receipt, Receipts, RecoveredTx, SealedBlock, SealedBlockWithSenders, SealedHeader, Transaction, TransactionSigned, - TransactionSignedEcRecovered, }; use reth_storage_api::NodePrimitivesProvider; use reth_trie::{root::state_root_unhashed, updates::TrieUpdates, HashedPostState}; @@ -91,7 +90,7 @@ impl TestBlockBuilder { ) -> SealedBlockWithSenders { let mut rng = thread_rng(); - let mock_tx = |nonce: u64| -> TransactionSignedEcRecovered { + let mock_tx = |nonce: u64| -> RecoveredTx { let tx = Transaction::Eip1559(TxEip1559 { chain_id: self.chain_spec.chain.id(), nonce, @@ -109,7 +108,7 @@ impl TestBlockBuilder { let num_txs = rng.gen_range(0..5); let signer_balance_decrease = Self::single_tx_cost() * U256::from(num_txs); - let transactions: Vec = (0..num_txs) + let transactions: Vec = (0..num_txs) .map(|_| { let tx = mock_tx(self.signer_build_account_info.nonce); self.signer_build_account_info.nonce += 1; diff --git a/crates/evm/execution-types/src/chain.rs b/crates/evm/execution-types/src/chain.rs index 20bf5c6d24d3..cbdb2296bf62 100644 --- a/crates/evm/execution-types/src/chain.rs +++ b/crates/evm/execution-types/src/chain.rs @@ -8,8 +8,8 @@ use alloy_primitives::{Address, BlockHash, BlockNumber, TxHash}; use core::{fmt, ops::RangeInclusive}; use reth_execution_errors::{BlockExecutionError, InternalBlockExecutionError}; use reth_primitives::{ - transaction::SignedTransactionIntoRecoveredExt, SealedBlockFor, SealedBlockWithSenders, - SealedHeader, TransactionSignedEcRecovered, + transaction::SignedTransactionIntoRecoveredExt, RecoveredTx, SealedBlockFor, + SealedBlockWithSenders, SealedHeader, }; use reth_primitives_traits::{Block, BlockBody, NodePrimitives, SignedTransaction}; use reth_trie::updates::TrieUpdates; @@ -436,14 +436,13 @@ impl>> ChainBlocks<'_, self.blocks.values().flat_map(|block| block.transactions_with_sender()) } - /// Returns an iterator over all [`TransactionSignedEcRecovered`] in the blocks + /// Returns an iterator over all [`RecoveredTx`] in the blocks /// /// Note: This clones the transactions since it is assumed this is part of a shared [Chain]. #[inline] pub fn transactions_ecrecovered( &self, - ) -> impl Iterator::Transaction>> + '_ - { + ) -> impl Iterator::Transaction>> + '_ { self.transactions_with_sender().map(|(signer, tx)| tx.clone().with_signer(*signer)) } diff --git a/crates/optimism/node/src/txpool.rs b/crates/optimism/node/src/txpool.rs index 6d269d361d8f..d8246aeb7dbb 100644 --- a/crates/optimism/node/src/txpool.rs +++ b/crates/optimism/node/src/txpool.rs @@ -237,7 +237,7 @@ mod tests { use alloy_primitives::{PrimitiveSignature as Signature, TxKind, U256}; use op_alloy_consensus::TxDeposit; use reth_chainspec::MAINNET; - use reth_primitives::{Transaction, TransactionSigned, TransactionSignedEcRecovered}; + use reth_primitives::{RecoveredTx, Transaction, TransactionSigned}; use reth_provider::test_utils::MockEthProvider; use reth_transaction_pool::{ blobstore::InMemoryBlobStore, validate::EthTransactionValidatorBuilder, @@ -266,8 +266,7 @@ mod tests { }); let signature = Signature::test_signature(); let signed_tx = TransactionSigned::new_unhashed(deposit_tx, signature); - let signed_recovered = - TransactionSignedEcRecovered::from_signed_transaction(signed_tx, signer); + let signed_recovered = RecoveredTx::from_signed_transaction(signed_tx, signer); let len = signed_recovered.encode_2718_len(); let pooled_tx = EthPooledTransaction::new(signed_recovered, len); let outcome = validator.validate_one(origin, pooled_tx); diff --git a/crates/optimism/node/tests/it/priority.rs b/crates/optimism/node/tests/it/priority.rs index 35be3dfd3ee1..b5487987f6a5 100644 --- a/crates/optimism/node/tests/it/priority.rs +++ b/crates/optimism/node/tests/it/priority.rs @@ -27,7 +27,7 @@ use reth_optimism_node::{ use reth_optimism_payload_builder::builder::OpPayloadTransactions; use reth_optimism_primitives::OpPrimitives; use reth_payload_util::{PayloadTransactions, PayloadTransactionsChain, PayloadTransactionsFixed}; -use reth_primitives::{SealedBlock, Transaction, TransactionSigned, TransactionSignedEcRecovered}; +use reth_primitives::{RecoveredTx, SealedBlock, Transaction, TransactionSigned}; use reth_provider::providers::BlockchainProvider2; use reth_tasks::TaskManager; use reth_transaction_pool::pool::BestPayloadTransactions; @@ -64,7 +64,7 @@ impl OpPayloadTransactions for CustomTxPriority { ..Default::default() }; let signature = sender.sign_transaction_sync(&mut end_of_block_tx).unwrap(); - let end_of_block_tx = TransactionSignedEcRecovered::from_signed_transaction( + let end_of_block_tx = RecoveredTx::from_signed_transaction( TransactionSigned::new_unhashed(Transaction::Eip1559(end_of_block_tx), signature), sender.address(), ); diff --git a/crates/optimism/payload/src/builder.rs b/crates/optimism/payload/src/builder.rs index aeaa8ef40790..6ae52188d180 100644 --- a/crates/optimism/payload/src/builder.rs +++ b/crates/optimism/payload/src/builder.rs @@ -749,7 +749,7 @@ where )) } - // Convert the transaction to a [TransactionSignedEcRecovered]. This is + // Convert the transaction to a [RecoveredTx]. This is // purely for the purposes of utilizing the `evm_config.tx_env`` function. // Deposit transactions do not have signatures, so if the tx is a deposit, this // will just pull in its `from` address. diff --git a/crates/optimism/payload/src/error.rs b/crates/optimism/payload/src/error.rs index 8a254e9835c2..6b2a85e7a97b 100644 --- a/crates/optimism/payload/src/error.rs +++ b/crates/optimism/payload/src/error.rs @@ -4,8 +4,8 @@ #[derive(Debug, thiserror::Error)] pub enum OpPayloadBuilderError { /// Thrown when a transaction fails to convert to a - /// [`reth_primitives::TransactionSignedEcRecovered`]. - #[error("failed to convert deposit transaction to TransactionSignedEcRecovered")] + /// [`reth_primitives::RecoveredTx`]. + #[error("failed to convert deposit transaction to RecoveredTx")] TransactionEcRecoverFailed, /// Thrown when the L1 block info could not be parsed from the calldata of the /// first transaction supplied in the payload attributes. diff --git a/crates/optimism/rpc/src/eth/transaction.rs b/crates/optimism/rpc/src/eth/transaction.rs index 2b92927f6495..3ba5edead55a 100644 --- a/crates/optimism/rpc/src/eth/transaction.rs +++ b/crates/optimism/rpc/src/eth/transaction.rs @@ -6,7 +6,7 @@ use alloy_rpc_types_eth::TransactionInfo; use op_alloy_consensus::OpTxEnvelope; use op_alloy_rpc_types::Transaction; use reth_node_api::FullNodeComponents; -use reth_primitives::{TransactionSigned, TransactionSignedEcRecovered}; +use reth_primitives::{RecoveredTx, TransactionSigned}; use reth_provider::{BlockReaderIdExt, ReceiptProvider, TransactionsProvider}; use reth_rpc_eth_api::{ helpers::{EthSigner, EthTransactions, LoadTransaction, SpawnBlocking}, @@ -81,7 +81,7 @@ where fn fill( &self, - tx: TransactionSignedEcRecovered, + tx: RecoveredTx, tx_info: TransactionInfo, ) -> Result { let from = tx.signer(); diff --git a/crates/payload/util/src/traits.rs b/crates/payload/util/src/traits.rs index 52dad5111698..5c1eb38bea38 100644 --- a/crates/payload/util/src/traits.rs +++ b/crates/payload/util/src/traits.rs @@ -1,5 +1,5 @@ use alloy_primitives::Address; -use reth_primitives::TransactionSignedEcRecovered; +use reth_primitives::RecoveredTx; /// Iterator that returns transactions for the block building process in the order they should be /// included in the block. @@ -12,7 +12,7 @@ pub trait PayloadTransactions { &mut self, // In the future, `ctx` can include access to state for block building purposes. ctx: (), - ) -> Option; + ) -> Option; /// Exclude descendants of the transaction with given sender and nonce from the iterator, /// because this transaction won't be included in the block. diff --git a/crates/payload/util/src/transaction.rs b/crates/payload/util/src/transaction.rs index a45e177d4d34..ebd3b0796262 100644 --- a/crates/payload/util/src/transaction.rs +++ b/crates/payload/util/src/transaction.rs @@ -1,7 +1,7 @@ use crate::PayloadTransactions; use alloy_consensus::Transaction; use alloy_primitives::Address; -use reth_primitives::TransactionSignedEcRecovered; +use reth_primitives::RecoveredTx; /// An implementation of [`crate::traits::PayloadTransactions`] that yields /// a pre-defined set of transactions. @@ -26,8 +26,8 @@ impl PayloadTransactionsFixed { } } -impl PayloadTransactions for PayloadTransactionsFixed { - fn next(&mut self, _ctx: ()) -> Option { +impl PayloadTransactions for PayloadTransactionsFixed { + fn next(&mut self, _ctx: ()) -> Option { (self.index < self.transactions.len()).then(|| { let tx = self.transactions[self.index].clone(); self.index += 1; @@ -92,7 +92,7 @@ where B: PayloadTransactions, A: PayloadTransactions, { - fn next(&mut self, ctx: ()) -> Option { + fn next(&mut self, ctx: ()) -> Option { while let Some(tx) = self.before.next(ctx) { if let Some(before_max_gas) = self.before_max_gas { if self.before_gas + tx.transaction.gas_limit() <= before_max_gas { diff --git a/crates/primitives/src/block.rs b/crates/primitives/src/block.rs index 9e00a2e582cb..9edbb2471efb 100644 --- a/crates/primitives/src/block.rs +++ b/crates/primitives/src/block.rs @@ -1,6 +1,6 @@ use crate::{ traits::BlockExt, transaction::SignedTransactionIntoRecoveredExt, BlockBodyTxExt, GotExpected, - SealedHeader, TransactionSigned, TransactionSignedEcRecovered, + RecoveredTx, SealedHeader, TransactionSigned, }; use alloc::vec::Vec; use alloy_consensus::Header; @@ -206,11 +206,7 @@ impl BlockWithSenders { #[inline] pub fn into_transactions_ecrecovered( self, - ) -> impl Iterator< - Item = TransactionSignedEcRecovered< - ::Transaction, - >, - > + ) -> impl Iterator::Transaction>> where ::Transaction: SignedTransaction, { @@ -560,11 +556,7 @@ impl SealedBlockWithSenders { #[inline] pub fn into_transactions_ecrecovered( self, - ) -> impl Iterator< - Item = TransactionSignedEcRecovered< - ::Transaction, - >, - > + ) -> impl Iterator::Transaction>> where ::Transaction: SignedTransaction, { diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index 224e025f39d5..97407ba610cf 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -52,8 +52,8 @@ pub use static_file::StaticFileSegment; pub use transaction::{ util::secp256k1::{public_key_to_address, recover_signer_unchecked, sign_message}, BlobTransaction, InvalidTransactionError, PooledTransactionsElement, - PooledTransactionsElementEcRecovered, Transaction, TransactionMeta, TransactionSigned, - TransactionSignedEcRecovered, TransactionSignedNoHash, TxType, + PooledTransactionsElementEcRecovered, RecoveredTx, Transaction, TransactionMeta, + TransactionSigned, TransactionSignedEcRecovered, TransactionSignedNoHash, TxType, }; // Re-exports diff --git a/crates/primitives/src/transaction/error.rs b/crates/primitives/src/transaction/error.rs index 790292cd82b7..78f6cf5e5fd3 100644 --- a/crates/primitives/src/transaction/error.rs +++ b/crates/primitives/src/transaction/error.rs @@ -76,7 +76,7 @@ pub enum TransactionConversionError { } /// Represents error variants than can happen when trying to convert a -/// [`TransactionSignedEcRecovered`](crate::TransactionSignedEcRecovered) transaction. +/// [`RecoveredTx`](crate::RecoveredTx) transaction. #[derive(Debug, Clone, Eq, PartialEq, derive_more::Display)] pub enum TryFromRecoveredTransactionError { /// Thrown if the transaction type is unsupported. diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index f4c4a0f2997e..0eeaf310853a 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -1107,56 +1107,56 @@ impl TransactionSigned { } } - /// Returns the [`TransactionSignedEcRecovered`] transaction with the given sender. + /// Returns the [`RecoveredTx`] transaction with the given sender. #[inline] - pub const fn with_signer(self, signer: Address) -> TransactionSignedEcRecovered { - TransactionSignedEcRecovered::from_signed_transaction(self, signer) + pub const fn with_signer(self, signer: Address) -> RecoveredTx { + RecoveredTx::from_signed_transaction(self, signer) } - /// Consumes the type, recover signer and return [`TransactionSignedEcRecovered`] + /// Consumes the type, recover signer and return [`RecoveredTx`] /// /// Returns `None` if the transaction's signature is invalid, see also [`Self::recover_signer`]. - pub fn into_ecrecovered(self) -> Option { + pub fn into_ecrecovered(self) -> Option { let signer = self.recover_signer()?; - Some(TransactionSignedEcRecovered { signed_transaction: self, signer }) + Some(RecoveredTx { signed_transaction: self, signer }) } - /// Consumes the type, recover signer and return [`TransactionSignedEcRecovered`] _without + /// Consumes the type, recover signer and return [`RecoveredTx`] _without /// ensuring that the signature has a low `s` value_ (EIP-2). /// /// Returns `None` if the transaction's signature is invalid, see also /// [`Self::recover_signer_unchecked`]. - pub fn into_ecrecovered_unchecked(self) -> Option { + pub fn into_ecrecovered_unchecked(self) -> Option { let signer = self.recover_signer_unchecked()?; - Some(TransactionSignedEcRecovered { signed_transaction: self, signer }) + Some(RecoveredTx { signed_transaction: self, signer }) } - /// Tries to recover signer and return [`TransactionSignedEcRecovered`] by cloning the type. - pub fn try_ecrecovered(&self) -> Option { + /// Tries to recover signer and return [`RecoveredTx`] by cloning the type. + pub fn try_ecrecovered(&self) -> Option { let signer = self.recover_signer()?; - Some(TransactionSignedEcRecovered { signed_transaction: self.clone(), signer }) + Some(RecoveredTx { signed_transaction: self.clone(), signer }) } - /// Tries to recover signer and return [`TransactionSignedEcRecovered`]. + /// Tries to recover signer and return [`RecoveredTx`]. /// /// Returns `Err(Self)` if the transaction's signature is invalid, see also /// [`Self::recover_signer`]. - pub fn try_into_ecrecovered(self) -> Result { + pub fn try_into_ecrecovered(self) -> Result { match self.recover_signer() { None => Err(self), - Some(signer) => Ok(TransactionSignedEcRecovered { signed_transaction: self, signer }), + Some(signer) => Ok(RecoveredTx { signed_transaction: self, signer }), } } - /// Tries to recover signer and return [`TransactionSignedEcRecovered`]. _without ensuring that + /// Tries to recover signer and return [`RecoveredTx`]. _without ensuring that /// the signature has a low `s` value_ (EIP-2). /// /// Returns `Err(Self)` if the transaction's signature is invalid, see also /// [`Self::recover_signer_unchecked`]. - pub fn try_into_ecrecovered_unchecked(self) -> Result { + pub fn try_into_ecrecovered_unchecked(self) -> Result { match self.recover_signer_unchecked() { None => Err(self), - Some(signer) => Ok(TransactionSignedEcRecovered { signed_transaction: self, signer }), + Some(signer) => Ok(RecoveredTx { signed_transaction: self, signer }), } } @@ -1433,8 +1433,8 @@ impl alloy_consensus::Transaction for TransactionSigned { } } -impl From for TransactionSigned { - fn from(recovered: TransactionSignedEcRecovered) -> Self { +impl From for TransactionSigned { + fn from(recovered: RecoveredTx) -> Self { recovered.signed_transaction } } @@ -1620,9 +1620,12 @@ impl<'a> arbitrary::Arbitrary<'a> for TransactionSigned { } } +/// Type alias kept for backward compatibility. +pub type TransactionSignedEcRecovered = RecoveredTx; + /// Signed transaction with recovered signer. #[derive(Debug, Clone, PartialEq, Hash, Eq, AsRef, Deref)] -pub struct TransactionSignedEcRecovered { +pub struct RecoveredTx { /// Signer of the transaction signer: Address, /// Signed transaction @@ -1631,9 +1634,9 @@ pub struct TransactionSignedEcRecovered { signed_transaction: T, } -// === impl TransactionSignedEcRecovered === +// === impl RecoveredTx === -impl TransactionSignedEcRecovered { +impl RecoveredTx { /// Signer of transaction recovered from signature pub const fn signer(&self) -> Address { self.signer @@ -1654,7 +1657,7 @@ impl TransactionSignedEcRecovered { (self.signed_transaction, self.signer) } - /// Create [`TransactionSignedEcRecovered`] from [`TransactionSigned`] and [`Address`] of the + /// Create [`RecoveredTx`] from [`TransactionSigned`] and [`Address`] of the /// signer. #[inline] pub const fn from_signed_transaction(signed_transaction: T, signer: Address) -> Self { @@ -1662,7 +1665,7 @@ impl TransactionSignedEcRecovered { } } -impl Encodable for TransactionSignedEcRecovered { +impl Encodable for RecoveredTx { /// This encodes the transaction _with_ the signature, and an rlp header. /// /// Refer to docs for [`TransactionSigned::encode`] for details on the exact format. @@ -1675,7 +1678,7 @@ impl Encodable for TransactionSignedEcRecovered { } } -impl Decodable for TransactionSignedEcRecovered { +impl Decodable for RecoveredTx { fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { let signed_transaction = T::decode(buf)?; let signer = signed_transaction @@ -1685,20 +1688,38 @@ impl Decodable for TransactionSignedEcRecovered { } } -/// Extension trait for [`SignedTransaction`] to convert it into [`TransactionSignedEcRecovered`]. +impl Encodable2718 for RecoveredTx { + fn type_flag(&self) -> Option { + self.signed_transaction.type_flag() + } + + fn encode_2718_len(&self) -> usize { + self.signed_transaction.encode_2718_len() + } + + fn encode_2718(&self, out: &mut dyn alloy_rlp::BufMut) { + self.signed_transaction.encode_2718(out) + } + + fn trie_hash(&self) -> B256 { + self.signed_transaction.trie_hash() + } +} + +/// Extension trait for [`SignedTransaction`] to convert it into [`RecoveredTx`]. pub trait SignedTransactionIntoRecoveredExt: SignedTransaction { - /// Consumes the type, recover signer and return [`TransactionSignedEcRecovered`] _without + /// Consumes the type, recover signer and return [`RecoveredTx`] _without /// ensuring that the signature has a low `s` value_ (EIP-2). /// /// Returns `None` if the transaction's signature is invalid. - fn into_ecrecovered_unchecked(self) -> Option> { + fn into_ecrecovered_unchecked(self) -> Option> { let signer = self.recover_signer_unchecked()?; - Some(TransactionSignedEcRecovered::from_signed_transaction(self, signer)) + Some(RecoveredTx::from_signed_transaction(self, signer)) } - /// Returns the [`TransactionSignedEcRecovered`] transaction with the given sender. - fn with_signer(self, signer: Address) -> TransactionSignedEcRecovered { - TransactionSignedEcRecovered::from_signed_transaction(self, signer) + /// Returns the [`RecoveredTx`] transaction with the given sender. + fn with_signer(self, signer: Address) -> RecoveredTx { + RecoveredTx::from_signed_transaction(self, signer) } } @@ -1944,7 +1965,7 @@ where mod tests { use crate::{ transaction::{TxEip1559, TxKind, TxLegacy}, - Transaction, TransactionSigned, TransactionSignedEcRecovered, + RecoveredTx, Transaction, TransactionSigned, }; use alloy_consensus::Transaction as _; use alloy_eips::eip2718::{Decodable2718, Encodable2718}; @@ -2205,8 +2226,7 @@ mod tests { let tx = TransactionSigned::decode(&mut &input[..]).unwrap(); let recovered = tx.into_ecrecovered().unwrap(); - let decoded = - TransactionSignedEcRecovered::decode(&mut &alloy_rlp::encode(&recovered)[..]).unwrap(); + let decoded = RecoveredTx::decode(&mut &alloy_rlp::encode(&recovered)[..]).unwrap(); assert_eq!(recovered, decoded) } diff --git a/crates/primitives/src/transaction/pooled.rs b/crates/primitives/src/transaction/pooled.rs index 5015f5b8e46c..cdcc6b808dd7 100644 --- a/crates/primitives/src/transaction/pooled.rs +++ b/crates/primitives/src/transaction/pooled.rs @@ -5,9 +5,7 @@ use super::{ error::TransactionConversionError, recover_signer_unchecked, signature::recover_signer, TxEip7702, }; -use crate::{ - BlobTransaction, Transaction, TransactionSigned, TransactionSignedEcRecovered, TxType, -}; +use crate::{BlobTransaction, RecoveredTx, Transaction, TransactionSigned, TxType}; use alloc::vec::Vec; use alloy_consensus::{ constants::EIP4844_TX_TYPE_ID, @@ -26,7 +24,6 @@ use alloy_primitives::{ use alloy_rlp::{Decodable, Encodable, Error as RlpError, Header}; use bytes::Buf; use core::hash::{Hash, Hasher}; -use derive_more::{AsRef, Deref}; use reth_primitives_traits::{InMemorySize, SignedTransaction}; use revm_primitives::keccak256; use serde::{Deserialize, Serialize}; @@ -77,7 +74,7 @@ impl PooledTransactionsElement { } } - /// Converts from an EIP-4844 [`TransactionSignedEcRecovered`] to a + /// Converts from an EIP-4844 [`RecoveredTx`] to a /// [`PooledTransactionsElementEcRecovered`] with the given sidecar. /// /// Returns an `Err` containing the original `TransactionSigned` if the transaction is not @@ -151,7 +148,7 @@ impl PooledTransactionsElement { pub fn try_into_ecrecovered(self) -> Result { match self.recover_signer() { None => Err(self), - Some(signer) => Ok(PooledTransactionsElementEcRecovered { transaction: self, signer }), + Some(signer) => Ok(RecoveredTx { signed_transaction: self, signer }), } } @@ -167,10 +164,10 @@ impl PooledTransactionsElement { } } - /// Create [`TransactionSignedEcRecovered`] by converting this transaction into + /// Create [`RecoveredTx`] by converting this transaction into /// [`TransactionSigned`] and [`Address`] of the signer. - pub fn into_ecrecovered_transaction(self, signer: Address) -> TransactionSignedEcRecovered { - TransactionSignedEcRecovered::from_signed_transaction(self.into_transaction(), signer) + pub fn into_ecrecovered_transaction(self, signer: Address) -> RecoveredTx { + RecoveredTx::from_signed_transaction(self.into_transaction(), signer) } /// Returns the inner [`TransactionSigned`]. @@ -645,7 +642,7 @@ impl InMemorySize for PooledTransactionsElement { impl From for PooledTransactionsElement { fn from(recovered: PooledTransactionsElementEcRecovered) -> Self { - recovered.into_transaction() + recovered.into_signed() } } @@ -691,92 +688,45 @@ impl<'a> arbitrary::Arbitrary<'a> for PooledTransactionsElement { } /// A signed pooled transaction with recovered signer. -#[derive(Debug, Clone, PartialEq, Eq, AsRef, Deref)] -pub struct PooledTransactionsElementEcRecovered { - /// Signer of the transaction - signer: Address, - /// Signed transaction - #[deref] - #[as_ref] - transaction: T, -} - -impl PooledTransactionsElementEcRecovered { - /// Create an instance from the given transaction and the [`Address`] of the signer. - pub const fn from_signed_transaction(transaction: T, signer: Address) -> Self { - Self { transaction, signer } - } - - /// Signer of transaction recovered from signature - pub const fn signer(&self) -> Address { - self.signer - } +pub type PooledTransactionsElementEcRecovered = RecoveredTx; - /// Consume the type and return the transaction - pub fn into_transaction(self) -> T { - self.transaction - } - - /// Dissolve Self to its component - pub fn into_components(self) -> (T, Address) { - (self.transaction, self.signer) - } -} impl PooledTransactionsElementEcRecovered { - /// Transform back to [`TransactionSignedEcRecovered`] - pub fn into_ecrecovered_transaction(self) -> TransactionSignedEcRecovered { - let (tx, signer) = self.into_components(); + /// Transform back to [`RecoveredTx`] + pub fn into_ecrecovered_transaction(self) -> RecoveredTx { + let (tx, signer) = self.to_components(); tx.into_ecrecovered_transaction(signer) } - /// Converts from an EIP-4844 [`TransactionSignedEcRecovered`] to a + /// Converts from an EIP-4844 [`RecoveredTx`] to a /// [`PooledTransactionsElementEcRecovered`] with the given sidecar. /// /// Returns the transaction is not an EIP-4844 transaction. pub fn try_from_blob_transaction( - tx: TransactionSignedEcRecovered, + tx: RecoveredTx, sidecar: BlobTransactionSidecar, - ) -> Result { - let TransactionSignedEcRecovered { signer, signed_transaction } = tx; + ) -> Result { + let RecoveredTx { signer, signed_transaction } = tx; let transaction = PooledTransactionsElement::try_from_blob_transaction(signed_transaction, sidecar) - .map_err(|tx| TransactionSignedEcRecovered { signer, signed_transaction: tx })?; - Ok(Self { transaction, signer }) + .map_err(|tx| RecoveredTx { signer, signed_transaction: tx })?; + Ok(Self::from_signed_transaction(transaction, signer)) } } -/// Converts a `TransactionSignedEcRecovered` into a `PooledTransactionsElementEcRecovered`. -impl TryFrom for PooledTransactionsElementEcRecovered { +/// Converts a `Recovered` into a `PooledTransactionsElementEcRecovered`. +impl TryFrom for PooledTransactionsElementEcRecovered { type Error = TransactionConversionError; - fn try_from(tx: TransactionSignedEcRecovered) -> Result { + fn try_from(tx: RecoveredTx) -> Result { match PooledTransactionsElement::try_from(tx.signed_transaction) { Ok(pooled_transaction) => { - Ok(Self { transaction: pooled_transaction, signer: tx.signer }) + Ok(Self::from_signed_transaction(pooled_transaction, tx.signer)) } Err(_) => Err(TransactionConversionError::UnsupportedForP2P), } } } -impl Encodable2718 for PooledTransactionsElementEcRecovered { - fn type_flag(&self) -> Option { - self.transaction.type_flag() - } - - fn encode_2718_len(&self) -> usize { - self.transaction.encode_2718_len() - } - - fn encode_2718(&self, out: &mut dyn alloy_rlp::BufMut) { - self.transaction.encode_2718(out) - } - - fn trie_hash(&self) -> B256 { - self.transaction.trie_hash() - } -} - #[cfg(test)] mod tests { use super::*; diff --git a/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs b/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs index 4394feb28341..72d53a22a238 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs @@ -18,7 +18,7 @@ use reth_evm::{ use reth_execution_types::ExecutionOutcome; use reth_primitives::{ proofs::calculate_transaction_root, Block, BlockBody, BlockExt, InvalidTransactionError, - Receipt, SealedBlockWithSenders, SealedHeader, TransactionSignedEcRecovered, + Receipt, RecoveredTx, SealedBlockWithSenders, SealedHeader, }; use reth_provider::{ BlockReader, BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, ProviderError, @@ -194,7 +194,7 @@ pub trait LoadPendingBlock: /// Assembles a [`Receipt`] for a transaction, based on its [`ExecutionResult`]. fn assemble_receipt( &self, - tx: &TransactionSignedEcRecovered, + tx: &RecoveredTx, result: ExecutionResult, cumulative_gas_used: u64, ) -> Receipt { diff --git a/crates/rpc/rpc-eth-types/src/transaction.rs b/crates/rpc/rpc-eth-types/src/transaction.rs index 83ef97807de0..f994638d3af8 100644 --- a/crates/rpc/rpc-eth-types/src/transaction.rs +++ b/crates/rpc/rpc-eth-types/src/transaction.rs @@ -4,7 +4,7 @@ use alloy_primitives::B256; use alloy_rpc_types_eth::TransactionInfo; -use reth_primitives::{TransactionSigned, TransactionSignedEcRecovered}; +use reth_primitives::{RecoveredTx, TransactionSigned}; use reth_primitives_traits::SignedTransaction; use reth_rpc_types_compat::{ transaction::{from_recovered, from_recovered_with_block_context}, @@ -15,13 +15,13 @@ use reth_rpc_types_compat::{ #[derive(Debug, Clone, Eq, PartialEq)] pub enum TransactionSource { /// Transaction exists in the pool (Pending) - Pool(TransactionSignedEcRecovered), + Pool(RecoveredTx), /// Transaction already included in a block /// /// This can be a historical block or a pending block (received from the CL) Block { /// Transaction fetched via provider - transaction: TransactionSignedEcRecovered, + transaction: RecoveredTx, /// Index of the transaction in the block index: u64, /// Hash of the block. @@ -37,7 +37,7 @@ pub enum TransactionSource { impl TransactionSource { /// Consumes the type and returns the wrapped transaction. - pub fn into_recovered(self) -> TransactionSignedEcRecovered { + pub fn into_recovered(self) -> RecoveredTx { self.into() } @@ -63,7 +63,7 @@ impl TransactionSource { } /// Returns the transaction and block related info, if not pending - pub fn split(self) -> (TransactionSignedEcRecovered, TransactionInfo) { + pub fn split(self) -> (RecoveredTx, TransactionInfo) { match self { Self::Pool(tx) => { let hash = tx.trie_hash(); @@ -86,7 +86,7 @@ impl TransactionSource { } } -impl From> for TransactionSignedEcRecovered { +impl From> for RecoveredTx { fn from(value: TransactionSource) -> Self { match value { TransactionSource::Pool(tx) => tx, diff --git a/crates/rpc/rpc-types-compat/src/transaction.rs b/crates/rpc/rpc-types-compat/src/transaction.rs index b439b61d44e8..d6180ca1ee20 100644 --- a/crates/rpc/rpc-types-compat/src/transaction.rs +++ b/crates/rpc/rpc-types-compat/src/transaction.rs @@ -8,7 +8,7 @@ use alloy_rpc_types_eth::{ request::{TransactionInput, TransactionRequest}, TransactionInfo, }; -use reth_primitives::{TransactionSigned, TransactionSignedEcRecovered}; +use reth_primitives::{RecoveredTx, TransactionSigned}; use serde::{Deserialize, Serialize}; /// Create a new rpc transaction result for a mined transaction, using the given block hash, @@ -17,7 +17,7 @@ use serde::{Deserialize, Serialize}; /// The block hash, number, and tx index fields should be from the original block where the /// transaction was mined. pub fn from_recovered_with_block_context>( - tx: TransactionSignedEcRecovered, + tx: RecoveredTx, tx_info: TransactionInfo, resp_builder: &T, ) -> Result { @@ -27,7 +27,7 @@ pub fn from_recovered_with_block_context>( /// Create a new rpc transaction result for a _pending_ signed transaction, setting block /// environment related fields to `None`. pub fn from_recovered>( - tx: TransactionSignedEcRecovered, + tx: RecoveredTx, resp_builder: &T, ) -> Result { resp_builder.fill(tx, TransactionInfo::default()) @@ -53,7 +53,7 @@ pub trait TransactionCompat: /// environment related fields to `None`. fn fill( &self, - tx: TransactionSignedEcRecovered, + tx: RecoveredTx, tx_inf: TransactionInfo, ) -> Result; @@ -63,8 +63,8 @@ pub trait TransactionCompat: fn otterscan_api_truncate_input(tx: &mut Self::Transaction); } -/// Convert [`TransactionSignedEcRecovered`] to [`TransactionRequest`] -pub fn transaction_to_call_request(tx: TransactionSignedEcRecovered) -> TransactionRequest { +/// Convert [`RecoveredTx`] to [`TransactionRequest`] +pub fn transaction_to_call_request(tx: RecoveredTx) -> TransactionRequest { let from = tx.signer(); let to = Some(tx.transaction.to().into()); let gas = tx.transaction.gas_limit(); diff --git a/crates/rpc/rpc/src/eth/bundle.rs b/crates/rpc/rpc/src/eth/bundle.rs index 3a748f529a0f..2924e6ea25fc 100644 --- a/crates/rpc/rpc/src/eth/bundle.rs +++ b/crates/rpc/rpc/src/eth/bundle.rs @@ -82,7 +82,7 @@ where .map(recover_raw_transaction) .collect::, _>>()? .into_iter() - .map(|tx| tx.into_components()) + .map(|tx| tx.to_components()) .collect::>(); // Validate that the bundle does not contain more than MAX_BLOB_NUMBER_PER_BLOCK blob diff --git a/crates/rpc/rpc/src/eth/filter.rs b/crates/rpc/rpc/src/eth/filter.rs index b16b370b2c02..c1ef67d9b595 100644 --- a/crates/rpc/rpc/src/eth/filter.rs +++ b/crates/rpc/rpc/src/eth/filter.rs @@ -9,7 +9,7 @@ use alloy_rpc_types_eth::{ use async_trait::async_trait; use jsonrpsee::{core::RpcResult, server::IdProvider}; use reth_chainspec::ChainInfo; -use reth_primitives::{Receipt, SealedBlockWithSenders, TransactionSignedEcRecovered}; +use reth_primitives::{Receipt, RecoveredTx, SealedBlockWithSenders}; use reth_provider::{BlockIdReader, BlockReader, ProviderError}; use reth_rpc_eth_api::{ EthApiTypes, EthFilterApiServer, FullEthApiTypes, RpcTransaction, TransactionCompat, @@ -621,7 +621,7 @@ where /// Returns all new pending transactions received since the last poll. async fn drain(&self) -> FilterChanges where - T: PoolTransaction>, + T: PoolTransaction>, { let mut pending_txs = Vec::new(); let mut prepared_stream = self.txs_stream.lock().await; @@ -651,7 +651,7 @@ trait FullTransactionsFilter: fmt::Debug + Send + Sync + Unpin + 'static { impl FullTransactionsFilter for FullTransactionsReceiver where - T: PoolTransaction> + 'static, + T: PoolTransaction> + 'static, TxCompat: TransactionCompat + 'static, { async fn drain(&self) -> FilterChanges { diff --git a/crates/rpc/rpc/src/eth/helpers/types.rs b/crates/rpc/rpc/src/eth/helpers/types.rs index 157213b54e66..79fb6fcc907f 100644 --- a/crates/rpc/rpc/src/eth/helpers/types.rs +++ b/crates/rpc/rpc/src/eth/helpers/types.rs @@ -3,7 +3,7 @@ use alloy_consensus::{Signed, Transaction as _, TxEip4844Variant, TxEnvelope}; use alloy_network::{Ethereum, Network}; use alloy_rpc_types_eth::{Transaction, TransactionInfo}; -use reth_primitives::{TransactionSigned, TransactionSignedEcRecovered}; +use reth_primitives::{RecoveredTx, TransactionSigned}; use reth_rpc_eth_api::EthApiTypes; use reth_rpc_eth_types::EthApiError; use reth_rpc_types_compat::TransactionCompat; @@ -37,7 +37,7 @@ where fn fill( &self, - tx: TransactionSignedEcRecovered, + tx: RecoveredTx, tx_info: TransactionInfo, ) -> Result { let from = tx.signer(); diff --git a/crates/rpc/rpc/src/eth/sim_bundle.rs b/crates/rpc/rpc/src/eth/sim_bundle.rs index f77b7e79da0c..87778ec6e650 100644 --- a/crates/rpc/rpc/src/eth/sim_bundle.rs +++ b/crates/rpc/rpc/src/eth/sim_bundle.rs @@ -172,7 +172,7 @@ where BundleItem::Tx { tx, can_revert } => { let recovered_tx = recover_raw_transaction(tx.clone()).map_err(EthApiError::from)?; - let (tx, signer) = recovered_tx.into_components(); + let (tx, signer) = recovered_tx.to_components(); let tx = tx.into_transaction(); let refund_percent = diff --git a/crates/rpc/rpc/src/txpool.rs b/crates/rpc/rpc/src/txpool.rs index 442e28ffc4cd..b12e8e7ab57f 100644 --- a/crates/rpc/rpc/src/txpool.rs +++ b/crates/rpc/rpc/src/txpool.rs @@ -8,7 +8,7 @@ use alloy_rpc_types_txpool::{ }; use async_trait::async_trait; use jsonrpsee::core::RpcResult; -use reth_primitives::TransactionSignedEcRecovered; +use reth_primitives::RecoveredTx; use reth_rpc_api::TxPoolApiServer; use reth_rpc_types_compat::{transaction::from_recovered, TransactionCompat}; use reth_transaction_pool::{AllPoolTransactions, PoolTransaction, TransactionPool}; @@ -44,7 +44,7 @@ where resp_builder: &RpcTxB, ) -> Result<(), RpcTxB::Error> where - Tx: PoolTransaction>, + Tx: PoolTransaction>, RpcTxB: TransactionCompat, { content.entry(tx.sender()).or_default().insert( @@ -96,12 +96,12 @@ where trace!(target: "rpc::eth", "Serving txpool_inspect"); #[inline] - fn insert>>( + fn insert>>( tx: &T, inspect: &mut BTreeMap>, ) { let entry = inspect.entry(tx.sender()).or_default(); - let tx: TransactionSignedEcRecovered = tx.clone_into_consensus().into(); + let tx: RecoveredTx = tx.clone_into_consensus().into(); entry.insert( tx.nonce().to_string(), TxpoolInspectSummary { diff --git a/crates/transaction-pool/src/maintain.rs b/crates/transaction-pool/src/maintain.rs index 1a5fd8399266..7e28b6e26859 100644 --- a/crates/transaction-pool/src/maintain.rs +++ b/crates/transaction-pool/src/maintain.rs @@ -19,8 +19,7 @@ use reth_chainspec::{ChainSpecProvider, EthChainSpec}; use reth_execution_types::ChangedAccount; use reth_fs_util::FsPathError; use reth_primitives::{ - PooledTransactionsElementEcRecovered, SealedHeader, TransactionSigned, - TransactionSignedEcRecovered, + PooledTransactionsElementEcRecovered, RecoveredTx, SealedHeader, TransactionSigned, }; use reth_primitives_traits::SignedTransaction; use reth_storage_api::{errors::provider::ProviderError, BlockReaderIdExt, StateProviderFactory}; @@ -604,8 +603,7 @@ where let local_transactions = local_transactions .into_iter() .map(|tx| { - let recovered: TransactionSignedEcRecovered = - tx.transaction.clone_into_consensus().into(); + let recovered: RecoveredTx = tx.transaction.clone_into_consensus().into(); recovered.into_signed() }) .collect::>(); diff --git a/crates/transaction-pool/src/pool/best.rs b/crates/transaction-pool/src/pool/best.rs index ed94bc676236..be49ce0b1fda 100644 --- a/crates/transaction-pool/src/pool/best.rs +++ b/crates/transaction-pool/src/pool/best.rs @@ -7,7 +7,7 @@ use crate::{ use alloy_primitives::Address; use core::fmt; use reth_payload_util::PayloadTransactions; -use reth_primitives::{InvalidTransactionError, TransactionSignedEcRecovered}; +use reth_primitives::{InvalidTransactionError, RecoveredTx}; use std::{ collections::{BTreeMap, BTreeSet, HashSet, VecDeque}, sync::Arc, @@ -226,7 +226,7 @@ impl Iterator for BestTransactions { #[derive(Debug)] pub struct BestPayloadTransactions where - T: PoolTransaction>, + T: PoolTransaction>, I: Iterator>>, { invalid: HashSet
, @@ -235,7 +235,7 @@ where impl BestPayloadTransactions where - T: PoolTransaction>, + T: PoolTransaction>, I: Iterator>>, { /// Create a new `BestPayloadTransactions` with the given iterator. @@ -246,10 +246,10 @@ where impl PayloadTransactions for BestPayloadTransactions where - T: PoolTransaction>, + T: PoolTransaction>, I: Iterator>>, { - fn next(&mut self, _ctx: ()) -> Option { + fn next(&mut self, _ctx: ()) -> Option { loop { let tx = self.best.next()?; if self.invalid.contains(&tx.sender()) { diff --git a/crates/transaction-pool/src/test_utils/mock.rs b/crates/transaction-pool/src/test_utils/mock.rs index 78982cb46575..05551151d780 100644 --- a/crates/transaction-pool/src/test_utils/mock.rs +++ b/crates/transaction-pool/src/test_utils/mock.rs @@ -26,7 +26,7 @@ use rand::{ }; use reth_primitives::{ transaction::TryFromRecoveredTransactionError, PooledTransactionsElementEcRecovered, - Transaction, TransactionSigned, TransactionSignedEcRecovered, TxType, + RecoveredTx, Transaction, TransactionSigned, TxType, }; use reth_primitives_traits::InMemorySize; use std::{ops::Range, sync::Arc, time::Instant, vec::IntoIter}; @@ -592,7 +592,7 @@ impl MockTransaction { impl PoolTransaction for MockTransaction { type TryFromConsensusError = TryFromRecoveredTransactionError; - type Consensus = TransactionSignedEcRecovered; + type Consensus = RecoveredTx; type Pooled = PooledTransactionsElementEcRecovered; @@ -804,10 +804,10 @@ impl EthPoolTransaction for MockTransaction { } } -impl TryFrom for MockTransaction { +impl TryFrom for MockTransaction { type Error = TryFromRecoveredTransactionError; - fn try_from(tx: TransactionSignedEcRecovered) -> Result { + fn try_from(tx: RecoveredTx) -> Result { let sender = tx.signer(); let transaction = tx.into_signed(); let hash = transaction.hash(); @@ -926,7 +926,7 @@ impl From for MockTransaction { } } -impl From for TransactionSignedEcRecovered { +impl From for RecoveredTx { fn from(tx: MockTransaction) -> Self { let signed_tx = TransactionSigned::new(tx.clone().into(), Signature::test_signature(), *tx.hash()); @@ -1029,11 +1029,9 @@ impl proptest::arbitrary::Arbitrary for MockTransaction { arb::<(TransactionSigned, Address)>() .prop_map(|(signed_transaction, signer)| { - TransactionSignedEcRecovered::from_signed_transaction(signed_transaction, signer) + RecoveredTx::from_signed_transaction(signed_transaction, signer) .try_into() - .expect( - "Failed to create an Arbitrary MockTransaction via TransactionSignedEcRecovered", - ) + .expect("Failed to create an Arbitrary MockTransaction via RecoveredTx") }) .boxed() } diff --git a/crates/transaction-pool/src/traits.rs b/crates/transaction-pool/src/traits.rs index 11c8db225b0a..a5c85ce125b6 100644 --- a/crates/transaction-pool/src/traits.rs +++ b/crates/transaction-pool/src/traits.rs @@ -20,8 +20,7 @@ use reth_eth_wire_types::HandleMempoolData; use reth_execution_types::ChangedAccount; use reth_primitives::{ kzg::KzgSettings, transaction::TryFromRecoveredTransactionError, PooledTransactionsElement, - PooledTransactionsElementEcRecovered, SealedBlock, Transaction, TransactionSigned, - TransactionSignedEcRecovered, + PooledTransactionsElementEcRecovered, RecoveredTx, SealedBlock, Transaction, TransactionSigned, }; use reth_primitives_traits::SignedTransaction; #[cfg(feature = "serde")] @@ -577,12 +576,12 @@ pub struct AllPoolTransactions { // === impl AllPoolTransactions === impl AllPoolTransactions { - /// Returns an iterator over all pending [`TransactionSignedEcRecovered`] transactions. + /// Returns an iterator over all pending [`RecoveredTx`] transactions. pub fn pending_recovered(&self) -> impl Iterator + '_ { self.pending.iter().map(|tx| tx.transaction.clone().into()) } - /// Returns an iterator over all queued [`TransactionSignedEcRecovered`] transactions. + /// Returns an iterator over all queued [`RecoveredTx`] transactions. pub fn queued_recovered(&self) -> impl Iterator + '_ { self.queued.iter().map(|tx| tx.transaction.clone().into()) } @@ -1132,9 +1131,7 @@ pub trait PoolTransaction: fmt::Debug + Send + Sync + Clone { /// Ethereum pool. pub trait EthPoolTransaction: PoolTransaction< - Consensus: From - + Into - + Into, + Consensus: From + Into + Into, Pooled: From + Into + Into, @@ -1166,10 +1163,10 @@ pub trait EthPoolTransaction: /// The default [`PoolTransaction`] for the [Pool](crate::Pool) for Ethereum. /// -/// This type is essentially a wrapper around [`TransactionSignedEcRecovered`] with additional +/// This type is essentially a wrapper around [`RecoveredTx`] with additional /// fields derived from the transaction that are frequently used by the pools for ordering. #[derive(Debug, Clone, PartialEq, Eq)] -pub struct EthPooledTransaction { +pub struct EthPooledTransaction { /// `EcRecovered` transaction, the consensus format. pub(crate) transaction: T, @@ -1192,7 +1189,7 @@ impl EthPooledTransaction { /// /// Caution: In case of blob transactions, this does marks the blob sidecar as /// [`EthBlobTransactionSidecar::Missing`] - pub fn new(transaction: TransactionSignedEcRecovered, encoded_length: usize) -> Self { + pub fn new(transaction: RecoveredTx, encoded_length: usize) -> Self { let mut blob_sidecar = EthBlobTransactionSidecar::None; let gas_cost = U256::from(transaction.transaction.max_fee_per_gas()) @@ -1215,7 +1212,7 @@ impl EthPooledTransaction { } /// Return the reference to the underlying transaction. - pub const fn transaction(&self) -> &TransactionSignedEcRecovered { + pub const fn transaction(&self) -> &RecoveredTx { &self.transaction } } @@ -1224,12 +1221,12 @@ impl EthPooledTransaction { impl From for EthPooledTransaction { fn from(tx: PooledTransactionsElementEcRecovered) -> Self { let encoded_length = tx.encode_2718_len(); - let (tx, signer) = tx.into_components(); + let (tx, signer) = tx.to_components(); match tx { PooledTransactionsElement::BlobTransaction(tx) => { // include the blob sidecar let (tx, blob) = tx.into_parts(); - let tx = TransactionSignedEcRecovered::from_signed_transaction(tx, signer); + let tx = RecoveredTx::from_signed_transaction(tx, signer); let mut pooled = Self::new(tx, encoded_length); pooled.blob_sidecar = EthBlobTransactionSidecar::Present(blob); pooled @@ -1245,7 +1242,7 @@ impl From for EthPooledTransaction { impl PoolTransaction for EthPooledTransaction { type TryFromConsensusError = TryFromRecoveredTransactionError; - type Consensus = TransactionSignedEcRecovered; + type Consensus = RecoveredTx; type Pooled = PooledTransactionsElementEcRecovered; @@ -1406,10 +1403,10 @@ impl EthPoolTransaction for EthPooledTransaction { } } -impl TryFrom for EthPooledTransaction { +impl TryFrom for EthPooledTransaction { type Error = TryFromRecoveredTransactionError; - fn try_from(tx: TransactionSignedEcRecovered) -> Result { + fn try_from(tx: RecoveredTx) -> Result { // ensure we can handle the transaction type and its format match tx.tx_type() as u8 { 0..=EIP1559_TX_TYPE_ID | EIP7702_TX_TYPE_ID => { @@ -1433,7 +1430,7 @@ impl TryFrom for EthPooledTransaction { } } -impl From for TransactionSignedEcRecovered { +impl From for RecoveredTx { fn from(tx: EthPooledTransaction) -> Self { tx.transaction } @@ -1645,8 +1642,7 @@ mod tests { }); let signature = Signature::test_signature(); let signed_tx = TransactionSigned::new_unhashed(tx, signature); - let transaction = - TransactionSignedEcRecovered::from_signed_transaction(signed_tx, Default::default()); + let transaction = RecoveredTx::from_signed_transaction(signed_tx, Default::default()); let pooled_tx = EthPooledTransaction::new(transaction.clone(), 200); // Check that the pooled transaction is created correctly @@ -1667,8 +1663,7 @@ mod tests { }); let signature = Signature::test_signature(); let signed_tx = TransactionSigned::new_unhashed(tx, signature); - let transaction = - TransactionSignedEcRecovered::from_signed_transaction(signed_tx, Default::default()); + let transaction = RecoveredTx::from_signed_transaction(signed_tx, Default::default()); let pooled_tx = EthPooledTransaction::new(transaction.clone(), 200); // Check that the pooled transaction is created correctly @@ -1689,8 +1684,7 @@ mod tests { }); let signature = Signature::test_signature(); let signed_tx = TransactionSigned::new_unhashed(tx, signature); - let transaction = - TransactionSignedEcRecovered::from_signed_transaction(signed_tx, Default::default()); + let transaction = RecoveredTx::from_signed_transaction(signed_tx, Default::default()); let pooled_tx = EthPooledTransaction::new(transaction.clone(), 200); // Check that the pooled transaction is created correctly @@ -1713,8 +1707,7 @@ mod tests { }); let signature = Signature::test_signature(); let signed_tx = TransactionSigned::new_unhashed(tx, signature); - let transaction = - TransactionSignedEcRecovered::from_signed_transaction(signed_tx, Default::default()); + let transaction = RecoveredTx::from_signed_transaction(signed_tx, Default::default()); let pooled_tx = EthPooledTransaction::new(transaction.clone(), 300); // Check that the pooled transaction is created correctly @@ -1737,8 +1730,7 @@ mod tests { }); let signature = Signature::test_signature(); let signed_tx = TransactionSigned::new_unhashed(tx, signature); - let transaction = - TransactionSignedEcRecovered::from_signed_transaction(signed_tx, Default::default()); + let transaction = RecoveredTx::from_signed_transaction(signed_tx, Default::default()); let pooled_tx = EthPooledTransaction::new(transaction.clone(), 200); // Check that the pooled transaction is created correctly diff --git a/crates/transaction-pool/src/validate/mod.rs b/crates/transaction-pool/src/validate/mod.rs index a93825212f82..d333be87963b 100644 --- a/crates/transaction-pool/src/validate/mod.rs +++ b/crates/transaction-pool/src/validate/mod.rs @@ -9,7 +9,7 @@ use crate::{ use alloy_eips::eip4844::BlobTransactionSidecar; use alloy_primitives::{Address, TxHash, B256, U256}; use futures_util::future::Either; -use reth_primitives::{SealedBlock, TransactionSignedEcRecovered}; +use reth_primitives::{RecoveredTx, SealedBlock}; use std::{fmt, future::Future, time::Instant}; mod constants; @@ -435,11 +435,11 @@ impl ValidPoolTransaction { } } -impl>> ValidPoolTransaction { - /// Converts to this type into a [`TransactionSignedEcRecovered`]. +impl>> ValidPoolTransaction { + /// Converts to this type into a [`RecoveredTx`]. /// /// Note: this takes `&self` since indented usage is via `Arc`. - pub fn to_recovered_transaction(&self) -> TransactionSignedEcRecovered { + pub fn to_recovered_transaction(&self) -> RecoveredTx { self.to_consensus().into() } } From ea82cbdc607f98ef5454c4a10912fa197810cec9 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Tue, 3 Dec 2024 00:47:46 -0600 Subject: [PATCH 36/68] chore(sdk): define `OpTransactionSigned` (#11433) --- Cargo.lock | 6 + crates/optimism/bin/Cargo.toml | 3 +- crates/optimism/cli/Cargo.toml | 1 + crates/optimism/evm/Cargo.toml | 4 +- crates/optimism/node/Cargo.toml | 5 +- crates/optimism/primitives/Cargo.toml | 42 +- crates/optimism/primitives/src/lib.rs | 9 +- .../primitives/src/transaction/mod.rs | 30 +- .../primitives/src/transaction/signed.rs | 479 ++++++++++++++++++ crates/optimism/rpc/Cargo.toml | 3 +- crates/primitives/src/transaction/mod.rs | 13 +- crates/primitives/src/transaction/util.rs | 5 +- crates/storage/provider/Cargo.toml | 1 + 13 files changed, 572 insertions(+), 29 deletions(-) create mode 100644 crates/optimism/primitives/src/transaction/signed.rs diff --git a/Cargo.lock b/Cargo.lock index 8142bbc83875..b799d0e0811d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8464,14 +8464,20 @@ dependencies = [ "alloy-consensus", "alloy-eips", "alloy-primitives", + "alloy-rlp", "arbitrary", "bytes", "derive_more 1.0.0", "op-alloy-consensus", + "proptest", + "proptest-arbitrary-interop", + "rand 0.8.5", "reth-codecs", "reth-primitives", "reth-primitives-traits", + "revm-primitives", "rstest", + "secp256k1", "serde", ] diff --git a/crates/optimism/bin/Cargo.toml b/crates/optimism/bin/Cargo.toml index 9007d0848915..60fde90f1914 100644 --- a/crates/optimism/bin/Cargo.toml +++ b/crates/optimism/bin/Cargo.toml @@ -44,7 +44,8 @@ optimism = [ "reth-optimism-evm/optimism", "reth-optimism-payload-builder/optimism", "reth-optimism-rpc/optimism", - "reth-provider/optimism" + "reth-provider/optimism", + "reth-optimism-primitives/op", ] dev = [ diff --git a/crates/optimism/cli/Cargo.toml b/crates/optimism/cli/Cargo.toml index b61a4628f4d2..48ea2d07decc 100644 --- a/crates/optimism/cli/Cargo.toml +++ b/crates/optimism/cli/Cargo.toml @@ -95,6 +95,7 @@ optimism = [ "reth-execution-types/optimism", "reth-db/optimism", "reth-db-api/optimism", + "reth-optimism-primitives/op", "reth-downloaders/optimism" ] asm-keccak = [ diff --git a/crates/optimism/evm/Cargo.toml b/crates/optimism/evm/Cargo.toml index 95657e0ff207..309ddc1cb4e1 100644 --- a/crates/optimism/evm/Cargo.toml +++ b/crates/optimism/evm/Cargo.toml @@ -64,6 +64,7 @@ std = [ "alloy-primitives/std", "revm-primitives/std", "revm/std", + "reth-optimism-primitives/std", "reth-ethereum-forks/std", "derive_more/std", "reth-optimism-forks/std" @@ -73,5 +74,6 @@ optimism = [ "reth-execution-types/optimism", "reth-optimism-consensus/optimism", "revm/optimism", - "revm-primitives/optimism" + "revm-primitives/optimism", + "reth-optimism-primitives/op", ] diff --git a/crates/optimism/node/Cargo.toml b/crates/optimism/node/Cargo.toml index 79e0c451b790..b0b7065f3363 100644 --- a/crates/optimism/node/Cargo.toml +++ b/crates/optimism/node/Cargo.toml @@ -41,7 +41,7 @@ reth-optimism-rpc.workspace = true reth-optimism-chainspec.workspace = true reth-optimism-consensus.workspace = true reth-optimism-forks.workspace = true -reth-optimism-primitives.workspace = true +reth-optimism-primitives = { workspace = true, features = ["serde"] } # revm with required optimism features revm = { workspace = true, features = ["secp256k1", "blst", "c-kzg"] } @@ -96,7 +96,8 @@ optimism = [ "reth-optimism-consensus/optimism", "reth-db/optimism", "reth-optimism-node/optimism", - "reth-node-core/optimism" + "reth-node-core/optimism", + "reth-optimism-primitives/op", ] asm-keccak = [ "reth-primitives/asm-keccak", diff --git a/crates/optimism/primitives/Cargo.toml b/crates/optimism/primitives/Cargo.toml index bdc423e14982..38f76aa6256a 100644 --- a/crates/optimism/primitives/Cargo.toml +++ b/crates/optimism/primitives/Cargo.toml @@ -20,45 +20,60 @@ reth-codecs = { workspace = true, optional = true, features = ["op"] } # ethereum alloy-primitives.workspace = true alloy-consensus.workspace = true +alloy-rlp.workspace = true alloy-eips.workspace = true +revm-primitives.workspace = true +secp256k1 = { workspace = true, optional = true } # op op-alloy-consensus.workspace = true # codec -bytes.workspace = true +bytes = { workspace = true, optional = true } serde = { workspace = true, optional = true } # misc -derive_more.workspace = true +derive_more = { workspace = true, features = ["deref", "from", "into", "constructor"] } +rand = { workspace = true, optional = true } # test arbitrary = { workspace = true, features = ["derive"], optional = true } +proptest = { workspace = true, optional = true } [dev-dependencies] +proptest-arbitrary-interop.workspace = true reth-codecs = { workspace = true, features = ["test-utils", "op"] } rstest.workspace = true arbitrary.workspace = true +proptest.workspace = true [features] -default = ["std", "reth-codec"] +default = ["std"] std = [ "reth-primitives-traits/std", "reth-primitives/std", - "reth-codecs/std", + "reth-codecs?/std", "alloy-consensus/std", "alloy-eips/std", "alloy-primitives/std", - "serde/std", - "bytes/std", - "derive_more/std" + "serde?/std", + "bytes?/std", + "derive_more/std", + "revm-primitives/std", + "secp256k1?/std", + "alloy-rlp/std", ] reth-codec = [ "dep:reth-codecs", + "std", + "rand", + "dep:proptest", + "dep:arbitrary", "reth-primitives/reth-codec", "reth-primitives-traits/reth-codec", "reth-codecs?/op", - "reth-primitives/reth-codec" + "reth-primitives/reth-codec", + "dep:bytes", ] serde = [ "dep:serde", @@ -66,12 +81,16 @@ serde = [ "alloy-primitives/serde", "alloy-consensus/serde", "alloy-eips/serde", - "bytes/serde", + "bytes?/serde", "reth-codecs?/serde", "op-alloy-consensus/serde", + "rand?/serde", + "revm-primitives/serde", + "secp256k1?/serde", ] arbitrary = [ "dep:arbitrary", + "dep:secp256k1", "reth-primitives-traits/arbitrary", "reth-primitives/arbitrary", "reth-codecs?/arbitrary", @@ -79,4 +98,9 @@ arbitrary = [ "alloy-consensus/arbitrary", "alloy-eips/arbitrary", "alloy-primitives/arbitrary", + "revm-primitives/arbitrary", + "rand", +] +op = [ + "revm-primitives/optimism", ] diff --git a/crates/optimism/primitives/src/lib.rs b/crates/optimism/primitives/src/lib.rs index 796f5cb06138..df5042110217 100644 --- a/crates/optimism/primitives/src/lib.rs +++ b/crates/optimism/primitives/src/lib.rs @@ -6,17 +6,20 @@ issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" )] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +// The `optimism` feature must be enabled to use this crate. +#![cfg(feature = "op")] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(not(feature = "std"), no_std)] +extern crate alloc; + pub mod bedrock; pub mod transaction; -use reth_primitives::EthPrimitives; -pub use transaction::{tx_type::OpTxType, OpTransaction}; +pub use transaction::{signed::OpTransactionSigned, tx_type::OpTxType, OpTransaction}; /// Optimism primitive types. -pub type OpPrimitives = EthPrimitives; +pub type OpPrimitives = reth_primitives::EthPrimitives; // TODO: once we are ready for separating primitive types, introduce a separate `NodePrimitives` // implementation used exclusively by legacy engine. diff --git a/crates/optimism/primitives/src/transaction/mod.rs b/crates/optimism/primitives/src/transaction/mod.rs index 5861a3229fe8..86ac822c744c 100644 --- a/crates/optimism/primitives/src/transaction/mod.rs +++ b/crates/optimism/primitives/src/transaction/mod.rs @@ -1,14 +1,21 @@ //! Wrapper of [`OpTypedTransaction`], that implements reth database encoding [`Compact`]. +pub mod signed; pub mod tx_type; use alloy_primitives::{bytes, Bytes, TxKind, Uint, B256}; -use alloy_consensus::{constants::EIP7702_TX_TYPE_ID, TxLegacy}; +#[cfg(any(test, feature = "reth-codec"))] +use alloy_consensus::constants::EIP7702_TX_TYPE_ID; +use alloy_consensus::{SignableTransaction, TxLegacy}; use alloy_eips::{eip2930::AccessList, eip7702::SignedAuthorization}; -use derive_more::{Deref, From}; -use op_alloy_consensus::{OpTypedTransaction, DEPOSIT_TX_TYPE_ID}; +use derive_more::{Constructor, Deref, From}; +use op_alloy_consensus::OpTypedTransaction; +#[cfg(any(test, feature = "reth-codec"))] +use op_alloy_consensus::DEPOSIT_TX_TYPE_ID; +#[cfg(any(test, feature = "reth-codec"))] use reth_codecs::Compact; +#[cfg(any(test, feature = "reth-codec"))] use reth_primitives::transaction::{ COMPACT_EXTENDED_IDENTIFIER_FLAG, COMPACT_IDENTIFIER_EIP1559, COMPACT_IDENTIFIER_EIP2930, COMPACT_IDENTIFIER_LEGACY, @@ -17,16 +24,31 @@ use reth_primitives_traits::InMemorySize; #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Debug, Clone, PartialEq, Eq, Deref, Hash, From)] +#[derive(Debug, Clone, PartialEq, Eq, Deref, Hash, From, Constructor)] /// Optimistic transaction. pub struct OpTransaction(OpTypedTransaction); +impl OpTransaction { + /// This encodes the transaction _without_ the signature, and is only suitable for creating a + /// hash intended for signing. + pub fn encode_for_signing(&self, out: &mut dyn bytes::BufMut) { + match self.deref() { + OpTypedTransaction::Legacy(tx) => tx.encode_for_signing(out), + OpTypedTransaction::Eip2930(tx) => tx.encode_for_signing(out), + OpTypedTransaction::Eip1559(tx) => tx.encode_for_signing(out), + OpTypedTransaction::Eip7702(tx) => tx.encode_for_signing(out), + OpTypedTransaction::Deposit(_) => {} + } + } +} + impl Default for OpTransaction { fn default() -> Self { Self(OpTypedTransaction::Legacy(TxLegacy::default())) } } +#[cfg(any(test, feature = "reth-codec"))] impl Compact for OpTransaction { fn to_compact(&self, out: &mut B) -> usize where diff --git a/crates/optimism/primitives/src/transaction/signed.rs b/crates/optimism/primitives/src/transaction/signed.rs new file mode 100644 index 000000000000..2dc72026e7cb --- /dev/null +++ b/crates/optimism/primitives/src/transaction/signed.rs @@ -0,0 +1,479 @@ +//! A signed Optimism transaction. + +use alloc::vec::Vec; +use core::{ + hash::{Hash, Hasher}, + mem, +}; +#[cfg(feature = "std")] +use std::sync::OnceLock; + +use alloy_consensus::{ + transaction::RlpEcdsaTx, SignableTransaction, Transaction, TxEip1559, TxEip2930, TxEip7702, +}; +use alloy_eips::{ + eip2718::{Decodable2718, Eip2718Error, Eip2718Result, Encodable2718}, + eip2930::AccessList, + eip7702::SignedAuthorization, +}; +use alloy_primitives::{ + keccak256, Address, Bytes, PrimitiveSignature as Signature, TxHash, TxKind, Uint, B256, U256, +}; +use alloy_rlp::Header; +use derive_more::{AsRef, Deref}; +#[cfg(not(feature = "std"))] +use once_cell::sync::OnceCell as OnceLock; +use op_alloy_consensus::{OpTypedTransaction, TxDeposit}; +#[cfg(any(test, feature = "reth-codec"))] +use proptest as _; +use reth_primitives::{ + transaction::{recover_signer, recover_signer_unchecked}, + TransactionSigned, +}; +use reth_primitives_traits::{FillTxEnv, InMemorySize, SignedTransaction}; +use revm_primitives::{AuthorizationList, OptimismFields, TxEnv}; + +use crate::{OpTransaction, OpTxType}; + +/// Signed transaction. +#[cfg_attr(any(test, feature = "reth-codec"), reth_codecs::add_arbitrary_tests(rlp))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[derive(Debug, Clone, Eq, AsRef, Deref)] +pub struct OpTransactionSigned { + /// Transaction hash + #[serde(skip)] + pub hash: OnceLock, + /// The transaction signature values + pub signature: Signature, + /// Raw transaction info + #[deref] + #[as_ref] + pub transaction: OpTransaction, +} + +impl OpTransactionSigned { + /// Calculates hash of given transaction and signature and returns new instance. + pub fn new(transaction: OpTypedTransaction, signature: Signature) -> Self { + let signed_tx = Self::new_unhashed(transaction, signature); + if !matches!(signed_tx.tx_type(), OpTxType::Deposit) { + signed_tx.hash.get_or_init(|| signed_tx.recalculate_hash()); + } + + signed_tx + } + + /// Creates a new signed transaction from the given transaction and signature without the hash. + /// + /// Note: this only calculates the hash on the first [`TransactionSigned::hash`] call. + pub fn new_unhashed(transaction: OpTypedTransaction, signature: Signature) -> Self { + Self { hash: Default::default(), signature, transaction: OpTransaction::new(transaction) } + } +} + +impl SignedTransaction for OpTransactionSigned { + type Type = OpTxType; + + fn tx_hash(&self) -> &TxHash { + self.hash.get_or_init(|| self.recalculate_hash()) + } + + fn signature(&self) -> &Signature { + &self.signature + } + + fn recover_signer(&self) -> Option
{ + // Optimism's Deposit transaction does not have a signature. Directly return the + // `from` address. + if let OpTypedTransaction::Deposit(TxDeposit { from, .. }) = *self.transaction { + return Some(from) + } + + let Self { transaction, signature, .. } = self; + let signature_hash = signature_hash(transaction); + recover_signer(signature, signature_hash) + } + + fn recover_signer_unchecked(&self) -> Option
{ + // Optimism's Deposit transaction does not have a signature. Directly return the + // `from` address. + if let OpTypedTransaction::Deposit(TxDeposit { from, .. }) = *self.transaction { + return Some(from) + } + + let Self { transaction, signature, .. } = self; + let signature_hash = signature_hash(transaction); + recover_signer_unchecked(signature, signature_hash) + } + + fn recalculate_hash(&self) -> B256 { + keccak256(self.encoded_2718()) + } + + fn recover_signer_unchecked_with_buf(&self, buf: &mut Vec) -> Option
{ + // Optimism's Deposit transaction does not have a signature. Directly return the + // `from` address. + if let OpTypedTransaction::Deposit(TxDeposit { from, .. }) = *self.transaction { + return Some(from) + } + self.encode_for_signing(buf); + let signature_hash = keccak256(buf); + recover_signer_unchecked(&self.signature, signature_hash) + } +} + +impl FillTxEnv for OpTransactionSigned { + fn fill_tx_env(&self, tx_env: &mut TxEnv, sender: Address) { + let envelope = self.encoded_2718(); + + tx_env.caller = sender; + match self.transaction.deref() { + OpTypedTransaction::Legacy(tx) => { + tx_env.gas_limit = tx.gas_limit; + tx_env.gas_price = U256::from(tx.gas_price); + tx_env.gas_priority_fee = None; + tx_env.transact_to = tx.to; + tx_env.value = tx.value; + tx_env.data = tx.input.clone(); + tx_env.chain_id = tx.chain_id; + tx_env.nonce = Some(tx.nonce); + tx_env.access_list.clear(); + tx_env.blob_hashes.clear(); + tx_env.max_fee_per_blob_gas.take(); + tx_env.authorization_list = None; + } + OpTypedTransaction::Eip2930(tx) => { + tx_env.gas_limit = tx.gas_limit; + tx_env.gas_price = U256::from(tx.gas_price); + tx_env.gas_priority_fee = None; + tx_env.transact_to = tx.to; + tx_env.value = tx.value; + tx_env.data = tx.input.clone(); + tx_env.chain_id = Some(tx.chain_id); + tx_env.nonce = Some(tx.nonce); + tx_env.access_list.clone_from(&tx.access_list.0); + tx_env.blob_hashes.clear(); + tx_env.max_fee_per_blob_gas.take(); + tx_env.authorization_list = None; + } + OpTypedTransaction::Eip1559(tx) => { + tx_env.gas_limit = tx.gas_limit; + tx_env.gas_price = U256::from(tx.max_fee_per_gas); + tx_env.gas_priority_fee = Some(U256::from(tx.max_priority_fee_per_gas)); + tx_env.transact_to = tx.to; + tx_env.value = tx.value; + tx_env.data = tx.input.clone(); + tx_env.chain_id = Some(tx.chain_id); + tx_env.nonce = Some(tx.nonce); + tx_env.access_list.clone_from(&tx.access_list.0); + tx_env.blob_hashes.clear(); + tx_env.max_fee_per_blob_gas.take(); + tx_env.authorization_list = None; + } + OpTypedTransaction::Eip7702(tx) => { + tx_env.gas_limit = tx.gas_limit; + tx_env.gas_price = U256::from(tx.max_fee_per_gas); + tx_env.gas_priority_fee = Some(U256::from(tx.max_priority_fee_per_gas)); + tx_env.transact_to = tx.to.into(); + tx_env.value = tx.value; + tx_env.data = tx.input.clone(); + tx_env.chain_id = Some(tx.chain_id); + tx_env.nonce = Some(tx.nonce); + tx_env.access_list.clone_from(&tx.access_list.0); + tx_env.blob_hashes.clear(); + tx_env.max_fee_per_blob_gas.take(); + tx_env.authorization_list = + Some(AuthorizationList::Signed(tx.authorization_list.clone())); + } + OpTypedTransaction::Deposit(tx) => { + tx_env.access_list.clear(); + tx_env.gas_limit = tx.gas_limit; + tx_env.gas_price = U256::ZERO; + tx_env.gas_priority_fee = None; + tx_env.transact_to = tx.to; + tx_env.value = tx.value; + tx_env.data = tx.input.clone(); + tx_env.chain_id = None; + tx_env.nonce = None; + tx_env.authorization_list = None; + + tx_env.optimism = OptimismFields { + source_hash: Some(tx.source_hash), + mint: tx.mint, + is_system_transaction: Some(tx.is_system_transaction), + enveloped_tx: Some(envelope.into()), + }; + return + } + } + + tx_env.optimism = OptimismFields { + source_hash: None, + mint: None, + is_system_transaction: Some(false), + enveloped_tx: Some(envelope.into()), + } + } +} + +impl InMemorySize for OpTransactionSigned { + #[inline] + fn size(&self) -> usize { + mem::size_of::() + self.transaction.size() + mem::size_of::() + } +} + +impl alloy_rlp::Encodable for OpTransactionSigned { + /// See [`alloy_rlp::Encodable`] impl for [`TransactionSigned`]. + fn encode(&self, out: &mut dyn alloy_rlp::bytes::BufMut) { + self.network_encode(out); + } + + fn length(&self) -> usize { + let mut payload_length = self.encode_2718_len(); + if !self.is_legacy() { + payload_length += Header { list: false, payload_length }.length(); + } + + payload_length + } +} + +impl alloy_rlp::Decodable for OpTransactionSigned { + /// See [`alloy_rlp::Decodable`] impl for [`TransactionSigned`]. + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { + Self::network_decode(buf).map_err(Into::into) + } +} + +impl Encodable2718 for OpTransactionSigned { + fn type_flag(&self) -> Option { + match self.tx_type() { + op_alloy_consensus::OpTxType::Legacy => None, + tx_type => Some(tx_type as u8), + } + } + + fn encode_2718_len(&self) -> usize { + match self.transaction.deref() { + OpTypedTransaction::Legacy(legacy_tx) => { + legacy_tx.eip2718_encoded_length(&self.signature) + } + OpTypedTransaction::Eip2930(access_list_tx) => { + access_list_tx.eip2718_encoded_length(&self.signature) + } + OpTypedTransaction::Eip1559(dynamic_fee_tx) => { + dynamic_fee_tx.eip2718_encoded_length(&self.signature) + } + OpTypedTransaction::Eip7702(set_code_tx) => { + set_code_tx.eip2718_encoded_length(&self.signature) + } + OpTypedTransaction::Deposit(deposit_tx) => deposit_tx.eip2718_encoded_length(), + } + } + + fn encode_2718(&self, out: &mut dyn alloy_rlp::BufMut) { + let Self { transaction, signature, .. } = self; + + match transaction.deref() { + OpTypedTransaction::Legacy(legacy_tx) => { + // do nothing w/ with_header + legacy_tx.eip2718_encode(signature, out) + } + OpTypedTransaction::Eip2930(access_list_tx) => { + access_list_tx.eip2718_encode(signature, out) + } + OpTypedTransaction::Eip1559(dynamic_fee_tx) => { + dynamic_fee_tx.eip2718_encode(signature, out) + } + OpTypedTransaction::Eip7702(set_code_tx) => set_code_tx.eip2718_encode(signature, out), + OpTypedTransaction::Deposit(deposit_tx) => deposit_tx.encode_2718(out), + } + } +} + +impl Decodable2718 for OpTransactionSigned { + fn typed_decode(ty: u8, buf: &mut &[u8]) -> Eip2718Result { + match ty.try_into().map_err(|_| Eip2718Error::UnexpectedType(ty))? { + op_alloy_consensus::OpTxType::Legacy => Err(Eip2718Error::UnexpectedType(0)), + op_alloy_consensus::OpTxType::Eip2930 => { + let (tx, signature, hash) = TxEip2930::rlp_decode_signed(buf)?.into_parts(); + let signed_tx = Self::new_unhashed(OpTypedTransaction::Eip2930(tx), signature); + signed_tx.hash.get_or_init(|| hash); + Ok(signed_tx) + } + op_alloy_consensus::OpTxType::Eip1559 => { + let (tx, signature, hash) = TxEip1559::rlp_decode_signed(buf)?.into_parts(); + let signed_tx = Self::new_unhashed(OpTypedTransaction::Eip1559(tx), signature); + signed_tx.hash.get_or_init(|| hash); + Ok(signed_tx) + } + op_alloy_consensus::OpTxType::Eip7702 => { + let (tx, signature, hash) = TxEip7702::rlp_decode_signed(buf)?.into_parts(); + let signed_tx = Self::new_unhashed(OpTypedTransaction::Eip7702(tx), signature); + signed_tx.hash.get_or_init(|| hash); + Ok(signed_tx) + } + op_alloy_consensus::OpTxType::Deposit => Ok(Self::new_unhashed( + OpTypedTransaction::Deposit(TxDeposit::rlp_decode(buf)?), + TxDeposit::signature(), + )), + } + } + + fn fallback_decode(buf: &mut &[u8]) -> Eip2718Result { + let (transaction, hash, signature) = + TransactionSigned::decode_rlp_legacy_transaction_tuple(buf)?; + let signed_tx = Self::new_unhashed(OpTypedTransaction::Legacy(transaction), signature); + signed_tx.hash.get_or_init(|| hash); + + Ok(signed_tx) + } +} + +impl Transaction for OpTransactionSigned { + fn chain_id(&self) -> Option { + self.deref().chain_id() + } + + fn nonce(&self) -> u64 { + self.deref().nonce() + } + + fn gas_limit(&self) -> u64 { + self.deref().gas_limit() + } + + fn gas_price(&self) -> Option { + self.deref().gas_price() + } + + fn max_fee_per_gas(&self) -> u128 { + self.deref().max_fee_per_gas() + } + + fn max_priority_fee_per_gas(&self) -> Option { + self.deref().max_priority_fee_per_gas() + } + + fn max_fee_per_blob_gas(&self) -> Option { + self.deref().max_fee_per_blob_gas() + } + + fn priority_fee_or_price(&self) -> u128 { + self.deref().priority_fee_or_price() + } + + fn kind(&self) -> TxKind { + self.deref().kind() + } + + fn is_create(&self) -> bool { + self.deref().is_create() + } + + fn value(&self) -> Uint<256, 4> { + self.deref().value() + } + + fn input(&self) -> &Bytes { + self.deref().input() + } + + fn ty(&self) -> u8 { + self.deref().ty() + } + + fn access_list(&self) -> Option<&AccessList> { + self.deref().access_list() + } + + fn blob_versioned_hashes(&self) -> Option<&[B256]> { + self.deref().blob_versioned_hashes() + } + + fn authorization_list(&self) -> Option<&[SignedAuthorization]> { + self.deref().authorization_list() + } + + fn is_dynamic_fee(&self) -> bool { + self.deref().is_dynamic_fee() + } + + fn effective_gas_price(&self, base_fee: Option) -> u128 { + self.deref().effective_gas_price(base_fee) + } + + fn effective_tip_per_gas(&self, base_fee: u64) -> Option { + self.deref().effective_tip_per_gas(base_fee) + } +} + +impl Default for OpTransactionSigned { + fn default() -> Self { + Self { + hash: Default::default(), + signature: Signature::test_signature(), + transaction: OpTransaction::new(OpTypedTransaction::Legacy(Default::default())), + } + } +} + +impl PartialEq for OpTransactionSigned { + fn eq(&self, other: &Self) -> bool { + self.signature == other.signature && + self.transaction == other.transaction && + self.tx_hash() == other.tx_hash() + } +} + +impl Hash for OpTransactionSigned { + fn hash(&self, state: &mut H) { + self.signature.hash(state); + self.transaction.hash(state); + } +} + +#[cfg(any(test, feature = "arbitrary"))] +impl<'a> arbitrary::Arbitrary<'a> for OpTransactionSigned { + fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { + #[allow(unused_mut)] + let mut transaction = OpTypedTransaction::arbitrary(u)?; + + let secp = secp256k1::Secp256k1::new(); + let key_pair = secp256k1::Keypair::new(&secp, &mut rand::thread_rng()); + let signature = reth_primitives::transaction::util::secp256k1::sign_message( + B256::from_slice(&key_pair.secret_bytes()[..]), + signature_hash(&transaction), + ) + .unwrap(); + + // Both `Some(0)` and `None` values are encoded as empty string byte. This introduces + // ambiguity in roundtrip tests. Patch the mint value of deposit transaction here, so that + // it's `None` if zero. + if let OpTypedTransaction::Deposit(ref mut tx_deposit) = transaction { + if tx_deposit.mint == Some(0) { + tx_deposit.mint = None; + } + } + + let signature = if is_deposit(&transaction) { TxDeposit::signature() } else { signature }; + + Ok(Self::new(transaction, signature)) + } +} + +/// Calculates the signing hash for the transaction. +pub fn signature_hash(tx: &OpTypedTransaction) -> B256 { + match tx { + OpTypedTransaction::Legacy(tx) => tx.signature_hash(), + OpTypedTransaction::Eip2930(tx) => tx.signature_hash(), + OpTypedTransaction::Eip1559(tx) => tx.signature_hash(), + OpTypedTransaction::Eip7702(tx) => tx.signature_hash(), + OpTypedTransaction::Deposit(_) => B256::ZERO, + } +} + +/// Returns `true` if transaction is deposit transaction. +pub const fn is_deposit(tx: &OpTypedTransaction) -> bool { + matches!(tx, OpTypedTransaction::Deposit(_)) +} diff --git a/crates/optimism/rpc/Cargo.toml b/crates/optimism/rpc/Cargo.toml index 4b25066d6759..9894dd8a3dba 100644 --- a/crates/optimism/rpc/Cargo.toml +++ b/crates/optimism/rpc/Cargo.toml @@ -72,5 +72,6 @@ optimism = [ "reth-provider/optimism", "revm/optimism", "reth-optimism-consensus/optimism", - "reth-optimism-payload-builder/optimism" + "reth-optimism-payload-builder/optimism", + "reth-optimism-primitives/op", ] diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index 0eeaf310853a..bae221531ca9 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -42,6 +42,11 @@ pub use sidecar::BlobTransaction; pub use signature::{recover_signer, recover_signer_unchecked}; pub use tx_type::TxType; +/// Handling transaction signature operations, including signature recovery, +/// applying chain IDs, and EIP-2 validation. +pub mod signature; +pub mod util; + pub(crate) mod access_list; mod compat; mod error; @@ -50,12 +55,6 @@ mod pooled; mod sidecar; mod tx_type; -/// Handling transaction signature operations, including signature recovery, -/// applying chain IDs, and EIP-2 validation. -pub mod signature; - -pub(crate) mod util; - #[cfg(any(test, feature = "reth-codec"))] pub use tx_type::{ COMPACT_EXTENDED_IDENTIFIER_FLAG, COMPACT_IDENTIFIER_EIP1559, COMPACT_IDENTIFIER_EIP2930, @@ -1178,7 +1177,7 @@ impl TransactionSigned { /// /// Refer to the docs for [`Self::decode_rlp_legacy_transaction`] for details on the exact /// format expected. - pub(crate) fn decode_rlp_legacy_transaction_tuple( + pub fn decode_rlp_legacy_transaction_tuple( data: &mut &[u8], ) -> alloy_rlp::Result<(TxLegacy, TxHash, Signature)> { // keep this around, so we can use it to calculate the hash diff --git a/crates/primitives/src/transaction/util.rs b/crates/primitives/src/transaction/util.rs index 7964cc1c5f00..8eb1a639d965 100644 --- a/crates/primitives/src/transaction/util.rs +++ b/crates/primitives/src/transaction/util.rs @@ -1,7 +1,10 @@ +//! Utility functions for signature. + use alloy_primitives::{Address, PrimitiveSignature as Signature}; +/// Secp256k1 utility functions. #[cfg(feature = "secp256k1")] -pub(crate) mod secp256k1 { +pub mod secp256k1 { pub use super::impl_secp256k1::*; } diff --git a/crates/storage/provider/Cargo.toml b/crates/storage/provider/Cargo.toml index 5a9595794d94..f6d577aadbec 100644 --- a/crates/storage/provider/Cargo.toml +++ b/crates/storage/provider/Cargo.toml @@ -96,6 +96,7 @@ optimism = [ "reth-db/optimism", "reth-db-api/optimism", "revm/optimism", + "reth-optimism-primitives/op", ] serde = [ "dashmap/serde", From ae8912fa739e50fc4def85241690ded929c9b5b5 Mon Sep 17 00:00:00 2001 From: Roman Krasiuk Date: Tue, 3 Dec 2024 09:38:17 +0100 Subject: [PATCH 37/68] feat(trie): proof blinded providers (#13085) --- Cargo.lock | 1 + crates/trie/sparse/src/blinded.rs | 8 ++ crates/trie/sparse/src/errors.rs | 3 + crates/trie/trie/Cargo.toml | 1 + crates/trie/trie/src/proof/blinded.rs | 116 ++++++++++++++++++ .../trie/trie/src/{proof.rs => proof/mod.rs} | 3 + 6 files changed, 132 insertions(+) create mode 100644 crates/trie/trie/src/proof/blinded.rs rename crates/trie/trie/src/{proof.rs => proof/mod.rs} (99%) diff --git a/Cargo.lock b/Cargo.lock index b799d0e0811d..c72a1c8ddcb1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9430,6 +9430,7 @@ dependencies = [ "reth-stages-types", "reth-storage-errors", "reth-trie-common", + "reth-trie-sparse", "revm", "serde_json", "tracing", diff --git a/crates/trie/sparse/src/blinded.rs b/crates/trie/sparse/src/blinded.rs index f82bdcd95bbd..4cd88bd92a26 100644 --- a/crates/trie/sparse/src/blinded.rs +++ b/crates/trie/sparse/src/blinded.rs @@ -55,3 +55,11 @@ impl BlindedProvider for DefaultBlindedProvider { Ok(None) } } + +/// Right pad the path with 0s and return as [`B256`]. +#[inline] +pub fn pad_path_to_key(path: &Nibbles) -> B256 { + let mut padded = path.pack(); + padded.resize(32, 0); + B256::from_slice(&padded) +} diff --git a/crates/trie/sparse/src/errors.rs b/crates/trie/sparse/src/errors.rs index 20545957e1cd..46102d2d4680 100644 --- a/crates/trie/sparse/src/errors.rs +++ b/crates/trie/sparse/src/errors.rs @@ -55,4 +55,7 @@ pub enum SparseTrieError { /// RLP error. #[error(transparent)] Rlp(#[from] alloy_rlp::Error), + /// Other. + #[error(transparent)] + Other(#[from] Box), } diff --git a/crates/trie/trie/Cargo.toml b/crates/trie/trie/Cargo.toml index c1c3ae4dd876..011c95e6a927 100644 --- a/crates/trie/trie/Cargo.toml +++ b/crates/trie/trie/Cargo.toml @@ -17,6 +17,7 @@ reth-execution-errors.workspace = true reth-primitives.workspace = true reth-stages-types.workspace = true reth-storage-errors.workspace = true +reth-trie-sparse.workspace = true reth-trie-common.workspace = true revm.workspace = true diff --git a/crates/trie/trie/src/proof/blinded.rs b/crates/trie/trie/src/proof/blinded.rs new file mode 100644 index 000000000000..adcaef46b08a --- /dev/null +++ b/crates/trie/trie/src/proof/blinded.rs @@ -0,0 +1,116 @@ +use super::{Proof, StorageProof}; +use crate::{hashed_cursor::HashedCursorFactory, trie_cursor::TrieCursorFactory}; +use alloy_primitives::{ + map::{HashMap, HashSet}, + Bytes, B256, +}; +use reth_trie_common::{prefix_set::TriePrefixSetsMut, Nibbles}; +use reth_trie_sparse::{ + blinded::{pad_path_to_key, BlindedProvider, BlindedProviderFactory}, + SparseTrieError, +}; +use std::sync::Arc; + +/// Factory for instantiating providers capable of retrieving blinded trie nodes via proofs. +#[derive(Debug)] +pub struct ProofBlindedProviderFactory { + /// The cursor factory for traversing trie nodes. + trie_cursor_factory: T, + /// The factory for hashed cursors. + hashed_cursor_factory: H, + /// A set of prefix sets that have changes. + prefix_sets: Arc, +} + +impl BlindedProviderFactory for ProofBlindedProviderFactory +where + T: TrieCursorFactory + Clone, + H: HashedCursorFactory + Clone, +{ + type AccountNodeProvider = ProofBlindedAccountProvider; + type StorageNodeProvider = ProofBlindedStorageProvider; + + fn account_node_provider(&self) -> Self::AccountNodeProvider { + ProofBlindedAccountProvider { + trie_cursor_factory: self.trie_cursor_factory.clone(), + hashed_cursor_factory: self.hashed_cursor_factory.clone(), + prefix_sets: self.prefix_sets.clone(), + } + } + + fn storage_node_provider(&self, account: B256) -> Self::StorageNodeProvider { + ProofBlindedStorageProvider { + trie_cursor_factory: self.trie_cursor_factory.clone(), + hashed_cursor_factory: self.hashed_cursor_factory.clone(), + prefix_sets: self.prefix_sets.clone(), + account, + } + } +} + +/// Blinded provider for retrieving account trie nodes by path. +#[derive(Debug)] +pub struct ProofBlindedAccountProvider { + /// The cursor factory for traversing trie nodes. + trie_cursor_factory: T, + /// The factory for hashed cursors. + hashed_cursor_factory: H, + /// A set of prefix sets that have changes. + prefix_sets: Arc, +} + +impl BlindedProvider for ProofBlindedAccountProvider +where + T: TrieCursorFactory + Clone, + H: HashedCursorFactory + Clone, +{ + type Error = SparseTrieError; + + fn blinded_node(&mut self, path: Nibbles) -> Result, Self::Error> { + let targets = HashMap::from_iter([(pad_path_to_key(&path), HashSet::default())]); + let proof = + Proof::new(self.trie_cursor_factory.clone(), self.hashed_cursor_factory.clone()) + .with_prefix_sets_mut(self.prefix_sets.as_ref().clone()) + .multiproof(targets) + .map_err(|error| SparseTrieError::Other(Box::new(error)))?; + + Ok(proof.account_subtree.into_inner().remove(&path)) + } +} + +/// Blinded provider for retrieving storage trie nodes by path. +#[derive(Debug)] +pub struct ProofBlindedStorageProvider { + /// The cursor factory for traversing trie nodes. + trie_cursor_factory: T, + /// The factory for hashed cursors. + hashed_cursor_factory: H, + /// A set of prefix sets that have changes. + prefix_sets: Arc, + /// Target account. + account: B256, +} + +impl BlindedProvider for ProofBlindedStorageProvider +where + T: TrieCursorFactory + Clone, + H: HashedCursorFactory + Clone, +{ + type Error = SparseTrieError; + + fn blinded_node(&mut self, path: Nibbles) -> Result, Self::Error> { + let targets = HashSet::from_iter([pad_path_to_key(&path)]); + let storage_prefix_set = + self.prefix_sets.storage_prefix_sets.get(&self.account).cloned().unwrap_or_default(); + let proof = StorageProof::new_hashed( + self.trie_cursor_factory.clone(), + self.hashed_cursor_factory.clone(), + self.account, + ) + .with_prefix_set_mut(storage_prefix_set) + .storage_multiproof(targets) + .map_err(|error| SparseTrieError::Other(Box::new(error)))?; + + Ok(proof.subtree.into_inner().remove(&path)) + } +} diff --git a/crates/trie/trie/src/proof.rs b/crates/trie/trie/src/proof/mod.rs similarity index 99% rename from crates/trie/trie/src/proof.rs rename to crates/trie/trie/src/proof/mod.rs index 3cb0ff6f2f70..c344ec76239a 100644 --- a/crates/trie/trie/src/proof.rs +++ b/crates/trie/trie/src/proof/mod.rs @@ -17,6 +17,9 @@ use reth_trie_common::{ proof::ProofRetainer, AccountProof, MultiProof, StorageMultiProof, TrieAccount, }; +mod blinded; +pub use blinded::*; + /// A struct for generating merkle proofs. /// /// Proof generator adds the target address and slots to the prefix set, enables the proof retainer From 5724114947e74d4b8c5977c1d3e6828efb408fc6 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Tue, 3 Dec 2024 12:46:37 +0400 Subject: [PATCH 38/68] feat: use primitive transaction as `PoolTransaction::Consensus` (#13086) --- crates/engine/util/src/reorg.rs | 5 ++- crates/ethereum/node/src/node.rs | 16 +++++--- crates/ethereum/payload/src/lib.rs | 9 +++-- crates/exex/test-utils/src/lib.rs | 7 ++-- crates/net/network/src/test_utils/testnet.rs | 15 ++++++-- crates/net/network/src/transactions/mod.rs | 21 +++++------ crates/node/api/src/node.rs | 6 +-- crates/node/builder/src/builder/mod.rs | 12 ++++-- crates/node/builder/src/components/builder.rs | 8 ++-- crates/node/builder/src/components/mod.rs | 10 +++-- crates/node/builder/src/components/pool.rs | 11 ++++-- crates/node/builder/src/rpc.rs | 3 ++ crates/optimism/node/src/node.rs | 16 +++++--- crates/optimism/node/src/txpool.rs | 6 +-- crates/optimism/node/tests/it/priority.rs | 8 ++-- crates/optimism/payload/src/builder.rs | 26 +++++++------ crates/optimism/rpc/src/eth/pending_block.rs | 7 ++-- crates/payload/util/src/traits.rs | 5 ++- crates/payload/util/src/transaction.rs | 30 ++++++++------- crates/primitives/src/transaction/mod.rs | 34 ++++++++--------- crates/rpc/rpc-builder/src/lib.rs | 18 ++++++--- .../rpc-eth-api/src/helpers/pending_block.rs | 10 +++-- .../rpc-eth-api/src/helpers/transaction.rs | 4 +- crates/rpc/rpc-eth-api/src/types.rs | 9 ++++- crates/rpc/rpc/src/eth/filter.rs | 19 ++++------ .../rpc/rpc/src/eth/helpers/pending_block.rs | 11 ++++-- crates/rpc/rpc/src/eth/pubsub.rs | 8 ++-- crates/rpc/rpc/src/txpool.rs | 25 +++++++------ crates/transaction-pool/src/maintain.rs | 26 ++++++------- crates/transaction-pool/src/pool/best.rs | 12 +++--- .../transaction-pool/src/test_utils/mock.rs | 10 +++-- crates/transaction-pool/src/traits.rs | 37 ++++++++++++------- crates/transaction-pool/src/validate/mod.rs | 11 +----- examples/custom-engine-types/src/main.rs | 10 +++-- examples/custom-evm/src/main.rs | 6 ++- examples/custom-inspector/src/main.rs | 3 +- examples/custom-payload-builder/src/main.rs | 8 ++-- examples/txpool-tracing/src/main.rs | 3 +- 38 files changed, 283 insertions(+), 202 deletions(-) diff --git a/crates/engine/util/src/reorg.rs b/crates/engine/util/src/reorg.rs index 8e9a195a1818..18a8c4737b5a 100644 --- a/crates/engine/util/src/reorg.rs +++ b/crates/engine/util/src/reorg.rs @@ -18,7 +18,10 @@ use reth_evm::{ ConfigureEvm, }; use reth_payload_validator::ExecutionPayloadValidator; -use reth_primitives::{proofs, Block, BlockBody, BlockExt, Receipt, Receipts}; +use reth_primitives::{ + proofs, transaction::SignedTransactionIntoRecoveredExt, Block, BlockBody, BlockExt, Receipt, + Receipts, +}; use reth_provider::{BlockReader, ExecutionOutcome, ProviderError, StateProviderFactory}; use reth_revm::{ database::StateProviderDatabase, diff --git a/crates/ethereum/node/src/node.rs b/crates/ethereum/node/src/node.rs index ad673588bf95..58b6aeaf6447 100644 --- a/crates/ethereum/node/src/node.rs +++ b/crates/ethereum/node/src/node.rs @@ -13,7 +13,7 @@ use reth_evm::execute::BasicBlockExecutorProvider; use reth_evm_ethereum::execute::EthExecutionStrategyFactory; use reth_network::{NetworkHandle, PeersInfo}; use reth_node_api::{ - AddOnsContext, ConfigureEvm, EngineValidator, FullNodeComponents, NodeTypesWithDB, + AddOnsContext, ConfigureEvm, EngineValidator, FullNodeComponents, NodeTypesWithDB, TxTy, }; use reth_node_builder::{ components::{ @@ -30,7 +30,7 @@ use reth_provider::{CanonStateSubscriptions, EthStorage}; use reth_rpc::EthApi; use reth_tracing::tracing::{debug, info}; use reth_transaction_pool::{ - blobstore::DiskFileBlobStore, EthTransactionPool, TransactionPool, + blobstore::DiskFileBlobStore, EthTransactionPool, PoolTransaction, TransactionPool, TransactionValidationTaskExecutor, }; use reth_trie_db::MerklePatriciaTrie; @@ -243,7 +243,9 @@ impl EthereumPayloadBuilder { Types: NodeTypesWithEngine, Node: FullNodeTypes, Evm: ConfigureEvm
, - Pool: TransactionPool + Unpin + 'static, + Pool: TransactionPool>> + + Unpin + + 'static, Types::Engine: PayloadTypes< BuiltPayload = EthBuiltPayload, PayloadAttributes = EthPayloadAttributes, @@ -280,7 +282,9 @@ impl PayloadServiceBuilder for EthereumPayloadBui where Types: NodeTypesWithEngine, Node: FullNodeTypes, - Pool: TransactionPool + Unpin + 'static, + Pool: TransactionPool>> + + Unpin + + 'static, Types::Engine: PayloadTypes< BuiltPayload = EthBuiltPayload, PayloadAttributes = EthPayloadAttributes, @@ -305,7 +309,9 @@ pub struct EthereumNetworkBuilder { impl NetworkBuilder for EthereumNetworkBuilder where Node: FullNodeTypes>, - Pool: TransactionPool + Unpin + 'static, + Pool: TransactionPool>> + + Unpin + + 'static, { async fn build_network( self, diff --git a/crates/ethereum/payload/src/lib.rs b/crates/ethereum/payload/src/lib.rs index a5c6434310e8..df900f1f36b3 100644 --- a/crates/ethereum/payload/src/lib.rs +++ b/crates/ethereum/payload/src/lib.rs @@ -31,12 +31,13 @@ use reth_payload_primitives::PayloadBuilderAttributes; use reth_primitives::{ proofs::{self}, Block, BlockBody, BlockExt, EthereumHardforks, InvalidTransactionError, Receipt, + TransactionSigned, }; use reth_provider::{ChainSpecProvider, StateProviderFactory}; use reth_revm::database::StateProviderDatabase; use reth_transaction_pool::{ error::InvalidPoolTransactionError, noop::NoopTransactionPool, BestTransactions, - BestTransactionsAttributes, TransactionPool, ValidPoolTransaction, + BestTransactionsAttributes, PoolTransaction, TransactionPool, ValidPoolTransaction, }; use reth_trie::HashedPostState; use revm::{ @@ -93,7 +94,7 @@ impl PayloadBuilder for EthereumPayloadBu where EvmConfig: ConfigureEvm
, Client: StateProviderFactory + ChainSpecProvider, - Pool: TransactionPool, + Pool: TransactionPool>, { type Attributes = EthPayloadBuilderAttributes; type BuiltPayload = EthBuiltPayload; @@ -157,7 +158,7 @@ pub fn default_ethereum_payload( where EvmConfig: ConfigureEvm
, Client: StateProviderFactory + ChainSpecProvider, - Pool: TransactionPool, + Pool: TransactionPool>, F: FnOnce(BestTransactionsAttributes) -> BestTransactionsIter, { let BuildArguments { client, pool, mut cached_reads, config, cancel, best_payload } = args; @@ -244,7 +245,7 @@ where } // convert tx to a signed transaction - let tx = pool_tx.to_recovered_transaction(); + let tx = pool_tx.to_consensus(); // There's only limited amount of blob space available per block, so we need to check if // the EIP-4844 can still fit in the block diff --git a/crates/exex/test-utils/src/lib.rs b/crates/exex/test-utils/src/lib.rs index 9acad4d4b659..939bf21c0223 100644 --- a/crates/exex/test-utils/src/lib.rs +++ b/crates/exex/test-utils/src/lib.rs @@ -30,7 +30,8 @@ use reth_execution_types::Chain; use reth_exex::{ExExContext, ExExEvent, ExExNotification, ExExNotifications, Wal}; use reth_network::{config::SecretKey, NetworkConfigBuilder, NetworkManager}; use reth_node_api::{ - FullNodeTypes, FullNodeTypesAdapter, NodeTypes, NodeTypesWithDBAdapter, NodeTypesWithEngine, + FullNodeTypes, FullNodeTypesAdapter, NodePrimitives, NodeTypes, NodeTypesWithDBAdapter, + NodeTypesWithEngine, }; use reth_node_builder::{ components::{ @@ -45,7 +46,7 @@ use reth_node_ethereum::{ EthEngineTypes, EthEvmConfig, }; use reth_payload_builder::noop::NoopPayloadBuilderService; -use reth_primitives::{BlockExt, EthPrimitives, Head, SealedBlockWithSenders}; +use reth_primitives::{BlockExt, EthPrimitives, Head, SealedBlockWithSenders, TransactionSigned}; use reth_provider::{ providers::{BlockchainProvider, StaticFileProvider}, BlockReader, EthStorage, ProviderFactory, @@ -64,7 +65,7 @@ pub struct TestPoolBuilder; impl PoolBuilder for TestPoolBuilder where - Node: FullNodeTypes, + Node: FullNodeTypes>>, { type Pool = TestPool; diff --git a/crates/net/network/src/test_utils/testnet.rs b/crates/net/network/src/test_utils/testnet.rs index bdd02118352b..08bf24b88532 100644 --- a/crates/net/network/src/test_utils/testnet.rs +++ b/crates/net/network/src/test_utils/testnet.rs @@ -17,6 +17,7 @@ use reth_network_api::{ NetworkEvent, NetworkEventListenerProvider, NetworkInfo, Peers, }; use reth_network_peers::PeerId; +use reth_primitives::TransactionSigned; use reth_provider::{test_utils::NoopProvider, ChainSpecProvider}; use reth_storage_api::{BlockReader, BlockReaderIdExt, HeaderProvider, StateProviderFactory}; use reth_tasks::TokioTaskExecutor; @@ -24,7 +25,7 @@ use reth_tokio_util::EventStream; use reth_transaction_pool::{ blobstore::InMemoryBlobStore, test_utils::{TestPool, TestPoolBuilder}, - EthTransactionPool, TransactionPool, TransactionValidationTaskExecutor, + EthTransactionPool, PoolTransaction, TransactionPool, TransactionValidationTaskExecutor, }; use secp256k1::SecretKey; use std::{ @@ -202,7 +203,9 @@ where + Clone + Unpin + 'static, - Pool: TransactionPool + Unpin + 'static, + Pool: TransactionPool> + + Unpin + + 'static, { /// Spawns the testnet to a separate task pub fn spawn(self) -> TestnetHandle { @@ -267,7 +270,9 @@ where > + HeaderProvider + Unpin + 'static, - Pool: TransactionPool + Unpin + 'static, + Pool: TransactionPool> + + Unpin + + 'static, { type Output = (); @@ -468,7 +473,9 @@ where > + HeaderProvider + Unpin + 'static, - Pool: TransactionPool + Unpin + 'static, + Pool: TransactionPool> + + Unpin + + 'static, { type Output = (); diff --git a/crates/net/network/src/transactions/mod.rs b/crates/net/network/src/transactions/mod.rs index e17069b67c50..5463b20f7f37 100644 --- a/crates/net/network/src/transactions/mod.rs +++ b/crates/net/network/src/transactions/mod.rs @@ -702,9 +702,8 @@ where BroadcastedTransaction: SignedTransaction, PooledTransaction: SignedTransaction, >, - <::Transaction as PoolTransaction>::Consensus: - Into, - <::Transaction as PoolTransaction>::Pooled: Into, + Pool::Transaction: + PoolTransaction>, { /// Invoked when transactions in the local mempool are considered __pending__. /// @@ -1011,9 +1010,8 @@ where impl TransactionsManager where Pool: TransactionPool + 'static, - <::Transaction as PoolTransaction>::Consensus: Into, - <::Transaction as PoolTransaction>::Pooled: - Into, + Pool::Transaction: + PoolTransaction>, { /// Handles dedicated transaction events related to the `eth` protocol. fn on_network_tx_event(&mut self, event: NetworkTransactionEvent) { @@ -1313,9 +1311,8 @@ where impl Future for TransactionsManager where Pool: TransactionPool + Unpin + 'static, - <::Transaction as PoolTransaction>::Consensus: Into, - <::Transaction as PoolTransaction>::Pooled: - Into, + Pool::Transaction: + PoolTransaction>, { type Output = (); @@ -1503,11 +1500,11 @@ impl PropagateTransaction { /// Create a new instance from a pooled transaction fn new

(tx: Arc>) -> Self where - P: PoolTransaction>, + P: PoolTransaction, { let size = tx.encoded_length(); - let transaction = tx.transaction.clone_into_consensus().into(); - let transaction = Arc::new(transaction); + let transaction = tx.transaction.clone_into_consensus(); + let transaction = Arc::new(transaction.into_signed()); Self { size, transaction } } diff --git a/crates/node/api/src/node.rs b/crates/node/api/src/node.rs index 7778fea7b5e1..83947208ca83 100644 --- a/crates/node/api/src/node.rs +++ b/crates/node/api/src/node.rs @@ -8,11 +8,11 @@ use reth_consensus::FullConsensus; use reth_evm::execute::BlockExecutorProvider; use reth_network_api::FullNetwork; use reth_node_core::node_config::NodeConfig; -use reth_node_types::{NodeTypes, NodeTypesWithDB, NodeTypesWithEngine}; +use reth_node_types::{NodeTypes, NodeTypesWithDB, NodeTypesWithEngine, TxTy}; use reth_payload_builder_primitives::PayloadBuilder; use reth_provider::FullProvider; use reth_tasks::TaskExecutor; -use reth_transaction_pool::TransactionPool; +use reth_transaction_pool::{PoolTransaction, TransactionPool}; use std::{future::Future, marker::PhantomData}; /// A helper trait that is downstream of the [`NodeTypesWithEngine`] trait and adds stateful @@ -47,7 +47,7 @@ where /// Encapsulates all types and components of the node. pub trait FullNodeComponents: FullNodeTypes + Clone + 'static { /// The transaction pool of the node. - type Pool: TransactionPool + Unpin; + type Pool: TransactionPool>> + Unpin; /// The node's EVM configuration, defining settings for the Ethereum Virtual Machine. type Evm: ConfigureEvm

; diff --git a/crates/node/builder/src/builder/mod.rs b/crates/node/builder/src/builder/mod.rs index b311cc4e2a0f..3cab01aa71be 100644 --- a/crates/node/builder/src/builder/mod.rs +++ b/crates/node/builder/src/builder/mod.rs @@ -37,7 +37,7 @@ use reth_provider::{ BlockReader, ChainSpecProvider, FullProvider, }; use reth_tasks::TaskExecutor; -use reth_transaction_pool::{PoolConfig, TransactionPool}; +use reth_transaction_pool::{PoolConfig, PoolTransaction, TransactionPool}; use revm_primitives::EnvKzgSettings; use secp256k1::SecretKey; use std::sync::Arc; @@ -650,7 +650,10 @@ impl BuilderContext { /// connected to that network. pub fn start_network(&self, builder: NetworkBuilder<(), ()>, pool: Pool) -> NetworkHandle where - Pool: TransactionPool + Unpin + 'static, + Pool: TransactionPool< + Transaction: PoolTransaction, + > + Unpin + + 'static, Node::Provider: BlockReader< Block = reth_primitives::Block, Receipt = reth_primitives::Receipt, @@ -673,7 +676,10 @@ impl BuilderContext { tx_config: TransactionsManagerConfig, ) -> NetworkHandle where - Pool: TransactionPool + Unpin + 'static, + Pool: TransactionPool< + Transaction: PoolTransaction, + > + Unpin + + 'static, Node::Provider: BlockReader< Block = reth_primitives::Block, Receipt = reth_primitives::Receipt, diff --git a/crates/node/builder/src/components/builder.rs b/crates/node/builder/src/components/builder.rs index b265dc927e75..4c04c9200d2f 100644 --- a/crates/node/builder/src/components/builder.rs +++ b/crates/node/builder/src/components/builder.rs @@ -10,9 +10,9 @@ use crate::{ use alloy_consensus::Header; use reth_consensus::FullConsensus; use reth_evm::execute::BlockExecutorProvider; -use reth_node_api::{NodeTypes, NodeTypesWithEngine}; +use reth_node_api::{NodeTypes, NodeTypesWithEngine, TxTy}; use reth_payload_builder::PayloadBuilderHandle; -use reth_transaction_pool::TransactionPool; +use reth_transaction_pool::{PoolTransaction, TransactionPool}; use std::{future::Future, marker::PhantomData}; /// A generic, general purpose and customizable [`NodeComponentsBuilder`] implementation. @@ -375,7 +375,9 @@ where Node: FullNodeTypes, F: FnOnce(&BuilderContext) -> Fut + Send, Fut: Future>> + Send, - Pool: TransactionPool + Unpin + 'static, + Pool: TransactionPool>> + + Unpin + + 'static, EVM: ConfigureEvm
, Executor: BlockExecutorProvider::Primitives>, Cons: FullConsensus<::Primitives> + Clone + Unpin + 'static, diff --git a/crates/node/builder/src/components/mod.rs b/crates/node/builder/src/components/mod.rs index a7d15dd29df1..22a47e3daa49 100644 --- a/crates/node/builder/src/components/mod.rs +++ b/crates/node/builder/src/components/mod.rs @@ -27,9 +27,9 @@ use reth_consensus::FullConsensus; use reth_evm::execute::BlockExecutorProvider; use reth_network::NetworkHandle; use reth_network_api::FullNetwork; -use reth_node_api::{NodeTypes, NodeTypesWithEngine}; +use reth_node_api::{NodeTypes, NodeTypesWithEngine, TxTy}; use reth_payload_builder::PayloadBuilderHandle; -use reth_transaction_pool::TransactionPool; +use reth_transaction_pool::{PoolTransaction, TransactionPool}; /// An abstraction over the components of a node, consisting of: /// - evm and executor @@ -38,7 +38,7 @@ use reth_transaction_pool::TransactionPool; /// - payload builder. pub trait NodeComponents: Clone + Unpin + Send + Sync + 'static { /// The transaction pool of the node. - type Pool: TransactionPool + Unpin; + type Pool: TransactionPool>> + Unpin; /// The node's EVM configuration, defining settings for the Ethereum Virtual Machine. type Evm: ConfigureEvm
; @@ -97,7 +97,9 @@ impl NodeComponents for Components where Node: FullNodeTypes, - Pool: TransactionPool + Unpin + 'static, + Pool: TransactionPool>> + + Unpin + + 'static, EVM: ConfigureEvm
, Executor: BlockExecutorProvider::Primitives>, Cons: FullConsensus<::Primitives> + Clone + Unpin + 'static, diff --git a/crates/node/builder/src/components/pool.rs b/crates/node/builder/src/components/pool.rs index 436a80c52e00..5b08e0a77395 100644 --- a/crates/node/builder/src/components/pool.rs +++ b/crates/node/builder/src/components/pool.rs @@ -1,7 +1,8 @@ //! Pool component for the node builder. use alloy_primitives::Address; -use reth_transaction_pool::{PoolConfig, SubPoolLimit, TransactionPool}; +use reth_node_api::TxTy; +use reth_transaction_pool::{PoolConfig, PoolTransaction, SubPoolLimit, TransactionPool}; use std::{collections::HashSet, future::Future}; use crate::{BuilderContext, FullNodeTypes}; @@ -9,7 +10,9 @@ use crate::{BuilderContext, FullNodeTypes}; /// A type that knows how to build the transaction pool. pub trait PoolBuilder: Send { /// The transaction pool to build. - type Pool: TransactionPool + Unpin + 'static; + type Pool: TransactionPool>> + + Unpin + + 'static; /// Creates the transaction pool. fn build_pool( @@ -21,7 +24,9 @@ pub trait PoolBuilder: Send { impl PoolBuilder for F where Node: FullNodeTypes, - Pool: TransactionPool + Unpin + 'static, + Pool: TransactionPool>> + + Unpin + + 'static, F: FnOnce(&BuilderContext) -> Fut + Send, Fut: Future> + Send, { diff --git a/crates/node/builder/src/rpc.rs b/crates/node/builder/src/rpc.rs index 55313f3e9898..24b7db77d888 100644 --- a/crates/node/builder/src/rpc.rs +++ b/crates/node/builder/src/rpc.rs @@ -33,6 +33,7 @@ use reth_rpc_builder::{ use reth_rpc_engine_api::{capabilities::EngineCapabilities, EngineApi}; use reth_tasks::TaskExecutor; use reth_tracing::tracing::{debug, info}; +use reth_transaction_pool::TransactionPool; use crate::EthApiBuilderCtx; @@ -405,6 +406,7 @@ where N: FullNodeComponents< Types: ProviderNodeTypes, PayloadBuilder: PayloadBuilder::Engine>, + Pool: TransactionPool::Transaction>, >, EthApi: EthApiTypes + FullEthApiServer + AddDevSigners + Unpin + 'static, EV: EngineValidatorBuilder, @@ -527,6 +529,7 @@ where N: FullNodeComponents< Types: ProviderNodeTypes, PayloadBuilder: PayloadBuilder::Engine>, + Pool: TransactionPool::Transaction>, >, EthApi: EthApiTypes + FullEthApiServer + AddDevSigners + Unpin + 'static, EV: EngineValidatorBuilder, diff --git a/crates/optimism/node/src/node.rs b/crates/optimism/node/src/node.rs index 73adcb43f18a..a13ab9dcec16 100644 --- a/crates/optimism/node/src/node.rs +++ b/crates/optimism/node/src/node.rs @@ -13,7 +13,7 @@ use reth_db::transaction::{DbTx, DbTxMut}; use reth_evm::{execute::BasicBlockExecutorProvider, ConfigureEvm}; use reth_network::{NetworkConfig, NetworkHandle, NetworkManager, PeersInfo}; use reth_node_api::{ - AddOnsContext, EngineValidator, FullNodeComponents, NodeAddOns, PayloadBuilder, + AddOnsContext, EngineValidator, FullNodeComponents, NodeAddOns, PayloadBuilder, TxTy, }; use reth_node_builder::{ components::{ @@ -42,7 +42,7 @@ use reth_provider::{ use reth_rpc_server_types::RethRpcModule; use reth_tracing::tracing::{debug, info}; use reth_transaction_pool::{ - blobstore::DiskFileBlobStore, CoinbaseTipOrdering, TransactionPool, + blobstore::DiskFileBlobStore, CoinbaseTipOrdering, PoolTransaction, TransactionPool, TransactionValidationTaskExecutor, }; use reth_trie_db::MerklePatriciaTrie; @@ -465,7 +465,9 @@ where Primitives = OpPrimitives, >, >, - Pool: TransactionPool + Unpin + 'static, + Pool: TransactionPool>> + + Unpin + + 'static, Evm: ConfigureEvm
, { let payload_builder = reth_optimism_payload_builder::OpPayloadBuilder::new(evm_config) @@ -505,7 +507,9 @@ where Primitives = OpPrimitives, >, >, - Pool: TransactionPool + Unpin + 'static, + Pool: TransactionPool>> + + Unpin + + 'static, Txs: OpPayloadTransactions, { async fn spawn_payload_service( @@ -577,7 +581,9 @@ impl OpNetworkBuilder { impl NetworkBuilder for OpNetworkBuilder where Node: FullNodeTypes>, - Pool: TransactionPool + Unpin + 'static, + Pool: TransactionPool>> + + Unpin + + 'static, { async fn build_network( self, diff --git a/crates/optimism/node/src/txpool.rs b/crates/optimism/node/src/txpool.rs index d8246aeb7dbb..a3e474a60760 100644 --- a/crates/optimism/node/src/txpool.rs +++ b/crates/optimism/node/src/txpool.rs @@ -70,7 +70,7 @@ impl OpTransactionValidator { impl OpTransactionValidator where Client: StateProviderFactory + BlockReaderIdExt, - Tx: EthPoolTransaction, + Tx: EthPoolTransaction, { /// Create a new [`OpTransactionValidator`]. pub fn new(inner: EthTransactionValidator) -> Self { @@ -142,7 +142,7 @@ where let l1_block_info = self.block_info.l1_block_info.read().clone(); let mut encoded = Vec::with_capacity(valid_tx.transaction().encoded_length()); - let tx: TransactionSigned = valid_tx.transaction().clone_into_consensus().into(); + let tx = valid_tx.transaction().clone_into_consensus(); tx.encode_2718(&mut encoded); let cost_addition = match l1_block_info.l1_tx_data_fee( @@ -196,7 +196,7 @@ where impl TransactionValidator for OpTransactionValidator where Client: StateProviderFactory + BlockReaderIdExt, - Tx: EthPoolTransaction, + Tx: EthPoolTransaction, { type Transaction = Tx; diff --git a/crates/optimism/node/tests/it/priority.rs b/crates/optimism/node/tests/it/priority.rs index b5487987f6a5..1b49ed684bfc 100644 --- a/crates/optimism/node/tests/it/priority.rs +++ b/crates/optimism/node/tests/it/priority.rs @@ -30,7 +30,7 @@ use reth_payload_util::{PayloadTransactions, PayloadTransactionsChain, PayloadTr use reth_primitives::{RecoveredTx, SealedBlock, Transaction, TransactionSigned}; use reth_provider::providers::BlockchainProvider2; use reth_tasks::TaskManager; -use reth_transaction_pool::pool::BestPayloadTransactions; +use reth_transaction_pool::{pool::BestPayloadTransactions, PoolTransaction}; use std::sync::Arc; use tokio::sync::Mutex; @@ -44,9 +44,11 @@ impl OpPayloadTransactions for CustomTxPriority { &self, pool: Pool, attr: reth_transaction_pool::BestTransactionsAttributes, - ) -> impl PayloadTransactions + ) -> impl PayloadTransactions where - Pool: reth_transaction_pool::TransactionPool, + Pool: reth_transaction_pool::TransactionPool< + Transaction: PoolTransaction, + >, { // Block composition: // 1. Best transactions from the pool (up to 250k gas) diff --git a/crates/optimism/payload/src/builder.rs b/crates/optimism/payload/src/builder.rs index 6ae52188d180..d385ca79546f 100644 --- a/crates/optimism/payload/src/builder.rs +++ b/crates/optimism/payload/src/builder.rs @@ -19,12 +19,13 @@ use reth_payload_builder_primitives::PayloadBuilderError; use reth_payload_primitives::PayloadBuilderAttributes; use reth_payload_util::PayloadTransactions; use reth_primitives::{ - proofs, Block, BlockBody, BlockExt, Receipt, SealedHeader, TransactionSigned, TxType, + proofs, transaction::SignedTransactionIntoRecoveredExt, Block, BlockBody, BlockExt, Receipt, + SealedHeader, TransactionSigned, TxType, }; use reth_provider::{ProviderError, StateProofProvider, StateProviderFactory, StateRootProvider}; use reth_revm::database::StateProviderDatabase; use reth_transaction_pool::{ - noop::NoopTransactionPool, BestTransactionsAttributes, TransactionPool, + noop::NoopTransactionPool, BestTransactionsAttributes, PoolTransaction, TransactionPool, }; use reth_trie::HashedPostState; use revm::{ @@ -112,7 +113,7 @@ where ) -> Result, PayloadBuilderError> where Client: StateProviderFactory + ChainSpecProvider, - Pool: TransactionPool, + Pool: TransactionPool>, { let (initialized_cfg, initialized_block_env) = self .cfg_and_block_env(&args.config.attributes, &args.config.parent_header) @@ -213,7 +214,7 @@ where impl PayloadBuilder for OpPayloadBuilder where Client: StateProviderFactory + ChainSpecProvider, - Pool: TransactionPool, + Pool: TransactionPool>, EvmConfig: ConfigureEvm
, Txs: OpPayloadTransactions, { @@ -281,7 +282,7 @@ pub struct OpBuilder { impl OpBuilder where - Pool: TransactionPool, + Pool: TransactionPool>, Txs: OpPayloadTransactions, { /// Executes the payload and returns the outcome. @@ -479,19 +480,23 @@ where pub trait OpPayloadTransactions: Clone + Send + Sync + Unpin + 'static { /// Returns an iterator that yields the transaction in the order they should get included in the /// new payload. - fn best_transactions( + fn best_transactions< + Pool: TransactionPool>, + >( &self, pool: Pool, attr: BestTransactionsAttributes, - ) -> impl PayloadTransactions; + ) -> impl PayloadTransactions; } impl OpPayloadTransactions for () { - fn best_transactions( + fn best_transactions< + Pool: TransactionPool>, + >( &self, pool: Pool, attr: BestTransactionsAttributes, - ) -> impl PayloadTransactions { + ) -> impl PayloadTransactions { BestPayloadTransactions::new(pool.best_transactions_with_attributes(attr)) } } @@ -830,11 +835,10 @@ where &self, info: &mut ExecutionInfo, db: &mut State, - mut best_txs: impl PayloadTransactions, + mut best_txs: impl PayloadTransactions, ) -> Result, PayloadBuilderError> where DB: Database, - Pool: TransactionPool, { let block_gas_limit = self.block_gas_limit(); let base_fee = self.base_fee(); diff --git a/crates/optimism/rpc/src/eth/pending_block.rs b/crates/optimism/rpc/src/eth/pending_block.rs index fec610bb1e93..9a8d169e5270 100644 --- a/crates/optimism/rpc/src/eth/pending_block.rs +++ b/crates/optimism/rpc/src/eth/pending_block.rs @@ -9,7 +9,7 @@ use reth_evm::ConfigureEvm; use reth_optimism_consensus::calculate_receipt_root_no_memo_optimism; use reth_primitives::{Receipt, SealedBlockWithSenders}; use reth_provider::{ - BlockReader, BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, ExecutionOutcome, + BlockReader, BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, ExecutionOutcome, ProviderTx, ReceiptProvider, StateProviderFactory, }; use reth_rpc_eth_api::{ @@ -17,7 +17,7 @@ use reth_rpc_eth_api::{ FromEthApiError, RpcNodeCore, }; use reth_rpc_eth_types::{EthApiError, PendingBlock}; -use reth_transaction_pool::TransactionPool; +use reth_transaction_pool::{PoolTransaction, TransactionPool}; use revm::primitives::BlockEnv; impl LoadPendingBlock for OpEthApi @@ -25,13 +25,14 @@ where Self: SpawnBlocking, N: RpcNodeCore< Provider: BlockReaderIdExt< + Transaction = reth_primitives::TransactionSigned, Block = reth_primitives::Block, Receipt = reth_primitives::Receipt, Header = reth_primitives::Header, > + EvmEnvProvider + ChainSpecProvider + StateProviderFactory, - Pool: TransactionPool, + Pool: TransactionPool>>, Evm: ConfigureEvm
, >, { diff --git a/crates/payload/util/src/traits.rs b/crates/payload/util/src/traits.rs index 5c1eb38bea38..e9bb7e03704c 100644 --- a/crates/payload/util/src/traits.rs +++ b/crates/payload/util/src/traits.rs @@ -7,12 +7,15 @@ use reth_primitives::RecoveredTx; /// Can include transactions from the pool and other sources (alternative pools, /// sequencer-originated transactions, etc.). pub trait PayloadTransactions { + /// The transaction type this iterator yields. + type Transaction; + /// Returns the next transaction to include in the block. fn next( &mut self, // In the future, `ctx` can include access to state for block building purposes. ctx: (), - ) -> Option; + ) -> Option>; /// Exclude descendants of the transaction with given sender and nonce from the iterator, /// because this transaction won't be included in the block. diff --git a/crates/payload/util/src/transaction.rs b/crates/payload/util/src/transaction.rs index ebd3b0796262..71387946aef1 100644 --- a/crates/payload/util/src/transaction.rs +++ b/crates/payload/util/src/transaction.rs @@ -26,8 +26,10 @@ impl PayloadTransactionsFixed { } } -impl PayloadTransactions for PayloadTransactionsFixed { - fn next(&mut self, _ctx: ()) -> Option { +impl PayloadTransactions for PayloadTransactionsFixed> { + type Transaction = T; + + fn next(&mut self, _ctx: ()) -> Option> { (self.index < self.transactions.len()).then(|| { let tx = self.transactions[self.index].clone(); self.index += 1; @@ -87,20 +89,22 @@ impl PayloadTransactionsChain PayloadTransactions for PayloadTransactionsChain +impl PayloadTransactions for PayloadTransactionsChain where - B: PayloadTransactions, - A: PayloadTransactions, + A: PayloadTransactions, + B: PayloadTransactions, { - fn next(&mut self, ctx: ()) -> Option { + type Transaction = A::Transaction; + + fn next(&mut self, ctx: ()) -> Option> { while let Some(tx) = self.before.next(ctx) { if let Some(before_max_gas) = self.before_max_gas { - if self.before_gas + tx.transaction.gas_limit() <= before_max_gas { - self.before_gas += tx.transaction.gas_limit(); + if self.before_gas + tx.as_signed().gas_limit() <= before_max_gas { + self.before_gas += tx.as_signed().gas_limit(); return Some(tx); } - self.before.mark_invalid(tx.signer(), tx.transaction.nonce()); - self.after.mark_invalid(tx.signer(), tx.transaction.nonce()); + self.before.mark_invalid(tx.signer(), tx.as_signed().nonce()); + self.after.mark_invalid(tx.signer(), tx.as_signed().nonce()); } else { return Some(tx); } @@ -108,11 +112,11 @@ where while let Some(tx) = self.after.next(ctx) { if let Some(after_max_gas) = self.after_max_gas { - if self.after_gas + tx.transaction.gas_limit() <= after_max_gas { - self.after_gas += tx.transaction.gas_limit(); + if self.after_gas + tx.as_signed().gas_limit() <= after_max_gas { + self.after_gas += tx.as_signed().gas_limit(); return Some(tx); } - self.after.mark_invalid(tx.signer(), tx.transaction.nonce()); + self.after.mark_invalid(tx.signer(), tx.as_signed().nonce()); } else { return Some(tx); } diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index bae221531ca9..6fd8fb55a6d9 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -1130,23 +1130,6 @@ impl TransactionSigned { Some(RecoveredTx { signed_transaction: self, signer }) } - /// Tries to recover signer and return [`RecoveredTx`] by cloning the type. - pub fn try_ecrecovered(&self) -> Option { - let signer = self.recover_signer()?; - Some(RecoveredTx { signed_transaction: self.clone(), signer }) - } - - /// Tries to recover signer and return [`RecoveredTx`]. - /// - /// Returns `Err(Self)` if the transaction's signature is invalid, see also - /// [`Self::recover_signer`]. - pub fn try_into_ecrecovered(self) -> Result { - match self.recover_signer() { - None => Err(self), - Some(signer) => Ok(RecoveredTx { signed_transaction: self, signer }), - } - } - /// Tries to recover signer and return [`RecoveredTx`]. _without ensuring that /// the signature has a low `s` value_ (EIP-2). /// @@ -1707,6 +1690,23 @@ impl Encodable2718 for RecoveredTx { /// Extension trait for [`SignedTransaction`] to convert it into [`RecoveredTx`]. pub trait SignedTransactionIntoRecoveredExt: SignedTransaction { + /// Tries to recover signer and return [`RecoveredTx`] by cloning the type. + fn try_ecrecovered(&self) -> Option> { + let signer = self.recover_signer()?; + Some(RecoveredTx { signed_transaction: self.clone(), signer }) + } + + /// Tries to recover signer and return [`RecoveredTx`]. + /// + /// Returns `Err(Self)` if the transaction's signature is invalid, see also + /// [`SignedTransaction::recover_signer`]. + fn try_into_ecrecovered(self) -> Result, Self> { + match self.recover_signer() { + None => Err(self), + Some(signer) => Ok(RecoveredTx { signed_transaction: self, signer }), + } + } + /// Consumes the type, recover signer and return [`RecoveredTx`] _without /// ensuring that the signature has a low `s` value_ (EIP-2). /// diff --git a/crates/rpc/rpc-builder/src/lib.rs b/crates/rpc/rpc-builder/src/lib.rs index e2141dcf1cee..99912eddf97f 100644 --- a/crates/rpc/rpc-builder/src/lib.rs +++ b/crates/rpc/rpc-builder/src/lib.rs @@ -26,7 +26,7 @@ //! RethRpcModule, RpcModuleBuilder, RpcServerConfig, ServerBuilder, TransportRpcModuleConfig, //! }; //! use reth_tasks::TokioTaskExecutor; -//! use reth_transaction_pool::TransactionPool; +//! use reth_transaction_pool::{PoolTransaction, TransactionPool}; //! //! pub async fn launch( //! provider: Provider, @@ -44,7 +44,9 @@ //! Header = reth_primitives::Header, //! > + AccountReader //! + ChangeSetReader, -//! Pool: TransactionPool + Unpin + 'static, +//! Pool: TransactionPool> +//! + Unpin +//! + 'static, //! Network: NetworkInfo + Peers + Clone + 'static, //! Events: //! CanonStateSubscriptions + Clone + 'static, @@ -95,7 +97,7 @@ //! }; //! use reth_rpc_layer::JwtSecret; //! use reth_tasks::TokioTaskExecutor; -//! use reth_transaction_pool::TransactionPool; +//! use reth_transaction_pool::{PoolTransaction, TransactionPool}; //! use tokio::try_join; //! //! pub async fn launch< @@ -125,7 +127,9 @@ //! Header = reth_primitives::Header, //! > + AccountReader //! + ChangeSetReader, -//! Pool: TransactionPool + Unpin + 'static, +//! Pool: TransactionPool> +//! + Unpin +//! + 'static, //! Network: NetworkInfo + Peers + Clone + 'static, //! Events: //! CanonStateSubscriptions + Clone + 'static, @@ -277,7 +281,7 @@ where Header = reth_primitives::Header, > + AccountReader + ChangeSetReader, - Pool: TransactionPool + 'static, + Pool: TransactionPool::Transaction> + 'static, Network: NetworkInfo + Peers + Clone + 'static, Tasks: TaskSpawner + Clone + 'static, Events: CanonStateSubscriptions + Clone + 'static, @@ -674,6 +678,7 @@ where Receipt = ::Receipt, Header = ::Header, >, + Pool: TransactionPool::Transaction>, { let Self { provider, @@ -793,6 +798,7 @@ where Receipt = ::Receipt, Header = ::Header, >, + Pool: TransactionPool::Transaction>, { let mut modules = TransportRpcModules::default(); @@ -1328,7 +1334,7 @@ where Header = ::Header, > + AccountReader + ChangeSetReader, - Pool: TransactionPool + 'static, + Pool: TransactionPool::Transaction> + 'static, Network: NetworkInfo + Peers + Clone + 'static, Tasks: TaskSpawner + Clone + 'static, Events: CanonStateSubscriptions + Clone + 'static, diff --git a/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs b/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs index 72d53a22a238..782c1a2a8f6b 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs @@ -22,7 +22,7 @@ use reth_primitives::{ }; use reth_provider::{ BlockReader, BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, ProviderError, - ProviderReceipt, ReceiptProvider, StateProviderFactory, + ProviderReceipt, ProviderTx, ReceiptProvider, StateProviderFactory, }; use reth_revm::{ database::StateProviderDatabase, @@ -33,7 +33,8 @@ use reth_revm::{ }; use reth_rpc_eth_types::{EthApiError, PendingBlock, PendingBlockEnv, PendingBlockEnvOrigin}; use reth_transaction_pool::{ - error::InvalidPoolTransactionError, BestTransactionsAttributes, TransactionPool, + error::InvalidPoolTransactionError, BestTransactionsAttributes, PoolTransaction, + TransactionPool, }; use reth_trie::HashedPostState; use revm::{db::states::bundle_state::BundleRetention, DatabaseCommit, State}; @@ -48,13 +49,14 @@ pub trait LoadPendingBlock: EthApiTypes + RpcNodeCore< Provider: BlockReaderIdExt< + Transaction = reth_primitives::TransactionSigned, Block = reth_primitives::Block, Receipt = reth_primitives::Receipt, Header = reth_primitives::Header, > + EvmEnvProvider + ChainSpecProvider + StateProviderFactory, - Pool: TransactionPool, + Pool: TransactionPool>>, Evm: ConfigureEvm
, > { @@ -319,7 +321,7 @@ pub trait LoadPendingBlock: } // convert tx to a signed transaction - let tx = pool_tx.to_recovered_transaction(); + let tx = pool_tx.to_consensus(); // There's only limited amount of blob space available per block, so we need to check if // the EIP-4844 can still fit in the block diff --git a/crates/rpc/rpc-eth-api/src/helpers/transaction.rs b/crates/rpc/rpc-eth-api/src/helpers/transaction.rs index 43ac03adaf71..9d77e01193b1 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/transaction.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/transaction.rs @@ -240,7 +240,7 @@ pub trait EthTransactions: LoadTransaction { RpcNodeCore::pool(self).get_transaction_by_sender_and_nonce(sender, nonce) { let transaction = tx.transaction.clone_into_consensus(); - return Ok(Some(from_recovered(transaction.into(), self.tx_resp_builder())?)); + return Ok(Some(from_recovered(transaction, self.tx_resp_builder())?)); } } @@ -385,7 +385,7 @@ pub trait EthTransactions: LoadTransaction { let pool_transaction = <::Pool as TransactionPool>::Transaction::try_from_consensus( - transaction.into(), + transaction, ) .map_err(|_| EthApiError::TransactionConversionError)?; diff --git a/crates/rpc/rpc-eth-api/src/types.rs b/crates/rpc/rpc-eth-api/src/types.rs index 2bac068483c7..62af1432b11a 100644 --- a/crates/rpc/rpc-eth-api/src/types.rs +++ b/crates/rpc/rpc-eth-api/src/types.rs @@ -8,8 +8,9 @@ use std::{ use alloy_network::Network; use alloy_rpc_types_eth::Block; use reth_primitives::TransactionSigned; -use reth_provider::{ReceiptProvider, TransactionsProvider}; +use reth_provider::{ProviderTx, ReceiptProvider, TransactionsProvider}; use reth_rpc_types_compat::TransactionCompat; +use reth_transaction_pool::{PoolTransaction, TransactionPool}; use crate::{AsEthApiError, FromEthApiError, FromEvmError, RpcNodeCore}; @@ -50,6 +51,9 @@ where Self: RpcNodeCore< Provider: TransactionsProvider + ReceiptProvider, + Pool: TransactionPool< + Transaction: PoolTransaction>, + >, > + EthApiTypes< TransactionCompat: TransactionCompat< ::Transaction, @@ -64,6 +68,9 @@ impl FullEthApiTypes for T where T: RpcNodeCore< Provider: TransactionsProvider + ReceiptProvider, + Pool: TransactionPool< + Transaction: PoolTransaction>, + >, > + EthApiTypes< TransactionCompat: TransactionCompat< ::Transaction, diff --git a/crates/rpc/rpc/src/eth/filter.rs b/crates/rpc/rpc/src/eth/filter.rs index c1ef67d9b595..6ed72b6ca746 100644 --- a/crates/rpc/rpc/src/eth/filter.rs +++ b/crates/rpc/rpc/src/eth/filter.rs @@ -9,7 +9,7 @@ use alloy_rpc_types_eth::{ use async_trait::async_trait; use jsonrpsee::{core::RpcResult, server::IdProvider}; use reth_chainspec::ChainInfo; -use reth_primitives::{Receipt, RecoveredTx, SealedBlockWithSenders}; +use reth_primitives::{Receipt, SealedBlockWithSenders}; use reth_provider::{BlockIdReader, BlockReader, ProviderError}; use reth_rpc_eth_api::{ EthApiTypes, EthFilterApiServer, FullEthApiTypes, RpcTransaction, TransactionCompat, @@ -145,7 +145,7 @@ where impl EthFilter where Provider: BlockReader + BlockIdReader + 'static, - Pool: TransactionPool + 'static, + Pool: TransactionPool::Transaction> + 'static, Eth: FullEthApiTypes, { /// Returns all the filter changes for the given id, if any @@ -245,7 +245,7 @@ impl EthFilterApiServer> for EthFilter where Provider: BlockReader + BlockIdReader + 'static, - Pool: TransactionPool + 'static, + Pool: TransactionPool::Transaction> + 'static, Eth: FullEthApiTypes + 'static, { /// Handler for `eth_newFilter` @@ -611,7 +611,7 @@ struct FullTransactionsReceiver { impl FullTransactionsReceiver where T: PoolTransaction + 'static, - TxCompat: TransactionCompat, + TxCompat: TransactionCompat, { /// Creates a new `FullTransactionsReceiver` encapsulating the provided transaction stream. fn new(stream: NewSubpoolTransactionStream, tx_resp_builder: TxCompat) -> Self { @@ -619,15 +619,12 @@ where } /// Returns all new pending transactions received since the last poll. - async fn drain(&self) -> FilterChanges - where - T: PoolTransaction>, - { + async fn drain(&self) -> FilterChanges { let mut pending_txs = Vec::new(); let mut prepared_stream = self.txs_stream.lock().await; while let Ok(tx) = prepared_stream.try_recv() { - match from_recovered(tx.transaction.to_recovered_transaction(), &self.tx_resp_builder) { + match from_recovered(tx.transaction.to_consensus(), &self.tx_resp_builder) { Ok(tx) => pending_txs.push(tx), Err(err) => { error!(target: "rpc", @@ -651,8 +648,8 @@ trait FullTransactionsFilter: fmt::Debug + Send + Sync + Unpin + 'static { impl FullTransactionsFilter for FullTransactionsReceiver where - T: PoolTransaction> + 'static, - TxCompat: TransactionCompat + 'static, + T: PoolTransaction + 'static, + TxCompat: TransactionCompat + 'static, { async fn drain(&self) -> FilterChanges { Self::drain(self).await diff --git a/crates/rpc/rpc/src/eth/helpers/pending_block.rs b/crates/rpc/rpc/src/eth/helpers/pending_block.rs index 794b9dde82f4..34c0ae962613 100644 --- a/crates/rpc/rpc/src/eth/helpers/pending_block.rs +++ b/crates/rpc/rpc/src/eth/helpers/pending_block.rs @@ -3,13 +3,15 @@ use alloy_consensus::Header; use reth_chainspec::{EthChainSpec, EthereumHardforks}; use reth_evm::ConfigureEvm; -use reth_provider::{BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, StateProviderFactory}; +use reth_provider::{ + BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, ProviderTx, StateProviderFactory, +}; use reth_rpc_eth_api::{ helpers::{LoadPendingBlock, SpawnBlocking}, RpcNodeCore, }; use reth_rpc_eth_types::PendingBlock; -use reth_transaction_pool::TransactionPool; +use reth_transaction_pool::{PoolTransaction, TransactionPool}; use crate::EthApi; @@ -19,13 +21,16 @@ where Self: SpawnBlocking + RpcNodeCore< Provider: BlockReaderIdExt< + Transaction = reth_primitives::TransactionSigned, Block = reth_primitives::Block, Receipt = reth_primitives::Receipt, Header = reth_primitives::Header, > + EvmEnvProvider + ChainSpecProvider + StateProviderFactory, - Pool: TransactionPool, + Pool: TransactionPool< + Transaction: PoolTransaction>, + >, Evm: ConfigureEvm
, >, { diff --git a/crates/rpc/rpc/src/eth/pubsub.rs b/crates/rpc/rpc/src/eth/pubsub.rs index 8ad809b8b186..58c62133730d 100644 --- a/crates/rpc/rpc/src/eth/pubsub.rs +++ b/crates/rpc/rpc/src/eth/pubsub.rs @@ -23,7 +23,7 @@ use reth_rpc_eth_types::logs_utils; use reth_rpc_server_types::result::{internal_rpc_err, invalid_params_rpc_err}; use reth_rpc_types_compat::transaction::from_recovered; use reth_tasks::{TaskSpawner, TokioTaskExecutor}; -use reth_transaction_pool::{NewTransactionEvent, TransactionPool}; +use reth_transaction_pool::{NewTransactionEvent, PoolConsensusTx, TransactionPool}; use serde::Serialize; use tokio_stream::{ wrappers::{BroadcastStream, ReceiverStream}, @@ -95,7 +95,7 @@ where > + Clone + 'static, Network: NetworkInfo + Clone + 'static, - Eth: TransactionCompat + 'static, + Eth: TransactionCompat> + 'static, { /// Handler for `eth_subscribe` async fn subscribe( @@ -135,7 +135,7 @@ where > + Clone + 'static, Network: NetworkInfo + Clone + 'static, - Eth: TransactionCompat, + Eth: TransactionCompat>, { match kind { SubscriptionKind::NewHeads => { @@ -165,7 +165,7 @@ where // full transaction objects requested let stream = pubsub.full_pending_transaction_stream().filter_map(|tx| { let tx_value = match from_recovered( - tx.transaction.to_recovered_transaction(), + tx.transaction.to_consensus(), &tx_resp_builder, ) { Ok(tx) => { diff --git a/crates/rpc/rpc/src/txpool.rs b/crates/rpc/rpc/src/txpool.rs index b12e8e7ab57f..4709c9878faf 100644 --- a/crates/rpc/rpc/src/txpool.rs +++ b/crates/rpc/rpc/src/txpool.rs @@ -8,10 +8,11 @@ use alloy_rpc_types_txpool::{ }; use async_trait::async_trait; use jsonrpsee::core::RpcResult; -use reth_primitives::RecoveredTx; use reth_rpc_api::TxPoolApiServer; use reth_rpc_types_compat::{transaction::from_recovered, TransactionCompat}; -use reth_transaction_pool::{AllPoolTransactions, PoolTransaction, TransactionPool}; +use reth_transaction_pool::{ + AllPoolTransactions, PoolConsensusTx, PoolTransaction, TransactionPool, +}; use tracing::trace; /// `txpool` API implementation. @@ -33,8 +34,8 @@ impl TxPoolApi { impl TxPoolApi where - Pool: TransactionPool + 'static, - Eth: TransactionCompat, + Pool: TransactionPool> + 'static, + Eth: TransactionCompat>, { fn content(&self) -> Result, Eth::Error> { #[inline] @@ -44,12 +45,12 @@ where resp_builder: &RpcTxB, ) -> Result<(), RpcTxB::Error> where - Tx: PoolTransaction>, - RpcTxB: TransactionCompat, + Tx: PoolTransaction, + RpcTxB: TransactionCompat, { content.entry(tx.sender()).or_default().insert( tx.nonce().to_string(), - from_recovered(tx.clone_into_consensus().into(), resp_builder)?, + from_recovered(tx.clone_into_consensus(), resp_builder)?, ); Ok(()) @@ -72,8 +73,8 @@ where #[async_trait] impl TxPoolApiServer for TxPoolApi where - Pool: TransactionPool + 'static, - Eth: TransactionCompat + 'static, + Pool: TransactionPool> + 'static, + Eth: TransactionCompat> + 'static, { /// Returns the number of transactions currently pending for inclusion in the next block(s), as /// well as the ones that are being scheduled for future execution only. @@ -96,19 +97,19 @@ where trace!(target: "rpc::eth", "Serving txpool_inspect"); #[inline] - fn insert>>( + fn insert>( tx: &T, inspect: &mut BTreeMap>, ) { let entry = inspect.entry(tx.sender()).or_default(); - let tx: RecoveredTx = tx.clone_into_consensus().into(); + let tx = tx.clone_into_consensus(); entry.insert( tx.nonce().to_string(), TxpoolInspectSummary { to: tx.to(), value: tx.value(), gas: tx.gas_limit() as u128, - gas_price: tx.transaction.max_fee_per_gas(), + gas_price: tx.max_fee_per_gas(), }, ); } diff --git a/crates/transaction-pool/src/maintain.rs b/crates/transaction-pool/src/maintain.rs index 7e28b6e26859..fa7b75e34ad1 100644 --- a/crates/transaction-pool/src/maintain.rs +++ b/crates/transaction-pool/src/maintain.rs @@ -10,6 +10,7 @@ use crate::{ use alloy_consensus::BlockHeader; use alloy_eips::BlockNumberOrTag; use alloy_primitives::{Address, BlockHash, BlockNumber}; +use alloy_rlp::Encodable; use futures_util::{ future::{BoxFuture, Fuse, FusedFuture}, FutureExt, Stream, StreamExt, @@ -19,7 +20,8 @@ use reth_chainspec::{ChainSpecProvider, EthChainSpec}; use reth_execution_types::ChangedAccount; use reth_fs_util::FsPathError; use reth_primitives::{ - PooledTransactionsElementEcRecovered, RecoveredTx, SealedHeader, TransactionSigned, + transaction::SignedTransactionIntoRecoveredExt, PooledTransactionsElementEcRecovered, + SealedHeader, TransactionSigned, }; use reth_primitives_traits::SignedTransaction; use reth_storage_api::{errors::provider::ProviderError, BlockReaderIdExt, StateProviderFactory}; @@ -78,7 +80,7 @@ pub fn maintain_transaction_pool_future( ) -> BoxFuture<'static, ()> where Client: StateProviderFactory + BlockReaderIdExt + ChainSpecProvider + Clone + Send + 'static, - P: TransactionPoolExt + 'static, + P: TransactionPoolExt> + 'static, St: Stream + Send + Unpin + 'static, Tasks: TaskSpawner + 'static, { @@ -99,7 +101,7 @@ pub async fn maintain_transaction_pool( config: MaintainPoolConfig, ) where Client: StateProviderFactory + BlockReaderIdExt + ChainSpecProvider + Clone + Send + 'static, - P: TransactionPoolExt + 'static, + P: TransactionPoolExt> + 'static, St: Stream + Send + Unpin + 'static, Tasks: TaskSpawner + 'static, { @@ -342,7 +344,7 @@ pub async fn maintain_transaction_pool(

::Transaction::from_pooled(tx.into()) }) } else { -

::Transaction::try_from_consensus(tx.into()).ok() +

::Transaction::try_from_consensus(tx).ok() } }) .collect::>(); @@ -559,7 +561,7 @@ async fn load_and_reinsert_transactions

( file_path: &Path, ) -> Result<(), TransactionsBackupError> where - P: TransactionPool, + P: TransactionPool>, { if !file_path.exists() { return Ok(()) @@ -572,14 +574,15 @@ where return Ok(()) } - let txs_signed: Vec = alloy_rlp::Decodable::decode(&mut data.as_slice())?; + let txs_signed: Vec<::Consensus> = + alloy_rlp::Decodable::decode(&mut data.as_slice())?; let pool_transactions = txs_signed .into_iter() .filter_map(|tx| tx.try_ecrecovered()) .filter_map(|tx| { // Filter out errors - ::try_from_consensus(tx.into()).ok() + ::try_from_consensus(tx).ok() }) .collect(); @@ -592,7 +595,7 @@ where fn save_local_txs_backup

(pool: P, file_path: &Path) where - P: TransactionPool, + P: TransactionPool>, { let local_transactions = pool.get_local_transactions(); if local_transactions.is_empty() { @@ -602,10 +605,7 @@ where let local_transactions = local_transactions .into_iter() - .map(|tx| { - let recovered: RecoveredTx = tx.transaction.clone_into_consensus().into(); - recovered.into_signed() - }) + .map(|tx| tx.transaction.clone_into_consensus().into_signed()) .collect::>(); let num_txs = local_transactions.len(); @@ -645,7 +645,7 @@ pub async fn backup_local_transactions_task

( pool: P, config: LocalTransactionBackupConfig, ) where - P: TransactionPool + Clone, + P: TransactionPool> + Clone, { let Some(transactions_path) = config.transactions_path else { // nothing to do diff --git a/crates/transaction-pool/src/pool/best.rs b/crates/transaction-pool/src/pool/best.rs index be49ce0b1fda..b770e3da4b0e 100644 --- a/crates/transaction-pool/src/pool/best.rs +++ b/crates/transaction-pool/src/pool/best.rs @@ -226,7 +226,7 @@ impl Iterator for BestTransactions { #[derive(Debug)] pub struct BestPayloadTransactions where - T: PoolTransaction>, + T: PoolTransaction, I: Iterator>>, { invalid: HashSet

, @@ -235,7 +235,7 @@ where impl BestPayloadTransactions where - T: PoolTransaction>, + T: PoolTransaction, I: Iterator>>, { /// Create a new `BestPayloadTransactions` with the given iterator. @@ -246,16 +246,18 @@ where impl PayloadTransactions for BestPayloadTransactions where - T: PoolTransaction>, + T: PoolTransaction, I: Iterator>>, { - fn next(&mut self, _ctx: ()) -> Option { + type Transaction = T::Consensus; + + fn next(&mut self, _ctx: ()) -> Option> { loop { let tx = self.best.next()?; if self.invalid.contains(&tx.sender()) { continue } - return Some(tx.to_recovered_transaction()) + return Some(tx.to_consensus()) } } diff --git a/crates/transaction-pool/src/test_utils/mock.rs b/crates/transaction-pool/src/test_utils/mock.rs index 05551151d780..471956fdca57 100644 --- a/crates/transaction-pool/src/test_utils/mock.rs +++ b/crates/transaction-pool/src/test_utils/mock.rs @@ -592,15 +592,17 @@ impl MockTransaction { impl PoolTransaction for MockTransaction { type TryFromConsensusError = TryFromRecoveredTransactionError; - type Consensus = RecoveredTx; + type Consensus = TransactionSigned; type Pooled = PooledTransactionsElementEcRecovered; - fn try_from_consensus(tx: Self::Consensus) -> Result { + fn try_from_consensus( + tx: RecoveredTx, + ) -> Result { tx.try_into() } - fn into_consensus(self) -> Self::Consensus { + fn into_consensus(self) -> RecoveredTx { self.into() } @@ -609,7 +611,7 @@ impl PoolTransaction for MockTransaction { } fn try_consensus_into_pooled( - tx: Self::Consensus, + tx: RecoveredTx, ) -> Result { Self::Pooled::try_from(tx).map_err(|_| TryFromRecoveredTransactionError::BlobSidecarMissing) } diff --git a/crates/transaction-pool/src/traits.rs b/crates/transaction-pool/src/traits.rs index a5c85ce125b6..6d4d562b3bdf 100644 --- a/crates/transaction-pool/src/traits.rs +++ b/crates/transaction-pool/src/traits.rs @@ -38,6 +38,9 @@ use tokio::sync::mpsc::Receiver; /// The `PeerId` type. pub type PeerId = alloy_primitives::B512; +/// Helper type alias to access [`PoolTransaction::Consensus`] for a given [`TransactionPool`]. +pub type PoolConsensusTx

= <

::Transaction as PoolTransaction>::Consensus; + /// General purpose abstraction of a transaction-pool. /// /// This is intended to be used by API-consumers such as RPC that need inject new incoming, @@ -577,17 +580,17 @@ pub struct AllPoolTransactions { impl AllPoolTransactions { /// Returns an iterator over all pending [`RecoveredTx`] transactions. - pub fn pending_recovered(&self) -> impl Iterator + '_ { + pub fn pending_recovered(&self) -> impl Iterator> + '_ { self.pending.iter().map(|tx| tx.transaction.clone().into()) } /// Returns an iterator over all queued [`RecoveredTx`] transactions. - pub fn queued_recovered(&self) -> impl Iterator + '_ { + pub fn queued_recovered(&self) -> impl Iterator> + '_ { self.queued.iter().map(|tx| tx.transaction.clone().into()) } /// Returns an iterator over all transactions, both pending and queued. - pub fn all(&self) -> impl Iterator + '_ { + pub fn all(&self) -> impl Iterator> + '_ { self.pending.iter().chain(self.queued.iter()).map(|tx| tx.transaction.clone().into()) } } @@ -963,30 +966,39 @@ impl BestTransactionsAttributes { /// This distinction is necessary for the EIP-4844 blob transactions, which require an additional /// sidecar when they are gossiped around the network. It is expected that the `Consensus` format is /// a subset of the `Pooled` format. -pub trait PoolTransaction: fmt::Debug + Send + Sync + Clone { +pub trait PoolTransaction: + fmt::Debug + + Send + + Sync + + Clone + + TryFrom, Error = Self::TryFromConsensusError> + + Into> +{ /// Associated error type for the `try_from_consensus` method. type TryFromConsensusError: fmt::Display; /// Associated type representing the raw consensus variant of the transaction. - type Consensus: From + TryInto; + type Consensus; /// Associated type representing the recovered pooled variant of the transaction. type Pooled: Encodable2718 + Into; /// Define a method to convert from the `Consensus` type to `Self` - fn try_from_consensus(tx: Self::Consensus) -> Result { + fn try_from_consensus( + tx: RecoveredTx, + ) -> Result { tx.try_into() } /// Clone the transaction into a consensus variant. /// /// This method is preferred when the [`PoolTransaction`] already wraps the consensus variant. - fn clone_into_consensus(&self) -> Self::Consensus { + fn clone_into_consensus(&self) -> RecoveredTx { self.clone().into_consensus() } /// Define a method to convert from the `Self` type to `Consensus` - fn into_consensus(self) -> Self::Consensus { + fn into_consensus(self) -> RecoveredTx { self.into() } @@ -1002,7 +1014,7 @@ pub trait PoolTransaction: fmt::Debug + Send + Sync + Clone { /// Tries to convert the `Consensus` type into the `Pooled` type. fn try_consensus_into_pooled( - tx: Self::Consensus, + tx: RecoveredTx, ) -> Result; /// Hash of the transaction. @@ -1131,7 +1143,6 @@ pub trait PoolTransaction: fmt::Debug + Send + Sync + Clone { /// Ethereum pool. pub trait EthPoolTransaction: PoolTransaction< - Consensus: From + Into + Into, Pooled: From + Into + Into, @@ -1242,16 +1253,16 @@ impl From for EthPooledTransaction { impl PoolTransaction for EthPooledTransaction { type TryFromConsensusError = TryFromRecoveredTransactionError; - type Consensus = RecoveredTx; + type Consensus = TransactionSigned; type Pooled = PooledTransactionsElementEcRecovered; - fn clone_into_consensus(&self) -> Self::Consensus { + fn clone_into_consensus(&self) -> RecoveredTx { self.transaction().clone() } fn try_consensus_into_pooled( - tx: Self::Consensus, + tx: RecoveredTx, ) -> Result { Self::Pooled::try_from(tx).map_err(|_| TryFromRecoveredTransactionError::BlobSidecarMissing) } diff --git a/crates/transaction-pool/src/validate/mod.rs b/crates/transaction-pool/src/validate/mod.rs index d333be87963b..6c625373401b 100644 --- a/crates/transaction-pool/src/validate/mod.rs +++ b/crates/transaction-pool/src/validate/mod.rs @@ -378,7 +378,7 @@ impl ValidPoolTransaction { /// Converts to this type into the consensus transaction of the pooled transaction. /// /// Note: this takes `&self` since indented usage is via `Arc`. - pub fn to_consensus(&self) -> T::Consensus { + pub fn to_consensus(&self) -> RecoveredTx { self.transaction.clone_into_consensus() } @@ -435,15 +435,6 @@ impl ValidPoolTransaction { } } -impl>> ValidPoolTransaction { - /// Converts to this type into a [`RecoveredTx`]. - /// - /// Note: this takes `&self` since indented usage is via `Arc`. - pub fn to_recovered_transaction(&self) -> RecoveredTx { - self.to_consensus().into() - } -} - #[cfg(test)] impl Clone for ValidPoolTransaction { fn clone(&self) -> Self { diff --git a/examples/custom-engine-types/src/main.rs b/examples/custom-engine-types/src/main.rs index f9ac5c238659..1034effebf84 100644 --- a/examples/custom-engine-types/src/main.rs +++ b/examples/custom-engine-types/src/main.rs @@ -38,14 +38,14 @@ use reth::{ }, network::NetworkHandle, payload::ExecutionPayloadValidator, - primitives::{Block, EthPrimitives, SealedBlockFor}, + primitives::{Block, EthPrimitives, SealedBlockFor, TransactionSigned}, providers::{CanonStateSubscriptions, EthStorage, StateProviderFactory}, rpc::{ eth::EthApi, types::engine::{ExecutionPayload, ExecutionPayloadSidecar, PayloadError}, }, tasks::TaskManager, - transaction_pool::TransactionPool, + transaction_pool::{PoolTransaction, TransactionPool}, }; use reth_basic_payload_builder::{ BasicPayloadJobGenerator, BasicPayloadJobGeneratorConfig, BuildArguments, BuildOutcome, @@ -340,7 +340,9 @@ where Primitives = EthPrimitives, >, >, - Pool: TransactionPool + Unpin + 'static, + Pool: TransactionPool> + + Unpin + + 'static, { async fn spawn_payload_service( self, @@ -380,7 +382,7 @@ pub struct CustomPayloadBuilder; impl PayloadBuilder for CustomPayloadBuilder where Client: StateProviderFactory + ChainSpecProvider, - Pool: TransactionPool, + Pool: TransactionPool>, { type Attributes = CustomPayloadBuilderAttributes; type BuiltPayload = EthBuiltPayload; diff --git a/examples/custom-evm/src/main.rs b/examples/custom-evm/src/main.rs index e7999818ae18..d9e341c02cc4 100644 --- a/examples/custom-evm/src/main.rs +++ b/examples/custom-evm/src/main.rs @@ -20,7 +20,7 @@ use reth::{ }, rpc::types::engine::PayloadAttributes, tasks::TaskManager, - transaction_pool::TransactionPool, + transaction_pool::{PoolTransaction, TransactionPool}, }; use reth_chainspec::{Chain, ChainSpec}; use reth_evm_ethereum::EthEvmConfig; @@ -183,7 +183,9 @@ impl PayloadServiceBuilder for MyPayloadBuilder where Types: NodeTypesWithEngine, Node: FullNodeTypes, - Pool: TransactionPool + Unpin + 'static, + Pool: TransactionPool> + + Unpin + + 'static, Types::Engine: PayloadTypes< BuiltPayload = EthBuiltPayload, PayloadAttributes = PayloadAttributes, diff --git a/examples/custom-inspector/src/main.rs b/examples/custom-inspector/src/main.rs index 67863d00e1e9..6b25c46b76ca 100644 --- a/examples/custom-inspector/src/main.rs +++ b/examples/custom-inspector/src/main.rs @@ -54,8 +54,7 @@ fn main() { if let Some(recipient) = tx.to() { if args.is_match(&recipient) { // convert the pool transaction - let call_request = - transaction_to_call_request(tx.to_recovered_transaction()); + let call_request = transaction_to_call_request(tx.to_consensus()); let result = eth_api .spawn_with_call_at( diff --git a/examples/custom-payload-builder/src/main.rs b/examples/custom-payload-builder/src/main.rs index 6047da0dd1ba..d7c42e341b59 100644 --- a/examples/custom-payload-builder/src/main.rs +++ b/examples/custom-payload-builder/src/main.rs @@ -17,14 +17,14 @@ use reth::{ cli::{config::PayloadBuilderConfig, Cli}, payload::PayloadBuilderHandle, providers::CanonStateSubscriptions, - transaction_pool::TransactionPool, + transaction_pool::{PoolTransaction, TransactionPool}, }; use reth_basic_payload_builder::BasicPayloadJobGeneratorConfig; use reth_chainspec::ChainSpec; use reth_node_api::NodeTypesWithEngine; use reth_node_ethereum::{node::EthereumAddOns, EthEngineTypes, EthEvmConfig, EthereumNode}; use reth_payload_builder::PayloadBuilderService; -use reth_primitives::EthPrimitives; +use reth_primitives::{EthPrimitives, TransactionSigned}; pub mod generator; pub mod job; @@ -42,7 +42,9 @@ where Primitives = EthPrimitives, >, >, - Pool: TransactionPool + Unpin + 'static, + Pool: TransactionPool> + + Unpin + + 'static, { async fn spawn_payload_service( self, diff --git a/examples/txpool-tracing/src/main.rs b/examples/txpool-tracing/src/main.rs index 94f800987a96..76abd65f4af6 100644 --- a/examples/txpool-tracing/src/main.rs +++ b/examples/txpool-tracing/src/main.rs @@ -44,8 +44,7 @@ fn main() { if let Some(recipient) = tx.to() { if args.is_match(&recipient) { // trace the transaction with `trace_call` - let callrequest = - transaction_to_call_request(tx.to_recovered_transaction()); + let callrequest = transaction_to_call_request(tx.to_consensus()); let tracerequest = TraceCallRequest::new(callrequest) .with_trace_type(TraceType::Trace); if let Ok(trace_result) = traceapi.trace_call(tracerequest).await { From 74017bac0aebf4143d34005301f53087fe76c00f Mon Sep 17 00:00:00 2001 From: morito Date: Tue, 3 Dec 2024 17:48:21 +0900 Subject: [PATCH 39/68] feat: Use `PrimitiveSignature` instead of `Signature` (#13087) --- crates/net/network/src/transactions/validation.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/net/network/src/transactions/validation.rs b/crates/net/network/src/transactions/validation.rs index 1575d9f3374a..1018cde6b55b 100644 --- a/crates/net/network/src/transactions/validation.rs +++ b/crates/net/network/src/transactions/validation.rs @@ -3,7 +3,7 @@ //! announcements. Validation and filtering of announcements is network dependent. use crate::metrics::{AnnouncedTxTypesMetrics, TxTypesCounter}; -use alloy_primitives::{Signature, TxHash}; +use alloy_primitives::{PrimitiveSignature as Signature, TxHash}; use derive_more::{Deref, DerefMut}; use reth_eth_wire::{ DedupPayload, Eth68TxMetadata, HandleMempoolData, PartiallyValidData, ValidAnnouncementData, From 383b8c242e0e93f7683a807c881c3111be0dad70 Mon Sep 17 00:00:00 2001 From: Federico Gimenez Date: Tue, 3 Dec 2024 10:01:02 +0100 Subject: [PATCH 40/68] fix(engine): get_proof_targets only add fetched accounts if they have new storage (#13015) Co-authored-by: Roman Krasiuk --- crates/engine/tree/src/tree/root.rs | 210 +++++++++++++++++++++++++--- 1 file changed, 189 insertions(+), 21 deletions(-) diff --git a/crates/engine/tree/src/tree/root.rs b/crates/engine/tree/src/tree/root.rs index 31e79ca04b57..70f54ce4d488 100644 --- a/crates/engine/tree/src/tree/root.rs +++ b/crates/engine/tree/src/tree/root.rs @@ -464,31 +464,37 @@ where } } +/// Returns accounts only with those storages that were not already fetched, and +/// if there are no such storages and the account itself was already fetched, the +/// account shouldn't be included. fn get_proof_targets( state_update: &HashedPostState, fetched_proof_targets: &HashMap>, ) -> HashMap> { - state_update - .accounts - .keys() - .filter(|hashed_address| !fetched_proof_targets.contains_key(*hashed_address)) - .map(|hashed_address| (*hashed_address, HashSet::default())) - .chain(state_update.storages.iter().map(|(hashed_address, storage)| { - let fetched_storage_proof_targets = fetched_proof_targets.get(hashed_address); - ( - *hashed_address, - storage - .storage - .keys() - .filter(|slot| { - !fetched_storage_proof_targets - .is_some_and(|targets| targets.contains(*slot)) - }) - .copied() - .collect(), - ) - })) - .collect() + let mut targets = HashMap::default(); + + // first collect all new accounts (not previously fetched) + for &hashed_address in state_update.accounts.keys() { + if !fetched_proof_targets.contains_key(&hashed_address) { + targets.insert(hashed_address, HashSet::default()); + } + } + + // then process storage slots for all accounts in the state update + for (hashed_address, storage) in &state_update.storages { + let fetched = fetched_proof_targets.get(hashed_address); + let mut changed_slots = storage + .storage + .keys() + .filter(|slot| !fetched.is_some_and(|f| f.contains(*slot))) + .peekable(); + + if changed_slots.peek().is_some() { + targets.entry(*hashed_address).or_default().extend(changed_slots); + } + } + + targets } /// Updates the sparse trie with the given proofs and state, and returns the updated trie and the @@ -793,4 +799,166 @@ mod tests { assert_eq!(ready.len(), 5); assert!(!sequencer.has_pending()); } + + fn create_get_proof_targets_state() -> HashedPostState { + let mut state = HashedPostState::default(); + + let addr1 = B256::random(); + let addr2 = B256::random(); + state.accounts.insert(addr1, Some(Default::default())); + state.accounts.insert(addr2, Some(Default::default())); + + let mut storage = HashedStorage::default(); + let slot1 = B256::random(); + let slot2 = B256::random(); + storage.storage.insert(slot1, U256::ZERO); + storage.storage.insert(slot2, U256::from(1)); + state.storages.insert(addr1, storage); + + state + } + + #[test] + fn test_get_proof_targets_new_account_targets() { + let state = create_get_proof_targets_state(); + let fetched = HashMap::default(); + + let targets = get_proof_targets(&state, &fetched); + + // should return all accounts as targets since nothing was fetched before + assert_eq!(targets.len(), state.accounts.len()); + for addr in state.accounts.keys() { + assert!(targets.contains_key(addr)); + } + } + + #[test] + fn test_get_proof_targets_new_storage_targets() { + let state = create_get_proof_targets_state(); + let fetched = HashMap::default(); + + let targets = get_proof_targets(&state, &fetched); + + // verify storage slots are included for accounts with storage + for (addr, storage) in &state.storages { + assert!(targets.contains_key(addr)); + let target_slots = &targets[addr]; + assert_eq!(target_slots.len(), storage.storage.len()); + for slot in storage.storage.keys() { + assert!(target_slots.contains(slot)); + } + } + } + + #[test] + fn test_get_proof_targets_filter_already_fetched_accounts() { + let state = create_get_proof_targets_state(); + let mut fetched = HashMap::default(); + + // select an account that has no storage updates + let fetched_addr = state + .accounts + .keys() + .find(|&&addr| !state.storages.contains_key(&addr)) + .expect("Should have an account without storage"); + + // mark the account as already fetched + fetched.insert(*fetched_addr, HashSet::default()); + + let targets = get_proof_targets(&state, &fetched); + + // should not include the already fetched account since it has no storage updates + assert!(!targets.contains_key(fetched_addr)); + // other accounts should still be included + assert_eq!(targets.len(), state.accounts.len() - 1); + } + + #[test] + fn test_get_proof_targets_filter_already_fetched_storage() { + let state = create_get_proof_targets_state(); + let mut fetched = HashMap::default(); + + // mark one storage slot as already fetched + let (addr, storage) = state.storages.iter().next().unwrap(); + let mut fetched_slots = HashSet::default(); + let fetched_slot = *storage.storage.keys().next().unwrap(); + fetched_slots.insert(fetched_slot); + fetched.insert(*addr, fetched_slots); + + let targets = get_proof_targets(&state, &fetched); + + // should not include the already fetched storage slot + let target_slots = &targets[addr]; + assert!(!target_slots.contains(&fetched_slot)); + assert_eq!(target_slots.len(), storage.storage.len() - 1); + } + + #[test] + fn test_get_proof_targets_empty_state() { + let state = HashedPostState::default(); + let fetched = HashMap::default(); + + let targets = get_proof_targets(&state, &fetched); + + assert!(targets.is_empty()); + } + + #[test] + fn test_get_proof_targets_mixed_fetched_state() { + let mut state = HashedPostState::default(); + let mut fetched = HashMap::default(); + + let addr1 = B256::random(); + let addr2 = B256::random(); + let slot1 = B256::random(); + let slot2 = B256::random(); + + state.accounts.insert(addr1, Some(Default::default())); + state.accounts.insert(addr2, Some(Default::default())); + + let mut storage = HashedStorage::default(); + storage.storage.insert(slot1, U256::ZERO); + storage.storage.insert(slot2, U256::from(1)); + state.storages.insert(addr1, storage); + + let mut fetched_slots = HashSet::default(); + fetched_slots.insert(slot1); + fetched.insert(addr1, fetched_slots); + + let targets = get_proof_targets(&state, &fetched); + + assert!(targets.contains_key(&addr2)); + assert!(!targets[&addr1].contains(&slot1)); + assert!(targets[&addr1].contains(&slot2)); + } + + #[test] + fn test_get_proof_targets_unmodified_account_with_storage() { + let mut state = HashedPostState::default(); + let fetched = HashMap::default(); + + let addr = B256::random(); + let slot1 = B256::random(); + let slot2 = B256::random(); + + // don't add the account to state.accounts (simulating unmodified account) + // but add storage updates for this account + let mut storage = HashedStorage::default(); + storage.storage.insert(slot1, U256::from(1)); + storage.storage.insert(slot2, U256::from(2)); + state.storages.insert(addr, storage); + + assert!(!state.accounts.contains_key(&addr)); + assert!(!fetched.contains_key(&addr)); + + let targets = get_proof_targets(&state, &fetched); + + // verify that we still get the storage slots for the unmodified account + assert!(targets.contains_key(&addr)); + + let target_slots = &targets[&addr]; + assert_eq!(target_slots.len(), 2); + assert!(target_slots.contains(&slot1)); + assert!(target_slots.contains(&slot2)); + } } From 82b97a8dd383d596b1a3978073bebacb2810c993 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Tue, 3 Dec 2024 10:46:41 +0100 Subject: [PATCH 41/68] chore: fix unused warning (#13090) --- crates/trie/common/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/trie/common/Cargo.toml b/crates/trie/common/Cargo.toml index 9f81d020eb3a..73fce5f8e7bd 100644 --- a/crates/trie/common/Cargo.toml +++ b/crates/trie/common/Cargo.toml @@ -67,7 +67,7 @@ serde = [ "alloy-primitives/serde", "alloy-consensus/serde", "alloy-trie/serde", - "alloy-rpc-types-eth/serde", + "alloy-rpc-types-eth?/serde", "revm-primitives/serde", "reth-primitives-traits/serde", "reth-codecs/serde" From 84e1fb92e0a17025c01ea46a86864303cff71983 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Tue, 3 Dec 2024 11:58:33 +0100 Subject: [PATCH 42/68] feat: impl more noop functions (#13029) --- crates/net/network/src/config.rs | 6 +- crates/storage/storage-api/src/noop.rs | 530 ++++++++++++++++++++++++- 2 files changed, 520 insertions(+), 16 deletions(-) diff --git a/crates/net/network/src/config.rs b/crates/net/network/src/config.rs index bde2cf78d979..44f34c3a4b08 100644 --- a/crates/net/network/src/config.rs +++ b/crates/net/network/src/config.rs @@ -16,7 +16,7 @@ use reth_eth_wire::{ use reth_ethereum_forks::{ForkFilter, Head}; use reth_network_peers::{mainnet_nodes, pk2id, sepolia_nodes, PeerId, TrustedPeer}; use reth_network_types::{PeersConfig, SessionsConfig}; -use reth_storage_api::{noop::NoopBlockReader, BlockNumReader, BlockReader, HeaderProvider}; +use reth_storage_api::{noop::NoopProvider, BlockNumReader, BlockReader, HeaderProvider}; use reth_tasks::{TaskSpawner, TokioTaskExecutor}; use secp256k1::SECP256K1; use std::{collections::HashSet, net::SocketAddr, sync::Arc}; @@ -498,11 +498,11 @@ impl NetworkConfigBuilder { pub fn build_with_noop_provider( self, chain_spec: Arc, - ) -> NetworkConfig, N> + ) -> NetworkConfig, N> where ChainSpec: EthChainSpec + Hardforks + 'static, { - self.build(NoopBlockReader::new(chain_spec)) + self.build(NoopProvider::eth(chain_spec)) } /// Sets the NAT resolver for external IP. diff --git a/crates/storage/storage-api/src/noop.rs b/crates/storage/storage-api/src/noop.rs index 7325e2b74360..9c971e7b293e 100644 --- a/crates/storage/storage-api/src/noop.rs +++ b/crates/storage/storage-api/src/noop.rs @@ -1,28 +1,81 @@ //! Various noop implementations for traits. -use std::sync::Arc; - -use crate::{BlockHashReader, BlockNumReader}; -use alloy_primitives::{BlockNumber, B256}; -use reth_chainspec::{ChainInfo, ChainSpecProvider, EthChainSpec}; +use crate::{ + AccountReader, BlockHashReader, BlockIdReader, BlockNumReader, BlockReader, BlockReaderIdExt, + BlockSource, ChangeSetReader, HeaderProvider, NodePrimitivesProvider, PruneCheckpointReader, + ReceiptProvider, ReceiptProviderIdExt, StageCheckpointReader, StateProofProvider, + StateProvider, StateRootProvider, StorageRootProvider, TransactionVariant, + TransactionsProvider, WithdrawalsProvider, +}; +use alloy_eips::{ + eip4895::{Withdrawal, Withdrawals}, + BlockHashOrNumber, BlockId, +}; +use alloy_primitives::{ + map::{HashMap, HashSet}, + Address, BlockHash, BlockNumber, Bytes, StorageKey, StorageValue, TxHash, TxNumber, B256, U256, +}; +use reth_chainspec::{ChainInfo, ChainSpecProvider, EthChainSpec, MAINNET}; +use reth_db_models::{AccountBeforeTx, StoredBlockBodyIndices}; +use reth_primitives::{ + BlockWithSenders, EthPrimitives, SealedBlockFor, SealedBlockWithSenders, TransactionMeta, +}; +use reth_primitives_traits::{Account, Bytecode, NodePrimitives, SealedHeader}; +use reth_prune_types::{PruneCheckpoint, PruneSegment}; +use reth_stages_types::{StageCheckpoint, StageId}; use reth_storage_errors::provider::ProviderResult; +use reth_trie::{ + updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof, TrieInput, +}; +use std::{ + marker::PhantomData, + ops::{RangeBounds, RangeInclusive}, + sync::Arc, +}; /// Supports various api interfaces for testing purposes. -#[derive(Debug, Clone)] +#[derive(Debug)] #[non_exhaustive] -pub struct NoopBlockReader { +pub struct NoopProvider { chain_spec: Arc, + _phantom: PhantomData, +} + +impl NoopProvider { + /// Create a new instance for specific primitive types. + pub fn new(chain_spec: Arc) -> Self { + Self { chain_spec, _phantom: Default::default() } + } } -impl NoopBlockReader { +impl NoopProvider { /// Create a new instance of the `NoopBlockReader`. - pub const fn new(chain_spec: Arc) -> Self { - Self { chain_spec } + pub fn eth(chain_spec: Arc) -> Self { + Self { chain_spec, _phantom: Default::default() } + } +} + +impl NoopProvider { + /// Create a new instance of the [`NoopProvider`] with the mainnet chain spec. + pub fn mainnet() -> Self { + Self::eth(MAINNET.clone()) + } +} + +impl Default for NoopProvider { + fn default() -> Self { + Self::mainnet() + } +} + +impl Clone for NoopProvider { + fn clone(&self) -> Self { + Self { chain_spec: Arc::clone(&self.chain_spec), _phantom: Default::default() } } } /// Noop implementation for testing purposes -impl BlockHashReader for NoopBlockReader { +impl BlockHashReader for NoopProvider { fn block_hash(&self, _number: u64) -> ProviderResult> { Ok(None) } @@ -36,7 +89,7 @@ impl BlockHashReader for NoopBlockReader { } } -impl BlockNumReader for NoopBlockReader { +impl BlockNumReader for NoopProvider { fn chain_info(&self) -> ProviderResult { Ok(ChainInfo::default()) } @@ -54,10 +107,461 @@ impl BlockNumReader for NoopBlockReader { } } -impl ChainSpecProvider for NoopBlockReader { +impl ChainSpecProvider + for NoopProvider +{ type ChainSpec = ChainSpec; fn chain_spec(&self) -> Arc { self.chain_spec.clone() } } + +impl BlockIdReader for NoopProvider { + fn pending_block_num_hash(&self) -> ProviderResult> { + Ok(None) + } + + fn safe_block_num_hash(&self) -> ProviderResult> { + Ok(None) + } + + fn finalized_block_num_hash(&self) -> ProviderResult> { + Ok(None) + } +} + +impl BlockReaderIdExt for NoopProvider { + fn block_by_id(&self, _id: BlockId) -> ProviderResult> { + Ok(None) + } + + fn sealed_header_by_id( + &self, + _id: BlockId, + ) -> ProviderResult>> { + Ok(None) + } + + fn header_by_id(&self, _id: BlockId) -> ProviderResult> { + Ok(None) + } + + fn ommers_by_id(&self, _id: BlockId) -> ProviderResult>> { + Ok(None) + } +} + +impl BlockReader for NoopProvider { + type Block = N::Block; + + fn find_block_by_hash( + &self, + _hash: B256, + _source: BlockSource, + ) -> ProviderResult> { + Ok(None) + } + + fn block(&self, _id: BlockHashOrNumber) -> ProviderResult> { + Ok(None) + } + + fn pending_block(&self) -> ProviderResult>> { + Ok(None) + } + + fn pending_block_with_senders( + &self, + ) -> ProviderResult>> { + Ok(None) + } + + fn pending_block_and_receipts( + &self, + ) -> ProviderResult, Vec)>> { + Ok(None) + } + + fn ommers(&self, _id: BlockHashOrNumber) -> ProviderResult>> { + Ok(None) + } + + fn block_body_indices(&self, _num: u64) -> ProviderResult> { + Ok(None) + } + + fn block_with_senders( + &self, + _id: BlockHashOrNumber, + _transaction_kind: TransactionVariant, + ) -> ProviderResult>> { + Ok(None) + } + + fn sealed_block_with_senders( + &self, + _id: BlockHashOrNumber, + _transaction_kind: TransactionVariant, + ) -> ProviderResult>> { + Ok(None) + } + + fn block_range(&self, _range: RangeInclusive) -> ProviderResult> { + Ok(vec![]) + } + + fn block_with_senders_range( + &self, + _range: RangeInclusive, + ) -> ProviderResult>> { + Ok(vec![]) + } + + fn sealed_block_with_senders_range( + &self, + _range: RangeInclusive, + ) -> ProviderResult>> { + Ok(vec![]) + } +} + +impl TransactionsProvider for NoopProvider { + type Transaction = N::SignedTx; + + fn transaction_id(&self, _tx_hash: TxHash) -> ProviderResult> { + Ok(None) + } + + fn transaction_by_id(&self, _id: TxNumber) -> ProviderResult> { + Ok(None) + } + + fn transaction_by_id_unhashed( + &self, + _id: TxNumber, + ) -> ProviderResult> { + Ok(None) + } + + fn transaction_by_hash(&self, _hash: TxHash) -> ProviderResult> { + Ok(None) + } + + fn transaction_by_hash_with_meta( + &self, + _hash: TxHash, + ) -> ProviderResult> { + Ok(None) + } + + fn transaction_block(&self, _id: TxNumber) -> ProviderResult> { + todo!() + } + + fn transactions_by_block( + &self, + _block_id: BlockHashOrNumber, + ) -> ProviderResult>> { + Ok(None) + } + + fn transactions_by_block_range( + &self, + _range: impl RangeBounds, + ) -> ProviderResult>> { + Ok(Vec::default()) + } + + fn transactions_by_tx_range( + &self, + _range: impl RangeBounds, + ) -> ProviderResult> { + Ok(Vec::default()) + } + + fn senders_by_tx_range( + &self, + _range: impl RangeBounds, + ) -> ProviderResult> { + Ok(Vec::default()) + } + + fn transaction_sender(&self, _id: TxNumber) -> ProviderResult> { + Ok(None) + } +} + +impl ReceiptProvider for NoopProvider { + type Receipt = N::Receipt; + + fn receipt(&self, _id: TxNumber) -> ProviderResult> { + Ok(None) + } + + fn receipt_by_hash(&self, _hash: TxHash) -> ProviderResult> { + Ok(None) + } + + fn receipts_by_block( + &self, + _block: BlockHashOrNumber, + ) -> ProviderResult>> { + Ok(None) + } + + fn receipts_by_tx_range( + &self, + _range: impl RangeBounds, + ) -> ProviderResult> { + Ok(vec![]) + } +} + +impl ReceiptProviderIdExt for NoopProvider {} + +impl HeaderProvider for NoopProvider { + type Header = N::BlockHeader; + + fn header(&self, _block_hash: &BlockHash) -> ProviderResult> { + Ok(None) + } + + fn header_by_number(&self, _num: u64) -> ProviderResult> { + Ok(None) + } + + fn header_td(&self, _hash: &BlockHash) -> ProviderResult> { + Ok(None) + } + + fn header_td_by_number(&self, _number: BlockNumber) -> ProviderResult> { + Ok(None) + } + + fn headers_range( + &self, + _range: impl RangeBounds, + ) -> ProviderResult> { + Ok(vec![]) + } + + fn sealed_header( + &self, + _number: BlockNumber, + ) -> ProviderResult>> { + Ok(None) + } + + fn sealed_headers_while( + &self, + _range: impl RangeBounds, + _predicate: impl FnMut(&SealedHeader) -> bool, + ) -> ProviderResult>> { + Ok(vec![]) + } +} + +impl AccountReader for NoopProvider { + fn basic_account(&self, _address: Address) -> ProviderResult> { + Ok(None) + } +} + +impl ChangeSetReader for NoopProvider { + fn account_block_changeset( + &self, + _block_number: BlockNumber, + ) -> ProviderResult> { + Ok(Vec::default()) + } +} + +impl StateRootProvider for NoopProvider { + fn state_root(&self, _state: HashedPostState) -> ProviderResult { + Ok(B256::default()) + } + + fn state_root_from_nodes(&self, _input: TrieInput) -> ProviderResult { + Ok(B256::default()) + } + + fn state_root_with_updates( + &self, + _state: HashedPostState, + ) -> ProviderResult<(B256, TrieUpdates)> { + Ok((B256::default(), TrieUpdates::default())) + } + + fn state_root_from_nodes_with_updates( + &self, + _input: TrieInput, + ) -> ProviderResult<(B256, TrieUpdates)> { + Ok((B256::default(), TrieUpdates::default())) + } +} + +impl StorageRootProvider for NoopProvider { + fn storage_root( + &self, + _address: Address, + _hashed_storage: HashedStorage, + ) -> ProviderResult { + Ok(B256::default()) + } + + fn storage_proof( + &self, + _address: Address, + slot: B256, + _hashed_storage: HashedStorage, + ) -> ProviderResult { + Ok(reth_trie::StorageProof::new(slot)) + } + + fn storage_multiproof( + &self, + _address: Address, + _slots: &[B256], + _hashed_storage: HashedStorage, + ) -> ProviderResult { + Ok(reth_trie::StorageMultiProof::empty()) + } +} + +impl StateProofProvider for NoopProvider { + fn proof( + &self, + _input: TrieInput, + address: Address, + _slots: &[B256], + ) -> ProviderResult { + Ok(AccountProof::new(address)) + } + + fn multiproof( + &self, + _input: TrieInput, + _targets: HashMap>, + ) -> ProviderResult { + Ok(MultiProof::default()) + } + + fn witness( + &self, + _input: TrieInput, + _target: HashedPostState, + ) -> ProviderResult> { + Ok(HashMap::default()) + } +} + +impl StateProvider for NoopProvider { + fn storage( + &self, + _account: Address, + _storage_key: StorageKey, + ) -> ProviderResult> { + Ok(None) + } + + fn bytecode_by_hash(&self, _code_hash: B256) -> ProviderResult> { + Ok(None) + } +} + +// impl EvmEnvProvider for NoopProvider { +// fn fill_env_at( +// &self, +// _cfg: &mut CfgEnvWithHandlerCfg, +// _block_env: &mut BlockEnv, +// _at: BlockHashOrNumber, +// _evm_config: EvmConfig, +// ) -> ProviderResult<()> +// where +// EvmConfig: ConfigureEvmEnv

, +// { +// Ok(()) +// } +// +// fn fill_env_with_header( +// &self, +// _cfg: &mut CfgEnvWithHandlerCfg, +// _block_env: &mut BlockEnv, +// _header: &Header, +// _evm_config: EvmConfig, +// ) -> ProviderResult<()> +// where +// EvmConfig: ConfigureEvmEnv
, +// { +// Ok(()) +// } +// +// fn fill_cfg_env_at( +// &self, +// _cfg: &mut CfgEnvWithHandlerCfg, +// _at: BlockHashOrNumber, +// _evm_config: EvmConfig, +// ) -> ProviderResult<()> +// where +// EvmConfig: ConfigureEvmEnv
, +// { +// Ok(()) +// } +// +// fn fill_cfg_env_with_header( +// &self, +// _cfg: &mut CfgEnvWithHandlerCfg, +// _header: &Header, +// _evm_config: EvmConfig, +// ) -> ProviderResult<()> +// where +// EvmConfig: ConfigureEvmEnv
, +// { +// Ok(()) +// } +// } + +impl StageCheckpointReader for NoopProvider { + fn get_stage_checkpoint(&self, _id: StageId) -> ProviderResult> { + Ok(None) + } + + fn get_stage_checkpoint_progress(&self, _id: StageId) -> ProviderResult>> { + Ok(None) + } + + fn get_all_checkpoints(&self) -> ProviderResult> { + Ok(Vec::new()) + } +} + +impl WithdrawalsProvider for NoopProvider { + fn withdrawals_by_block( + &self, + _id: BlockHashOrNumber, + _timestamp: u64, + ) -> ProviderResult> { + Ok(None) + } + fn latest_withdrawal(&self) -> ProviderResult> { + Ok(None) + } +} + +impl PruneCheckpointReader for NoopProvider { + fn get_prune_checkpoint( + &self, + _segment: PruneSegment, + ) -> ProviderResult> { + Ok(None) + } + + fn get_prune_checkpoints(&self) -> ProviderResult> { + Ok(Vec::new()) + } +} + +impl NodePrimitivesProvider for NoopProvider { + type Primitives = N; +} From bfcd98326cde86382b1b0ffa8c7b2089fc6fa311 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Tue, 3 Dec 2024 13:38:00 +0100 Subject: [PATCH 43/68] feat: add Op DA config (#13095) --- crates/optimism/payload/src/config.rs | 87 +++++++++++++++++++++++++++ crates/optimism/payload/src/lib.rs | 2 + 2 files changed, 89 insertions(+) create mode 100644 crates/optimism/payload/src/config.rs diff --git a/crates/optimism/payload/src/config.rs b/crates/optimism/payload/src/config.rs new file mode 100644 index 000000000000..5055c05c42ea --- /dev/null +++ b/crates/optimism/payload/src/config.rs @@ -0,0 +1,87 @@ +//! Additional configuration for the OP builder + +use std::sync::{atomic::AtomicU64, Arc}; + +/// Contains the Data Availability configuration for the OP builder. +#[derive(Debug, Clone, Default)] +pub struct OpDAConfig { + inner: Arc, +} + +impl OpDAConfig { + /// Creates a new Data Availability configuration with the given maximum sizes. + pub fn new(max_da_tx_size: u64, max_da_block_size: u64) -> Self { + let this = Self::default(); + this.set_max_da_size(max_da_tx_size, max_da_block_size); + this + } + + /// Returns the max allowed data availability size per transactions, if any. + pub fn max_da_tx_size(&self) -> Option { + let val = self.inner.max_da_tx_size.load(std::sync::atomic::Ordering::Relaxed); + if val == 0 { + None + } else { + Some(val) + } + } + + /// Returns the max allowed data availability size per block, if any. + pub fn max_da_block_size(&self) -> Option { + let val = self.inner.max_da_block_size.load(std::sync::atomic::Ordering::Relaxed); + if val == 0 { + None + } else { + Some(val) + } + } + + /// Sets the maximum data availability size currently allowed for inclusion. 0 means no maximum. + pub fn set_max_da_size(&self, max_da_tx_size: u64, max_da_block_size: u64) { + self.set_max_tx_size(max_da_tx_size); + self.set_max_block_size(max_da_block_size); + } + + /// Sets the maximum data availability size per transaction currently allowed for inclusion. 0 + /// means no maximum. + pub fn set_max_tx_size(&self, max_da_tx_size: u64) { + self.inner.max_da_tx_size.store(max_da_tx_size, std::sync::atomic::Ordering::Relaxed); + } + + /// Sets the maximum data availability size per block currently allowed for inclusion. 0 means + /// no maximum. + pub fn set_max_block_size(&self, max_da_block_size: u64) { + self.inner.max_da_block_size.store(max_da_block_size, std::sync::atomic::Ordering::Relaxed); + } +} + +#[derive(Debug, Default)] +struct OpDAConfigInner { + /// Don't include any transactions with data availability size larger than this in any built + /// block + /// + /// 0 means no limit. + max_da_tx_size: AtomicU64, + /// Maximum total data availability size for a block + /// + /// 0 means no limit. + max_da_block_size: AtomicU64, +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_da() { + let da = OpDAConfig::default(); + assert_eq!(da.max_da_tx_size(), None); + assert_eq!(da.max_da_block_size(), None); + da.set_max_da_size(100, 200); + assert_eq!(da.max_da_tx_size(), Some(100)); + assert_eq!(da.max_da_block_size(), Some(200)); + da.set_max_da_size(0, 0); + assert_eq!(da.max_da_tx_size(), None); + assert_eq!(da.max_da_block_size(), None); + } +} diff --git a/crates/optimism/payload/src/lib.rs b/crates/optimism/payload/src/lib.rs index 8447026d783a..53fad1118fd0 100644 --- a/crates/optimism/payload/src/lib.rs +++ b/crates/optimism/payload/src/lib.rs @@ -16,3 +16,5 @@ pub use builder::OpPayloadBuilder; pub mod error; pub mod payload; pub use payload::{OpBuiltPayload, OpPayloadAttributes, OpPayloadBuilderAttributes}; + +pub mod config; From bedc68e8f4bd26927c1285e64e1cc652a0d839ff Mon Sep 17 00:00:00 2001 From: Roman Krasiuk Date: Tue, 3 Dec 2024 13:39:29 +0100 Subject: [PATCH 44/68] chore(evm): migrate execution errors back to `thiserror` (#13097) --- Cargo.lock | 2 +- crates/evm/execution-errors/Cargo.toml | 4 +- crates/evm/execution-errors/src/lib.rs | 96 ++++++++----------------- crates/evm/execution-errors/src/trie.rs | 75 ++++++------------- 4 files changed, 56 insertions(+), 121 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c72a1c8ddcb1..8c290d0ea9fc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7601,12 +7601,12 @@ dependencies = [ "alloy-eips", "alloy-primitives", "alloy-rlp", - "derive_more 1.0.0", "nybbles", "reth-consensus", "reth-prune-types", "reth-storage-errors", "revm-primitives", + "thiserror 2.0.3", ] [[package]] diff --git a/crates/evm/execution-errors/Cargo.toml b/crates/evm/execution-errors/Cargo.toml index 5e1755c0c552..b4b9992a979a 100644 --- a/crates/evm/execution-errors/Cargo.toml +++ b/crates/evm/execution-errors/Cargo.toml @@ -22,7 +22,7 @@ alloy-eips.workspace = true revm-primitives.workspace = true nybbles.workspace = true -derive_more.workspace = true +thiserror.workspace = true [features] default = ["std"] @@ -32,6 +32,6 @@ std = [ "alloy-primitives/std", "revm-primitives/std", "alloy-rlp/std", - "derive_more/std", + "thiserror/std", "nybbles/std" ] diff --git a/crates/evm/execution-errors/src/lib.rs b/crates/evm/execution-errors/src/lib.rs index 4dbbfb7abdce..db7887d1b8d2 100644 --- a/crates/evm/execution-errors/src/lib.rs +++ b/crates/evm/execution-errors/src/lib.rs @@ -14,20 +14,20 @@ extern crate alloc; use alloc::{boxed::Box, string::String}; use alloy_eips::BlockNumHash; use alloy_primitives::B256; -use derive_more::{Display, From}; use reth_consensus::ConsensusError; use reth_prune_types::PruneSegmentError; use reth_storage_errors::provider::ProviderError; use revm_primitives::EVMError; +use thiserror::Error; pub mod trie; pub use trie::*; /// Transaction validation errors -#[derive(Clone, Debug, Display, Eq, PartialEq)] +#[derive(Error, PartialEq, Eq, Clone, Debug)] pub enum BlockValidationError { /// EVM error with transaction hash and message - #[display("EVM reported invalid transaction ({hash}): {error}")] + #[error("EVM reported invalid transaction ({hash}): {error}")] EVM { /// The hash of the transaction hash: B256, @@ -35,16 +35,16 @@ pub enum BlockValidationError { error: Box>, }, /// Error when recovering the sender for a transaction - #[display("failed to recover sender for transaction")] + #[error("failed to recover sender for transaction")] SenderRecoveryError, /// Error when incrementing balance in post execution - #[display("incrementing balance in post execution failed")] + #[error("incrementing balance in post execution failed")] IncrementBalanceFailed, /// Error when the state root does not match the expected value. - // #[from(ignore)] - StateRoot(StateRootError), + #[error(transparent)] + StateRoot(#[from] StateRootError), /// Error when transaction gas limit exceeds available block gas - #[display( + #[error( "transaction gas limit {transaction_gas_limit} is more than blocks available gas {block_available_gas}" )] TransactionGasLimitMoreThanAvailableBlockGas { @@ -54,22 +54,22 @@ pub enum BlockValidationError { block_available_gas: u64, }, /// Error for pre-merge block - #[display("block {hash} is pre merge")] + #[error("block {hash} is pre merge")] BlockPreMerge { /// The hash of the block hash: B256, }, /// Error for missing total difficulty - #[display("missing total difficulty for block {hash}")] + #[error("missing total difficulty for block {hash}")] MissingTotalDifficulty { /// The hash of the block hash: B256, }, /// Error for EIP-4788 when parent beacon block root is missing - #[display("EIP-4788 parent beacon block root missing for active Cancun block")] + #[error("EIP-4788 parent beacon block root missing for active Cancun block")] MissingParentBeaconBlockRoot, /// Error for Cancun genesis block when parent beacon block root is not zero - #[display( + #[error( "the parent beacon block root is not zero for Cancun genesis block: {parent_beacon_block_root}" )] CancunGenesisParentBeaconBlockRootNotZero { @@ -79,9 +79,7 @@ pub enum BlockValidationError { /// EVM error during [EIP-4788] beacon root contract call. /// /// [EIP-4788]: https://eips.ethereum.org/EIPS/eip-4788 - #[display( - "failed to apply beacon root contract call at {parent_beacon_block_root}: {message}" - )] + #[error("failed to apply beacon root contract call at {parent_beacon_block_root}: {message}")] BeaconRootContractCall { /// The beacon block root parent_beacon_block_root: Box, @@ -91,7 +89,7 @@ pub enum BlockValidationError { /// EVM error during [EIP-2935] blockhash contract call. /// /// [EIP-2935]: https://eips.ethereum.org/EIPS/eip-2935 - #[display("failed to apply blockhash contract call: {message}")] + #[error("failed to apply blockhash contract call: {message}")] BlockHashContractCall { /// The error message. message: String, @@ -99,7 +97,7 @@ pub enum BlockValidationError { /// EVM error during withdrawal requests contract call [EIP-7002] /// /// [EIP-7002]: https://eips.ethereum.org/EIPS/eip-7002 - #[display("failed to apply withdrawal requests contract call: {message}")] + #[error("failed to apply withdrawal requests contract call: {message}")] WithdrawalRequestsContractCall { /// The error message. message: String, @@ -107,7 +105,7 @@ pub enum BlockValidationError { /// EVM error during consolidation requests contract call [EIP-7251] /// /// [EIP-7251]: https://eips.ethereum.org/EIPS/eip-7251 - #[display("failed to apply consolidation requests contract call: {message}")] + #[error("failed to apply consolidation requests contract call: {message}")] ConsolidationRequestsContractCall { /// The error message. message: String, @@ -115,35 +113,22 @@ pub enum BlockValidationError { /// Error when decoding deposit requests from receipts [EIP-6110] /// /// [EIP-6110]: https://eips.ethereum.org/EIPS/eip-6110 - #[display("failed to decode deposit requests from receipts: {_0}")] + #[error("failed to decode deposit requests from receipts: {_0}")] DepositRequestDecode(String), } -impl From for BlockValidationError { - fn from(error: StateRootError) -> Self { - Self::StateRoot(error) - } -} - -impl core::error::Error for BlockValidationError { - fn source(&self) -> Option<&(dyn core::error::Error + 'static)> { - match self { - Self::EVM { error, .. } => core::error::Error::source(error), - Self::StateRoot(source) => core::error::Error::source(source), - _ => Option::None, - } - } -} - /// `BlockExecutor` Errors -#[derive(Debug, From, Display)] +#[derive(Error, Debug)] pub enum BlockExecutionError { /// Validation error, transparently wrapping [`BlockValidationError`] - Validation(BlockValidationError), + #[error(transparent)] + Validation(#[from] BlockValidationError), /// Consensus error, transparently wrapping [`ConsensusError`] - Consensus(ConsensusError), + #[error(transparent)] + Consensus(#[from] ConsensusError), /// Internal, i.e. non consensus or validation related Block Executor Errors - Internal(InternalBlockExecutionError), + #[error(transparent)] + Internal(#[from] InternalBlockExecutionError), } impl BlockExecutionError { @@ -184,24 +169,14 @@ impl From for BlockExecutionError { } } -impl core::error::Error for BlockExecutionError { - fn source(&self) -> Option<&(dyn core::error::Error + 'static)> { - match self { - Self::Validation(source) => core::error::Error::source(source), - Self::Consensus(source) => core::error::Error::source(source), - Self::Internal(source) => core::error::Error::source(source), - } - } -} - /// Internal (i.e., not validation or consensus related) `BlockExecutor` Errors -#[derive(Display, Debug, From)] +#[derive(Error, Debug)] pub enum InternalBlockExecutionError { /// Pruning error, transparently wrapping [`PruneSegmentError`] - #[from] - Pruning(PruneSegmentError), + #[error(transparent)] + Pruning(#[from] PruneSegmentError), /// Error when appending chain on fork is not possible - #[display( + #[error( "appending chain on fork (other_chain_fork:?) is not possible as the tip is {chain_tip:?}" )] AppendChainDoesntConnect { @@ -211,9 +186,10 @@ pub enum InternalBlockExecutionError { other_chain_fork: Box, }, /// Error when fetching latest block state. - #[from] - LatestBlock(ProviderError), + #[error(transparent)] + LatestBlock(#[from] ProviderError), /// Arbitrary Block Executor Errors + #[error(transparent)] Other(Box), } @@ -233,13 +209,3 @@ impl InternalBlockExecutionError { Self::Other(msg.to_string().into()) } } - -impl core::error::Error for InternalBlockExecutionError { - fn source(&self) -> Option<&(dyn core::error::Error + 'static)> { - match self { - Self::Pruning(source) => core::error::Error::source(source), - Self::LatestBlock(source) => core::error::Error::source(source), - _ => Option::None, - } - } -} diff --git a/crates/evm/execution-errors/src/trie.rs b/crates/evm/execution-errors/src/trie.rs index 9e4b16d8d0c2..4d3398e41616 100644 --- a/crates/evm/execution-errors/src/trie.rs +++ b/crates/evm/execution-errors/src/trie.rs @@ -2,26 +2,19 @@ use alloc::string::ToString; use alloy_primitives::B256; -use derive_more::{Display, From}; use nybbles::Nibbles; use reth_storage_errors::{db::DatabaseError, provider::ProviderError}; +use thiserror::Error; /// State root errors. -#[derive(Display, Debug, From, PartialEq, Eq, Clone)] +#[derive(Error, PartialEq, Eq, Clone, Debug)] pub enum StateRootError { /// Internal database error. - Database(DatabaseError), + #[error(transparent)] + Database(#[from] DatabaseError), /// Storage root error. - StorageRootError(StorageRootError), -} - -impl core::error::Error for StateRootError { - fn source(&self) -> Option<&(dyn core::error::Error + 'static)> { - match self { - Self::Database(source) => core::error::Error::source(source), - Self::StorageRootError(source) => core::error::Error::source(source), - } - } + #[error(transparent)] + StorageRootError(#[from] StorageRootError), } impl From for DatabaseError { @@ -34,10 +27,11 @@ impl From for DatabaseError { } /// Storage root error. -#[derive(Display, From, PartialEq, Eq, Clone, Debug)] +#[derive(Error, PartialEq, Eq, Clone, Debug)] pub enum StorageRootError { /// Internal database error. - Database(DatabaseError), + #[error(transparent)] + Database(#[from] DatabaseError), } impl From for DatabaseError { @@ -48,21 +42,15 @@ impl From for DatabaseError { } } -impl core::error::Error for StorageRootError { - fn source(&self) -> Option<&(dyn core::error::Error + 'static)> { - match self { - Self::Database(source) => core::error::Error::source(source), - } - } -} - /// State proof errors. -#[derive(Display, From, Debug, PartialEq, Eq, Clone)] +#[derive(Error, PartialEq, Eq, Clone, Debug)] pub enum StateProofError { /// Internal database error. - Database(DatabaseError), + #[error(transparent)] + Database(#[from] DatabaseError), /// RLP decoding error. - Rlp(alloy_rlp::Error), + #[error(transparent)] + Rlp(#[from] alloy_rlp::Error), } impl From for ProviderError { @@ -74,32 +62,23 @@ impl From for ProviderError { } } -impl core::error::Error for StateProofError { - fn source(&self) -> Option<&(dyn core::error::Error + 'static)> { - match self { - Self::Database(source) => core::error::Error::source(source), - Self::Rlp(source) => core::error::Error::source(source), - } - } -} - /// Trie witness errors. -#[derive(Display, From, Debug, PartialEq, Eq, Clone)] +#[derive(Error, PartialEq, Eq, Clone, Debug)] pub enum TrieWitnessError { /// Error gather proofs. - #[from] - Proof(StateProofError), + #[error(transparent)] + Proof(#[from] StateProofError), /// RLP decoding error. - #[from] - Rlp(alloy_rlp::Error), + #[error(transparent)] + Rlp(#[from] alloy_rlp::Error), /// Missing account. - #[display("missing account {_0}")] + #[error("missing account {_0}")] MissingAccount(B256), /// Missing target node. - #[display("target node missing from proof {_0:?}")] + #[error("target node missing from proof {_0:?}")] MissingTargetNode(Nibbles), /// Unexpected empty root. - #[display("unexpected empty root: {_0:?}")] + #[error("unexpected empty root: {_0:?}")] UnexpectedEmptyRoot(Nibbles), } @@ -108,13 +87,3 @@ impl From for ProviderError { Self::TrieWitnessError(error.to_string()) } } - -impl core::error::Error for TrieWitnessError { - fn source(&self) -> Option<&(dyn core::error::Error + 'static)> { - match self { - Self::Proof(source) => core::error::Error::source(source), - Self::Rlp(source) => core::error::Error::source(source), - _ => Option::None, - } - } -} From e4c0f192ee971c3eee5204557b8ff1acbff44b83 Mon Sep 17 00:00:00 2001 From: Roman Krasiuk Date: Tue, 3 Dec 2024 14:08:54 +0100 Subject: [PATCH 45/68] chore(trie): exclude blinded providers from `Debug` impl (#13098) --- crates/trie/sparse/src/state.rs | 16 ++++++++++++++-- crates/trie/sparse/src/trie.rs | 13 +++++++++++-- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/crates/trie/sparse/src/state.rs b/crates/trie/sparse/src/state.rs index cf0bc20abe4f..58bb484e7f44 100644 --- a/crates/trie/sparse/src/state.rs +++ b/crates/trie/sparse/src/state.rs @@ -3,6 +3,7 @@ use crate::{ RevealedSparseTrie, SparseStateTrieError, SparseStateTrieResult, SparseTrie, SparseTrieError, }; use alloy_primitives::{ + hex, map::{HashMap, HashSet}, Bytes, B256, }; @@ -13,10 +14,9 @@ use reth_trie_common::{ updates::{StorageTrieUpdates, TrieUpdates}, MultiProof, Nibbles, TrieAccount, TrieNode, EMPTY_ROOT_HASH, TRIE_ACCOUNT_RLP_MAX_SIZE, }; -use std::iter::Peekable; +use std::{fmt, iter::Peekable}; /// Sparse state trie representing lazy-loaded Ethereum state trie. -#[derive(Debug)] pub struct SparseStateTrie { /// Blinded node provider factory. provider_factory: F, @@ -45,6 +45,18 @@ impl Default for SparseStateTrie { } } +impl fmt::Debug for SparseStateTrie { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("SparseStateTrie") + .field("state", &self.state) + .field("storages", &self.storages) + .field("revealed", &self.revealed) + .field("retain_updates", &self.retain_updates) + .field("account_rlp_buf", &hex::encode(&self.account_rlp_buf)) + .finish_non_exhaustive() + } +} + impl SparseStateTrie { /// Create state trie from state trie. pub fn from_state(state: SparseTrie) -> Self { diff --git a/crates/trie/sparse/src/trie.rs b/crates/trie/sparse/src/trie.rs index dd609a77c99c..cc6f110e0218 100644 --- a/crates/trie/sparse/src/trie.rs +++ b/crates/trie/sparse/src/trie.rs @@ -19,7 +19,7 @@ use std::{borrow::Cow, fmt}; /// Inner representation of the sparse trie. /// Sparse trie is blind by default until nodes are revealed. -#[derive(PartialEq, Eq, Debug)] +#[derive(PartialEq, Eq)] pub enum SparseTrie

{ /// None of the trie nodes are known. Blind, @@ -27,6 +27,15 @@ pub enum SparseTrie

{ Revealed(Box>), } +impl

fmt::Debug for SparseTrie

{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Blind => write!(f, "Blind"), + Self::Revealed(revealed) => write!(f, "Revealed({revealed:?})"), + } + } +} + impl

Default for SparseTrie

{ fn default() -> Self { Self::Blind @@ -164,7 +173,7 @@ impl

fmt::Debug for RevealedSparseTrie

{ .field("prefix_set", &self.prefix_set) .field("updates", &self.updates) .field("rlp_buf", &hex::encode(&self.rlp_buf)) - .finish() + .finish_non_exhaustive() } } From 1404073e053fa2831ddd1a428db932f7e4b152c9 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Tue, 3 Dec 2024 14:12:13 +0100 Subject: [PATCH 46/68] feat: add miner rpc bindings (#13099) --- crates/rpc/rpc-api/src/lib.rs | 3 +++ crates/rpc/rpc-api/src/miner.rs | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 crates/rpc/rpc-api/src/miner.rs diff --git a/crates/rpc/rpc-api/src/lib.rs b/crates/rpc/rpc-api/src/lib.rs index ac39b4802a87..098214f103f8 100644 --- a/crates/rpc/rpc-api/src/lib.rs +++ b/crates/rpc/rpc-api/src/lib.rs @@ -21,6 +21,7 @@ mod engine; mod ganache; mod hardhat; mod mev; +mod miner; mod net; mod otterscan; mod reth; @@ -40,6 +41,7 @@ pub mod servers { debug::{DebugApiServer, DebugExecutionWitnessApiServer}, engine::{EngineApiServer, EngineEthApiServer}, mev::{MevFullApiServer, MevSimApiServer}, + miner::MinerApiServer, net::NetApiServer, otterscan::OtterscanServer, reth::RethApiServer, @@ -70,6 +72,7 @@ pub mod clients { ganache::GanacheApiClient, hardhat::HardhatApiClient, mev::{MevFullApiClient, MevSimApiClient}, + miner::MinerApiClient, net::NetApiClient, otterscan::OtterscanClient, reth::RethApiClient, diff --git a/crates/rpc/rpc-api/src/miner.rs b/crates/rpc/rpc-api/src/miner.rs new file mode 100644 index 000000000000..3673b51c6eb8 --- /dev/null +++ b/crates/rpc/rpc-api/src/miner.rs @@ -0,0 +1,21 @@ +use alloy_primitives::{Bytes, U128}; +use jsonrpsee::{core::RpcResult, proc_macros::rpc}; + +/// Miner namespace rpc interface that can control miner/builder settings +#[cfg_attr(not(feature = "client"), rpc(server, namespace = "miner"))] +#[cfg_attr(feature = "client", rpc(server, client, namespace = "miner"))] +pub trait MinerApi { + /// Sets the extra data string that is included when this miner mines a block. + /// + /// Returns an error if the extra data is too long. + #[method(name = "setExtra")] + fn set_extra(&self, record: Bytes) -> RpcResult; + + /// Sets the minimum accepted gas price for the miner. + #[method(name = "setGasPrice")] + fn set_gas_price(&self, gas_price: U128) -> RpcResult; + + /// Sets the gaslimit to target towards during mining. + #[method(name = "setGasLimit")] + fn set_gas_limit(&self, gas_price: U128) -> RpcResult; +} From a8feec839f0a52ab489999a7fbcf5c161aedb811 Mon Sep 17 00:00:00 2001 From: Alexey Shekhirin Date: Tue, 3 Dec 2024 13:22:25 +0000 Subject: [PATCH 47/68] perf(engine): do not clone proof targets (#13061) --- crates/engine/tree/src/tree/root.rs | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/crates/engine/tree/src/tree/root.rs b/crates/engine/tree/src/tree/root.rs index 70f54ce4d488..d65d1f89000a 100644 --- a/crates/engine/tree/src/tree/root.rs +++ b/crates/engine/tree/src/tree/root.rs @@ -216,10 +216,10 @@ where view: ConsistentDbView, input: Arc, update: EvmState, - fetched_proof_targets: &HashMap>, + fetched_proof_targets: &mut HashMap>, proof_sequence_number: u64, state_root_message_sender: Sender, - ) -> HashMap> { + ) { let mut hashed_state_update = HashedPostState::default(); for (address, account) in update { if account.is_touched() { @@ -249,9 +249,11 @@ where } let proof_targets = get_proof_targets(&hashed_state_update, fetched_proof_targets); + for (address, slots) in &proof_targets { + fetched_proof_targets.entry(*address).or_default().extend(slots) + } // Dispatch proof gathering for this state update - let targets = proof_targets.clone(); rayon::spawn(move || { let provider = match view.provider_ro() { Ok(provider) => provider, @@ -266,7 +268,7 @@ where provider.tx_ref(), // TODO(alexey): this clone can be expensive, we should avoid it input.as_ref().clone(), - targets, + proof_targets, ); match result { Ok(proof) => { @@ -281,8 +283,6 @@ where } } }); - - proof_targets } /// Handler for new proof calculated, aggregates all the existing sequential proofs. @@ -357,17 +357,14 @@ where total_updates = updates_received, "Received new state update" ); - let targets = Self::on_state_update( + Self::on_state_update( self.config.consistent_view.clone(), self.config.input.clone(), update, - &self.fetched_proof_targets, + &mut self.fetched_proof_targets, self.proof_sequencer.next_sequence(), self.tx.clone(), ); - for (address, slots) in targets { - self.fetched_proof_targets.entry(address).or_default().extend(slots) - } } StateRootMessage::ProofCalculated { proof, state_update, sequence_number } => { proofs_processed += 1; From 0aa4701d30f5c195d6f4958cdfb655df697366c8 Mon Sep 17 00:00:00 2001 From: Roman Krasiuk Date: Tue, 3 Dec 2024 14:40:29 +0100 Subject: [PATCH 48/68] fix(trie): short circuit leaf removal if missing (#12988) Co-authored-by: Alexey Shekhirin --- crates/trie/sparse/src/trie.rs | 40 +++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/crates/trie/sparse/src/trie.rs b/crates/trie/sparse/src/trie.rs index cc6f110e0218..b5064fa2c475 100644 --- a/crates/trie/sparse/src/trie.rs +++ b/crates/trie/sparse/src/trie.rs @@ -823,8 +823,16 @@ where { /// Remove leaf node from the trie. pub fn remove_leaf(&mut self, path: &Nibbles) -> SparseTrieResult<()> { + if self.values.remove(path).is_none() { + if let Some(SparseNode::Hash(hash)) = self.nodes.get(path) { + // Leaf is present in the trie, but it's blinded. + return Err(SparseTrieError::BlindedNode { path: path.clone(), hash: *hash }) + } + + // Leaf is not present in the trie. + return Ok(()) + } self.prefix_set.insert(path.clone()); - self.values.remove(path); // If the path wasn't present in `values`, we still need to walk the trie and ensure that // there is no node at the path. When a leaf node is a blinded `Hash`, it will have an entry @@ -1731,6 +1739,36 @@ mod tests { ); } + #[test] + fn sparse_trie_remove_leaf_non_existent() { + let leaf = LeafNode::new( + Nibbles::default(), + alloy_rlp::encode_fixed_size(&U256::from(1)).to_vec(), + ); + let branch = TrieNode::Branch(BranchNode::new( + vec![ + RlpNode::word_rlp(&B256::repeat_byte(1)), + RlpNode::from_raw_rlp(&alloy_rlp::encode(leaf.clone())).unwrap(), + ], + TrieMask::new(0b11), + )); + + let mut sparse = RevealedSparseTrie::from_root(branch.clone(), false).unwrap(); + + // Reveal a branch node and one of its children + // + // Branch (Mask = 11) + // ├── 0 -> Hash (Path = 0) + // └── 1 -> Leaf (Path = 1) + sparse.reveal_node(Nibbles::default(), branch).unwrap(); + sparse.reveal_node(Nibbles::from_nibbles([0x1]), TrieNode::Leaf(leaf)).unwrap(); + + // Removing a non-existent leaf should be a noop + let sparse_old = sparse.clone(); + assert_matches!(sparse.remove_leaf(&Nibbles::from_nibbles([0x2])), Ok(())); + assert_eq!(sparse, sparse_old); + } + #[allow(clippy::type_complexity)] #[test] fn sparse_trie_fuzz() { From ca3d9895e2120bb959bc41f2197bf9db74ceee8f Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Tue, 3 Dec 2024 14:50:59 +0100 Subject: [PATCH 49/68] feat: impl noop miner api endpoint (#13102) --- book/cli/reth/node.md | 4 ++-- crates/rpc/rpc-builder/src/lib.rs | 5 +++-- crates/rpc/rpc-server-types/src/module.rs | 2 ++ crates/rpc/rpc/src/lib.rs | 2 ++ crates/rpc/rpc/src/miner.rs | 25 +++++++++++++++++++++++ 5 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 crates/rpc/rpc/src/miner.rs diff --git a/book/cli/reth/node.md b/book/cli/reth/node.md index d8b66588056f..cf05ae66e28e 100644 --- a/book/cli/reth/node.md +++ b/book/cli/reth/node.md @@ -245,7 +245,7 @@ RPC: --http.api Rpc Modules to be configured for the HTTP server - [possible values: admin, debug, eth, net, trace, txpool, web3, rpc, reth, ots, flashbots] + [possible values: admin, debug, eth, net, trace, txpool, web3, rpc, reth, ots, flashbots, miner] --http.corsdomain Http Corsdomain to allow request from @@ -269,7 +269,7 @@ RPC: --ws.api Rpc Modules to be configured for the WS server - [possible values: admin, debug, eth, net, trace, txpool, web3, rpc, reth, ots, flashbots] + [possible values: admin, debug, eth, net, trace, txpool, web3, rpc, reth, ots, flashbots, miner] --ipcdisable Disable the IPC-RPC server diff --git a/crates/rpc/rpc-builder/src/lib.rs b/crates/rpc/rpc-builder/src/lib.rs index 99912eddf97f..0b9a84a5b987 100644 --- a/crates/rpc/rpc-builder/src/lib.rs +++ b/crates/rpc/rpc-builder/src/lib.rs @@ -210,8 +210,8 @@ use reth_provider::{ EvmEnvProvider, FullRpcProvider, HeaderProvider, ReceiptProvider, StateProviderFactory, }; use reth_rpc::{ - AdminApi, DebugApi, EngineEthApi, EthBundle, NetApi, OtterscanApi, RPCApi, RethApi, TraceApi, - TxPoolApi, ValidationApi, ValidationApiConfig, Web3Api, + AdminApi, DebugApi, EngineEthApi, EthBundle, MinerApi, NetApi, OtterscanApi, RPCApi, RethApi, + TraceApi, TxPoolApi, ValidationApi, ValidationApiConfig, Web3Api, }; use reth_rpc_api::servers::*; use reth_rpc_eth_api::{ @@ -1499,6 +1499,7 @@ where ) .into_rpc() .into(), + RethRpcModule::Miner => MinerApi::default().into_rpc().into(), }) .clone() }) diff --git a/crates/rpc/rpc-server-types/src/module.rs b/crates/rpc/rpc-server-types/src/module.rs index 43e4a9374369..3eb34b34a7f2 100644 --- a/crates/rpc/rpc-server-types/src/module.rs +++ b/crates/rpc/rpc-server-types/src/module.rs @@ -269,6 +269,8 @@ pub enum RethRpcModule { Ots, /// `flashbots_` module Flashbots, + /// `miner_` module + Miner, } // === impl RethRpcModule === diff --git a/crates/rpc/rpc/src/lib.rs b/crates/rpc/rpc/src/lib.rs index 76fb96f91629..d957913dffb9 100644 --- a/crates/rpc/rpc/src/lib.rs +++ b/crates/rpc/rpc/src/lib.rs @@ -36,6 +36,7 @@ mod admin; mod debug; mod engine; pub mod eth; +mod miner; mod net; mod otterscan; mod reth; @@ -49,6 +50,7 @@ pub use admin::AdminApi; pub use debug::DebugApi; pub use engine::{EngineApi, EngineEthApi}; pub use eth::{EthApi, EthBundle, EthFilter, EthPubSub}; +pub use miner::MinerApi; pub use net::NetApi; pub use otterscan::OtterscanApi; pub use reth::RethApi; diff --git a/crates/rpc/rpc/src/miner.rs b/crates/rpc/rpc/src/miner.rs new file mode 100644 index 000000000000..ab8fa5e0cd28 --- /dev/null +++ b/crates/rpc/rpc/src/miner.rs @@ -0,0 +1,25 @@ +use alloy_primitives::{Bytes, U128}; +use async_trait::async_trait; +use jsonrpsee::core::RpcResult; +use reth_rpc_api::MinerApiServer; + +/// `miner` API implementation. +/// +/// This type provides the functionality for handling `miner` related requests. +#[derive(Clone, Debug, Default)] +pub struct MinerApi {} + +#[async_trait] +impl MinerApiServer for MinerApi { + fn set_extra(&self, _record: Bytes) -> RpcResult { + Ok(false) + } + + fn set_gas_price(&self, _gas_price: U128) -> RpcResult { + Ok(false) + } + + fn set_gas_limit(&self, _gas_price: U128) -> RpcResult { + Ok(false) + } +} From 61cb3dedcaf236d9bfa1a7e9d01625335536fe6c Mon Sep 17 00:00:00 2001 From: Alexey Shekhirin Date: Tue, 3 Dec 2024 13:51:04 +0000 Subject: [PATCH 50/68] fix(trie): do not persist root branch nodes in sparse trie (#13071) Co-authored-by: Roman Krasiuk --- crates/trie/sparse/src/state.rs | 57 ++-------- crates/trie/sparse/src/trie.rs | 190 ++++++++++++++++++-------------- 2 files changed, 119 insertions(+), 128 deletions(-) diff --git a/crates/trie/sparse/src/state.rs b/crates/trie/sparse/src/state.rs index 58bb484e7f44..c73eaa1736b2 100644 --- a/crates/trie/sparse/src/state.rs +++ b/crates/trie/sparse/src/state.rs @@ -392,10 +392,7 @@ mod tests { use assert_matches::assert_matches; use rand::{rngs::StdRng, Rng, SeedableRng}; use reth_primitives_traits::Account; - use reth_trie::{ - updates::StorageTrieUpdates, BranchNodeCompact, HashBuilder, TrieAccount, TrieMask, - EMPTY_ROOT_HASH, - }; + use reth_trie::{updates::StorageTrieUpdates, HashBuilder, TrieAccount, EMPTY_ROOT_HASH}; use reth_trie_common::proof::ProofRetainer; #[test] @@ -541,49 +538,15 @@ mod tests { pretty_assertions::assert_eq!( sparse_updates, TrieUpdates { - account_nodes: HashMap::from_iter([ - ( - Nibbles::default(), - BranchNodeCompact { - state_mask: TrieMask::new(0b110), - tree_mask: TrieMask::new(0b000), - hash_mask: TrieMask::new(0b010), - hashes: vec![b256!( - "4c4ffbda3569fcf2c24ea2000b4cec86ef8b92cbf9ff415db43184c0f75a212e" - )], - root_hash: Some(b256!( - "60944bd29458529c3065d19f63c6e3d5269596fd3b04ca2e7b318912dc89ca4c" - )) - }, - ), - ]), - storage_tries: HashMap::from_iter([ - ( - b256!("1000000000000000000000000000000000000000000000000000000000000000"), - StorageTrieUpdates { - is_deleted: false, - storage_nodes: HashMap::from_iter([( - Nibbles::default(), - BranchNodeCompact { - state_mask: TrieMask::new(0b110), - tree_mask: TrieMask::new(0b000), - hash_mask: TrieMask::new(0b010), - hashes: vec![b256!("5bc8b4fdf51839c1e18b8d6a4bd3e2e52c9f641860f0e4d197b68c2679b0e436")], - root_hash: Some(b256!("c44abf1a9e1a92736ac479b20328e8d7998aa8838b6ef52620324c9ce85e3201")) - } - )]), - removed_nodes: HashSet::default() - } - ), - ( - b256!("1100000000000000000000000000000000000000000000000000000000000000"), - StorageTrieUpdates { - is_deleted: true, - storage_nodes: HashMap::default(), - removed_nodes: HashSet::default() - } - ) - ]), + account_nodes: HashMap::default(), + storage_tries: HashMap::from_iter([( + b256!("1100000000000000000000000000000000000000000000000000000000000000"), + StorageTrieUpdates { + is_deleted: true, + storage_nodes: HashMap::default(), + removed_nodes: HashSet::default() + } + )]), removed_nodes: HashSet::default() } ); diff --git a/crates/trie/sparse/src/trie.rs b/crates/trie/sparse/src/trie.rs index b5064fa2c475..1b4c019b1e9a 100644 --- a/crates/trie/sparse/src/trie.rs +++ b/crates/trie/sparse/src/trie.rs @@ -764,7 +764,11 @@ impl

RevealedSparseTrie

{ let rlp_node = branch_node_ref.rlp(&mut self.rlp_buf); *hash = rlp_node.as_hash(); - let store_in_db_trie_value = if let Some(updates) = self.updates.as_mut() { + // Save a branch node update only if it's not a root node, and we need to + // persist updates. + let store_in_db_trie_value = if let Some(updates) = + self.updates.as_mut().filter(|_| !path.is_empty()) + { let mut tree_mask_values = tree_mask_values.into_iter().rev(); let mut hash_mask_values = hash_mask_values.into_iter().rev(); let mut tree_mask = TrieMask::default(); @@ -1181,6 +1185,7 @@ mod tests { hashed_cursor::{noop::NoopHashedAccountCursor, HashedPostStateAccountCursor}, node_iter::{TrieElement, TrieNodeIter}, trie_cursor::noop::NoopAccountTrieCursor, + updates::TrieUpdates, walker::TrieWalker, BranchNode, ExtensionNode, HashedPostState, LeafNode, TrieAccount, }; @@ -1210,8 +1215,9 @@ mod tests { /// Returns the state root and the retained proof nodes. fn run_hash_builder( state: impl IntoIterator + Clone, + destroyed_accounts: HashSet, proof_targets: impl IntoIterator, - ) -> HashBuilder { + ) -> (B256, TrieUpdates, ProofNodes) { let mut account_rlp = Vec::new(); let mut hash_builder = HashBuilder::default() @@ -1249,9 +1255,14 @@ mod tests { } } } - hash_builder.root(); + let root = hash_builder.root(); + let proof_nodes = hash_builder.take_proof_nodes(); + + let mut trie_updates = TrieUpdates::default(); + let removed_keys = node_iter.walker.take_removed_keys(); + trie_updates.finalize(hash_builder, removed_keys, destroyed_accounts); - hash_builder + (root, trie_updates, proof_nodes) } /// Assert that the sparse trie nodes and the proof nodes from the hash builder are equal. @@ -1313,16 +1324,17 @@ mod tests { account_rlp }; - let mut hash_builder = run_hash_builder([(key.clone(), value())], [key.clone()]); + let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes) = + run_hash_builder([(key.clone(), value())], Default::default(), [key.clone()]); let mut sparse = RevealedSparseTrie::default().with_updates(true); sparse.update_leaf(key, value_encoded()).unwrap(); let sparse_root = sparse.root(); let sparse_updates = sparse.take_updates(); - assert_eq!(sparse_root, hash_builder.root()); - assert_eq!(sparse_updates.updated_nodes, hash_builder.updated_branch_nodes.take().unwrap()); - assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder.take_proof_nodes()); + assert_eq!(sparse_root, hash_builder_root); + assert_eq!(sparse_updates.updated_nodes, hash_builder_updates.account_nodes); + assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder_proof_nodes); } #[test] @@ -1337,8 +1349,9 @@ mod tests { account_rlp }; - let mut hash_builder = run_hash_builder( + let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes) = run_hash_builder( paths.iter().cloned().zip(std::iter::repeat_with(value)), + Default::default(), paths.clone(), ); @@ -1349,9 +1362,9 @@ mod tests { let sparse_root = sparse.root(); let sparse_updates = sparse.take_updates(); - assert_eq!(sparse_root, hash_builder.root()); - assert_eq!(sparse_updates.updated_nodes, hash_builder.updated_branch_nodes.take().unwrap()); - assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder.take_proof_nodes()); + assert_eq!(sparse_root, hash_builder_root); + assert_eq!(sparse_updates.updated_nodes, hash_builder_updates.account_nodes); + assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder_proof_nodes); } #[test] @@ -1364,8 +1377,9 @@ mod tests { account_rlp }; - let mut hash_builder = run_hash_builder( + let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes) = run_hash_builder( paths.iter().cloned().zip(std::iter::repeat_with(value)), + Default::default(), paths.clone(), ); @@ -1376,9 +1390,9 @@ mod tests { let sparse_root = sparse.root(); let sparse_updates = sparse.take_updates(); - assert_eq!(sparse_root, hash_builder.root()); - assert_eq!(sparse_updates.updated_nodes, hash_builder.updated_branch_nodes.take().unwrap()); - assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder.take_proof_nodes()); + assert_eq!(sparse_root, hash_builder_root); + assert_eq!(sparse_updates.updated_nodes, hash_builder_updates.account_nodes); + assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder_proof_nodes); } #[test] @@ -1399,8 +1413,9 @@ mod tests { account_rlp }; - let mut hash_builder = run_hash_builder( + let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes) = run_hash_builder( paths.iter().sorted_unstable().cloned().zip(std::iter::repeat_with(value)), + Default::default(), paths.clone(), ); @@ -1411,12 +1426,12 @@ mod tests { let sparse_root = sparse.root(); let sparse_updates = sparse.take_updates(); - assert_eq!(sparse_root, hash_builder.root()); + assert_eq!(sparse_root, hash_builder_root); pretty_assertions::assert_eq!( BTreeMap::from_iter(sparse_updates.updated_nodes), - BTreeMap::from_iter(hash_builder.updated_branch_nodes.take().unwrap()) + BTreeMap::from_iter(hash_builder_updates.account_nodes) ); - assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder.take_proof_nodes()); + assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder_proof_nodes); } #[test] @@ -1435,8 +1450,9 @@ mod tests { account_rlp }; - let mut hash_builder = run_hash_builder( + let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes) = run_hash_builder( paths.iter().cloned().zip(std::iter::repeat_with(|| old_value)), + Default::default(), paths.clone(), ); @@ -1447,12 +1463,13 @@ mod tests { let sparse_root = sparse.root(); let sparse_updates = sparse.updates_ref(); - assert_eq!(sparse_root, hash_builder.root()); - assert_eq!(sparse_updates.updated_nodes, hash_builder.updated_branch_nodes.take().unwrap()); - assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder.take_proof_nodes()); + assert_eq!(sparse_root, hash_builder_root); + assert_eq!(sparse_updates.updated_nodes, hash_builder_updates.account_nodes); + assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder_proof_nodes); - let mut hash_builder = run_hash_builder( + let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes) = run_hash_builder( paths.iter().cloned().zip(std::iter::repeat_with(|| new_value)), + Default::default(), paths.clone(), ); @@ -1462,9 +1479,9 @@ mod tests { let sparse_root = sparse.root(); let sparse_updates = sparse.take_updates(); - assert_eq!(sparse_root, hash_builder.root()); - assert_eq!(sparse_updates.updated_nodes, hash_builder.updated_branch_nodes.take().unwrap()); - assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder.take_proof_nodes()); + assert_eq!(sparse_root, hash_builder_root); + assert_eq!(sparse_updates.updated_nodes, hash_builder_updates.account_nodes); + assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder_proof_nodes); } #[test] @@ -1799,21 +1816,22 @@ mod tests { // Insert state updates into the hash builder and calculate the root state.extend(update); - let mut hash_builder = - run_hash_builder(state.clone(), state.keys().cloned().collect::>()); + let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes) = + run_hash_builder( + state.clone(), + Default::default(), + state.keys().cloned().collect::>(), + ); // Assert that the sparse trie root matches the hash builder root - assert_eq!(sparse_root, hash_builder.root()); + assert_eq!(sparse_root, hash_builder_root); // Assert that the sparse trie updates match the hash builder updates pretty_assertions::assert_eq!( sparse_updates.updated_nodes, - hash_builder.updated_branch_nodes.take().unwrap() + hash_builder_updates.account_nodes ); // Assert that the sparse trie nodes match the hash builder proof nodes - assert_eq_sparse_trie_proof_nodes( - &updated_sparse, - hash_builder.take_proof_nodes(), - ); + assert_eq_sparse_trie_proof_nodes(&updated_sparse, hash_builder_proof_nodes); // Delete some keys from both the hash builder and the sparse trie and check // that the sparse trie root still matches the hash builder root @@ -1829,21 +1847,22 @@ mod tests { let sparse_root = updated_sparse.root(); let sparse_updates = updated_sparse.take_updates(); - let mut hash_builder = - run_hash_builder(state.clone(), state.keys().cloned().collect::>()); + let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes) = + run_hash_builder( + state.clone(), + Default::default(), + state.keys().cloned().collect::>(), + ); // Assert that the sparse trie root matches the hash builder root - assert_eq!(sparse_root, hash_builder.root()); + assert_eq!(sparse_root, hash_builder_root); // Assert that the sparse trie updates match the hash builder updates pretty_assertions::assert_eq!( sparse_updates.updated_nodes, - hash_builder.updated_branch_nodes.take().unwrap() + hash_builder_updates.account_nodes ); // Assert that the sparse trie nodes match the hash builder proof nodes - assert_eq_sparse_trie_proof_nodes( - &updated_sparse, - hash_builder.take_proof_nodes(), - ); + assert_eq_sparse_trie_proof_nodes(&updated_sparse, hash_builder_proof_nodes); } } } @@ -1909,19 +1928,21 @@ mod tests { }; // Generate the proof for the root node and initialize the sparse trie with it - let proof_nodes = - run_hash_builder([(key1(), value()), (key3(), value())], [Nibbles::default()]) - .take_proof_nodes(); + let (_, _, hash_builder_proof_nodes) = run_hash_builder( + [(key1(), value()), (key3(), value())], + Default::default(), + [Nibbles::default()], + ); let mut sparse = RevealedSparseTrie::from_root( - TrieNode::decode(&mut &proof_nodes.nodes_sorted()[0].1[..]).unwrap(), + TrieNode::decode(&mut &hash_builder_proof_nodes.nodes_sorted()[0].1[..]).unwrap(), false, ) .unwrap(); // Generate the proof for the first key and reveal it in the sparse trie - let proof_nodes = - run_hash_builder([(key1(), value()), (key3(), value())], [key1()]).take_proof_nodes(); - for (path, node) in proof_nodes.nodes_sorted() { + let (_, _, hash_builder_proof_nodes) = + run_hash_builder([(key1(), value()), (key3(), value())], Default::default(), [key1()]); + for (path, node) in hash_builder_proof_nodes.nodes_sorted() { sparse.reveal_node(path, TrieNode::decode(&mut &node[..]).unwrap()).unwrap(); } @@ -1941,9 +1962,9 @@ mod tests { ); // Generate the proof for the third key and reveal it in the sparse trie - let proof_nodes_3 = - run_hash_builder([(key1(), value()), (key3(), value())], [key3()]).take_proof_nodes(); - for (path, node) in proof_nodes_3.nodes_sorted() { + let (_, _, hash_builder_proof_nodes) = + run_hash_builder([(key1(), value()), (key3(), value())], Default::default(), [key3()]); + for (path, node) in hash_builder_proof_nodes.nodes_sorted() { sparse.reveal_node(path, TrieNode::decode(&mut &node[..]).unwrap()).unwrap(); } @@ -1955,13 +1976,13 @@ mod tests { // Generate the nodes for the full trie with all three key using the hash builder, and // compare them to the sparse trie - let proof_nodes = run_hash_builder( + let (_, _, hash_builder_proof_nodes) = run_hash_builder( [(key1(), value()), (key2(), value()), (key3(), value())], + Default::default(), [key1(), key2(), key3()], - ) - .take_proof_nodes(); + ); - assert_eq_sparse_trie_proof_nodes(&sparse, proof_nodes); + assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder_proof_nodes); } /// We have three leaves: 0x0000, 0x0101, and 0x0102. Hash builder trie has all nodes, and we @@ -1982,25 +2003,25 @@ mod tests { let value = || Account::default(); // Generate the proof for the root node and initialize the sparse trie with it - let proof_nodes = run_hash_builder( + let (_, _, hash_builder_proof_nodes) = run_hash_builder( [(key1(), value()), (key2(), value()), (key3(), value())], + Default::default(), [Nibbles::default()], - ) - .take_proof_nodes(); + ); let mut sparse = RevealedSparseTrie::from_root( - TrieNode::decode(&mut &proof_nodes.nodes_sorted()[0].1[..]).unwrap(), + TrieNode::decode(&mut &hash_builder_proof_nodes.nodes_sorted()[0].1[..]).unwrap(), false, ) .unwrap(); // Generate the proof for the children of the root branch node and reveal it in the sparse // trie - let proof_nodes = run_hash_builder( + let (_, _, hash_builder_proof_nodes) = run_hash_builder( [(key1(), value()), (key2(), value()), (key3(), value())], + Default::default(), [key1(), Nibbles::from_nibbles_unchecked([0x01])], - ) - .take_proof_nodes(); - for (path, node) in proof_nodes.nodes_sorted() { + ); + for (path, node) in hash_builder_proof_nodes.nodes_sorted() { sparse.reveal_node(path, TrieNode::decode(&mut &node[..]).unwrap()).unwrap(); } @@ -2020,10 +2041,12 @@ mod tests { ); // Generate the proof for the third key and reveal it in the sparse trie - let proof_nodes = - run_hash_builder([(key1(), value()), (key2(), value()), (key3(), value())], [key2()]) - .take_proof_nodes(); - for (path, node) in proof_nodes.nodes_sorted() { + let (_, _, hash_builder_proof_nodes) = run_hash_builder( + [(key1(), value()), (key2(), value()), (key3(), value())], + Default::default(), + [key2()], + ); + for (path, node) in hash_builder_proof_nodes.nodes_sorted() { sparse.reveal_node(path, TrieNode::decode(&mut &node[..]).unwrap()).unwrap(); } @@ -2055,11 +2078,13 @@ mod tests { }; // Generate the proof for the root node and initialize the sparse trie with it - let proof_nodes = - run_hash_builder([(key1(), value()), (key2(), value())], [Nibbles::default()]) - .take_proof_nodes(); + let (_, _, hash_builder_proof_nodes) = run_hash_builder( + [(key1(), value()), (key2(), value())], + Default::default(), + [Nibbles::default()], + ); let mut sparse = RevealedSparseTrie::from_root( - TrieNode::decode(&mut &proof_nodes.nodes_sorted()[0].1[..]).unwrap(), + TrieNode::decode(&mut &hash_builder_proof_nodes.nodes_sorted()[0].1[..]).unwrap(), false, ) .unwrap(); @@ -2080,9 +2105,9 @@ mod tests { ); // Generate the proof for the first key and reveal it in the sparse trie - let proof_nodes = - run_hash_builder([(key1(), value()), (key2(), value())], [key1()]).take_proof_nodes(); - for (path, node) in proof_nodes.nodes_sorted() { + let (_, _, hash_builder_proof_nodes) = + run_hash_builder([(key1(), value()), (key2(), value())], Default::default(), [key1()]); + for (path, node) in hash_builder_proof_nodes.nodes_sorted() { sparse.reveal_node(path, TrieNode::decode(&mut &node[..]).unwrap()).unwrap(); } @@ -2177,16 +2202,19 @@ mod tests { account_rlp }; - let mut hash_builder = - run_hash_builder([(key1(), value()), (key2(), value())], [Nibbles::default()]); + let (hash_builder_root, hash_builder_updates, _) = run_hash_builder( + [(key1(), value()), (key2(), value())], + Default::default(), + [Nibbles::default()], + ); let mut sparse = RevealedSparseTrie::default(); sparse.update_leaf(key1(), value_encoded()).unwrap(); sparse.update_leaf(key2(), value_encoded()).unwrap(); let sparse_root = sparse.root(); let sparse_updates = sparse.take_updates(); - assert_eq!(sparse_root, hash_builder.root()); - assert_eq!(sparse_updates.updated_nodes, hash_builder.updated_branch_nodes.take().unwrap()); + assert_eq!(sparse_root, hash_builder_root); + assert_eq!(sparse_updates.updated_nodes, hash_builder_updates.account_nodes); } #[test] From 8f61af0136e1a20119832925081c341ae89b93f0 Mon Sep 17 00:00:00 2001 From: Darshan Kathiriya <8559992+lakshya-sky@users.noreply.github.com> Date: Tue, 3 Dec 2024 09:07:43 -0500 Subject: [PATCH 51/68] introduce tableset and impl for tables enum (#12617) Co-authored-by: dkathiriya Co-authored-by: Matthias Seitz --- crates/storage/db/src/tables/mod.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/crates/storage/db/src/tables/mod.rs b/crates/storage/db/src/tables/mod.rs index 9ff21261eee5..8a11c4ac055d 100644 --- a/crates/storage/db/src/tables/mod.rs +++ b/crates/storage/db/src/tables/mod.rs @@ -98,6 +98,15 @@ pub trait TableViewer { } } +/// General trait for defining the set of tables +/// Used to initialize database +pub trait TableSet { + /// Returns all the table names in the database. + fn table_names(&self) -> Vec<&'static str>; + /// Returns `true` if the table at the given index is a `DUPSORT` table. + fn is_dupsort(&self, idx: usize) -> bool; +} + /// Defines all the tables in the database. #[macro_export] macro_rules! tables { @@ -243,6 +252,18 @@ macro_rules! tables { } } + impl TableSet for Tables { + fn table_names(&self) -> Vec<&'static str> { + //vec![$(table_names::$name,)*] + Self::ALL.iter().map(|t| t.name()).collect() + } + + fn is_dupsort(&self, idx: usize) -> bool { + let table: Self = self.table_names()[idx].parse().expect("should be valid table name"); + table.is_dupsort() + } + } + // Need constants to match on in the `FromStr` implementation. #[allow(non_upper_case_globals)] mod table_names { From 39f936ede20ee8fc08e87528dbd7215856cae726 Mon Sep 17 00:00:00 2001 From: Roman Krasiuk Date: Tue, 3 Dec 2024 15:20:15 +0100 Subject: [PATCH 52/68] chore: move sparse errors to `reth-execution-errors` (#13101) --- Cargo.lock | 1 + crates/engine/tree/src/tree/root.rs | 5 +- crates/evm/execution-errors/src/trie.rs | 59 +++++++++++++++++++++++- crates/trie/sparse/Cargo.toml | 3 +- crates/trie/sparse/src/blinded.rs | 2 +- crates/trie/sparse/src/errors.rs | 61 ------------------------- crates/trie/sparse/src/lib.rs | 10 ++-- crates/trie/sparse/src/state.rs | 3 +- crates/trie/sparse/src/trie.rs | 6 +-- crates/trie/trie/src/proof/blinded.rs | 6 +-- 10 files changed, 78 insertions(+), 78 deletions(-) delete mode 100644 crates/trie/sparse/src/errors.rs diff --git a/Cargo.lock b/Cargo.lock index 8c290d0ea9fc..0f001fea0920 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9537,6 +9537,7 @@ dependencies = [ "proptest", "proptest-arbitrary-interop", "rand 0.8.5", + "reth-execution-errors", "reth-primitives-traits", "reth-testing-utils", "reth-tracing", diff --git a/crates/engine/tree/src/tree/root.rs b/crates/engine/tree/src/tree/root.rs index d65d1f89000a..78a8332b5ebc 100644 --- a/crates/engine/tree/src/tree/root.rs +++ b/crates/engine/tree/src/tree/root.rs @@ -10,7 +10,10 @@ use reth_trie::{ }; use reth_trie_db::DatabaseProof; use reth_trie_parallel::root::ParallelStateRootError; -use reth_trie_sparse::{SparseStateTrie, SparseStateTrieResult, SparseTrieError}; +use reth_trie_sparse::{ + errors::{SparseStateTrieResult, SparseTrieError}, + SparseStateTrie, +}; use revm_primitives::{keccak256, EvmState, B256}; use std::{ collections::BTreeMap, diff --git a/crates/evm/execution-errors/src/trie.rs b/crates/evm/execution-errors/src/trie.rs index 4d3398e41616..83210faab52f 100644 --- a/crates/evm/execution-errors/src/trie.rs +++ b/crates/evm/execution-errors/src/trie.rs @@ -1,7 +1,7 @@ //! Errors when computing the state root. -use alloc::string::ToString; -use alloy_primitives::B256; +use alloc::{boxed::Box, string::ToString}; +use alloy_primitives::{Bytes, B256}; use nybbles::Nibbles; use reth_storage_errors::{db::DatabaseError, provider::ProviderError}; use thiserror::Error; @@ -62,6 +62,61 @@ impl From for ProviderError { } } +/// Result type with [`SparseStateTrieError`] as error. +pub type SparseStateTrieResult = Result; + +/// Error encountered in `SparseStateTrie`. +#[derive(Error, Debug)] +pub enum SparseStateTrieError { + /// Encountered invalid root node. + #[error("invalid root node at {path:?}: {node:?}")] + InvalidRootNode { + /// Path to first proof node. + path: Nibbles, + /// Encoded first proof node. + node: Bytes, + }, + /// Sparse trie error. + #[error(transparent)] + Sparse(#[from] SparseTrieError), + /// RLP error. + #[error(transparent)] + Rlp(#[from] alloy_rlp::Error), +} + +/// Result type with [`SparseTrieError`] as error. +pub type SparseTrieResult = Result; + +/// Error encountered in `SparseTrie`. +#[derive(Error, Debug)] +pub enum SparseTrieError { + /// Sparse trie is still blind. Thrown on attempt to update it. + #[error("sparse trie is blind")] + Blind, + /// Encountered blinded node on update. + #[error("attempted to update blind node at {path:?}: {hash}")] + BlindedNode { + /// Blind node path. + path: Nibbles, + /// Node hash + hash: B256, + }, + /// Encountered unexpected node at path when revealing. + #[error("encountered an invalid node at path {path:?} when revealing: {node:?}")] + Reveal { + /// Path to the node. + path: Nibbles, + /// Node that was at the path when revealing. + node: Box, + }, + /// RLP error. + #[error(transparent)] + Rlp(#[from] alloy_rlp::Error), + /// Other. + #[error(transparent)] + Other(#[from] Box), +} + /// Trie witness errors. #[derive(Error, PartialEq, Eq, Clone, Debug)] pub enum TrieWitnessError { diff --git a/crates/trie/sparse/Cargo.toml b/crates/trie/sparse/Cargo.toml index efd68020ccd7..09826e410847 100644 --- a/crates/trie/sparse/Cargo.toml +++ b/crates/trie/sparse/Cargo.toml @@ -15,6 +15,7 @@ workspace = true [dependencies] # reth reth-primitives-traits.workspace = true +reth-execution-errors.workspace = true reth-trie-common.workspace = true reth-tracing.workspace = true @@ -28,9 +29,9 @@ thiserror.workspace = true [dev-dependencies] reth-primitives-traits = { workspace = true, features = ["arbitrary"] } -reth-testing-utils.workspace = true reth-trie = { workspace = true, features = ["test-utils"] } reth-trie-common = { workspace = true, features = ["test-utils", "arbitrary"] } +reth-testing-utils.workspace = true arbitrary.workspace = true assert_matches.workspace = true diff --git a/crates/trie/sparse/src/blinded.rs b/crates/trie/sparse/src/blinded.rs index 4cd88bd92a26..22471cf99ffd 100644 --- a/crates/trie/sparse/src/blinded.rs +++ b/crates/trie/sparse/src/blinded.rs @@ -1,7 +1,7 @@ //! Traits and default implementations related to retrieval of blinded trie nodes. -use crate::SparseTrieError; use alloy_primitives::{Bytes, B256}; +use reth_execution_errors::SparseTrieError; use reth_trie_common::Nibbles; /// Factory for instantiating blinded node providers. diff --git a/crates/trie/sparse/src/errors.rs b/crates/trie/sparse/src/errors.rs deleted file mode 100644 index 46102d2d4680..000000000000 --- a/crates/trie/sparse/src/errors.rs +++ /dev/null @@ -1,61 +0,0 @@ -//! Errors for sparse trie. - -use crate::SparseNode; -use alloy_primitives::{Bytes, B256}; -use reth_trie_common::Nibbles; -use thiserror::Error; - -/// Result type with [`SparseStateTrieError`] as error. -pub type SparseStateTrieResult = Result; - -/// Error encountered in [`crate::SparseStateTrie`]. -#[derive(Error, Debug)] -pub enum SparseStateTrieError { - /// Encountered invalid root node. - #[error("invalid root node at {path:?}: {node:?}")] - InvalidRootNode { - /// Path to first proof node. - path: Nibbles, - /// Encoded first proof node. - node: Bytes, - }, - /// Sparse trie error. - #[error(transparent)] - Sparse(#[from] SparseTrieError), - /// RLP error. - #[error(transparent)] - Rlp(#[from] alloy_rlp::Error), -} - -/// Result type with [`SparseTrieError`] as error. -pub type SparseTrieResult = Result; - -/// Error encountered in [`crate::SparseTrie`]. -#[derive(Error, Debug)] -pub enum SparseTrieError { - /// Sparse trie is still blind. Thrown on attempt to update it. - #[error("sparse trie is blind")] - Blind, - /// Encountered blinded node on update. - #[error("attempted to update blind node at {path:?}: {hash}")] - BlindedNode { - /// Blind node path. - path: Nibbles, - /// Node hash - hash: B256, - }, - /// Encountered unexpected node at path when revealing. - #[error("encountered an invalid node at path {path:?} when revealing: {node:?}")] - Reveal { - /// Path to the node. - path: Nibbles, - /// Node that was at the path when revealing. - node: Box, - }, - /// RLP error. - #[error(transparent)] - Rlp(#[from] alloy_rlp::Error), - /// Other. - #[error(transparent)] - Other(#[from] Box), -} diff --git a/crates/trie/sparse/src/lib.rs b/crates/trie/sparse/src/lib.rs index ec5117fdbc1f..1a0f3f73648e 100644 --- a/crates/trie/sparse/src/lib.rs +++ b/crates/trie/sparse/src/lib.rs @@ -6,7 +6,11 @@ pub use state::*; mod trie; pub use trie::*; -mod errors; -pub use errors::*; - pub mod blinded; + +/// Re-export sparse trie error types. +pub mod errors { + pub use reth_execution_errors::{ + SparseStateTrieError, SparseStateTrieResult, SparseTrieError, SparseTrieResult, + }; +} diff --git a/crates/trie/sparse/src/state.rs b/crates/trie/sparse/src/state.rs index c73eaa1736b2..85116868f336 100644 --- a/crates/trie/sparse/src/state.rs +++ b/crates/trie/sparse/src/state.rs @@ -1,6 +1,6 @@ use crate::{ blinded::{BlindedProvider, BlindedProviderFactory, DefaultBlindedProviderFactory}, - RevealedSparseTrie, SparseStateTrieError, SparseStateTrieResult, SparseTrie, SparseTrieError, + RevealedSparseTrie, SparseTrie, }; use alloy_primitives::{ hex, @@ -8,6 +8,7 @@ use alloy_primitives::{ Bytes, B256, }; use alloy_rlp::{Decodable, Encodable}; +use reth_execution_errors::{SparseStateTrieError, SparseStateTrieResult, SparseTrieError}; use reth_primitives_traits::Account; use reth_tracing::tracing::trace; use reth_trie_common::{ diff --git a/crates/trie/sparse/src/trie.rs b/crates/trie/sparse/src/trie.rs index 1b4c019b1e9a..df5dd25486c1 100644 --- a/crates/trie/sparse/src/trie.rs +++ b/crates/trie/sparse/src/trie.rs @@ -1,13 +1,11 @@ -use crate::{ - blinded::{BlindedProvider, DefaultBlindedProvider}, - SparseTrieError, SparseTrieResult, -}; +use crate::blinded::{BlindedProvider, DefaultBlindedProvider}; use alloy_primitives::{ hex, keccak256, map::{HashMap, HashSet}, B256, }; use alloy_rlp::Decodable; +use reth_execution_errors::{SparseTrieError, SparseTrieResult}; use reth_tracing::tracing::trace; use reth_trie_common::{ prefix_set::{PrefixSet, PrefixSetMut}, diff --git a/crates/trie/trie/src/proof/blinded.rs b/crates/trie/trie/src/proof/blinded.rs index adcaef46b08a..5fd3ecdc08e9 100644 --- a/crates/trie/trie/src/proof/blinded.rs +++ b/crates/trie/trie/src/proof/blinded.rs @@ -4,11 +4,9 @@ use alloy_primitives::{ map::{HashMap, HashSet}, Bytes, B256, }; +use reth_execution_errors::SparseTrieError; use reth_trie_common::{prefix_set::TriePrefixSetsMut, Nibbles}; -use reth_trie_sparse::{ - blinded::{pad_path_to_key, BlindedProvider, BlindedProviderFactory}, - SparseTrieError, -}; +use reth_trie_sparse::blinded::{pad_path_to_key, BlindedProvider, BlindedProviderFactory}; use std::sync::Arc; /// Factory for instantiating providers capable of retrieving blinded trie nodes via proofs. From 6baf519c9e0938b945e07ee5d90e844919f8ba25 Mon Sep 17 00:00:00 2001 From: Alessandro Mazza <121622391+alessandromazza98@users.noreply.github.com> Date: Tue, 3 Dec 2024 15:27:20 +0100 Subject: [PATCH 53/68] feat(custom-tables): don't record metrics for custom tables (#13104) --- crates/storage/db/src/metrics.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/crates/storage/db/src/metrics.rs b/crates/storage/db/src/metrics.rs index 2d908c68156f..ed265d6e3aa3 100644 --- a/crates/storage/db/src/metrics.rs +++ b/crates/storage/db/src/metrics.rs @@ -104,10 +104,11 @@ impl DatabaseEnvMetrics { value_size: Option, f: impl FnOnce() -> R, ) -> R { - self.operations - .get(&(table, operation)) - .expect("operation & table metric handle not found") - .record(value_size, f) + if let Some(metrics) = self.operations.get(&(table, operation)) { + metrics.record(value_size, f) + } else { + f() + } } /// Record metrics for opening a database transaction. From 7008ac22df00f6bf3035d655388b1a32586d9343 Mon Sep 17 00:00:00 2001 From: Hai | RISE <150876604+hai-rise@users.noreply.github.com> Date: Tue, 3 Dec 2024 21:53:07 +0700 Subject: [PATCH 54/68] perf(validate-tx-pool): fast non-allocating `is_local` (#13096) --- crates/primitives/src/transaction/mod.rs | 5 +++++ crates/transaction-pool/src/config.rs | 20 +++++++++---------- crates/transaction-pool/src/pool/txpool.rs | 2 +- .../transaction-pool/src/test_utils/mock.rs | 4 ++++ crates/transaction-pool/src/traits.rs | 8 ++++++++ crates/transaction-pool/src/validate/eth.rs | 2 +- crates/transaction-pool/src/validate/mod.rs | 5 +++++ 7 files changed, 34 insertions(+), 12 deletions(-) diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index 6fd8fb55a6d9..aaa6b82dc4ef 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -1624,6 +1624,11 @@ impl RecoveredTx { self.signer } + /// Reference to the signer of transaction recovered from signature + pub const fn signer_ref(&self) -> &Address { + &self.signer + } + /// Returns a reference to [`TransactionSigned`] pub const fn as_signed(&self) -> &T { &self.signed_transaction diff --git a/crates/transaction-pool/src/config.rs b/crates/transaction-pool/src/config.rs index 212df34bd371..a9603215c834 100644 --- a/crates/transaction-pool/src/config.rs +++ b/crates/transaction-pool/src/config.rs @@ -196,15 +196,15 @@ impl LocalTransactionConfig { /// Returns whether the local addresses vector contains the given address. #[inline] - pub fn contains_local_address(&self, address: Address) -> bool { - self.local_addresses.contains(&address) + pub fn contains_local_address(&self, address: &Address) -> bool { + self.local_addresses.contains(address) } /// Returns whether the particular transaction should be considered local. /// /// This always returns false if the local exemptions are disabled. #[inline] - pub fn is_local(&self, origin: TransactionOrigin, sender: Address) -> bool { + pub fn is_local(&self, origin: TransactionOrigin, sender: &Address) -> bool { if self.no_local_exemptions() { return false } @@ -286,10 +286,10 @@ mod tests { let config = LocalTransactionConfig { local_addresses, ..Default::default() }; // Should contain the inserted address - assert!(config.contains_local_address(address)); + assert!(config.contains_local_address(&address)); // Should not contain another random address - assert!(!config.contains_local_address(Address::new([2; 20]))); + assert!(!config.contains_local_address(&Address::new([2; 20]))); } #[test] @@ -302,7 +302,7 @@ mod tests { }; // Should return false as no exemptions is set to true - assert!(!config.is_local(TransactionOrigin::Local, address)); + assert!(!config.is_local(TransactionOrigin::Local, &address)); } #[test] @@ -315,13 +315,13 @@ mod tests { LocalTransactionConfig { no_exemptions: false, local_addresses, ..Default::default() }; // Should return true as the transaction origin is local - assert!(config.is_local(TransactionOrigin::Local, Address::new([2; 20]))); - assert!(config.is_local(TransactionOrigin::Local, address)); + assert!(config.is_local(TransactionOrigin::Local, &Address::new([2; 20]))); + assert!(config.is_local(TransactionOrigin::Local, &address)); // Should return true as the address is in the local_addresses set - assert!(config.is_local(TransactionOrigin::External, address)); + assert!(config.is_local(TransactionOrigin::External, &address)); // Should return false as the address is not in the local_addresses set - assert!(!config.is_local(TransactionOrigin::External, Address::new([2; 20]))); + assert!(!config.is_local(TransactionOrigin::External, &Address::new([2; 20]))); } #[test] diff --git a/crates/transaction-pool/src/pool/txpool.rs b/crates/transaction-pool/src/pool/txpool.rs index 86bf5f741c3d..c9d4e0a488e3 100644 --- a/crates/transaction-pool/src/pool/txpool.rs +++ b/crates/transaction-pool/src/pool/txpool.rs @@ -1462,7 +1462,7 @@ impl AllTransactions { transaction: ValidPoolTransaction, on_chain_nonce: u64, ) -> Result, InsertErr> { - if !self.local_transactions_config.is_local(transaction.origin, transaction.sender()) { + if !self.local_transactions_config.is_local(transaction.origin, transaction.sender_ref()) { let current_txs = self.tx_counter.get(&transaction.sender_id()).copied().unwrap_or_default(); diff --git a/crates/transaction-pool/src/test_utils/mock.rs b/crates/transaction-pool/src/test_utils/mock.rs index 471956fdca57..0e8b26faf83b 100644 --- a/crates/transaction-pool/src/test_utils/mock.rs +++ b/crates/transaction-pool/src/test_utils/mock.rs @@ -624,6 +624,10 @@ impl PoolTransaction for MockTransaction { *self.get_sender() } + fn sender_ref(&self) -> &Address { + self.get_sender() + } + fn nonce(&self) -> u64 { *self.get_nonce() } diff --git a/crates/transaction-pool/src/traits.rs b/crates/transaction-pool/src/traits.rs index 6d4d562b3bdf..15f824e7d436 100644 --- a/crates/transaction-pool/src/traits.rs +++ b/crates/transaction-pool/src/traits.rs @@ -1023,6 +1023,9 @@ pub trait PoolTransaction: /// The Sender of the transaction. fn sender(&self) -> Address; + /// Reference to the Sender of the transaction. + fn sender_ref(&self) -> &Address; + /// Returns the nonce for this transaction. fn nonce(&self) -> u64; @@ -1277,6 +1280,11 @@ impl PoolTransaction for EthPooledTransaction { self.transaction.signer() } + /// Returns a reference to the Sender of the transaction. + fn sender_ref(&self) -> &Address { + self.transaction.signer_ref() + } + /// Returns the nonce for this transaction. fn nonce(&self) -> u64 { self.transaction.nonce() diff --git a/crates/transaction-pool/src/validate/eth.rs b/crates/transaction-pool/src/validate/eth.rs index 5249c1befa2c..e3b7af736cd8 100644 --- a/crates/transaction-pool/src/validate/eth.rs +++ b/crates/transaction-pool/src/validate/eth.rs @@ -263,7 +263,7 @@ where // Drop non-local transactions with a fee lower than the configured fee for acceptance into // the pool. - if !self.local_transactions_config.is_local(origin, transaction.sender()) && + if !self.local_transactions_config.is_local(origin, transaction.sender_ref()) && transaction.is_eip1559() && transaction.max_priority_fee_per_gas() < self.minimum_priority_fee { diff --git a/crates/transaction-pool/src/validate/mod.rs b/crates/transaction-pool/src/validate/mod.rs index 6c625373401b..84caae6e7caa 100644 --- a/crates/transaction-pool/src/validate/mod.rs +++ b/crates/transaction-pool/src/validate/mod.rs @@ -282,6 +282,11 @@ impl ValidPoolTransaction { self.transaction.sender() } + /// Returns a reference to the address of the sender + pub fn sender_ref(&self) -> &Address { + self.transaction.sender_ref() + } + /// Returns the recipient of the transaction if it is not a CREATE transaction. pub fn to(&self) -> Option

{ self.transaction.to() From 9d5e159968737950473a572cdce3881af033f9fc Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Tue, 3 Dec 2024 19:38:10 +0400 Subject: [PATCH 55/68] feat: make InvalidBlockHook generic over NodePrimitives (#13105) --- Cargo.lock | 1 - .../engine/invalid-block-hooks/src/witness.rs | 67 ++++++++++--------- crates/engine/local/src/service.rs | 2 +- .../primitives/src/invalid_block_hook.rs | 25 +++---- crates/engine/service/src/service.rs | 2 +- .../tree/src/tree/invalid_block_hook.rs | 22 +++--- crates/engine/tree/src/tree/mod.rs | 9 ++- crates/ethereum/evm/src/execute.rs | 4 +- crates/evm/src/state_change.rs | 38 +++++++---- crates/evm/src/system_calls/eip2935.rs | 3 +- crates/evm/src/system_calls/eip4788.rs | 3 +- crates/evm/src/system_calls/eip7002.rs | 3 +- crates/evm/src/system_calls/eip7251.rs | 3 +- crates/evm/src/system_calls/mod.rs | 20 +++--- crates/node/api/Cargo.toml | 1 - crates/node/api/src/node.rs | 5 +- crates/node/builder/src/components/builder.rs | 5 +- crates/node/builder/src/components/execute.rs | 7 +- crates/node/builder/src/components/mod.rs | 9 ++- crates/node/builder/src/launch/common.rs | 17 +++-- crates/optimism/evm/src/execute.rs | 2 +- 21 files changed, 133 insertions(+), 115 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0f001fea0920..91ab9d891f5d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7998,7 +7998,6 @@ dependencies = [ name = "reth-node-api" version = "1.1.2" dependencies = [ - "alloy-consensus", "alloy-rpc-types-engine", "eyre", "reth-beacon-consensus", diff --git a/crates/engine/invalid-block-hooks/src/witness.rs b/crates/engine/invalid-block-hooks/src/witness.rs index 98ee8dd2d137..08681a9d17a9 100644 --- a/crates/engine/invalid-block-hooks/src/witness.rs +++ b/crates/engine/invalid-block-hooks/src/witness.rs @@ -1,4 +1,4 @@ -use alloy_consensus::Header; +use alloy_consensus::BlockHeader; use alloy_primitives::{keccak256, B256, U256}; use alloy_rpc_types_debug::ExecutionWitness; use eyre::OptionExt; @@ -8,8 +8,8 @@ use reth_engine_primitives::InvalidBlockHook; use reth_evm::{ state_change::post_block_balance_increments, system_calls::SystemCaller, ConfigureEvm, }; -use reth_primitives::{Receipt, SealedBlockWithSenders, SealedHeader}; -use reth_primitives_traits::SignedTransaction; +use reth_primitives::{NodePrimitives, SealedBlockWithSenders, SealedHeader, TransactionSigned}; +use reth_primitives_traits::{HeaderTy, SignedTransaction}; use reth_provider::{BlockExecutionOutput, ChainSpecProvider, StateProviderFactory}; use reth_revm::{ database::StateProviderDatabase, db::states::bundle_state::BundleRetention, @@ -54,15 +54,18 @@ where + Send + Sync + 'static, - EvmConfig: ConfigureEvm
, { - fn on_invalid_block( + fn on_invalid_block( &self, - parent_header: &SealedHeader, - block: &SealedBlockWithSenders, - output: &BlockExecutionOutput, + parent_header: &SealedHeader, + block: &SealedBlockWithSenders, + output: &BlockExecutionOutput, trie_updates: Option<(&TrieUpdates, B256)>, - ) -> eyre::Result<()> { + ) -> eyre::Result<()> + where + N: NodePrimitives, + EvmConfig: ConfigureEvm
, + { // TODO(alexey): unify with `DebugApi::debug_execution_witness` // Setup database. @@ -86,7 +89,7 @@ where SystemCaller::new(self.evm_config.clone(), self.provider.chain_spec()); // Apply pre-block system contract calls. - system_caller.apply_pre_execution_changes(&block.clone().unseal(), &mut evm)?; + system_caller.apply_pre_execution_changes(&block.clone().unseal().block, &mut evm)?; // Re-execute all of the transactions in the block to load all touched accounts into // the cache DB. @@ -106,7 +109,7 @@ where // NOTE: This is not mut because we are not doing the DAO irregular state change here let balance_increments = post_block_balance_increments( self.provider.chain_spec().as_ref(), - &block.block.clone().unseal(), + &block.clone().unseal().block, U256::MAX, ); @@ -163,24 +166,24 @@ where keys: state_preimages, }; let re_executed_witness_path = self.save_file( - format!("{}_{}.witness.re_executed.json", block.number, block.hash()), + format!("{}_{}.witness.re_executed.json", block.number(), block.hash()), &response, )?; if let Some(healthy_node_client) = &self.healthy_node_client { // Compare the witness against the healthy node. let healthy_node_witness = futures::executor::block_on(async move { - DebugApiClient::debug_execution_witness(healthy_node_client, block.number.into()) + DebugApiClient::debug_execution_witness(healthy_node_client, block.number().into()) .await })?; let healthy_path = self.save_file( - format!("{}_{}.witness.healthy.json", block.number, block.hash()), + format!("{}_{}.witness.healthy.json", block.number(), block.hash()), &healthy_node_witness, )?; // If the witnesses are different, write the diff to the output directory. if response != healthy_node_witness { - let filename = format!("{}_{}.witness.diff", block.number, block.hash()); + let filename = format!("{}_{}.witness.diff", block.number(), block.hash()); let diff_path = self.save_diff(filename, &response, &healthy_node_witness)?; warn!( target: "engine::invalid_block_hooks::witness", @@ -210,15 +213,15 @@ where if bundle_state != output.state { let original_path = self.save_file( - format!("{}_{}.bundle_state.original.json", block.number, block.hash()), + format!("{}_{}.bundle_state.original.json", block.number(), block.hash()), &output.state, )?; let re_executed_path = self.save_file( - format!("{}_{}.bundle_state.re_executed.json", block.number, block.hash()), + format!("{}_{}.bundle_state.re_executed.json", block.number(), block.hash()), &bundle_state, )?; - let filename = format!("{}_{}.bundle_state.diff", block.number, block.hash()); + let filename = format!("{}_{}.bundle_state.diff", block.number(), block.hash()); let diff_path = self.save_diff(filename, &bundle_state, &output.state)?; warn!( @@ -236,26 +239,27 @@ where state_provider.state_root_with_updates(hashed_state)?; if let Some((original_updates, original_root)) = trie_updates { if re_executed_root != original_root { - let filename = format!("{}_{}.state_root.diff", block.number, block.hash()); + let filename = format!("{}_{}.state_root.diff", block.number(), block.hash()); let diff_path = self.save_diff(filename, &re_executed_root, &original_root)?; warn!(target: "engine::invalid_block_hooks::witness", ?original_root, ?re_executed_root, diff_path = %diff_path.display(), "State root mismatch after re-execution"); } // If the re-executed state root does not match the _header_ state root, also log that. - if re_executed_root != block.state_root { - let filename = format!("{}_{}.header_state_root.diff", block.number, block.hash()); - let diff_path = self.save_diff(filename, &re_executed_root, &block.state_root)?; - warn!(target: "engine::invalid_block_hooks::witness", header_state_root=?block.state_root, ?re_executed_root, diff_path = %diff_path.display(), "Re-executed state root does not match block state root"); + if re_executed_root != block.state_root() { + let filename = + format!("{}_{}.header_state_root.diff", block.number(), block.hash()); + let diff_path = self.save_diff(filename, &re_executed_root, &block.state_root())?; + warn!(target: "engine::invalid_block_hooks::witness", header_state_root=?block.state_root(), ?re_executed_root, diff_path = %diff_path.display(), "Re-executed state root does not match block state root"); } if &trie_output != original_updates { // Trie updates are too big to diff, so we just save the original and re-executed let original_path = self.save_file( - format!("{}_{}.trie_updates.original.json", block.number, block.hash()), + format!("{}_{}.trie_updates.original.json", block.number(), block.hash()), original_updates, )?; let re_executed_path = self.save_file( - format!("{}_{}.trie_updates.re_executed.json", block.number, block.hash()), + format!("{}_{}.trie_updates.re_executed.json", block.number(), block.hash()), &trie_output, )?; warn!( @@ -292,23 +296,24 @@ where } } -impl InvalidBlockHook for InvalidBlockWitnessHook +impl InvalidBlockHook for InvalidBlockWitnessHook where + N: NodePrimitives, P: StateProviderFactory + ChainSpecProvider + Send + Sync + 'static, - EvmConfig: ConfigureEvm
, + EvmConfig: ConfigureEvm
>, { fn on_invalid_block( &self, - parent_header: &SealedHeader, - block: &SealedBlockWithSenders, - output: &BlockExecutionOutput, + parent_header: &SealedHeader, + block: &SealedBlockWithSenders, + output: &BlockExecutionOutput, trie_updates: Option<(&TrieUpdates, B256)>, ) { - if let Err(err) = self.on_invalid_block(parent_header, block, output, trie_updates) { + if let Err(err) = self.on_invalid_block::(parent_header, block, output, trie_updates) { warn!(target: "engine::invalid_block_hooks::witness", %err, "Failed to invoke hook"); } } diff --git a/crates/engine/local/src/service.rs b/crates/engine/local/src/service.rs index b06750d66df0..b8cab99970af 100644 --- a/crates/engine/local/src/service.rs +++ b/crates/engine/local/src/service.rs @@ -72,7 +72,7 @@ where payload_builder: PayloadBuilderHandle, payload_validator: V, tree_config: TreeConfig, - invalid_block_hook: Box, + invalid_block_hook: Box>, sync_metrics_tx: MetricEventsSender, to_engine: UnboundedSender>, from_engine: EngineMessageStream, diff --git a/crates/engine/primitives/src/invalid_block_hook.rs b/crates/engine/primitives/src/invalid_block_hook.rs index 13c606511ddc..cfd127ae6f4c 100644 --- a/crates/engine/primitives/src/invalid_block_hook.rs +++ b/crates/engine/primitives/src/invalid_block_hook.rs @@ -1,35 +1,36 @@ use alloy_primitives::B256; use reth_execution_types::BlockExecutionOutput; -use reth_primitives::{Receipt, SealedBlockWithSenders, SealedHeader}; +use reth_primitives::{NodePrimitives, SealedBlockWithSenders, SealedHeader}; use reth_trie::updates::TrieUpdates; /// An invalid block hook. -pub trait InvalidBlockHook: Send + Sync { +pub trait InvalidBlockHook: Send + Sync { /// Invoked when an invalid block is encountered. fn on_invalid_block( &self, - parent_header: &SealedHeader, - block: &SealedBlockWithSenders, - output: &BlockExecutionOutput, + parent_header: &SealedHeader, + block: &SealedBlockWithSenders, + output: &BlockExecutionOutput, trie_updates: Option<(&TrieUpdates, B256)>, ); } -impl InvalidBlockHook for F +impl InvalidBlockHook for F where + N: NodePrimitives, F: Fn( - &SealedHeader, - &SealedBlockWithSenders, - &BlockExecutionOutput, + &SealedHeader, + &SealedBlockWithSenders, + &BlockExecutionOutput, Option<(&TrieUpdates, B256)>, ) + Send + Sync, { fn on_invalid_block( &self, - parent_header: &SealedHeader, - block: &SealedBlockWithSenders, - output: &BlockExecutionOutput, + parent_header: &SealedHeader, + block: &SealedBlockWithSenders, + output: &BlockExecutionOutput, trie_updates: Option<(&TrieUpdates, B256)>, ) { self(parent_header, block, output, trie_updates) diff --git a/crates/engine/service/src/service.rs b/crates/engine/service/src/service.rs index d3c07c638711..bc3e36beafc8 100644 --- a/crates/engine/service/src/service.rs +++ b/crates/engine/service/src/service.rs @@ -78,7 +78,7 @@ where payload_builder: PayloadBuilderHandle, payload_validator: V, tree_config: TreeConfig, - invalid_block_hook: Box, + invalid_block_hook: Box>, sync_metrics_tx: MetricEventsSender, ) -> Self where diff --git a/crates/engine/tree/src/tree/invalid_block_hook.rs b/crates/engine/tree/src/tree/invalid_block_hook.rs index 98244ed13499..7c7b0631dd20 100644 --- a/crates/engine/tree/src/tree/invalid_block_hook.rs +++ b/crates/engine/tree/src/tree/invalid_block_hook.rs @@ -1,6 +1,6 @@ use alloy_primitives::B256; use reth_engine_primitives::InvalidBlockHook; -use reth_primitives::{Receipt, SealedBlockWithSenders, SealedHeader}; +use reth_primitives::{NodePrimitives, SealedBlockWithSenders, SealedHeader}; use reth_provider::BlockExecutionOutput; use reth_trie::updates::TrieUpdates; @@ -9,32 +9,32 @@ use reth_trie::updates::TrieUpdates; #[non_exhaustive] pub struct NoopInvalidBlockHook; -impl InvalidBlockHook for NoopInvalidBlockHook { +impl InvalidBlockHook for NoopInvalidBlockHook { fn on_invalid_block( &self, - _parent_header: &SealedHeader, - _block: &SealedBlockWithSenders, - _output: &BlockExecutionOutput, + _parent_header: &SealedHeader, + _block: &SealedBlockWithSenders, + _output: &BlockExecutionOutput, _trie_updates: Option<(&TrieUpdates, B256)>, ) { } } /// Multiple [`InvalidBlockHook`]s that are executed in order. -pub struct InvalidBlockHooks(pub Vec>); +pub struct InvalidBlockHooks(pub Vec>>); -impl std::fmt::Debug for InvalidBlockHooks { +impl std::fmt::Debug for InvalidBlockHooks { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("InvalidBlockHooks").field("len", &self.0.len()).finish() } } -impl InvalidBlockHook for InvalidBlockHooks { +impl InvalidBlockHook for InvalidBlockHooks { fn on_invalid_block( &self, - parent_header: &SealedHeader, - block: &SealedBlockWithSenders, - output: &BlockExecutionOutput, + parent_header: &SealedHeader, + block: &SealedBlockWithSenders, + output: &BlockExecutionOutput, trie_updates: Option<(&TrieUpdates, B256)>, ) { for hook in &self.0 { diff --git a/crates/engine/tree/src/tree/mod.rs b/crates/engine/tree/src/tree/mod.rs index 16e07e518443..c65035973816 100644 --- a/crates/engine/tree/src/tree/mod.rs +++ b/crates/engine/tree/src/tree/mod.rs @@ -469,6 +469,7 @@ pub enum TreeAction { /// emitting events. pub struct EngineApiTreeHandler where + N: NodePrimitives, T: EngineTypes, { provider: P, @@ -507,7 +508,7 @@ where /// Metrics for the engine api. metrics: EngineApiMetrics, /// An invalid block hook. - invalid_block_hook: Box, + invalid_block_hook: Box>, /// The engine API variant of this handler engine_kind: EngineApiKind, /// Captures the types the engine operates on @@ -516,6 +517,8 @@ where impl std::fmt::Debug for EngineApiTreeHandler +where + N: NodePrimitives, { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("EngineApiTreeHandler") @@ -597,7 +600,7 @@ where } /// Sets the invalid block hook. - fn set_invalid_block_hook(&mut self, invalid_block_hook: Box) { + fn set_invalid_block_hook(&mut self, invalid_block_hook: Box>) { self.invalid_block_hook = invalid_block_hook; } @@ -616,7 +619,7 @@ where payload_builder: PayloadBuilderHandle, canonical_in_memory_state: CanonicalInMemoryState, config: TreeConfig, - invalid_block_hook: Box, + invalid_block_hook: Box>, kind: EngineApiKind, ) -> (Sender>>, UnboundedReceiver) { let best_block_number = provider.best_block_number().unwrap_or(0); diff --git a/crates/ethereum/evm/src/execute.rs b/crates/ethereum/evm/src/execute.rs index 65fbbdd25682..e21b42433ddb 100644 --- a/crates/ethereum/evm/src/execute.rs +++ b/crates/ethereum/evm/src/execute.rs @@ -152,7 +152,7 @@ where let env = self.evm_env_for_block(&block.header, total_difficulty); let mut evm = self.evm_config.evm_with_env(&mut self.state, env); - self.system_caller.apply_pre_execution_changes(block, &mut evm)?; + self.system_caller.apply_pre_execution_changes(&block.block, &mut evm)?; Ok(()) } @@ -247,7 +247,7 @@ where drop(evm); let mut balance_increments = - post_block_balance_increments(&self.chain_spec, block, total_difficulty); + post_block_balance_increments(&self.chain_spec, &block.block, total_difficulty); // Irregular state change at Ethereum DAO hardfork if self.chain_spec.fork(EthereumHardfork::Dao).transitions_at_block(block.number) { diff --git a/crates/evm/src/state_change.rs b/crates/evm/src/state_change.rs index 0e207fc2dbeb..5104c466399b 100644 --- a/crates/evm/src/state_change.rs +++ b/crates/evm/src/state_change.rs @@ -1,43 +1,55 @@ //! State changes that are not related to transactions. +use alloy_consensus::BlockHeader; use alloy_eips::eip4895::Withdrawal; use alloy_primitives::{map::HashMap, Address, U256}; use reth_chainspec::EthereumHardforks; use reth_consensus_common::calc; -use reth_primitives::Block; +use reth_primitives_traits::BlockBody; /// Collect all balance changes at the end of the block. /// /// Balance changes might include the block reward, uncle rewards, withdrawals, or irregular /// state changes (DAO fork). #[inline] -pub fn post_block_balance_increments( +pub fn post_block_balance_increments( chain_spec: &ChainSpec, block: &Block, total_difficulty: U256, -) -> HashMap { +) -> HashMap +where + ChainSpec: EthereumHardforks, + Block: reth_primitives_traits::Block, +{ let mut balance_increments = HashMap::default(); // Add block rewards if they are enabled. - if let Some(base_block_reward) = - calc::base_block_reward(chain_spec, block.number, block.difficulty, total_difficulty) - { + if let Some(base_block_reward) = calc::base_block_reward( + chain_spec, + block.header().number(), + block.header().difficulty(), + total_difficulty, + ) { // Ommer rewards - for ommer in &block.body.ommers { - *balance_increments.entry(ommer.beneficiary).or_default() += - calc::ommer_reward(base_block_reward, block.number, ommer.number); + if let Some(ommers) = block.body().ommers() { + for ommer in ommers { + *balance_increments.entry(ommer.beneficiary()).or_default() += + calc::ommer_reward(base_block_reward, block.header().number(), ommer.number()); + } } // Full block reward - *balance_increments.entry(block.beneficiary).or_default() += - calc::block_reward(base_block_reward, block.body.ommers.len()); + *balance_increments.entry(block.header().beneficiary()).or_default() += calc::block_reward( + base_block_reward, + block.body().ommers().map(|s| s.len()).unwrap_or(0), + ); } // process withdrawals insert_post_block_withdrawals_balance_increments( chain_spec, - block.timestamp, - block.body.withdrawals.as_ref().map(|w| w.as_slice()), + block.header().timestamp(), + block.body().withdrawals().as_ref().map(|w| w.as_slice()), &mut balance_increments, ); diff --git a/crates/evm/src/system_calls/eip2935.rs b/crates/evm/src/system_calls/eip2935.rs index 4848feb7281c..0cc2b83a3ca5 100644 --- a/crates/evm/src/system_calls/eip2935.rs +++ b/crates/evm/src/system_calls/eip2935.rs @@ -4,7 +4,6 @@ use alloc::{boxed::Box, string::ToString}; use alloy_eips::eip2935::HISTORY_STORAGE_ADDRESS; use crate::ConfigureEvm; -use alloy_consensus::Header; use alloy_primitives::B256; use reth_chainspec::EthereumHardforks; use reth_execution_errors::{BlockExecutionError, BlockValidationError}; @@ -35,7 +34,7 @@ pub(crate) fn transact_blockhashes_contract_call( where DB: Database, DB::Error: core::fmt::Display, - EvmConfig: ConfigureEvm
, + EvmConfig: ConfigureEvm, { if !chain_spec.is_prague_active_at_timestamp(block_timestamp) { return Ok(None) diff --git a/crates/evm/src/system_calls/eip4788.rs b/crates/evm/src/system_calls/eip4788.rs index 2ad02c26eb90..bfd5797214e5 100644 --- a/crates/evm/src/system_calls/eip4788.rs +++ b/crates/evm/src/system_calls/eip4788.rs @@ -2,7 +2,6 @@ use alloc::{boxed::Box, string::ToString}; use crate::ConfigureEvm; -use alloy_consensus::Header; use alloy_eips::eip4788::BEACON_ROOTS_ADDRESS; use alloy_primitives::B256; use reth_chainspec::EthereumHardforks; @@ -31,7 +30,7 @@ pub(crate) fn transact_beacon_root_contract_call( where DB: Database, DB::Error: core::fmt::Display, - EvmConfig: ConfigureEvm
, + EvmConfig: ConfigureEvm, Spec: EthereumHardforks, { if !chain_spec.is_cancun_active_at_timestamp(block_timestamp) { diff --git a/crates/evm/src/system_calls/eip7002.rs b/crates/evm/src/system_calls/eip7002.rs index f20b7a54c089..d3c6d84903ed 100644 --- a/crates/evm/src/system_calls/eip7002.rs +++ b/crates/evm/src/system_calls/eip7002.rs @@ -1,7 +1,6 @@ //! [EIP-7002](https://eips.ethereum.org/EIPS/eip-7002) system call implementation. use crate::ConfigureEvm; use alloc::{boxed::Box, format}; -use alloy_consensus::Header; use alloy_eips::eip7002::WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS; use alloy_primitives::Bytes; use reth_execution_errors::{BlockExecutionError, BlockValidationError}; @@ -21,7 +20,7 @@ pub(crate) fn transact_withdrawal_requests_contract_call( where DB: Database, DB::Error: core::fmt::Display, - EvmConfig: ConfigureEvm
, + EvmConfig: ConfigureEvm, { // get previous env let previous_env = Box::new(evm.context.env().clone()); diff --git a/crates/evm/src/system_calls/eip7251.rs b/crates/evm/src/system_calls/eip7251.rs index 112f724df764..28ae0160cdf6 100644 --- a/crates/evm/src/system_calls/eip7251.rs +++ b/crates/evm/src/system_calls/eip7251.rs @@ -1,7 +1,6 @@ //! [EIP-7251](https://eips.ethereum.org/EIPS/eip-7251) system call implementation. use crate::ConfigureEvm; use alloc::{boxed::Box, format}; -use alloy_consensus::Header; use alloy_eips::eip7251::CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS; use alloy_primitives::Bytes; use reth_execution_errors::{BlockExecutionError, BlockValidationError}; @@ -22,7 +21,7 @@ pub(crate) fn transact_consolidation_requests_contract_call( where DB: Database, DB::Error: core::fmt::Display, - EvmConfig: ConfigureEvm
, + EvmConfig: ConfigureEvm, { // get previous env let previous_env = Box::new(evm.context.env().clone()); diff --git a/crates/evm/src/system_calls/mod.rs b/crates/evm/src/system_calls/mod.rs index 2a5b80ad66d9..8af72094be47 100644 --- a/crates/evm/src/system_calls/mod.rs +++ b/crates/evm/src/system_calls/mod.rs @@ -2,7 +2,7 @@ use crate::ConfigureEvm; use alloc::{boxed::Box, sync::Arc}; -use alloy_consensus::Header; +use alloy_consensus::BlockHeader; use alloy_eips::{ eip7002::WITHDRAWAL_REQUEST_TYPE, eip7251::CONSOLIDATION_REQUEST_TYPE, eip7685::Requests, }; @@ -10,7 +10,6 @@ use alloy_primitives::Bytes; use core::fmt::Display; use reth_chainspec::EthereumHardforks; use reth_execution_errors::BlockExecutionError; -use reth_primitives::Block; use revm::{Database, DatabaseCommit, Evm}; use revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, EvmState, B256}; @@ -91,11 +90,11 @@ where impl SystemCaller where - EvmConfig: ConfigureEvm
, + EvmConfig: ConfigureEvm, Chainspec: EthereumHardforks, { /// Apply pre execution changes. - pub fn apply_pre_execution_changes( + pub fn apply_pre_execution_changes( &mut self, block: &Block, evm: &mut Evm<'_, Ext, DB>, @@ -103,17 +102,18 @@ where where DB: Database + DatabaseCommit, DB::Error: Display, + Block: reth_primitives_traits::Block
, { self.apply_blockhashes_contract_call( - block.timestamp, - block.number, - block.parent_hash, + block.header().timestamp(), + block.header().number(), + block.header().parent_hash(), evm, )?; self.apply_beacon_root_contract_call( - block.timestamp, - block.number, - block.parent_beacon_block_root, + block.header().timestamp(), + block.header().number(), + block.header().parent_beacon_block_root(), evm, )?; diff --git a/crates/node/api/Cargo.toml b/crates/node/api/Cargo.toml index ab4595d33624..7d209a90fcad 100644 --- a/crates/node/api/Cargo.toml +++ b/crates/node/api/Cargo.toml @@ -26,6 +26,5 @@ reth-node-types.workspace = true reth-node-core.workspace = true alloy-rpc-types-engine.workspace = true -alloy-consensus.workspace = true eyre.workspace = true diff --git a/crates/node/api/src/node.rs b/crates/node/api/src/node.rs index 83947208ca83..1b490c4cf416 100644 --- a/crates/node/api/src/node.rs +++ b/crates/node/api/src/node.rs @@ -1,14 +1,13 @@ //! Traits for configuring a node. use crate::ConfigureEvm; -use alloy_consensus::Header; use alloy_rpc_types_engine::JwtSecret; use reth_beacon_consensus::BeaconConsensusEngineHandle; use reth_consensus::FullConsensus; use reth_evm::execute::BlockExecutorProvider; use reth_network_api::FullNetwork; use reth_node_core::node_config::NodeConfig; -use reth_node_types::{NodeTypes, NodeTypesWithDB, NodeTypesWithEngine, TxTy}; +use reth_node_types::{HeaderTy, NodeTypes, NodeTypesWithDB, NodeTypesWithEngine, TxTy}; use reth_payload_builder_primitives::PayloadBuilder; use reth_provider::FullProvider; use reth_tasks::TaskExecutor; @@ -50,7 +49,7 @@ pub trait FullNodeComponents: FullNodeTypes + Clone + 'static { type Pool: TransactionPool>> + Unpin; /// The node's EVM configuration, defining settings for the Ethereum Virtual Machine. - type Evm: ConfigureEvm
; + type Evm: ConfigureEvm
>; /// The type that knows how to execute blocks. type Executor: BlockExecutorProvider::Primitives>; diff --git a/crates/node/builder/src/components/builder.rs b/crates/node/builder/src/components/builder.rs index 4c04c9200d2f..15f6c12319ff 100644 --- a/crates/node/builder/src/components/builder.rs +++ b/crates/node/builder/src/components/builder.rs @@ -7,10 +7,9 @@ use crate::{ }, BuilderContext, ConfigureEvm, FullNodeTypes, }; -use alloy_consensus::Header; use reth_consensus::FullConsensus; use reth_evm::execute::BlockExecutorProvider; -use reth_node_api::{NodeTypes, NodeTypesWithEngine, TxTy}; +use reth_node_api::{HeaderTy, NodeTypes, NodeTypesWithEngine, TxTy}; use reth_payload_builder::PayloadBuilderHandle; use reth_transaction_pool::{PoolTransaction, TransactionPool}; use std::{future::Future, marker::PhantomData}; @@ -378,7 +377,7 @@ where Pool: TransactionPool>> + Unpin + 'static, - EVM: ConfigureEvm
, + EVM: ConfigureEvm
>, Executor: BlockExecutorProvider::Primitives>, Cons: FullConsensus<::Primitives> + Clone + Unpin + 'static, { diff --git a/crates/node/builder/src/components/execute.rs b/crates/node/builder/src/components/execute.rs index 0c75ef3016f2..5ecc67d8b764 100644 --- a/crates/node/builder/src/components/execute.rs +++ b/crates/node/builder/src/components/execute.rs @@ -1,8 +1,7 @@ //! EVM component for the node builder. use crate::{BuilderContext, FullNodeTypes}; -use alloy_consensus::Header; use reth_evm::execute::BlockExecutorProvider; -use reth_node_api::ConfigureEvm; +use reth_node_api::{ConfigureEvm, HeaderTy}; use std::future::Future; /// A type that knows how to build the executor types. @@ -10,7 +9,7 @@ pub trait ExecutorBuilder: Send { /// The EVM config to use. /// /// This provides the node with the necessary configuration to configure an EVM. - type EVM: ConfigureEvm
; + type EVM: ConfigureEvm
>; /// The type that knows how to execute blocks. type Executor: BlockExecutorProvider< @@ -27,7 +26,7 @@ pub trait ExecutorBuilder: Send { impl ExecutorBuilder for F where Node: FullNodeTypes, - EVM: ConfigureEvm
, + EVM: ConfigureEvm
>, Executor: BlockExecutorProvider::Primitives>, F: FnOnce(&BuilderContext) -> Fut + Send, diff --git a/crates/node/builder/src/components/mod.rs b/crates/node/builder/src/components/mod.rs index 22a47e3daa49..764277dcbf27 100644 --- a/crates/node/builder/src/components/mod.rs +++ b/crates/node/builder/src/components/mod.rs @@ -22,12 +22,11 @@ pub use payload::*; pub use pool::*; use crate::{ConfigureEvm, FullNodeTypes}; -use alloy_consensus::Header; use reth_consensus::FullConsensus; use reth_evm::execute::BlockExecutorProvider; use reth_network::NetworkHandle; use reth_network_api::FullNetwork; -use reth_node_api::{NodeTypes, NodeTypesWithEngine, TxTy}; +use reth_node_api::{HeaderTy, NodeTypes, NodeTypesWithEngine, TxTy}; use reth_payload_builder::PayloadBuilderHandle; use reth_transaction_pool::{PoolTransaction, TransactionPool}; @@ -41,7 +40,7 @@ pub trait NodeComponents: Clone + Unpin + Send + Sync + 'stati type Pool: TransactionPool>> + Unpin; /// The node's EVM configuration, defining settings for the Ethereum Virtual Machine. - type Evm: ConfigureEvm
; + type Evm: ConfigureEvm
>; /// The type that knows how to execute blocks. type Executor: BlockExecutorProvider::Primitives>; @@ -100,7 +99,7 @@ where Pool: TransactionPool>> + Unpin + 'static, - EVM: ConfigureEvm
, + EVM: ConfigureEvm
>, Executor: BlockExecutorProvider::Primitives>, Cons: FullConsensus<::Primitives> + Clone + Unpin + 'static, { @@ -140,7 +139,7 @@ impl Clone for Components, + EVM: ConfigureEvm
>, Executor: BlockExecutorProvider, Cons: Clone, { diff --git a/crates/node/builder/src/launch/common.rs b/crates/node/builder/src/launch/common.rs index 25c81a8d5cf0..f4557bd2272e 100644 --- a/crates/node/builder/src/launch/common.rs +++ b/crates/node/builder/src/launch/common.rs @@ -22,7 +22,9 @@ use reth_evm::noop::NoopBlockExecutorProvider; use reth_fs_util as fs; use reth_invalid_block_hooks::InvalidBlockWitnessHook; use reth_network_p2p::headers::client::HeadersClient; -use reth_node_api::{FullNodePrimitives, FullNodeTypes, NodeTypes, NodeTypesWithDB}; +use reth_node_api::{ + FullNodePrimitives, FullNodeTypes, NodePrimitives, NodeTypes, NodeTypesWithDB, +}; use reth_node_core::{ args::InvalidBlockHookType, dirs::{ChainPath, DataDirPath}, @@ -39,7 +41,7 @@ use reth_node_metrics::{ server::{MetricServer, MetricServerConfig}, version::VersionInfo, }; -use reth_primitives::Head; +use reth_primitives::{Head, TransactionSigned}; use reth_provider::{ providers::{ProviderNodeTypes, StaticFileProvider}, BlockHashReader, BlockNumReader, ChainSpecProvider, ProviderError, ProviderFactory, @@ -870,11 +872,16 @@ impl Attached::ChainSpec>, WithComponents>, > where - T: FullNodeTypes, + T: FullNodeTypes< + Provider: StateProviderFactory + ChainSpecProvider, + Types: ProviderNodeTypes>, + >, CB: NodeComponentsBuilder, { /// Returns the [`InvalidBlockHook`] to use for the node. - pub fn invalid_block_hook(&self) -> eyre::Result> { + pub fn invalid_block_hook( + &self, + ) -> eyre::Result::Primitives>>> { let Some(ref hook) = self.node_config().debug.invalid_block_hook else { return Ok(Box::new(NoopInvalidBlockHook::default())) }; @@ -898,7 +905,7 @@ where InvalidBlockHookType::PreState | InvalidBlockHookType::Opcode => { eyre::bail!("invalid block hook {hook:?} is not implemented yet") } - } as Box) + } as Box>) }) .collect::>()?; diff --git a/crates/optimism/evm/src/execute.rs b/crates/optimism/evm/src/execute.rs index 549f52c89def..3673f73a894b 100644 --- a/crates/optimism/evm/src/execute.rs +++ b/crates/optimism/evm/src/execute.rs @@ -258,7 +258,7 @@ where _receipts: &[Receipt], ) -> Result { let balance_increments = - post_block_balance_increments(&self.chain_spec.clone(), block, total_difficulty); + post_block_balance_increments(&self.chain_spec.clone(), &block.block, total_difficulty); // increment balances self.state .increment_balances(balance_increments.clone()) From 64c6343fd126310efb037494a5fd1420d4f874a6 Mon Sep 17 00:00:00 2001 From: Dan Cline <6798349+Rjected@users.noreply.github.com> Date: Tue, 3 Dec 2024 11:42:54 -0500 Subject: [PATCH 56/68] chore: propagate network primitives to `on_command`, `on_network_event` (#13084) --- crates/net/network/src/transactions/mod.rs | 88 +++++++++++----------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/crates/net/network/src/transactions/mod.rs b/crates/net/network/src/transactions/mod.rs index 5463b20f7f37..b352dfe31366 100644 --- a/crates/net/network/src/transactions/mod.rs +++ b/crates/net/network/src/transactions/mod.rs @@ -1005,51 +1005,9 @@ where let _ = response.send(Ok(resp)); } } -} - -impl TransactionsManager -where - Pool: TransactionPool + 'static, - Pool::Transaction: - PoolTransaction>, -{ - /// Handles dedicated transaction events related to the `eth` protocol. - fn on_network_tx_event(&mut self, event: NetworkTransactionEvent) { - match event { - NetworkTransactionEvent::IncomingTransactions { peer_id, msg } => { - // ensure we didn't receive any blob transactions as these are disallowed to be - // broadcasted in full - - let has_blob_txs = msg.has_eip4844(); - - let non_blob_txs = msg - .0 - .into_iter() - .map(PooledTransactionsElement::try_from_broadcast) - .filter_map(Result::ok) - .collect(); - - self.import_transactions(peer_id, non_blob_txs, TransactionSource::Broadcast); - - if has_blob_txs { - debug!(target: "net::tx", ?peer_id, "received bad full blob transaction broadcast"); - self.report_peer_bad_transactions(peer_id); - } - } - NetworkTransactionEvent::IncomingPooledTransactionHashes { peer_id, msg } => { - self.on_new_pooled_transaction_hashes(peer_id, msg) - } - NetworkTransactionEvent::GetPooledTransactions { peer_id, request, response } => { - self.on_get_pooled_transactions(peer_id, request, response) - } - NetworkTransactionEvent::GetTransactionsHandle(response) => { - let _ = response.send(Some(self.handle())); - } - } - } /// Handles a command received from a detached [`TransactionsHandle`] - fn on_command(&mut self, cmd: TransactionsCommand) { + fn on_command(&mut self, cmd: TransactionsCommand) { match cmd { TransactionsCommand::PropagateHash(hash) => { self.on_new_pending_transactions(vec![hash]) @@ -1089,7 +1047,7 @@ where } /// Handles a received event related to common network events. - fn on_network_event(&mut self, event_result: NetworkEvent) { + fn on_network_event(&mut self, event_result: NetworkEvent>) { match event_result { NetworkEvent::SessionClosed { peer_id, .. } => { // remove the peer @@ -1141,6 +1099,48 @@ where _ => {} } } +} + +impl TransactionsManager +where + Pool: TransactionPool + 'static, + Pool::Transaction: + PoolTransaction>, +{ + /// Handles dedicated transaction events related to the `eth` protocol. + fn on_network_tx_event(&mut self, event: NetworkTransactionEvent) { + match event { + NetworkTransactionEvent::IncomingTransactions { peer_id, msg } => { + // ensure we didn't receive any blob transactions as these are disallowed to be + // broadcasted in full + + let has_blob_txs = msg.has_eip4844(); + + let non_blob_txs = msg + .0 + .into_iter() + .map(PooledTransactionsElement::try_from_broadcast) + .filter_map(Result::ok) + .collect(); + + self.import_transactions(peer_id, non_blob_txs, TransactionSource::Broadcast); + + if has_blob_txs { + debug!(target: "net::tx", ?peer_id, "received bad full blob transaction broadcast"); + self.report_peer_bad_transactions(peer_id); + } + } + NetworkTransactionEvent::IncomingPooledTransactionHashes { peer_id, msg } => { + self.on_new_pooled_transaction_hashes(peer_id, msg) + } + NetworkTransactionEvent::GetPooledTransactions { peer_id, request, response } => { + self.on_get_pooled_transactions(peer_id, request, response) + } + NetworkTransactionEvent::GetTransactionsHandle(response) => { + let _ = response.send(Some(self.handle())); + } + } + } /// Starts the import process for the given transactions. fn import_transactions( From e4c7fac9dbd175f705035ef72ff164db5250b9b9 Mon Sep 17 00:00:00 2001 From: Roman Krasiuk Date: Tue, 3 Dec 2024 17:43:35 +0100 Subject: [PATCH 57/68] chore(trie): make Debug impl work for any provider (#13107) --- crates/trie/sparse/src/state.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/trie/sparse/src/state.rs b/crates/trie/sparse/src/state.rs index 85116868f336..9b4b38002511 100644 --- a/crates/trie/sparse/src/state.rs +++ b/crates/trie/sparse/src/state.rs @@ -46,7 +46,7 @@ impl Default for SparseStateTrie { } } -impl fmt::Debug for SparseStateTrie { +impl fmt::Debug for SparseStateTrie

{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("SparseStateTrie") .field("state", &self.state) From 886471d69383a9df371bb32b99791bdab91f648d Mon Sep 17 00:00:00 2001 From: frisitano <35734660+frisitano@users.noreply.github.com> Date: Wed, 4 Dec 2024 00:56:17 +0800 Subject: [PATCH 58/68] Introduce `HashedPostStateProvider` (#12607) Co-authored-by: Matthias Seitz --- Cargo.lock | 5 +--- .../src/commands/debug_cmd/build_block.rs | 5 ++-- .../commands/debug_cmd/in_memory_merkle.rs | 10 ++++--- crates/blockchain-tree/src/blockchain_tree.rs | 13 +++++--- crates/blockchain-tree/src/chain.rs | 11 ++++--- crates/chain-state/Cargo.toml | 6 ++-- crates/chain-state/src/in_memory.rs | 10 +++++-- crates/chain-state/src/memory_overlay.rs | 11 +++++-- .../engine/invalid-block-hooks/src/witness.rs | 4 +-- crates/engine/tree/src/tree/mod.rs | 10 ++++--- crates/engine/tree/src/tree/root.rs | 8 ++++- crates/engine/util/src/reorg.rs | 3 +- crates/ethereum/payload/Cargo.toml | 1 - crates/ethereum/payload/src/lib.rs | 3 +- .../execution-types/src/execution_outcome.rs | 6 ++-- crates/optimism/payload/Cargo.toml | 1 - crates/optimism/payload/src/builder.rs | 27 +++++++++-------- crates/revm/src/test_utils.rs | 14 ++++++--- crates/rpc/rpc-eth-api/Cargo.toml | 1 - .../rpc-eth-api/src/helpers/pending_block.rs | 3 +- crates/rpc/rpc-eth-types/src/cache/db.rs | 11 ++++++- crates/rpc/rpc/Cargo.toml | 1 - crates/rpc/rpc/src/validation.rs | 3 +- .../src/providers/blockchain_provider.rs | 27 ++++++++++++++--- .../src/providers/bundle_state_provider.rs | 22 +++++++++----- .../provider/src/providers/consistent_view.rs | 10 ++++--- .../provider/src/providers/database/mod.rs | 29 ++++++++++++++---- .../src/providers/state/historical.rs | 30 +++++++++++++++++-- .../provider/src/providers/state/latest.rs | 26 ++++++++++++++-- .../provider/src/providers/state/macros.rs | 3 ++ .../storage/provider/src/test_utils/mock.rs | 13 +++++++- .../storage/provider/src/test_utils/noop.rs | 10 ++++++- crates/storage/provider/src/writer/mod.rs | 10 ++----- crates/storage/storage-api/Cargo.toml | 1 + crates/storage/storage-api/src/noop.rs | 12 ++++++-- crates/storage/storage-api/src/state.rs | 12 +++++++- crates/trie/db/src/prefix_set.rs | 29 +++++++++++------- crates/trie/db/src/state.rs | 20 +++++++------ crates/trie/parallel/src/proof.rs | 8 ++++- crates/trie/parallel/src/root.rs | 8 ++++- crates/trie/trie/benches/hash_post_state.rs | 4 +-- crates/trie/trie/src/state.rs | 14 +++++---- 42 files changed, 318 insertions(+), 137 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 91ab9d891f5d..3448ddbd4519 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7528,7 +7528,6 @@ dependencies = [ "reth-provider", "reth-revm", "reth-transaction-pool", - "reth-trie", "revm", "tracing", ] @@ -8449,7 +8448,6 @@ dependencies = [ "reth-revm", "reth-rpc-types-compat", "reth-transaction-pool", - "reth-trie", "revm", "sha2 0.10.8", "thiserror 2.0.3", @@ -8861,7 +8859,6 @@ dependencies = [ "reth-tasks", "reth-testing-utils", "reth-transaction-pool", - "reth-trie", "revm", "revm-inspectors", "revm-primitives", @@ -9041,7 +9038,6 @@ dependencies = [ "reth-rpc-types-compat", "reth-tasks", "reth-transaction-pool", - "reth-trie", "reth-trie-common", "revm", "revm-inspectors", @@ -9292,6 +9288,7 @@ dependencies = [ "reth-storage-errors", "reth-trie", "reth-trie-db", + "revm", ] [[package]] diff --git a/bin/reth/src/commands/debug_cmd/build_block.rs b/bin/reth/src/commands/debug_cmd/build_block.rs index c7e1be893af8..0e4d3f7188a9 100644 --- a/bin/reth/src/commands/debug_cmd/build_block.rs +++ b/bin/reth/src/commands/debug_cmd/build_block.rs @@ -263,7 +263,8 @@ impl> Command { let block_with_senders = SealedBlockWithSenders::>::new(block.clone(), senders).unwrap(); - let db = StateProviderDatabase::new(blockchain_db.latest()?); + let state_provider = blockchain_db.latest()?; + let db = StateProviderDatabase::new(&state_provider); let executor = EthExecutorProvider::ethereum(provider_factory.chain_spec()).executor(db); @@ -273,7 +274,7 @@ impl> Command { ExecutionOutcome::from((block_execution_output, block.number)); debug!(target: "reth::cli", ?execution_outcome, "Executed block"); - let hashed_post_state = execution_outcome.hash_state_slow(); + let hashed_post_state = state_provider.hashed_post_state(execution_outcome.state()); let (state_root, trie_updates) = StateRoot::overlay_root_with_updates( provider_factory.provider()?.tx_ref(), hashed_post_state.clone(), diff --git a/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs b/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs index 6fbfa33b891d..58b86648b901 100644 --- a/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs +++ b/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs @@ -24,8 +24,9 @@ use reth_node_ethereum::EthExecutorProvider; use reth_primitives::BlockExt; use reth_provider::{ providers::ProviderNodeTypes, AccountExtReader, ChainSpecProvider, DatabaseProviderFactory, - HashingWriter, HeaderProvider, LatestStateProviderRef, OriginalValuesKnown, ProviderFactory, - StageCheckpointReader, StateWriter, StorageLocation, StorageReader, + HashedPostStateProvider, HashingWriter, HeaderProvider, LatestStateProviderRef, + OriginalValuesKnown, ProviderFactory, StageCheckpointReader, StateWriter, StorageLocation, + StorageReader, }; use reth_revm::database::StateProviderDatabase; use reth_stages::StageId; @@ -143,7 +144,8 @@ impl> Command { ) .await?; - let db = StateProviderDatabase::new(LatestStateProviderRef::new(&provider)); + let state_provider = LatestStateProviderRef::new(&provider); + let db = StateProviderDatabase::new(&state_provider); let executor = EthExecutorProvider::ethereum(provider_factory.chain_spec()).executor(db); @@ -165,7 +167,7 @@ impl> Command { // Unpacked `BundleState::state_root_slow` function let (in_memory_state_root, in_memory_updates) = StateRoot::overlay_root_with_updates( provider.tx_ref(), - execution_outcome.hash_state_slow(), + state_provider.hashed_post_state(execution_outcome.state()), )?; if in_memory_state_root == block.state_root { diff --git a/crates/blockchain-tree/src/blockchain_tree.rs b/crates/blockchain-tree/src/blockchain_tree.rs index 91ddd75f2a71..e8576de4a711 100644 --- a/crates/blockchain-tree/src/blockchain_tree.rs +++ b/crates/blockchain-tree/src/blockchain_tree.rs @@ -24,8 +24,8 @@ use reth_primitives::{ use reth_provider::{ BlockExecutionWriter, BlockNumReader, BlockWriter, CanonStateNotification, CanonStateNotificationSender, CanonStateNotifications, ChainSpecProvider, ChainSplit, - ChainSplitTarget, DBProvider, DisplayBlocksChain, HeaderProvider, ProviderError, - StaticFileProviderFactory, StorageLocation, + ChainSplitTarget, DBProvider, DisplayBlocksChain, HashedPostStateProvider, HeaderProvider, + ProviderError, StaticFileProviderFactory, StorageLocation, }; use reth_stages_api::{MetricEvent, MetricEventsSender}; use reth_storage_errors::provider::{ProviderResult, RootMismatch}; @@ -1215,7 +1215,7 @@ where recorder: &mut MakeCanonicalDurationsRecorder, ) -> Result<(), CanonicalError> { let (blocks, state, chain_trie_updates) = chain.into_inner(); - let hashed_state = state.hash_state_slow(); + let hashed_state = self.externals.provider_factory.hashed_post_state(state.state()); let prefix_sets = hashed_state.construct_prefix_sets().freeze(); let hashed_state_sorted = hashed_state.into_sorted(); @@ -1885,7 +1885,12 @@ mod tests { ); let provider = tree.externals.provider_factory.provider().unwrap(); - let prefix_sets = exec5.hash_state_slow().construct_prefix_sets().freeze(); + let prefix_sets = tree + .externals + .provider_factory + .hashed_post_state(exec5.state()) + .construct_prefix_sets() + .freeze(); let state_root = StateRoot::from_tx(provider.tx_ref()).with_prefix_sets(prefix_sets).root().unwrap(); assert_eq!(state_root, block5.state_root); diff --git a/crates/blockchain-tree/src/chain.rs b/crates/blockchain-tree/src/chain.rs index a3cbd432de88..4002fae1ac91 100644 --- a/crates/blockchain-tree/src/chain.rs +++ b/crates/blockchain-tree/src/chain.rs @@ -18,11 +18,11 @@ use reth_execution_types::{Chain, ExecutionOutcome}; use reth_primitives::{GotExpected, SealedBlockWithSenders, SealedHeader}; use reth_provider::{ providers::{BundleStateProvider, ConsistentDbView, TreeNodeTypes}, - DBProvider, FullExecutionDataProvider, ProviderError, StateRootProvider, - TryIntoHistoricalStateProvider, + DBProvider, FullExecutionDataProvider, HashedPostStateProvider, ProviderError, + StateRootProvider, TryIntoHistoricalStateProvider, }; use reth_revm::database::StateProviderDatabase; -use reth_trie::{updates::TrieUpdates, HashedPostState, TrieInput}; +use reth_trie::{updates::TrieUpdates, TrieInput}; use reth_trie_parallel::root::ParallelStateRoot; use std::{ collections::BTreeMap, @@ -228,14 +228,13 @@ impl AppendableChain { execution_outcome.extend(initial_execution_outcome.clone()); ParallelStateRoot::new( consistent_view, - TrieInput::from_state(execution_outcome.hash_state_slow()), + TrieInput::from_state(provider.hashed_post_state(execution_outcome.state())), ) .incremental_root_with_updates() .map(|(root, updates)| (root, Some(updates))) .map_err(ProviderError::from)? } else { - let hashed_state = - HashedPostState::from_bundle_state(&initial_execution_outcome.state().state); + let hashed_state = provider.hashed_post_state(initial_execution_outcome.state()); let state_root = provider.state_root(hashed_state)?; (state_root, None) }; diff --git a/crates/chain-state/Cargo.toml b/crates/chain-state/Cargo.toml index d2ef5870947b..2b06bd93707b 100644 --- a/crates/chain-state/Cargo.toml +++ b/crates/chain-state/Cargo.toml @@ -26,6 +26,7 @@ reth-trie.workspace = true alloy-eips.workspace = true alloy-primitives.workspace = true alloy-consensus.workspace = true +revm.workspace = true # async tokio = { workspace = true, default-features = false, features = ["sync", "macros"] } @@ -44,7 +45,6 @@ pin-project.workspace = true alloy-signer = { workspace = true, optional = true } alloy-signer-local = { workspace = true, optional = true } rand = { workspace = true, optional = true } -revm = { workspace = true, optional = true } [dev-dependencies] reth-testing-utils.workspace = true @@ -52,17 +52,15 @@ alloy-signer.workspace = true alloy-signer-local.workspace = true alloy-consensus.workspace = true rand.workspace = true -revm.workspace = true [features] test-utils = [ "alloy-signer", "alloy-signer-local", "rand", - "revm", "reth-chainspec/test-utils", "reth-primitives/test-utils", "reth-primitives-traits/test-utils", "reth-trie/test-utils", - "revm?/test-utils", + "revm/test-utils", ] diff --git a/crates/chain-state/src/in_memory.rs b/crates/chain-state/src/in_memory.rs index 3cd6f4645628..670c340db4bf 100644 --- a/crates/chain-state/src/in_memory.rs +++ b/crates/chain-state/src/in_memory.rs @@ -949,8 +949,8 @@ mod tests { use reth_errors::ProviderResult; use reth_primitives::{Account, Bytecode, EthPrimitives, Receipt}; use reth_storage_api::{ - AccountReader, BlockHashReader, StateProofProvider, StateProvider, StateRootProvider, - StorageRootProvider, + AccountReader, BlockHashReader, HashedPostStateProvider, StateProofProvider, StateProvider, + StateRootProvider, StorageRootProvider, }; use reth_trie::{ AccountProof, HashedStorage, MultiProof, StorageMultiProof, StorageProof, TrieInput, @@ -1047,6 +1047,12 @@ mod tests { } } + impl HashedPostStateProvider for MockStateProvider { + fn hashed_post_state(&self, _bundle_state: &revm::db::BundleState) -> HashedPostState { + HashedPostState::default() + } + } + impl StorageRootProvider for MockStateProvider { fn storage_root( &self, diff --git a/crates/chain-state/src/memory_overlay.rs b/crates/chain-state/src/memory_overlay.rs index c84bd8c93f06..21bc30b07cf7 100644 --- a/crates/chain-state/src/memory_overlay.rs +++ b/crates/chain-state/src/memory_overlay.rs @@ -8,13 +8,14 @@ use alloy_primitives::{ use reth_errors::ProviderResult; use reth_primitives::{Account, Bytecode, NodePrimitives}; use reth_storage_api::{ - AccountReader, BlockHashReader, StateProofProvider, StateProvider, StateRootProvider, - StorageRootProvider, + AccountReader, BlockHashReader, HashedPostStateProvider, StateProofProvider, StateProvider, + StateRootProvider, StorageRootProvider, }; use reth_trie::{ updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof, StorageMultiProof, TrieInput, }; +use revm::db::BundleState; use std::sync::OnceLock; /// A state provider that stores references to in-memory blocks along with their state as well as a @@ -218,6 +219,12 @@ macro_rules! impl_state_provider { } } + impl $($tokens)* HashedPostStateProvider for $type { + fn hashed_post_state(&self, bundle_state: &BundleState) -> HashedPostState { + self.historical.hashed_post_state(bundle_state) + } + } + impl $($tokens)* StateProvider for $type { fn storage( &self, diff --git a/crates/engine/invalid-block-hooks/src/witness.rs b/crates/engine/invalid-block-hooks/src/witness.rs index 08681a9d17a9..cc98837a98c5 100644 --- a/crates/engine/invalid-block-hooks/src/witness.rs +++ b/crates/engine/invalid-block-hooks/src/witness.rs @@ -17,7 +17,7 @@ use reth_revm::{ }; use reth_rpc_api::DebugApiClient; use reth_tracing::tracing::warn; -use reth_trie::{updates::TrieUpdates, HashedPostState, HashedStorage}; +use reth_trie::{updates::TrieUpdates, HashedStorage}; use serde::Serialize; use std::{collections::HashMap, fmt::Debug, fs::File, io::Write, path::PathBuf}; @@ -129,7 +129,7 @@ where // // Note: We grab *all* accounts in the cache here, as the `BundleState` prunes // referenced accounts + storage slots. - let mut hashed_state = HashedPostState::from_bundle_state(&bundle_state.state); + let mut hashed_state = db.database.hashed_post_state(&bundle_state); for (address, account) in db.cache.accounts { let hashed_address = keccak256(address); hashed_state diff --git a/crates/engine/tree/src/tree/mod.rs b/crates/engine/tree/src/tree/mod.rs index c65035973816..763d5d990c5d 100644 --- a/crates/engine/tree/src/tree/mod.rs +++ b/crates/engine/tree/src/tree/mod.rs @@ -41,8 +41,8 @@ use reth_primitives::{ }; use reth_provider::{ providers::ConsistentDbView, BlockReader, DatabaseProviderFactory, ExecutionOutcome, - ProviderError, StateProviderBox, StateProviderFactory, StateReader, StateRootProvider, - TransactionVariant, + HashedPostStateProvider, ProviderError, StateCommitmentProvider, StateProviderBox, + StateProviderFactory, StateReader, StateRootProvider, TransactionVariant, }; use reth_revm::database::StateProviderDatabase; use reth_stages_api::ControlFlow; @@ -552,6 +552,8 @@ where + BlockReader + StateProviderFactory + StateReader + + StateCommitmentProvider + + HashedPostStateProvider + Clone + 'static,

::Provider: BlockReader, @@ -1568,7 +1570,7 @@ where .provider .get_state(block.number())? .ok_or_else(|| ProviderError::StateForNumberNotFound(block.number()))?; - let hashed_state = execution_output.hash_state_slow(); + let hashed_state = self.provider.hashed_post_state(execution_output.state()); Ok(Some(ExecutedBlock { block: Arc::new(block), @@ -2242,7 +2244,7 @@ where return Err(err.into()) } - let hashed_state = HashedPostState::from_bundle_state(&output.state.state); + let hashed_state = self.provider.hashed_post_state(&output.state); trace!(target: "engine::tree", block=?sealed_block.num_hash(), "Calculating block state root"); let root_time = Instant::now(); diff --git a/crates/engine/tree/src/tree/root.rs b/crates/engine/tree/src/tree/root.rs index 78a8332b5ebc..eea236fdaaec 100644 --- a/crates/engine/tree/src/tree/root.rs +++ b/crates/engine/tree/src/tree/root.rs @@ -3,6 +3,7 @@ use alloy_primitives::map::{HashMap, HashSet}; use reth_provider::{ providers::ConsistentDbView, BlockReader, DBProvider, DatabaseProviderFactory, + StateCommitmentProvider, }; use reth_trie::{ proof::Proof, updates::TrieUpdates, HashedPostState, HashedStorage, MultiProof, Nibbles, @@ -179,7 +180,12 @@ pub(crate) struct StateRootTask { #[allow(dead_code)] impl StateRootTask where - Factory: DatabaseProviderFactory + Clone + Send + Sync + 'static, + Factory: DatabaseProviderFactory + + StateCommitmentProvider + + Clone + + Send + + Sync + + 'static, { /// Creates a new state root task with the unified message channel pub(crate) fn new( diff --git a/crates/engine/util/src/reorg.rs b/crates/engine/util/src/reorg.rs index 18a8c4737b5a..4f7e213b058c 100644 --- a/crates/engine/util/src/reorg.rs +++ b/crates/engine/util/src/reorg.rs @@ -29,7 +29,6 @@ use reth_revm::{ DatabaseCommit, }; use reth_rpc_types_compat::engine::payload::block_to_payload; -use reth_trie::HashedPostState; use revm_primitives::{calc_excess_blob_gas, EVMError, EnvWithHandlerCfg}; use std::{ collections::VecDeque, @@ -382,7 +381,7 @@ where reorg_target.number, Default::default(), ); - let hashed_state = HashedPostState::from_bundle_state(&outcome.state().state); + let hashed_state = state_provider.hashed_post_state(outcome.state()); let (blob_gas_used, excess_blob_gas) = if chain_spec.is_cancun_active_at_timestamp(reorg_target.timestamp) { diff --git a/crates/ethereum/payload/Cargo.toml b/crates/ethereum/payload/Cargo.toml index 4e0880d1d153..b01f4c5bc74f 100644 --- a/crates/ethereum/payload/Cargo.toml +++ b/crates/ethereum/payload/Cargo.toml @@ -25,7 +25,6 @@ reth-basic-payload-builder.workspace = true reth-evm.workspace = true reth-evm-ethereum.workspace = true reth-errors.workspace = true -reth-trie.workspace = true reth-chain-state.workspace = true reth-chainspec.workspace = true diff --git a/crates/ethereum/payload/src/lib.rs b/crates/ethereum/payload/src/lib.rs index df900f1f36b3..a5e6bcaa5f00 100644 --- a/crates/ethereum/payload/src/lib.rs +++ b/crates/ethereum/payload/src/lib.rs @@ -39,7 +39,6 @@ use reth_transaction_pool::{ error::InvalidPoolTransactionError, noop::NoopTransactionPool, BestTransactions, BestTransactionsAttributes, PoolTransaction, TransactionPool, ValidPoolTransaction, }; -use reth_trie::HashedPostState; use revm::{ db::{states::bundle_state::BundleRetention, State}, primitives::{ @@ -413,7 +412,7 @@ where let logs_bloom = execution_outcome.block_logs_bloom(block_number).expect("Number is in range"); // calculate the state root - let hashed_state = HashedPostState::from_bundle_state(&execution_outcome.state().state); + let hashed_state = db.database.db.hashed_post_state(execution_outcome.state()); let (state_root, trie_output) = { db.database.inner().state_root_with_updates(hashed_state.clone()).inspect_err(|err| { warn!(target: "payload_builder", diff --git a/crates/evm/execution-types/src/execution_outcome.rs b/crates/evm/execution-types/src/execution_outcome.rs index c9e85ae444fd..1dca5f2fc9e9 100644 --- a/crates/evm/execution-types/src/execution_outcome.rs +++ b/crates/evm/execution-types/src/execution_outcome.rs @@ -3,7 +3,7 @@ use alloy_eips::eip7685::Requests; use alloy_primitives::{logs_bloom, Address, BlockNumber, Bloom, Log, B256, U256}; use reth_primitives::Receipts; use reth_primitives_traits::{receipt::ReceiptExt, Account, Bytecode, Receipt, StorageEntry}; -use reth_trie::HashedPostState; +use reth_trie::{HashedPostState, KeyHasher}; use revm::{ db::{states::BundleState, BundleAccount}, primitives::AccountInfo, @@ -164,8 +164,8 @@ impl ExecutionOutcome { /// Returns [`HashedPostState`] for this execution outcome. /// See [`HashedPostState::from_bundle_state`] for more info. - pub fn hash_state_slow(&self) -> HashedPostState { - HashedPostState::from_bundle_state(&self.bundle.state) + pub fn hash_state_slow(&self) -> HashedPostState { + HashedPostState::from_bundle_state::(&self.bundle.state) } /// Transform block number to the index of block. diff --git a/crates/optimism/payload/Cargo.toml b/crates/optimism/payload/Cargo.toml index 7f47da7e2360..1c4f855b6aa2 100644 --- a/crates/optimism/payload/Cargo.toml +++ b/crates/optimism/payload/Cargo.toml @@ -26,7 +26,6 @@ reth-payload-builder-primitives.workspace = true reth-payload-util.workspace = true reth-payload-primitives = { workspace = true, features = ["op"] } reth-basic-payload-builder.workspace = true -reth-trie.workspace = true reth-chain-state.workspace = true # op-reth diff --git a/crates/optimism/payload/src/builder.rs b/crates/optimism/payload/src/builder.rs index d385ca79546f..91e70d0c3c8b 100644 --- a/crates/optimism/payload/src/builder.rs +++ b/crates/optimism/payload/src/builder.rs @@ -22,12 +22,14 @@ use reth_primitives::{ proofs, transaction::SignedTransactionIntoRecoveredExt, Block, BlockBody, BlockExt, Receipt, SealedHeader, TransactionSigned, TxType, }; -use reth_provider::{ProviderError, StateProofProvider, StateProviderFactory, StateRootProvider}; +use reth_provider::{ + HashedPostStateProvider, ProviderError, StateProofProvider, StateProviderFactory, + StateRootProvider, +}; use reth_revm::database::StateProviderDatabase; use reth_transaction_pool::{ noop::NoopTransactionPool, BestTransactionsAttributes, PoolTransaction, TransactionPool, }; -use reth_trie::HashedPostState; use revm::{ db::{states::bundle_state::BundleRetention, State}, primitives::{ @@ -339,7 +341,7 @@ where where EvmConfig: ConfigureEvm

, DB: Database + AsRef

, - P: StateRootProvider, + P: StateRootProvider + HashedPostStateProvider, { let ExecutedPayload { info, withdrawals_root } = match self.execute(&mut state, &ctx)? { BuildOutcomeKind::Better { payload } | BuildOutcomeKind::Freeze(payload) => payload, @@ -367,17 +369,16 @@ where execution_outcome.block_logs_bloom(block_number).expect("Number is in range"); // // calculate the state root - let hashed_state = HashedPostState::from_bundle_state(&execution_outcome.state().state); + let state_provider = state.database.as_ref(); + let hashed_state = state_provider.hashed_post_state(execution_outcome.state()); let (state_root, trie_output) = { - state.database.as_ref().state_root_with_updates(hashed_state.clone()).inspect_err( - |err| { - warn!(target: "payload_builder", - parent_header=%ctx.parent().hash(), - %err, - "failed to calculate state root for payload" - ); - }, - )? + state_provider.state_root_with_updates(hashed_state.clone()).inspect_err(|err| { + warn!(target: "payload_builder", + parent_header=%ctx.parent().hash(), + %err, + "failed to calculate state root for payload" + ); + })? }; // create the block header diff --git a/crates/revm/src/test_utils.rs b/crates/revm/src/test_utils.rs index 443d1d5ebcf2..9460d3e1c784 100644 --- a/crates/revm/src/test_utils.rs +++ b/crates/revm/src/test_utils.rs @@ -6,13 +6,13 @@ use alloy_primitives::{ }; use reth_primitives::{Account, Bytecode}; use reth_storage_api::{ - AccountReader, BlockHashReader, StateProofProvider, StateProvider, StateRootProvider, - StorageRootProvider, + AccountReader, BlockHashReader, HashedPostStateProvider, StateProofProvider, StateProvider, + StateRootProvider, StorageRootProvider, }; use reth_storage_errors::provider::ProviderResult; use reth_trie::{ - updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof, - StorageMultiProof, StorageProof, TrieInput, + updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, KeccakKeyHasher, + MultiProof, StorageMultiProof, StorageProof, TrieInput, }; /// Mock state for testing @@ -150,6 +150,12 @@ impl StateProofProvider for StateProviderTest { } } +impl HashedPostStateProvider for StateProviderTest { + fn hashed_post_state(&self, bundle_state: &revm::db::BundleState) -> HashedPostState { + HashedPostState::from_bundle_state::(bundle_state.state()) + } +} + impl StateProvider for StateProviderTest { fn storage( &self, diff --git a/crates/rpc/rpc-eth-api/Cargo.toml b/crates/rpc/rpc-eth-api/Cargo.toml index 859caa821cdc..cf701187dad3 100644 --- a/crates/rpc/rpc-eth-api/Cargo.toml +++ b/crates/rpc/rpc-eth-api/Cargo.toml @@ -30,7 +30,6 @@ reth-rpc-eth-types.workspace = true reth-rpc-server-types.workspace = true reth-network-api.workspace = true reth-node-api.workspace = true -reth-trie.workspace = true reth-trie-common = { workspace = true, features = ["eip1186"] } # ethereum diff --git a/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs b/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs index 782c1a2a8f6b..4c81626649d9 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs @@ -36,7 +36,6 @@ use reth_transaction_pool::{ error::InvalidPoolTransactionError, BestTransactionsAttributes, PoolTransaction, TransactionPool, }; -use reth_trie::HashedPostState; use revm::{db::states::bundle_state::BundleRetention, DatabaseCommit, State}; use std::time::{Duration, Instant}; use tokio::sync::Mutex; @@ -427,7 +426,7 @@ pub trait LoadPendingBlock: block_number, Vec::new(), ); - let hashed_state = HashedPostState::from_bundle_state(&execution_outcome.state().state); + let hashed_state = db.database.hashed_post_state(execution_outcome.state()); let receipts_root = self.receipts_root(&block_env, &execution_outcome, block_number); diff --git a/crates/rpc/rpc-eth-types/src/cache/db.rs b/crates/rpc/rpc-eth-types/src/cache/db.rs index 1fbe16a2ed9c..ed107f3b0a9e 100644 --- a/crates/rpc/rpc-eth-types/src/cache/db.rs +++ b/crates/rpc/rpc-eth-types/src/cache/db.rs @@ -8,7 +8,7 @@ use alloy_primitives::{ }; use reth_errors::ProviderResult; use reth_revm::{database::StateProviderDatabase, db::CacheDB, DatabaseRef}; -use reth_storage_api::StateProvider; +use reth_storage_api::{HashedPostStateProvider, StateProvider}; use reth_trie::HashedStorage; use revm::Database; @@ -139,6 +139,15 @@ impl reth_storage_api::BlockHashReader for StateProviderTraitObjWrapper<'_> { } } +impl HashedPostStateProvider for StateProviderTraitObjWrapper<'_> { + fn hashed_post_state( + &self, + bundle_state: &revm::db::BundleState, + ) -> reth_trie::HashedPostState { + self.0.hashed_post_state(bundle_state) + } +} + impl StateProvider for StateProviderTraitObjWrapper<'_> { fn storage( &self, diff --git a/crates/rpc/rpc/Cargo.toml b/crates/rpc/rpc/Cargo.toml index 834b1a963bfe..5efae46f0061 100644 --- a/crates/rpc/rpc/Cargo.toml +++ b/crates/rpc/rpc/Cargo.toml @@ -34,7 +34,6 @@ reth-evm.workspace = true reth-rpc-eth-types.workspace = true reth-rpc-server-types.workspace = true reth-network-types.workspace = true -reth-trie.workspace = true reth-consensus.workspace = true reth-payload-validator.workspace = true diff --git a/crates/rpc/rpc/src/validation.rs b/crates/rpc/rpc/src/validation.rs index d862bc5f30dd..b72a5d35769f 100644 --- a/crates/rpc/rpc/src/validation.rs +++ b/crates/rpc/rpc/src/validation.rs @@ -25,7 +25,6 @@ use reth_revm::{cached::CachedReads, database::StateProviderDatabase}; use reth_rpc_api::BlockSubmissionValidationApiServer; use reth_rpc_server_types::result::internal_rpc_err; use reth_tasks::TaskSpawner; -use reth_trie::HashedPostState; use revm_primitives::{Address, B256, U256}; use serde::{Deserialize, Serialize}; use std::{collections::HashSet, sync::Arc}; @@ -186,7 +185,7 @@ where self.ensure_payment(&block, &output, &message)?; let state_root = - state_provider.state_root(HashedPostState::from_bundle_state(&output.state.state))?; + state_provider.state_root(state_provider.hashed_post_state(&output.state))?; if state_root != block.state_root { return Err(ConsensusError::BodyStateRootDiff( diff --git a/crates/storage/provider/src/providers/blockchain_provider.rs b/crates/storage/provider/src/providers/blockchain_provider.rs index 1bb65a6e4fb4..8330ef3a66e8 100644 --- a/crates/storage/provider/src/providers/blockchain_provider.rs +++ b/crates/storage/provider/src/providers/blockchain_provider.rs @@ -4,8 +4,8 @@ use crate::{ AccountReader, BlockHashReader, BlockIdReader, BlockNumReader, BlockReader, BlockReaderIdExt, BlockSource, CanonChainTracker, CanonStateNotifications, CanonStateSubscriptions, ChainSpecProvider, ChainStateBlockReader, ChangeSetReader, DatabaseProvider, - DatabaseProviderFactory, EvmEnvProvider, FullProvider, HeaderProvider, ProviderError, - ProviderFactory, PruneCheckpointReader, ReceiptProvider, ReceiptProviderIdExt, + DatabaseProviderFactory, EvmEnvProvider, FullProvider, HashedPostStateProvider, HeaderProvider, + ProviderError, ProviderFactory, PruneCheckpointReader, ReceiptProvider, ReceiptProviderIdExt, StageCheckpointReader, StateProviderBox, StateProviderFactory, StateReader, StaticFileProviderFactory, TransactionVariant, TransactionsProvider, WithdrawalsProvider, }; @@ -34,9 +34,16 @@ use reth_primitives::{ use reth_primitives_traits::BlockBody as _; use reth_prune_types::{PruneCheckpoint, PruneSegment}; use reth_stages_types::{StageCheckpoint, StageId}; -use reth_storage_api::{DBProvider, NodePrimitivesProvider, StorageChangeSetReader}; +use reth_storage_api::{ + DBProvider, NodePrimitivesProvider, StateCommitmentProvider, StorageChangeSetReader, +}; use reth_storage_errors::provider::ProviderResult; -use revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg}; +use reth_trie::HashedPostState; +use reth_trie_db::StateCommitment; +use revm::{ + db::BundleState, + primitives::{BlockEnv, CfgEnvWithHandlerCfg}, +}; use std::{ ops::{Add, RangeBounds, RangeInclusive, Sub}, sync::Arc, @@ -171,6 +178,10 @@ impl DatabaseProviderFactory for BlockchainProvider2 { } } +impl StateCommitmentProvider for BlockchainProvider2 { + type StateCommitment = N::StateCommitment; +} + impl StaticFileProviderFactory for BlockchainProvider2 { fn static_file_provider(&self) -> StaticFileProvider { self.database.static_file_provider() @@ -663,6 +674,14 @@ impl StateProviderFactory for BlockchainProvider2 { } } +impl HashedPostStateProvider for BlockchainProvider2 { + fn hashed_post_state(&self, bundle_state: &BundleState) -> HashedPostState { + HashedPostState::from_bundle_state::<::KeyHasher>( + bundle_state.state(), + ) + } +} + impl CanonChainTracker for BlockchainProvider2 { type Header = HeaderTy; diff --git a/crates/storage/provider/src/providers/bundle_state_provider.rs b/crates/storage/provider/src/providers/bundle_state_provider.rs index 652f6fb33fd2..619296b57f38 100644 --- a/crates/storage/provider/src/providers/bundle_state_provider.rs +++ b/crates/storage/provider/src/providers/bundle_state_provider.rs @@ -6,7 +6,7 @@ use alloy_primitives::{ Address, BlockNumber, Bytes, B256, }; use reth_primitives::{Account, Bytecode}; -use reth_storage_api::{StateProofProvider, StorageRootProvider}; +use reth_storage_api::{HashedPostStateProvider, StateProofProvider, StorageRootProvider}; use reth_storage_errors::provider::ProviderResult; use reth_trie::{ updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof, @@ -87,7 +87,7 @@ impl StateRootProvider { fn state_root(&self, hashed_state: HashedPostState) -> ProviderResult { let bundle_state = self.block_execution_data_provider.execution_outcome().state(); - let mut state = HashedPostState::from_bundle_state(&bundle_state.state); + let mut state = self.hashed_post_state(bundle_state); state.extend(hashed_state); self.state_provider.state_root(state) } @@ -101,7 +101,7 @@ impl StateRootProvider hashed_state: HashedPostState, ) -> ProviderResult<(B256, TrieUpdates)> { let bundle_state = self.block_execution_data_provider.execution_outcome().state(); - let mut state = HashedPostState::from_bundle_state(&bundle_state.state); + let mut state = self.hashed_post_state(bundle_state); state.extend(hashed_state); self.state_provider.state_root_with_updates(state) } @@ -111,7 +111,7 @@ impl StateRootProvider mut input: TrieInput, ) -> ProviderResult<(B256, TrieUpdates)> { let bundle_state = self.block_execution_data_provider.execution_outcome().state(); - input.prepend(HashedPostState::from_bundle_state(&bundle_state.state)); + input.prepend(self.hashed_post_state(bundle_state)); self.state_provider.state_root_from_nodes_with_updates(input) } } @@ -162,7 +162,7 @@ impl StateProofProvider slots: &[B256], ) -> ProviderResult { let bundle_state = self.block_execution_data_provider.execution_outcome().state(); - input.prepend(HashedPostState::from_bundle_state(&bundle_state.state)); + input.prepend(self.hashed_post_state(bundle_state)); self.state_provider.proof(input, address, slots) } @@ -172,7 +172,7 @@ impl StateProofProvider targets: HashMap>, ) -> ProviderResult { let bundle_state = self.block_execution_data_provider.execution_outcome().state(); - input.prepend(HashedPostState::from_bundle_state(&bundle_state.state)); + input.prepend(self.hashed_post_state(bundle_state)); self.state_provider.multiproof(input, targets) } @@ -182,11 +182,19 @@ impl StateProofProvider target: HashedPostState, ) -> ProviderResult> { let bundle_state = self.block_execution_data_provider.execution_outcome().state(); - input.prepend(HashedPostState::from_bundle_state(&bundle_state.state)); + input.prepend(self.hashed_post_state(bundle_state)); self.state_provider.witness(input, target) } } +impl HashedPostStateProvider + for BundleStateProvider +{ + fn hashed_post_state(&self, bundle_state: &revm::db::BundleState) -> HashedPostState { + self.state_provider.hashed_post_state(bundle_state) + } +} + impl StateProvider for BundleStateProvider { fn storage( &self, diff --git a/crates/storage/provider/src/providers/consistent_view.rs b/crates/storage/provider/src/providers/consistent_view.rs index 4640f4603354..479537f120cc 100644 --- a/crates/storage/provider/src/providers/consistent_view.rs +++ b/crates/storage/provider/src/providers/consistent_view.rs @@ -2,11 +2,11 @@ use crate::{BlockNumReader, DatabaseProviderFactory, HeaderProvider}; use alloy_primitives::B256; use reth_errors::ProviderError; use reth_primitives::GotExpected; -use reth_storage_api::{BlockReader, DBProvider}; +use reth_storage_api::{BlockReader, DBProvider, StateCommitmentProvider}; use reth_storage_errors::provider::ProviderResult; use reth_trie::HashedPostState; -use reth_trie_db::DatabaseHashedPostState; +use reth_trie_db::{DatabaseHashedPostState, StateCommitment}; pub use reth_storage_errors::provider::ConsistentViewError; @@ -33,7 +33,7 @@ pub struct ConsistentDbView { impl ConsistentDbView where - Factory: DatabaseProviderFactory, + Factory: DatabaseProviderFactory + StateCommitmentProvider, { /// Creates new consistent database view. pub const fn new(factory: Factory, tip: Option) -> Self { @@ -59,7 +59,9 @@ where { Ok(HashedPostState::default()) } else { - Ok(HashedPostState::from_reverts(provider.tx_ref(), block_number + 1)?) + Ok(HashedPostState::from_reverts::< + ::KeyHasher, + >(provider.tx_ref(), block_number + 1)?) } } diff --git a/crates/storage/provider/src/providers/database/mod.rs b/crates/storage/provider/src/providers/database/mod.rs index d34d67d9dc86..39230e253ed6 100644 --- a/crates/storage/provider/src/providers/database/mod.rs +++ b/crates/storage/provider/src/providers/database/mod.rs @@ -3,9 +3,9 @@ use crate::{ to_range, traits::{BlockSource, ReceiptProvider}, BlockHashReader, BlockNumReader, BlockReader, ChainSpecProvider, DatabaseProviderFactory, - EvmEnvProvider, HeaderProvider, HeaderSyncGap, HeaderSyncGapProvider, ProviderError, - PruneCheckpointReader, StageCheckpointReader, StateProviderBox, StaticFileProviderFactory, - TransactionVariant, TransactionsProvider, WithdrawalsProvider, + EvmEnvProvider, HashedPostStateProvider, HeaderProvider, HeaderSyncGap, HeaderSyncGapProvider, + ProviderError, PruneCheckpointReader, StageCheckpointReader, StateProviderBox, + StaticFileProviderFactory, TransactionVariant, TransactionsProvider, WithdrawalsProvider, }; use alloy_eips::{ eip4895::{Withdrawal, Withdrawals}, @@ -25,9 +25,16 @@ use reth_primitives::{ }; use reth_prune_types::{PruneCheckpoint, PruneModes, PruneSegment}; use reth_stages_types::{StageCheckpoint, StageId}; -use reth_storage_api::{NodePrimitivesProvider, TryIntoHistoricalStateProvider}; +use reth_storage_api::{ + NodePrimitivesProvider, StateCommitmentProvider, TryIntoHistoricalStateProvider, +}; use reth_storage_errors::provider::ProviderResult; -use revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg}; +use reth_trie::HashedPostState; +use reth_trie_db::StateCommitment; +use revm::{ + db::BundleState, + primitives::{BlockEnv, CfgEnvWithHandlerCfg}, +}; use std::{ ops::{RangeBounds, RangeInclusive}, path::Path, @@ -219,6 +226,10 @@ impl DatabaseProviderFactory for ProviderFactory { } } +impl StateCommitmentProvider for ProviderFactory { + type StateCommitment = N::StateCommitment; +} + impl StaticFileProviderFactory for ProviderFactory { /// Returns static file provider fn static_file_provider(&self) -> StaticFileProvider { @@ -651,6 +662,14 @@ impl PruneCheckpointReader for ProviderFactory { } } +impl HashedPostStateProvider for ProviderFactory { + fn hashed_post_state(&self, bundle_state: &BundleState) -> HashedPostState { + HashedPostState::from_bundle_state::<::KeyHasher>( + bundle_state.state(), + ) + } +} + impl Clone for ProviderFactory { fn clone(&self) -> Self { Self { diff --git a/crates/storage/provider/src/providers/state/historical.rs b/crates/storage/provider/src/providers/state/historical.rs index ad36a4a5ab3e..93752c1e278d 100644 --- a/crates/storage/provider/src/providers/state/historical.rs +++ b/crates/storage/provider/src/providers/state/historical.rs @@ -1,6 +1,6 @@ use crate::{ providers::state::macros::delegate_provider_impls, AccountReader, BlockHashReader, - ProviderError, StateProvider, StateRootProvider, + HashedPostStateProvider, ProviderError, StateProvider, StateRootProvider, }; use alloy_eips::merge::EPOCH_SLOTS; use alloy_primitives::{ @@ -28,7 +28,7 @@ use reth_trie::{ }; use reth_trie_db::{ DatabaseHashedPostState, DatabaseHashedStorage, DatabaseProof, DatabaseStateRoot, - DatabaseStorageProof, DatabaseStorageRoot, DatabaseTrieWitness, + DatabaseStorageProof, DatabaseStorageRoot, DatabaseTrieWitness, StateCommitment, }; use std::fmt::Debug; @@ -136,7 +136,9 @@ impl<'b, Provider: DBProvider + BlockNumReader + StateCommitmentProvider> ); } - Ok(HashedPostState::from_reverts(self.tx(), self.block_number)?) + Ok(HashedPostState::from_reverts::< + ::KeyHasher, + >(self.tx(), self.block_number)?) } /// Retrieve revert hashed storage for this history provider and target address. @@ -394,6 +396,16 @@ impl StateProof } } +impl HashedPostStateProvider + for HistoricalStateProviderRef<'_, Provider> +{ + fn hashed_post_state(&self, bundle_state: &revm::db::BundleState) -> HashedPostState { + HashedPostState::from_bundle_state::< + ::KeyHasher, + >(bundle_state.state()) + } +} + impl StateProvider for HistoricalStateProviderRef<'_, Provider> { @@ -433,6 +445,12 @@ impl StateCommitmentProvider + for HistoricalStateProviderRef<'_, Provider> +{ + type StateCommitment = Provider::StateCommitment; +} + /// State provider for a given block number. /// For more detailed description, see [`HistoricalStateProviderRef`]. #[derive(Debug)] @@ -482,6 +500,12 @@ impl } } +impl StateCommitmentProvider + for HistoricalStateProvider +{ + type StateCommitment = Provider::StateCommitment; +} + // Delegates all provider impls to [HistoricalStateProviderRef] delegate_provider_impls!(HistoricalStateProvider where [Provider: DBProvider + BlockNumReader + BlockHashReader + StateCommitmentProvider]); diff --git a/crates/storage/provider/src/providers/state/latest.rs b/crates/storage/provider/src/providers/state/latest.rs index a2ec4972d105..bdb6de1e569e 100644 --- a/crates/storage/provider/src/providers/state/latest.rs +++ b/crates/storage/provider/src/providers/state/latest.rs @@ -1,6 +1,6 @@ use crate::{ providers::state::macros::delegate_provider_impls, AccountReader, BlockHashReader, - StateProvider, StateRootProvider, + HashedPostStateProvider, StateProvider, StateRootProvider, }; use alloy_primitives::{ map::{HashMap, HashSet}, @@ -22,7 +22,7 @@ use reth_trie::{ }; use reth_trie_db::{ DatabaseProof, DatabaseStateRoot, DatabaseStorageProof, DatabaseStorageRoot, - DatabaseTrieWitness, + DatabaseTrieWitness, StateCommitment, }; /// State provider over latest state that takes tx reference. @@ -157,6 +157,16 @@ impl StateProofProvider } } +impl HashedPostStateProvider + for LatestStateProviderRef<'_, Provider> +{ + fn hashed_post_state(&self, bundle_state: &revm::db::BundleState) -> HashedPostState { + HashedPostState::from_bundle_state::< + ::KeyHasher, + >(bundle_state.state()) + } +} + impl StateProvider for LatestStateProviderRef<'_, Provider> { @@ -181,11 +191,17 @@ impl StateProv } } +impl StateCommitmentProvider + for LatestStateProviderRef<'_, Provider> +{ + type StateCommitment = Provider::StateCommitment; +} + /// State provider for the latest state. #[derive(Debug)] pub struct LatestStateProvider(Provider); -impl LatestStateProvider { +impl LatestStateProvider { /// Create new state provider pub const fn new(db: Provider) -> Self { Self(db) @@ -198,6 +214,10 @@ impl LatestStateProvider { } } +impl StateCommitmentProvider for LatestStateProvider { + type StateCommitment = Provider::StateCommitment; +} + // Delegates all provider impls to [LatestStateProviderRef] delegate_provider_impls!(LatestStateProvider where [Provider: DBProvider + BlockHashReader + StateCommitmentProvider]); diff --git a/crates/storage/provider/src/providers/state/macros.rs b/crates/storage/provider/src/providers/state/macros.rs index f2648fb15e6a..1fa15214e9a9 100644 --- a/crates/storage/provider/src/providers/state/macros.rs +++ b/crates/storage/provider/src/providers/state/macros.rs @@ -57,6 +57,9 @@ macro_rules! delegate_provider_impls { fn multiproof(&self, input: reth_trie::TrieInput, targets: alloy_primitives::map::HashMap>) -> reth_storage_errors::provider::ProviderResult; fn witness(&self, input: reth_trie::TrieInput, target: reth_trie::HashedPostState) -> reth_storage_errors::provider::ProviderResult>; } + HashedPostStateProvider $(where [$($generics)*])? { + fn hashed_post_state(&self, bundle_state: &revm::db::BundleState) -> reth_trie::HashedPostState; + } ); } } diff --git a/crates/storage/provider/src/test_utils/mock.rs b/crates/storage/provider/src/test_utils/mock.rs index 385e5e8205df..6815bbcb1238 100644 --- a/crates/storage/provider/src/test_utils/mock.rs +++ b/crates/storage/provider/src/test_utils/mock.rs @@ -29,7 +29,8 @@ use reth_primitives::{ use reth_primitives_traits::SignedTransaction; use reth_stages_types::{StageCheckpoint, StageId}; use reth_storage_api::{ - DatabaseProviderFactory, StageCheckpointReader, StateProofProvider, StorageRootProvider, + DatabaseProviderFactory, HashedPostStateProvider, StageCheckpointReader, + StateCommitmentProvider, StateProofProvider, StorageRootProvider, }; use reth_storage_errors::provider::{ConsistentViewError, ProviderError, ProviderResult}; use reth_trie::{ @@ -164,6 +165,10 @@ impl NodeTypes for MockNode { type Storage = EthStorage; } +impl StateCommitmentProvider for MockEthProvider { + type StateCommitment = ::StateCommitment; +} + impl DatabaseProviderFactory for MockEthProvider { type DB = DatabaseMock; type Provider = DatabaseProvider; @@ -682,6 +687,12 @@ impl StateProofProvider for MockEthProvider { } } +impl HashedPostStateProvider for MockEthProvider { + fn hashed_post_state(&self, _state: &revm::db::BundleState) -> HashedPostState { + HashedPostState::default() + } +} + impl StateProvider for MockEthProvider { fn storage( &self, diff --git a/crates/storage/provider/src/test_utils/noop.rs b/crates/storage/provider/src/test_utils/noop.rs index 5120afffa857..a33e4159be22 100644 --- a/crates/storage/provider/src/test_utils/noop.rs +++ b/crates/storage/provider/src/test_utils/noop.rs @@ -27,7 +27,9 @@ use reth_primitives::{ }; use reth_prune_types::{PruneCheckpoint, PruneSegment}; use reth_stages_types::{StageCheckpoint, StageId}; -use reth_storage_api::{NodePrimitivesProvider, StateProofProvider, StorageRootProvider}; +use reth_storage_api::{ + HashedPostStateProvider, NodePrimitivesProvider, StateProofProvider, StorageRootProvider, +}; use reth_storage_errors::provider::ProviderResult; use reth_trie::{ updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof, TrieInput, @@ -413,6 +415,12 @@ impl StateProofProvider for NoopProvider { } } +impl HashedPostStateProvider for NoopProvider { + fn hashed_post_state(&self, _bundle_state: &revm::db::BundleState) -> HashedPostState { + HashedPostState::default() + } +} + impl StateProvider for NoopProvider { fn storage( &self, diff --git a/crates/storage/provider/src/writer/mod.rs b/crates/storage/provider/src/writer/mod.rs index 02e912050d5e..dc5af491efc2 100644 --- a/crates/storage/provider/src/writer/mod.rs +++ b/crates/storage/provider/src/writer/mod.rs @@ -234,7 +234,7 @@ mod tests { }; use reth_execution_types::ExecutionOutcome; use reth_primitives::{Account, Receipt, Receipts, StorageEntry}; - use reth_storage_api::DatabaseProviderFactory; + use reth_storage_api::{DatabaseProviderFactory, HashedPostStateProvider}; use reth_trie::{ test_utils::{state_root, storage_root_prehashed}, HashedPostState, HashedStorage, StateRoot, StorageRoot, @@ -1118,13 +1118,7 @@ mod tests { assert_eq!( StateRoot::overlay_root( tx, - ExecutionOutcome::::new( - state.bundle_state.clone(), - Receipts::default(), - 0, - Vec::new() - ) - .hash_state_slow(), + provider_factory.hashed_post_state(&state.bundle_state) ) .unwrap(), state_root(expected.clone().into_iter().map(|(address, (account, storage))| ( diff --git a/crates/storage/storage-api/Cargo.toml b/crates/storage/storage-api/Cargo.toml index ba2ccf1b1573..7ebff976d135 100644 --- a/crates/storage/storage-api/Cargo.toml +++ b/crates/storage/storage-api/Cargo.toml @@ -25,6 +25,7 @@ reth-storage-errors.workspace = true reth-trie.workspace = true reth-trie-db.workspace = true reth-db.workspace = true +revm.workspace = true # ethereum alloy-eips.workspace = true diff --git a/crates/storage/storage-api/src/noop.rs b/crates/storage/storage-api/src/noop.rs index 9c971e7b293e..0a6341cc4b42 100644 --- a/crates/storage/storage-api/src/noop.rs +++ b/crates/storage/storage-api/src/noop.rs @@ -2,9 +2,9 @@ use crate::{ AccountReader, BlockHashReader, BlockIdReader, BlockNumReader, BlockReader, BlockReaderIdExt, - BlockSource, ChangeSetReader, HeaderProvider, NodePrimitivesProvider, PruneCheckpointReader, - ReceiptProvider, ReceiptProviderIdExt, StageCheckpointReader, StateProofProvider, - StateProvider, StateRootProvider, StorageRootProvider, TransactionVariant, + BlockSource, ChangeSetReader, HashedPostStateProvider, HeaderProvider, NodePrimitivesProvider, + PruneCheckpointReader, ReceiptProvider, ReceiptProviderIdExt, StageCheckpointReader, + StateProofProvider, StateProvider, StateRootProvider, StorageRootProvider, TransactionVariant, TransactionsProvider, WithdrawalsProvider, }; use alloy_eips::{ @@ -456,6 +456,12 @@ impl StateProofProvider for NoopProvider HashedPostStateProvider for NoopProvider { + fn hashed_post_state(&self, _bundle_state: &revm::db::BundleState) -> HashedPostState { + HashedPostState::default() + } +} + impl StateProvider for NoopProvider { fn storage( &self, diff --git a/crates/storage/storage-api/src/state.rs b/crates/storage/storage-api/src/state.rs index 0cb26d307434..dc53319f4c5f 100644 --- a/crates/storage/storage-api/src/state.rs +++ b/crates/storage/storage-api/src/state.rs @@ -8,7 +8,9 @@ use alloy_primitives::{Address, BlockHash, BlockNumber, StorageKey, StorageValue use auto_impl::auto_impl; use reth_primitives::Bytecode; use reth_storage_errors::provider::ProviderResult; +use reth_trie::HashedPostState; use reth_trie_db::StateCommitment; +use revm::db::states::BundleState; /// Type alias of boxed [`StateProvider`]. pub type StateProviderBox = Box; @@ -21,6 +23,7 @@ pub trait StateProvider: + StateRootProvider + StorageRootProvider + StateProofProvider + + HashedPostStateProvider + Send + Sync { @@ -83,11 +86,18 @@ pub trait StateProvider: } /// Trait implemented for database providers that can provide the [`StateCommitment`] type. -pub trait StateCommitmentProvider { +pub trait StateCommitmentProvider: Send + Sync { /// The [`StateCommitment`] type that can be used to perform state commitment operations. type StateCommitment: StateCommitment; } +/// Trait that provides the hashed state from various sources. +#[auto_impl(&, Arc, Box)] +pub trait HashedPostStateProvider: Send + Sync { + /// Returns the `HashedPostState` of the provided [`BundleState`]. + fn hashed_post_state(&self, bundle_state: &BundleState) -> HashedPostState; +} + /// Trait implemented for database providers that can be converted into a historical state provider. pub trait TryIntoHistoricalStateProvider { /// Returns a historical [`StateProvider`] indexed by the given historic block number. diff --git a/crates/trie/db/src/prefix_set.rs b/crates/trie/db/src/prefix_set.rs index ac8c3b05304c..95ff6d91f374 100644 --- a/crates/trie/db/src/prefix_set.rs +++ b/crates/trie/db/src/prefix_set.rs @@ -1,4 +1,4 @@ -use alloy_primitives::{keccak256, BlockNumber, B256}; +use alloy_primitives::{BlockNumber, B256}; use derive_more::Deref; use reth_db::tables; use reth_db_api::{ @@ -10,25 +10,34 @@ use reth_db_api::{ use reth_primitives::StorageEntry; use reth_trie::{ prefix_set::{PrefixSetMut, TriePrefixSets}, - Nibbles, + KeyHasher, Nibbles, }; use std::{ collections::{HashMap, HashSet}, + marker::PhantomData, ops::RangeInclusive, }; /// A wrapper around a database transaction that loads prefix sets within a given block range. -#[derive(Deref, Debug)] -pub struct PrefixSetLoader<'a, TX>(&'a TX); +#[derive(Debug)] +pub struct PrefixSetLoader<'a, TX, KH>(&'a TX, PhantomData); -impl<'a, TX> PrefixSetLoader<'a, TX> { +impl<'a, TX, KH> PrefixSetLoader<'a, TX, KH> { /// Create a new loader. pub const fn new(tx: &'a TX) -> Self { - Self(tx) + Self(tx, PhantomData) } } -impl PrefixSetLoader<'_, TX> { +impl Deref for PrefixSetLoader<'_, TX, KH> { + type Target = TX; + + fn deref(&self) -> &Self::Target { + self.0 + } +} + +impl PrefixSetLoader<'_, TX, KH> { /// Load all account and storage changes for the given block range. pub fn load(self, range: RangeInclusive) -> Result { // Initialize prefix sets. @@ -41,7 +50,7 @@ impl PrefixSetLoader<'_, TX> { let mut account_hashed_state_cursor = self.cursor_read::()?; for account_entry in account_changeset_cursor.walk_range(range.clone())? { let (_, AccountBeforeTx { address, .. }) = account_entry?; - let hashed_address = keccak256(address); + let hashed_address = KH::hash_key(address); account_prefix_set.insert(Nibbles::unpack(hashed_address)); if account_hashed_state_cursor.seek_exact(hashed_address)?.is_none() { @@ -55,12 +64,12 @@ impl PrefixSetLoader<'_, TX> { let storage_range = BlockNumberAddress::range(range); for storage_entry in storage_cursor.walk_range(storage_range)? { let (BlockNumberAddress((_, address)), StorageEntry { key, .. }) = storage_entry?; - let hashed_address = keccak256(address); + let hashed_address = KH::hash_key(address); account_prefix_set.insert(Nibbles::unpack(hashed_address)); storage_prefix_sets .entry(hashed_address) .or_default() - .insert(Nibbles::unpack(keccak256(key))); + .insert(Nibbles::unpack(KH::hash_key(key))); } Ok(TriePrefixSets { diff --git a/crates/trie/db/src/state.rs b/crates/trie/db/src/state.rs index 6e2cea5051d0..5aaf3ebe5b0f 100644 --- a/crates/trie/db/src/state.rs +++ b/crates/trie/db/src/state.rs @@ -1,5 +1,5 @@ use crate::{DatabaseHashedCursorFactory, DatabaseTrieCursorFactory, PrefixSetLoader}; -use alloy_primitives::{keccak256, Address, BlockNumber, B256, U256}; +use alloy_primitives::{Address, BlockNumber, B256, U256}; use reth_db::tables; use reth_db_api::{ cursor::DbCursorRO, @@ -10,7 +10,8 @@ use reth_execution_errors::StateRootError; use reth_storage_errors::db::DatabaseError; use reth_trie::{ hashed_cursor::HashedPostStateCursorFactory, trie_cursor::InMemoryTrieCursorFactory, - updates::TrieUpdates, HashedPostState, HashedStorage, StateRoot, StateRootProgress, TrieInput, + updates::TrieUpdates, HashedPostState, HashedStorage, KeccakKeyHasher, KeyHasher, StateRoot, + StateRootProgress, TrieInput, }; use std::{collections::HashMap, ops::RangeInclusive}; use tracing::debug; @@ -122,7 +123,7 @@ pub trait DatabaseStateRoot<'a, TX>: Sized { pub trait DatabaseHashedPostState: Sized { /// Initializes [`HashedPostState`] from reverts. Iterates over state reverts from the specified /// block up to the current tip and aggregates them into hashed state in reverse. - fn from_reverts(tx: &TX, from: BlockNumber) -> Result; + fn from_reverts(tx: &TX, from: BlockNumber) -> Result; } impl<'a, TX: DbTx> DatabaseStateRoot<'a, TX> @@ -136,7 +137,7 @@ impl<'a, TX: DbTx> DatabaseStateRoot<'a, TX> tx: &'a TX, range: RangeInclusive, ) -> Result { - let loaded_prefix_sets = PrefixSetLoader::new(tx).load(range)?; + let loaded_prefix_sets = PrefixSetLoader::<_, KeccakKeyHasher>::new(tx).load(range)?; Ok(Self::from_tx(tx).with_prefix_sets(loaded_prefix_sets)) } @@ -216,7 +217,7 @@ impl<'a, TX: DbTx> DatabaseStateRoot<'a, TX> } impl DatabaseHashedPostState for HashedPostState { - fn from_reverts(tx: &TX, from: BlockNumber) -> Result { + fn from_reverts(tx: &TX, from: BlockNumber) -> Result { // Iterate over account changesets and record value before first occurring account change. let mut accounts = HashMap::new(); let mut account_changesets_cursor = tx.cursor_read::()?; @@ -237,19 +238,19 @@ impl DatabaseHashedPostState for HashedPostState { } let hashed_accounts = - accounts.into_iter().map(|(address, info)| (keccak256(address), info)).collect(); + accounts.into_iter().map(|(address, info)| (KH::hash_key(address), info)).collect(); let hashed_storages = storages .into_iter() .map(|(address, storage)| { ( - keccak256(address), + KH::hash_key(address), HashedStorage::from_iter( // The `wiped` flag indicates only whether previous storage entries // should be looked up in db or not. For reverts it's a noop since all // wiped changes had been written as storage reverts. false, - storage.into_iter().map(|(slot, value)| (keccak256(slot), value)), + storage.into_iter().map(|(slot, value)| (KH::hash_key(slot), value)), ), ) }) @@ -265,6 +266,7 @@ mod tests { use alloy_primitives::{hex, map::HashMap, Address, U256}; use reth_db::test_utils::create_test_rw_db; use reth_db_api::database::Database; + use reth_trie::KeccakKeyHasher; use revm::{db::BundleState, primitives::AccountInfo}; #[test] @@ -285,7 +287,7 @@ mod tests { .build(); assert_eq!(bundle_state.reverts.len(), 1); - let post_state = HashedPostState::from_bundle_state(&bundle_state.state); + let post_state = HashedPostState::from_bundle_state::(&bundle_state.state); assert_eq!(post_state.accounts.len(), 2); assert_eq!(post_state.storages.len(), 2); diff --git a/crates/trie/parallel/src/proof.rs b/crates/trie/parallel/src/proof.rs index 94138823e005..f90a53fa99a8 100644 --- a/crates/trie/parallel/src/proof.rs +++ b/crates/trie/parallel/src/proof.rs @@ -9,6 +9,7 @@ use reth_db::DatabaseError; use reth_execution_errors::StorageRootError; use reth_provider::{ providers::ConsistentDbView, BlockReader, DBProvider, DatabaseProviderFactory, ProviderError, + StateCommitmentProvider, }; use reth_trie::{ hashed_cursor::{HashedCursorFactory, HashedPostStateCursorFactory}, @@ -53,7 +54,12 @@ impl ParallelProof { impl ParallelProof where - Factory: DatabaseProviderFactory + Clone + Send + Sync + 'static, + Factory: DatabaseProviderFactory + + StateCommitmentProvider + + Clone + + Send + + Sync + + 'static, { /// Generate a state multiproof according to specified targets. pub fn multiproof( diff --git a/crates/trie/parallel/src/root.rs b/crates/trie/parallel/src/root.rs index 8d2b18f5e111..e66d1f782132 100644 --- a/crates/trie/parallel/src/root.rs +++ b/crates/trie/parallel/src/root.rs @@ -8,6 +8,7 @@ use reth_db::DatabaseError; use reth_execution_errors::StorageRootError; use reth_provider::{ providers::ConsistentDbView, BlockReader, DBProvider, DatabaseProviderFactory, ProviderError, + StateCommitmentProvider, }; use reth_trie::{ hashed_cursor::{HashedCursorFactory, HashedPostStateCursorFactory}, @@ -58,7 +59,12 @@ impl ParallelStateRoot { impl ParallelStateRoot where - Factory: DatabaseProviderFactory + Clone + Send + Sync + 'static, + Factory: DatabaseProviderFactory + + StateCommitmentProvider + + Clone + + Send + + Sync + + 'static, { /// Calculate incremental state root in parallel. pub fn incremental_root(self) -> Result { diff --git a/crates/trie/trie/benches/hash_post_state.rs b/crates/trie/trie/benches/hash_post_state.rs index 6e913ef78a3c..7111a785f469 100644 --- a/crates/trie/trie/benches/hash_post_state.rs +++ b/crates/trie/trie/benches/hash_post_state.rs @@ -2,7 +2,7 @@ use alloy_primitives::{keccak256, map::HashMap, Address, B256, U256}; use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; use proptest::{prelude::*, strategy::ValueTree, test_runner::TestRunner}; -use reth_trie::{HashedPostState, HashedStorage}; +use reth_trie::{HashedPostState, HashedStorage, KeccakKeyHasher}; use revm::db::{states::BundleBuilder, BundleAccount}; pub fn hash_post_state(c: &mut Criterion) { @@ -19,7 +19,7 @@ pub fn hash_post_state(c: &mut Criterion) { // parallel group.bench_function(BenchmarkId::new("parallel hashing", size), |b| { - b.iter(|| HashedPostState::from_bundle_state(&state)) + b.iter(|| HashedPostState::from_bundle_state::(&state)) }); } } diff --git a/crates/trie/trie/src/state.rs b/crates/trie/trie/src/state.rs index fdfb86a53ddb..3e390bf97bcf 100644 --- a/crates/trie/trie/src/state.rs +++ b/crates/trie/trie/src/state.rs @@ -10,6 +10,7 @@ use alloy_primitives::{ use itertools::Itertools; use rayon::prelude::{IntoParallelIterator, ParallelIterator}; use reth_primitives::Account; +use reth_trie_common::KeyHasher; use revm::db::{states::CacheAccount, AccountStatus, BundleAccount}; use std::borrow::Cow; @@ -26,13 +27,13 @@ impl HashedPostState { /// Initialize [`HashedPostState`] from bundle state. /// Hashes all changed accounts and storage entries that are currently stored in the bundle /// state. - pub fn from_bundle_state<'a>( + pub fn from_bundle_state<'a, KH: KeyHasher>( state: impl IntoParallelIterator, ) -> Self { let hashed = state .into_par_iter() .map(|(address, account)| { - let hashed_address = keccak256(address); + let hashed_address = KH::hash_key(address); let hashed_account = account.info.clone().map(Into::into); let hashed_storage = HashedStorage::from_plain_storage( account.status, @@ -53,13 +54,13 @@ impl HashedPostState { /// Initialize [`HashedPostState`] from cached state. /// Hashes all changed accounts and storage entries that are currently stored in cache. - pub fn from_cache_state<'a>( + pub fn from_cache_state<'a, KH: KeyHasher>( state: impl IntoParallelIterator, ) -> Self { let hashed = state .into_par_iter() .map(|(address, account)| { - let hashed_address = keccak256(address); + let hashed_address = KH::hash_key(address); let hashed_account = account.account.as_ref().map(|a| a.info.clone().into()); let hashed_storage = HashedStorage::from_plain_storage( account.status, @@ -354,6 +355,7 @@ impl HashedStorageSorted { mod tests { use super::*; use alloy_primitives::Bytes; + use reth_trie_common::KeccakKeyHasher; use revm::{ db::{ states::{plain_account::PlainStorage, StorageSlot}, @@ -467,7 +469,7 @@ mod tests { let state = vec![(&address, &account)]; // Convert the bundle state into a hashed post state. - let hashed_state = HashedPostState::from_bundle_state(state); + let hashed_state = HashedPostState::from_bundle_state::(state); // Validate the hashed post state. assert_eq!(hashed_state.accounts.len(), 1); @@ -506,7 +508,7 @@ mod tests { let state = vec![(&address, &account)]; // Convert the cache state into a hashed post state. - let hashed_state = HashedPostState::from_cache_state(state); + let hashed_state = HashedPostState::from_cache_state::(state); // Validate the hashed post state. assert_eq!(hashed_state.accounts.len(), 1); From 0fcc6cf19eeb7139ac330d6ef58db41bfb217c83 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Tue, 3 Dec 2024 21:09:44 +0400 Subject: [PATCH 59/68] feat: Add `Transaction` AT to `ConfigureEvm` (#13106) --- Cargo.lock | 1 + crates/engine/invalid-block-hooks/src/witness.rs | 12 ++++++------ crates/engine/util/src/reorg.rs | 4 ++-- crates/ethereum/evm/src/execute.rs | 16 +++++++++++++--- crates/ethereum/evm/src/lib.rs | 1 + crates/ethereum/node/Cargo.toml | 2 -- crates/ethereum/node/src/node.rs | 6 +++--- crates/ethereum/payload/src/lib.rs | 4 ++-- crates/evm/src/lib.rs | 12 +++++++----- crates/node/api/src/node.rs | 2 +- crates/node/builder/src/components/builder.rs | 2 +- crates/node/builder/src/components/execute.rs | 6 +++--- crates/node/builder/src/components/mod.rs | 6 +++--- crates/optimism/evm/src/execute.rs | 12 ++++++++---- crates/optimism/evm/src/lib.rs | 1 + crates/optimism/node/src/node.rs | 4 ++-- crates/optimism/payload/src/builder.rs | 14 +++++++------- crates/optimism/rpc/src/eth/pending_block.rs | 4 ++-- crates/optimism/rpc/src/witness.rs | 4 ++-- crates/rpc/rpc-builder/src/lib.rs | 4 ++-- crates/rpc/rpc-eth-api/Cargo.toml | 1 + crates/rpc/rpc-eth-api/src/helpers/call.rs | 7 ++++--- .../rpc/rpc-eth-api/src/helpers/pending_block.rs | 2 +- crates/rpc/rpc/src/eth/helpers/pending_block.rs | 2 +- examples/custom-evm/src/main.rs | 2 ++ examples/stateful-precompile/src/main.rs | 1 + 26 files changed, 77 insertions(+), 55 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3448ddbd4519..855c02a22b9c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9031,6 +9031,7 @@ dependencies = [ "reth-network-api", "reth-node-api", "reth-primitives", + "reth-primitives-traits", "reth-provider", "reth-revm", "reth-rpc-eth-types", diff --git a/crates/engine/invalid-block-hooks/src/witness.rs b/crates/engine/invalid-block-hooks/src/witness.rs index cc98837a98c5..632428d6b642 100644 --- a/crates/engine/invalid-block-hooks/src/witness.rs +++ b/crates/engine/invalid-block-hooks/src/witness.rs @@ -8,8 +8,8 @@ use reth_engine_primitives::InvalidBlockHook; use reth_evm::{ state_change::post_block_balance_increments, system_calls::SystemCaller, ConfigureEvm, }; -use reth_primitives::{NodePrimitives, SealedBlockWithSenders, SealedHeader, TransactionSigned}; -use reth_primitives_traits::{HeaderTy, SignedTransaction}; +use reth_primitives::{NodePrimitives, SealedBlockWithSenders, SealedHeader}; +use reth_primitives_traits::SignedTransaction; use reth_provider::{BlockExecutionOutput, ChainSpecProvider, StateProviderFactory}; use reth_revm::{ database::StateProviderDatabase, db::states::bundle_state::BundleRetention, @@ -63,8 +63,8 @@ where trie_updates: Option<(&TrieUpdates, B256)>, ) -> eyre::Result<()> where - N: NodePrimitives, - EvmConfig: ConfigureEvm

, + N: NodePrimitives, + EvmConfig: ConfigureEvm
, { // TODO(alexey): unify with `DebugApi::debug_execution_witness` @@ -298,13 +298,13 @@ where impl InvalidBlockHook for InvalidBlockWitnessHook where - N: NodePrimitives, + N: NodePrimitives, P: StateProviderFactory + ChainSpecProvider + Send + Sync + 'static, - EvmConfig: ConfigureEvm
>, + EvmConfig: ConfigureEvm
, { fn on_invalid_block( &self, diff --git a/crates/engine/util/src/reorg.rs b/crates/engine/util/src/reorg.rs index 4f7e213b058c..24e141622842 100644 --- a/crates/engine/util/src/reorg.rs +++ b/crates/engine/util/src/reorg.rs @@ -110,7 +110,7 @@ where S: Stream>, Engine: EngineTypes, Provider: BlockReader + StateProviderFactory, - Evm: ConfigureEvm
, + Evm: ConfigureEvm
, Spec: EthereumHardforks, { type Item = S::Item; @@ -257,7 +257,7 @@ fn create_reorg_head( ) -> RethResult<(ExecutionPayload, ExecutionPayloadSidecar)> where Provider: BlockReader + StateProviderFactory, - Evm: ConfigureEvm
, + Evm: ConfigureEvm
, Spec: EthereumHardforks, { let chain_spec = payload_validator.chain_spec(); diff --git a/crates/ethereum/evm/src/execute.rs b/crates/ethereum/evm/src/execute.rs index e21b42433ddb..6cbbb69c906b 100644 --- a/crates/ethereum/evm/src/execute.rs +++ b/crates/ethereum/evm/src/execute.rs @@ -58,8 +58,15 @@ impl EthExecutionStrategyFactory { impl BlockExecutionStrategyFactory for EthExecutionStrategyFactory where - EvmConfig: - Clone + Unpin + Sync + Send + 'static + ConfigureEvm
, + EvmConfig: Clone + + Unpin + + Sync + + Send + + 'static + + ConfigureEvm< + Header = alloy_consensus::Header, + Transaction = reth_primitives::TransactionSigned, + >, { type Primitives = EthPrimitives; @@ -128,7 +135,10 @@ where impl BlockExecutionStrategy for EthExecutionStrategy where DB: Database + Display>, - EvmConfig: ConfigureEvm
, + EvmConfig: ConfigureEvm< + Header = alloy_consensus::Header, + Transaction = reth_primitives::TransactionSigned, + >, { type DB = DB; type Error = BlockExecutionError; diff --git a/crates/ethereum/evm/src/lib.rs b/crates/ethereum/evm/src/lib.rs index 8042562357f4..509b61cb2ece 100644 --- a/crates/ethereum/evm/src/lib.rs +++ b/crates/ethereum/evm/src/lib.rs @@ -62,6 +62,7 @@ impl EthEvmConfig { impl ConfigureEvmEnv for EthEvmConfig { type Header = Header; + type Transaction = TransactionSigned; type Error = Infallible; fn fill_tx_env(&self, tx_env: &mut TxEnv, transaction: &TransactionSigned, sender: Address) { diff --git a/crates/ethereum/node/Cargo.toml b/crates/ethereum/node/Cargo.toml index 55421cf8478d..f5fe1dac234c 100644 --- a/crates/ethereum/node/Cargo.toml +++ b/crates/ethereum/node/Cargo.toml @@ -32,8 +32,6 @@ reth-primitives.workspace = true reth-revm = { workspace = true, features = ["std"] } reth-trie-db.workspace = true -alloy-consensus.workspace = true - # revm with required ethereum features revm = { workspace = true, features = ["secp256k1", "blst", "c-kzg"] } diff --git a/crates/ethereum/node/src/node.rs b/crates/ethereum/node/src/node.rs index 58b6aeaf6447..dd4f1e5802c8 100644 --- a/crates/ethereum/node/src/node.rs +++ b/crates/ethereum/node/src/node.rs @@ -2,7 +2,6 @@ use std::sync::Arc; -use alloy_consensus::Header; use reth_basic_payload_builder::{BasicPayloadJobGenerator, BasicPayloadJobGeneratorConfig}; use reth_beacon_consensus::EthBeaconConsensus; use reth_chainspec::ChainSpec; @@ -13,7 +12,8 @@ use reth_evm::execute::BasicBlockExecutorProvider; use reth_evm_ethereum::execute::EthExecutionStrategyFactory; use reth_network::{NetworkHandle, PeersInfo}; use reth_node_api::{ - AddOnsContext, ConfigureEvm, EngineValidator, FullNodeComponents, NodeTypesWithDB, TxTy, + AddOnsContext, ConfigureEvm, EngineValidator, FullNodeComponents, HeaderTy, NodeTypesWithDB, + TxTy, }; use reth_node_builder::{ components::{ @@ -242,7 +242,7 @@ impl EthereumPayloadBuilder { where Types: NodeTypesWithEngine, Node: FullNodeTypes, - Evm: ConfigureEvm
, + Evm: ConfigureEvm
, Transaction = TxTy>, Pool: TransactionPool>> + Unpin + 'static, diff --git a/crates/ethereum/payload/src/lib.rs b/crates/ethereum/payload/src/lib.rs index a5e6bcaa5f00..f909d3840e22 100644 --- a/crates/ethereum/payload/src/lib.rs +++ b/crates/ethereum/payload/src/lib.rs @@ -91,7 +91,7 @@ where // Default implementation of [PayloadBuilder] for unit type impl PayloadBuilder for EthereumPayloadBuilder where - EvmConfig: ConfigureEvm
, + EvmConfig: ConfigureEvm
, Client: StateProviderFactory + ChainSpecProvider, Pool: TransactionPool>, { @@ -155,7 +155,7 @@ pub fn default_ethereum_payload( best_txs: F, ) -> Result, PayloadBuilderError> where - EvmConfig: ConfigureEvm
, + EvmConfig: ConfigureEvm
, Client: StateProviderFactory + ChainSpecProvider, Pool: TransactionPool>, F: FnOnce(BestTransactionsAttributes) -> BestTransactionsIter, diff --git a/crates/evm/src/lib.rs b/crates/evm/src/lib.rs index ae884bdd5f86..29f6d7c65817 100644 --- a/crates/evm/src/lib.rs +++ b/crates/evm/src/lib.rs @@ -20,7 +20,6 @@ extern crate alloc; use crate::builder::RethEvmBuilder; use alloy_consensus::BlockHeader as _; use alloy_primitives::{Address, Bytes, B256, U256}; -use reth_primitives::TransactionSigned; use reth_primitives_traits::BlockHeader; use revm::{Database, Evm, GetInspector}; use revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg, Env, EnvWithHandlerCfg, SpecId, TxEnv}; @@ -116,18 +115,21 @@ pub trait ConfigureEvmEnv: Send + Sync + Unpin + Clone + 'static { /// The header type used by the EVM. type Header: BlockHeader; + /// The transaction type. + type Transaction; + /// The error type that is returned by [`Self::next_cfg_and_block_env`]. type Error: core::error::Error + Send + Sync; - /// Returns a [`TxEnv`] from a [`TransactionSigned`] and [`Address`]. - fn tx_env(&self, transaction: &TransactionSigned, signer: Address) -> TxEnv { + /// Returns a [`TxEnv`] from a transaction and [`Address`]. + fn tx_env(&self, transaction: &Self::Transaction, signer: Address) -> TxEnv { let mut tx_env = TxEnv::default(); self.fill_tx_env(&mut tx_env, transaction, signer); tx_env } - /// Fill transaction environment from a [`TransactionSigned`] and the given sender address. - fn fill_tx_env(&self, tx_env: &mut TxEnv, transaction: &TransactionSigned, sender: Address); + /// Fill transaction environment from a transaction and the given sender address. + fn fill_tx_env(&self, tx_env: &mut TxEnv, transaction: &Self::Transaction, sender: Address); /// Fill transaction environment with a system contract call. fn fill_tx_env_system_contract_call( diff --git a/crates/node/api/src/node.rs b/crates/node/api/src/node.rs index 1b490c4cf416..fc6366a2eb5d 100644 --- a/crates/node/api/src/node.rs +++ b/crates/node/api/src/node.rs @@ -49,7 +49,7 @@ pub trait FullNodeComponents: FullNodeTypes + Clone + 'static { type Pool: TransactionPool>> + Unpin; /// The node's EVM configuration, defining settings for the Ethereum Virtual Machine. - type Evm: ConfigureEvm
>; + type Evm: ConfigureEvm
, Transaction = TxTy>; /// The type that knows how to execute blocks. type Executor: BlockExecutorProvider::Primitives>; diff --git a/crates/node/builder/src/components/builder.rs b/crates/node/builder/src/components/builder.rs index 15f6c12319ff..7e2d0eb43cc0 100644 --- a/crates/node/builder/src/components/builder.rs +++ b/crates/node/builder/src/components/builder.rs @@ -377,7 +377,7 @@ where Pool: TransactionPool>> + Unpin + 'static, - EVM: ConfigureEvm
>, + EVM: ConfigureEvm
, Transaction = TxTy>, Executor: BlockExecutorProvider::Primitives>, Cons: FullConsensus<::Primitives> + Clone + Unpin + 'static, { diff --git a/crates/node/builder/src/components/execute.rs b/crates/node/builder/src/components/execute.rs index 5ecc67d8b764..e3226fa8e371 100644 --- a/crates/node/builder/src/components/execute.rs +++ b/crates/node/builder/src/components/execute.rs @@ -1,7 +1,7 @@ //! EVM component for the node builder. use crate::{BuilderContext, FullNodeTypes}; use reth_evm::execute::BlockExecutorProvider; -use reth_node_api::{ConfigureEvm, HeaderTy}; +use reth_node_api::{ConfigureEvm, HeaderTy, TxTy}; use std::future::Future; /// A type that knows how to build the executor types. @@ -9,7 +9,7 @@ pub trait ExecutorBuilder: Send { /// The EVM config to use. /// /// This provides the node with the necessary configuration to configure an EVM. - type EVM: ConfigureEvm
>; + type EVM: ConfigureEvm
, Transaction = TxTy>; /// The type that knows how to execute blocks. type Executor: BlockExecutorProvider< @@ -26,7 +26,7 @@ pub trait ExecutorBuilder: Send { impl ExecutorBuilder for F where Node: FullNodeTypes, - EVM: ConfigureEvm
>, + EVM: ConfigureEvm
, Transaction = TxTy>, Executor: BlockExecutorProvider::Primitives>, F: FnOnce(&BuilderContext) -> Fut + Send, diff --git a/crates/node/builder/src/components/mod.rs b/crates/node/builder/src/components/mod.rs index 764277dcbf27..b643e2aa2a65 100644 --- a/crates/node/builder/src/components/mod.rs +++ b/crates/node/builder/src/components/mod.rs @@ -40,7 +40,7 @@ pub trait NodeComponents: Clone + Unpin + Send + Sync + 'stati type Pool: TransactionPool>> + Unpin; /// The node's EVM configuration, defining settings for the Ethereum Virtual Machine. - type Evm: ConfigureEvm
>; + type Evm: ConfigureEvm
, Transaction = TxTy>; /// The type that knows how to execute blocks. type Executor: BlockExecutorProvider::Primitives>; @@ -99,7 +99,7 @@ where Pool: TransactionPool>> + Unpin + 'static, - EVM: ConfigureEvm
>, + EVM: ConfigureEvm
, Transaction = TxTy>, Executor: BlockExecutorProvider::Primitives>, Cons: FullConsensus<::Primitives> + Clone + Unpin + 'static, { @@ -139,7 +139,7 @@ impl Clone for Components>, + EVM: ConfigureEvm
, Transaction = TxTy>, Executor: BlockExecutorProvider, Cons: Clone, { diff --git a/crates/optimism/evm/src/execute.rs b/crates/optimism/evm/src/execute.rs index 3673f73a894b..205c85160dcd 100644 --- a/crates/optimism/evm/src/execute.rs +++ b/crates/optimism/evm/src/execute.rs @@ -22,7 +22,7 @@ use reth_optimism_chainspec::OpChainSpec; use reth_optimism_consensus::validate_block_post_execution; use reth_optimism_forks::OpHardfork; use reth_optimism_primitives::OpPrimitives; -use reth_primitives::{BlockWithSenders, Receipt, TxType}; +use reth_primitives::{BlockWithSenders, Receipt, TransactionSigned, TxType}; use reth_revm::{Database, State}; use revm_primitives::{db::DatabaseCommit, EnvWithHandlerCfg, ResultAndState, U256}; use tracing::trace; @@ -52,8 +52,12 @@ impl OpExecutionStrategyFactory { impl BlockExecutionStrategyFactory for OpExecutionStrategyFactory where - EvmConfig: - Clone + Unpin + Sync + Send + 'static + ConfigureEvm
, + EvmConfig: Clone + + Unpin + + Sync + + Send + + 'static + + ConfigureEvm
, { type Primitives = OpPrimitives; type Strategy + Display>> = @@ -115,7 +119,7 @@ where impl BlockExecutionStrategy for OpExecutionStrategy where DB: Database + Display>, - EvmConfig: ConfigureEvm
, + EvmConfig: ConfigureEvm
, { type DB = DB; type Primitives = OpPrimitives; diff --git a/crates/optimism/evm/src/lib.rs b/crates/optimism/evm/src/lib.rs index 176864de6dc5..7424379f5ae7 100644 --- a/crates/optimism/evm/src/lib.rs +++ b/crates/optimism/evm/src/lib.rs @@ -57,6 +57,7 @@ impl OpEvmConfig { impl ConfigureEvmEnv for OpEvmConfig { type Header = Header; + type Transaction = TransactionSigned; type Error = DecodeError; fn fill_tx_env(&self, tx_env: &mut TxEnv, transaction: &TransactionSigned, sender: Address) { diff --git a/crates/optimism/node/src/node.rs b/crates/optimism/node/src/node.rs index a13ab9dcec16..b2203331ddfa 100644 --- a/crates/optimism/node/src/node.rs +++ b/crates/optimism/node/src/node.rs @@ -34,7 +34,7 @@ use reth_optimism_rpc::{ OpEthApi, SequencerClient, }; use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService}; -use reth_primitives::BlockBody; +use reth_primitives::{BlockBody, TransactionSigned}; use reth_provider::{ providers::ChainStorage, BlockBodyReader, BlockBodyWriter, CanonStateSubscriptions, ChainSpecProvider, DBProvider, EthStorage, ProviderResult, ReadBodyInput, @@ -468,7 +468,7 @@ where Pool: TransactionPool>> + Unpin + 'static, - Evm: ConfigureEvm
, + Evm: ConfigureEvm
, { let payload_builder = reth_optimism_payload_builder::OpPayloadBuilder::new(evm_config) .with_transactions(self.best_transactions) diff --git a/crates/optimism/payload/src/builder.rs b/crates/optimism/payload/src/builder.rs index 91e70d0c3c8b..f370ed496f04 100644 --- a/crates/optimism/payload/src/builder.rs +++ b/crates/optimism/payload/src/builder.rs @@ -98,7 +98,7 @@ impl OpPayloadBuilder { } impl OpPayloadBuilder where - EvmConfig: ConfigureEvm
, + EvmConfig: ConfigureEvm
, Txs: OpPayloadTransactions, { /// Constructs an Optimism payload from the transactions sent via the @@ -155,7 +155,7 @@ where impl OpPayloadBuilder where - EvmConfig: ConfigureEvm
, + EvmConfig: ConfigureEvm
, { /// Returns the configured [`CfgEnvWithHandlerCfg`] and [`BlockEnv`] for the targeted payload /// (that has the `parent` as its parent). @@ -217,7 +217,7 @@ impl PayloadBuilder for OpPayloadBui where Client: StateProviderFactory + ChainSpecProvider, Pool: TransactionPool>, - EvmConfig: ConfigureEvm
, + EvmConfig: ConfigureEvm
, Txs: OpPayloadTransactions, { type Attributes = OpPayloadBuilderAttributes; @@ -294,7 +294,7 @@ where ctx: &OpPayloadBuilderCtx, ) -> Result, PayloadBuilderError> where - EvmConfig: ConfigureEvm
, + EvmConfig: ConfigureEvm
, DB: Database, { let Self { pool, best } = self; @@ -339,7 +339,7 @@ where ctx: OpPayloadBuilderCtx, ) -> Result, PayloadBuilderError> where - EvmConfig: ConfigureEvm
, + EvmConfig: ConfigureEvm
, DB: Database + AsRef

, P: StateRootProvider + HashedPostStateProvider, { @@ -465,7 +465,7 @@ where ctx: &OpPayloadBuilderCtx, ) -> Result where - EvmConfig: ConfigureEvm

, + EvmConfig: ConfigureEvm
, DB: Database + AsRef

, P: StateProofProvider, { @@ -700,7 +700,7 @@ impl OpPayloadBuilderCtx { impl OpPayloadBuilderCtx where - EvmConfig: ConfigureEvm

, + EvmConfig: ConfigureEvm
, { /// apply eip-4788 pre block contract call pub fn apply_pre_beacon_root_contract_call( diff --git a/crates/optimism/rpc/src/eth/pending_block.rs b/crates/optimism/rpc/src/eth/pending_block.rs index 9a8d169e5270..eebb61c8cb02 100644 --- a/crates/optimism/rpc/src/eth/pending_block.rs +++ b/crates/optimism/rpc/src/eth/pending_block.rs @@ -7,7 +7,7 @@ use alloy_primitives::{BlockNumber, B256}; use reth_chainspec::{EthChainSpec, EthereumHardforks}; use reth_evm::ConfigureEvm; use reth_optimism_consensus::calculate_receipt_root_no_memo_optimism; -use reth_primitives::{Receipt, SealedBlockWithSenders}; +use reth_primitives::{Receipt, SealedBlockWithSenders, TransactionSigned}; use reth_provider::{ BlockReader, BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, ExecutionOutcome, ProviderTx, ReceiptProvider, StateProviderFactory, @@ -33,7 +33,7 @@ where + ChainSpecProvider + StateProviderFactory, Pool: TransactionPool>>, - Evm: ConfigureEvm
, + Evm: ConfigureEvm
, >, { #[inline] diff --git a/crates/optimism/rpc/src/witness.rs b/crates/optimism/rpc/src/witness.rs index 278c785cbe9a..8cc4bd98ef25 100644 --- a/crates/optimism/rpc/src/witness.rs +++ b/crates/optimism/rpc/src/witness.rs @@ -9,7 +9,7 @@ use reth_chainspec::ChainSpecProvider; use reth_evm::ConfigureEvm; use reth_optimism_chainspec::OpChainSpec; use reth_optimism_payload_builder::OpPayloadBuilder; -use reth_primitives::SealedHeader; +use reth_primitives::{SealedHeader, TransactionSigned}; use reth_provider::{BlockReaderIdExt, ProviderError, ProviderResult, StateProviderFactory}; pub use reth_rpc_api::DebugExecutionWitnessApiServer; use reth_rpc_server_types::{result::internal_rpc_err, ToRpcResult}; @@ -49,7 +49,7 @@ where + StateProviderFactory + ChainSpecProvider + 'static, - EvmConfig: ConfigureEvm
+ 'static, + EvmConfig: ConfigureEvm
+ 'static, { fn execute_payload( &self, diff --git a/crates/rpc/rpc-builder/src/lib.rs b/crates/rpc/rpc-builder/src/lib.rs index 0b9a84a5b987..031f960096fa 100644 --- a/crates/rpc/rpc-builder/src/lib.rs +++ b/crates/rpc/rpc-builder/src/lib.rs @@ -50,7 +50,7 @@ //! Network: NetworkInfo + Peers + Clone + 'static, //! Events: //! CanonStateSubscriptions + Clone + 'static, -//! EvmConfig: ConfigureEvm
, +//! EvmConfig: ConfigureEvm
, //! BlockExecutor: BlockExecutorProvider, //! Consensus: reth_consensus::FullConsensus + Clone + 'static, //! { @@ -135,7 +135,7 @@ //! CanonStateSubscriptions + Clone + 'static, //! EngineApi: EngineApiServer, //! EngineT: EngineTypes, -//! EvmConfig: ConfigureEvm
, +//! EvmConfig: ConfigureEvm
, //! BlockExecutor: BlockExecutorProvider, //! Consensus: reth_consensus::FullConsensus + Clone + 'static, //! { diff --git a/crates/rpc/rpc-eth-api/Cargo.toml b/crates/rpc/rpc-eth-api/Cargo.toml index cf701187dad3..bffd4fa308ec 100644 --- a/crates/rpc/rpc-eth-api/Cargo.toml +++ b/crates/rpc/rpc-eth-api/Cargo.toml @@ -16,6 +16,7 @@ workspace = true revm.workspace = true revm-inspectors.workspace = true revm-primitives = { workspace = true, features = ["dev"] } +reth-primitives-traits.workspace = true reth-errors.workspace = true reth-evm.workspace = true reth-primitives.workspace = true diff --git a/crates/rpc/rpc-eth-api/src/helpers/call.rs b/crates/rpc/rpc-eth-api/src/helpers/call.rs index f9441f0630ab..aaa2ce131c9c 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/call.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/call.rs @@ -19,7 +19,7 @@ use futures::Future; use reth_chainspec::EthChainSpec; use reth_evm::{ConfigureEvm, ConfigureEvmEnv}; use reth_node_api::BlockBody; -use reth_primitives::TransactionSigned; +use reth_primitives_traits::SignedTransaction; use reth_provider::{BlockIdReader, ChainSpecProvider, HeaderProvider}; use reth_revm::{ database::StateProviderDatabase, @@ -664,14 +664,15 @@ pub trait Call: LoadState> + SpawnBlocking { where DB: Database + DatabaseCommit, EthApiError: From, - I: IntoIterator, + I: IntoIterator::Transaction)>, + ::Transaction: SignedTransaction, { let env = EnvWithHandlerCfg::new_with_cfg_env(cfg, block_env, Default::default()); let mut evm = self.evm_config().evm_with_env(db, env); let mut index = 0; for (sender, tx) in transactions { - if tx.hash() == target_tx_hash { + if *tx.tx_hash() == target_tx_hash { // reached the target transaction break } diff --git a/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs b/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs index 4c81626649d9..c5bb0994607c 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs @@ -56,7 +56,7 @@ pub trait LoadPendingBlock: + ChainSpecProvider + StateProviderFactory, Pool: TransactionPool>>, - Evm: ConfigureEvm
, + Evm: ConfigureEvm
>, > { /// Returns a handle to the pending block. diff --git a/crates/rpc/rpc/src/eth/helpers/pending_block.rs b/crates/rpc/rpc/src/eth/helpers/pending_block.rs index 34c0ae962613..afd69a2f4041 100644 --- a/crates/rpc/rpc/src/eth/helpers/pending_block.rs +++ b/crates/rpc/rpc/src/eth/helpers/pending_block.rs @@ -31,7 +31,7 @@ where Pool: TransactionPool< Transaction: PoolTransaction>, >, - Evm: ConfigureEvm
, + Evm: ConfigureEvm
>, >, { #[inline] diff --git a/examples/custom-evm/src/main.rs b/examples/custom-evm/src/main.rs index d9e341c02cc4..8990ba2252ec 100644 --- a/examples/custom-evm/src/main.rs +++ b/examples/custom-evm/src/main.rs @@ -84,6 +84,8 @@ impl MyEvmConfig { impl ConfigureEvmEnv for MyEvmConfig { type Header = Header; + type Transaction = TransactionSigned; + type Error = Infallible; fn fill_tx_env(&self, tx_env: &mut TxEnv, transaction: &TransactionSigned, sender: Address) { diff --git a/examples/stateful-precompile/src/main.rs b/examples/stateful-precompile/src/main.rs index 29d5051434bf..03ed1fa69433 100644 --- a/examples/stateful-precompile/src/main.rs +++ b/examples/stateful-precompile/src/main.rs @@ -148,6 +148,7 @@ impl StatefulPrecompileMut for WrappedPrecompile { impl ConfigureEvmEnv for MyEvmConfig { type Header = Header; + type Transaction = TransactionSigned; type Error = Infallible; fn fill_tx_env(&self, tx_env: &mut TxEnv, transaction: &TransactionSigned, sender: Address) { From 35cfd41863e6c865f464353b0fb8b67337be0f86 Mon Sep 17 00:00:00 2001 From: Dan Cline <6798349+Rjected@users.noreply.github.com> Date: Tue, 3 Dec 2024 15:55:04 -0500 Subject: [PATCH 60/68] feat: make `import_transactions` use network generics (#13110) --- crates/net/eth-wire-types/src/primitives.rs | 6 ++- crates/net/network/src/transactions/mod.rs | 43 ++++++++++----------- 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/crates/net/eth-wire-types/src/primitives.rs b/crates/net/eth-wire-types/src/primitives.rs index ff7ab1c801bd..1b0c16c0622d 100644 --- a/crates/net/eth-wire-types/src/primitives.rs +++ b/crates/net/eth-wire-types/src/primitives.rs @@ -21,6 +21,7 @@ pub trait NetworkPrimitives: + PartialEq + Eq + 'static; + /// The block body type. type BlockBody: Encodable + Decodable @@ -32,6 +33,7 @@ pub trait NetworkPrimitives: + PartialEq + Eq + 'static; + /// Full block type. type Block: Block
+ Encodable @@ -58,8 +60,10 @@ pub trait NetworkPrimitives: + PartialEq + Eq + 'static; + /// The transaction type which peers return in `PooledTransactions` messages. - type PooledTransaction: Encodable + type PooledTransaction: TryFrom + + Encodable + Decodable + Send + Sync diff --git a/crates/net/network/src/transactions/mod.rs b/crates/net/network/src/transactions/mod.rs index b352dfe31366..4a7167a8064f 100644 --- a/crates/net/network/src/transactions/mod.rs +++ b/crates/net/network/src/transactions/mod.rs @@ -48,7 +48,10 @@ use reth_network_p2p::{ }; use reth_network_peers::PeerId; use reth_network_types::ReputationChangeKind; -use reth_primitives::{PooledTransactionsElement, TransactionSigned}; +use reth_primitives::{ + transaction::SignedTransactionIntoRecoveredExt, PooledTransactionsElement, RecoveredTx, + TransactionSigned, +}; use reth_primitives_traits::{SignedTransaction, TxType}; use reth_tokio_util::EventStream; use reth_transaction_pool::{ @@ -272,7 +275,7 @@ pub struct TransactionsManager, /// Incoming events from the [`NetworkManager`](crate::NetworkManager). - transaction_events: UnboundedMeteredReceiver, + transaction_events: UnboundedMeteredReceiver>, /// How the `TransactionsManager` is configured. config: TransactionsManagerConfig, /// `TransactionsManager` metrics @@ -697,13 +700,15 @@ where impl TransactionsManager where - Pool: TransactionPool, + Pool: TransactionPool + 'static, N: NetworkPrimitives< BroadcastedTransaction: SignedTransaction, PooledTransaction: SignedTransaction, >, - Pool::Transaction: - PoolTransaction>, + Pool::Transaction: PoolTransaction< + Consensus = N::BroadcastedTransaction, + Pooled: Into + From>, + >, { /// Invoked when transactions in the local mempool are considered __pending__. /// @@ -1099,16 +1104,9 @@ where _ => {} } } -} -impl TransactionsManager -where - Pool: TransactionPool + 'static, - Pool::Transaction: - PoolTransaction>, -{ /// Handles dedicated transaction events related to the `eth` protocol. - fn on_network_tx_event(&mut self, event: NetworkTransactionEvent) { + fn on_network_tx_event(&mut self, event: NetworkTransactionEvent) { match event { NetworkTransactionEvent::IncomingTransactions { peer_id, msg } => { // ensure we didn't receive any blob transactions as these are disallowed to be @@ -1119,7 +1117,7 @@ where let non_blob_txs = msg .0 .into_iter() - .map(PooledTransactionsElement::try_from_broadcast) + .map(N::PooledTransaction::try_from) .filter_map(Result::ok) .collect(); @@ -1146,7 +1144,7 @@ where fn import_transactions( &mut self, peer_id: PeerId, - transactions: PooledTransactions, + transactions: PooledTransactions, source: TransactionSource, ) { // If the node is pipeline syncing, ignore transactions @@ -1162,7 +1160,7 @@ where // mark the transactions as received self.transaction_fetcher - .remove_hashes_from_transaction_fetcher(transactions.iter().map(|tx| *tx.hash())); + .remove_hashes_from_transaction_fetcher(transactions.iter().map(|tx| *tx.tx_hash())); // track that the peer knows these transaction, but only if this is a new broadcast. // If we received the transactions as the response to our `GetPooledTransactions`` @@ -1170,7 +1168,7 @@ where // recorded the hashes as seen by this peer in `Self::on_new_pooled_transaction_hashes`. let mut num_already_seen_by_peer = 0; for tx in &transactions { - if source.is_broadcast() && !peer.seen_transactions.insert(*tx.hash()) { + if source.is_broadcast() && !peer.seen_transactions.insert(*tx.tx_hash()) { num_already_seen_by_peer += 1; } } @@ -1199,7 +1197,7 @@ where Err(badtx) => { trace!(target: "net::tx", peer_id=format!("{peer_id:#}"), - hash=%badtx.hash(), + hash=%badtx.tx_hash(), client_version=%peer.client_version, "failed ecrecovery for transaction" ); @@ -1208,22 +1206,23 @@ where } }; - match self.transactions_by_peers.entry(*tx.hash()) { + match self.transactions_by_peers.entry(*tx.tx_hash()) { Entry::Occupied(mut entry) => { // transaction was already inserted entry.get_mut().insert(peer_id); } Entry::Vacant(entry) => { - if self.bad_imports.contains(tx.hash()) { + if self.bad_imports.contains(tx.tx_hash()) { trace!(target: "net::tx", peer_id=format!("{peer_id:#}"), - hash=%tx.hash(), + hash=%tx.tx_hash(), client_version=%peer.client_version, "received a known bad transaction from peer" ); has_bad_transactions = true; } else { // this is a new transaction that should be imported into the pool + let pool_transaction = Pool::Transaction::from_pooled(tx.into()); new_txs.push(pool_transaction); @@ -1285,7 +1284,7 @@ where } /// Processes a [`FetchEvent`]. - fn on_fetch_event(&mut self, fetch_event: FetchEvent) { + fn on_fetch_event(&mut self, fetch_event: FetchEvent) { match fetch_event { FetchEvent::TransactionsFetched { peer_id, transactions } => { self.import_transactions(peer_id, transactions, TransactionSource::Response); From e9484b2437fa6d0bb9516d161afa1a4fdfe1422d Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Tue, 3 Dec 2024 21:55:08 +0100 Subject: [PATCH 61/68] chore: remove redundant enum (#13113) --- crates/rpc/rpc-engine-api/src/lib.rs | 4 ---- crates/rpc/rpc-engine-api/src/message.rs | 14 -------------- 2 files changed, 18 deletions(-) delete mode 100644 crates/rpc/rpc-engine-api/src/message.rs diff --git a/crates/rpc/rpc-engine-api/src/lib.rs b/crates/rpc/rpc-engine-api/src/lib.rs index a2da00eee702..a9305a00820b 100644 --- a/crates/rpc/rpc-engine-api/src/lib.rs +++ b/crates/rpc/rpc-engine-api/src/lib.rs @@ -15,9 +15,6 @@ mod engine_api; /// Engine API capabilities. pub mod capabilities; -/// The Engine API message type. -mod message; - /// Engine API error. mod error; @@ -26,7 +23,6 @@ mod metrics; pub use engine_api::{EngineApi, EngineApiSender}; pub use error::*; -pub use message::EngineApiMessageVersion; // re-export server trait for convenience pub use reth_rpc_api::EngineApiServer; diff --git a/crates/rpc/rpc-engine-api/src/message.rs b/crates/rpc/rpc-engine-api/src/message.rs deleted file mode 100644 index c0d6b85d5118..000000000000 --- a/crates/rpc/rpc-engine-api/src/message.rs +++ /dev/null @@ -1,14 +0,0 @@ -/// The version of Engine API message. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum EngineApiMessageVersion { - /// Version 1 - V1, - /// Version 2 - /// - /// Added for shanghai hardfork. - V2, - /// Version 3 - /// - /// Added for cancun hardfork. - V3, -} From 601e8b9147ac720849dbb2888549c4190762aa9c Mon Sep 17 00:00:00 2001 From: Dan Cline <6798349+Rjected@users.noreply.github.com> Date: Tue, 3 Dec 2024 17:06:29 -0500 Subject: [PATCH 62/68] feat: make TransactionsManager Future impl generic over NetworkPrimitives (#13115) --- crates/net/eth-wire-types/src/primitives.rs | 14 +------ .../net/network/src/transactions/fetcher.rs | 39 ++++++++++--------- crates/net/network/src/transactions/mod.rs | 15 ++++--- 3 files changed, 33 insertions(+), 35 deletions(-) diff --git a/crates/net/eth-wire-types/src/primitives.rs b/crates/net/eth-wire-types/src/primitives.rs index 1b0c16c0622d..78083e9e0928 100644 --- a/crates/net/eth-wire-types/src/primitives.rs +++ b/crates/net/eth-wire-types/src/primitives.rs @@ -1,7 +1,7 @@ //! Abstraction over primitive types in network messages. use alloy_rlp::{Decodable, Encodable}; -use reth_primitives_traits::{Block, BlockHeader}; +use reth_primitives_traits::{Block, BlockHeader, SignedTransaction}; use std::fmt::Debug; /// Abstraction over primitive types which might appear in network messages. See @@ -62,17 +62,7 @@ pub trait NetworkPrimitives: + 'static; /// The transaction type which peers return in `PooledTransactions` messages. - type PooledTransaction: TryFrom - + Encodable - + Decodable - + Send - + Sync - + Unpin - + Clone - + Debug - + PartialEq - + Eq - + 'static; + type PooledTransaction: SignedTransaction + TryFrom + 'static; /// The transaction type which peers return in `GetReceipts` messages. type Receipt: Encodable diff --git a/crates/net/network/src/transactions/fetcher.rs b/crates/net/network/src/transactions/fetcher.rs index 180a619fff9e..025ae36ea142 100644 --- a/crates/net/network/src/transactions/fetcher.rs +++ b/crates/net/network/src/transactions/fetcher.rs @@ -50,6 +50,7 @@ use reth_network_api::PeerRequest; use reth_network_p2p::error::{RequestError, RequestResult}; use reth_network_peers::PeerId; use reth_primitives::PooledTransactionsElement; +use reth_primitives_traits::SignedTransaction; use schnellru::ByLength; #[cfg(debug_assertions)] use smallvec::{smallvec, SmallVec}; @@ -895,16 +896,14 @@ impl TransactionFetcher { approx_capacity_get_pooled_transactions_req_eth66() } } -} -impl TransactionFetcher { /// Processes a resolved [`GetPooledTransactions`] request. Queues the outcome as a /// [`FetchEvent`], which will then be streamed by /// [`TransactionsManager`](super::TransactionsManager). pub fn on_resolved_get_pooled_transactions_request_fut( &mut self, - response: GetPooledTxResponse, - ) -> FetchEvent { + response: GetPooledTxResponse, + ) -> FetchEvent { // update peer activity, requests for buffered hashes can only be made to idle // fallback peers let GetPooledTxResponse { peer_id, mut requested_hashes, result } = response; @@ -1026,8 +1025,8 @@ impl TransactionFetcher { } } -impl Stream for TransactionFetcher { - type Item = FetchEvent; +impl Stream for TransactionFetcher { + type Item = FetchEvent; /// Advances all inflight requests and returns the next event. fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { @@ -1176,18 +1175,18 @@ impl Future for GetPooledTxRequestFut { /// Wrapper of unverified [`PooledTransactions`]. #[derive(Debug, Constructor, Deref)] -pub struct UnverifiedPooledTransactions { - txns: PooledTransactions, +pub struct UnverifiedPooledTransactions { + txns: PooledTransactions, } /// [`PooledTransactions`] that have been successfully verified. #[derive(Debug, Constructor, Deref)] -pub struct VerifiedPooledTransactions { - txns: PooledTransactions, +pub struct VerifiedPooledTransactions { + txns: PooledTransactions, } -impl DedupPayload for VerifiedPooledTransactions { - type Value = PooledTransactionsElement; +impl DedupPayload for VerifiedPooledTransactions { + type Value = T; fn is_empty(&self) -> bool { self.txns.is_empty() @@ -1199,26 +1198,30 @@ impl DedupPayload for VerifiedPooledTransactions { fn dedup(self) -> PartiallyValidData { PartiallyValidData::from_raw_data( - self.txns.into_iter().map(|tx| (*tx.hash(), tx)).collect(), + self.txns.into_iter().map(|tx| (*tx.tx_hash(), tx)).collect(), None, ) } } trait VerifyPooledTransactionsResponse { + type Transaction: SignedTransaction; + fn verify( self, requested_hashes: &RequestTxHashes, peer_id: &PeerId, - ) -> (VerificationOutcome, VerifiedPooledTransactions); + ) -> (VerificationOutcome, VerifiedPooledTransactions); } -impl VerifyPooledTransactionsResponse for UnverifiedPooledTransactions { +impl VerifyPooledTransactionsResponse for UnverifiedPooledTransactions { + type Transaction = T; + fn verify( self, requested_hashes: &RequestTxHashes, _peer_id: &PeerId, - ) -> (VerificationOutcome, VerifiedPooledTransactions) { + ) -> (VerificationOutcome, VerifiedPooledTransactions) { let mut verification_outcome = VerificationOutcome::Ok; let Self { mut txns } = self; @@ -1229,11 +1232,11 @@ impl VerifyPooledTransactionsResponse for UnverifiedPooledTransactions { let mut tx_hashes_not_requested_count = 0; txns.0.retain(|tx| { - if !requested_hashes.contains(tx.hash()) { + if !requested_hashes.contains(tx.tx_hash()) { verification_outcome = VerificationOutcome::ReportPeer; #[cfg(debug_assertions)] - tx_hashes_not_requested.push(*tx.hash()); + tx_hashes_not_requested.push(*tx.tx_hash()); #[cfg(not(debug_assertions))] { tx_hashes_not_requested_count += 1; diff --git a/crates/net/network/src/transactions/mod.rs b/crates/net/network/src/transactions/mod.rs index 4a7167a8064f..a1097dacf550 100644 --- a/crates/net/network/src/transactions/mod.rs +++ b/crates/net/network/src/transactions/mod.rs @@ -49,8 +49,7 @@ use reth_network_p2p::{ use reth_network_peers::PeerId; use reth_network_types::ReputationChangeKind; use reth_primitives::{ - transaction::SignedTransactionIntoRecoveredExt, PooledTransactionsElement, RecoveredTx, - TransactionSigned, + transaction::SignedTransactionIntoRecoveredExt, RecoveredTx, TransactionSigned, }; use reth_primitives_traits::{SignedTransaction, TxType}; use reth_tokio_util::EventStream; @@ -1307,11 +1306,17 @@ where // // spawned in `NodeConfig::start_network`(reth_node_core::NodeConfig) and // `NetworkConfig::start_network`(reth_network::NetworkConfig) -impl Future for TransactionsManager +impl Future for TransactionsManager where Pool: TransactionPool + Unpin + 'static, - Pool::Transaction: - PoolTransaction>, + N: NetworkPrimitives< + BroadcastedTransaction: SignedTransaction, + PooledTransaction: SignedTransaction, + >, + Pool::Transaction: PoolTransaction< + Consensus = N::BroadcastedTransaction, + Pooled: Into + From>, + >, { type Output = (); From bdfbcab53138c9fdf64c136aac6dcb2a84f6ff94 Mon Sep 17 00:00:00 2001 From: Dan Cline <6798349+Rjected@users.noreply.github.com> Date: Tue, 3 Dec 2024 17:06:36 -0500 Subject: [PATCH 63/68] feat: use generic CapabilityMessage everywhere (#13116) --- crates/net/network/src/manager.rs | 2 +- crates/net/network/src/session/handle.rs | 2 +- crates/net/network/src/session/mod.rs | 2 +- crates/net/network/src/swarm.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/net/network/src/manager.rs b/crates/net/network/src/manager.rs index e123377acd23..bad6ecba5fad 100644 --- a/crates/net/network/src/manager.rs +++ b/crates/net/network/src/manager.rs @@ -398,7 +398,7 @@ impl NetworkManager { &mut self, peer_id: PeerId, _capabilities: Arc, - _message: CapabilityMessage, + _message: CapabilityMessage, ) { trace!(target: "net", ?peer_id, "received unexpected message"); self.swarm diff --git a/crates/net/network/src/session/handle.rs b/crates/net/network/src/session/handle.rs index d167dc0e6ec4..d24d7ec68417 100644 --- a/crates/net/network/src/session/handle.rs +++ b/crates/net/network/src/session/handle.rs @@ -264,7 +264,7 @@ pub enum ActiveSessionMessage { /// Announced capabilities of the remote peer. capabilities: Arc, /// Message received from the peer. - message: CapabilityMessage, + message: CapabilityMessage, }, /// Received a bad message from the peer. BadMessage { diff --git a/crates/net/network/src/session/mod.rs b/crates/net/network/src/session/mod.rs index a020c540e385..b19281b079af 100644 --- a/crates/net/network/src/session/mod.rs +++ b/crates/net/network/src/session/mod.rs @@ -710,7 +710,7 @@ pub enum SessionEvent { /// Announced capabilities of the remote peer. capabilities: Arc, /// Message received from the peer. - message: CapabilityMessage, + message: CapabilityMessage, }, /// Received a bad message from the peer. BadMessage { diff --git a/crates/net/network/src/swarm.rs b/crates/net/network/src/swarm.rs index 47447783f428..c4a2bd14d36e 100644 --- a/crates/net/network/src/swarm.rs +++ b/crates/net/network/src/swarm.rs @@ -350,7 +350,7 @@ pub(crate) enum SwarmEvent { /// Announced capabilities of the remote peer. capabilities: Arc, /// Message received from the peer. - message: CapabilityMessage, + message: CapabilityMessage, }, /// Received a bad message from the peer. BadMessage { From c6add45c0dea83b0ea5ab2fb53030d1d2348bd89 Mon Sep 17 00:00:00 2001 From: Dan Cline <6798349+Rjected@users.noreply.github.com> Date: Tue, 3 Dec 2024 17:06:42 -0500 Subject: [PATCH 64/68] chore: propagate network primitives generic to EthStream usages (#13117) --- crates/net/network/src/session/active.rs | 2 +- examples/manual-p2p/src/main.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/net/network/src/session/active.rs b/crates/net/network/src/session/active.rs index 76701f7e2abf..af9bb2f08568 100644 --- a/crates/net/network/src/session/active.rs +++ b/crates/net/network/src/session/active.rs @@ -839,7 +839,7 @@ mod tests { f: F, ) -> Pin + Send>> where - F: FnOnce(EthStream>>) -> O + Send + 'static, + F: FnOnce(EthStream>, N>) -> O + Send + 'static, O: Future + Send + Sync, { let status = self.status; diff --git a/examples/manual-p2p/src/main.rs b/examples/manual-p2p/src/main.rs index 79a2ff26a274..15b14d98ea8a 100644 --- a/examples/manual-p2p/src/main.rs +++ b/examples/manual-p2p/src/main.rs @@ -16,7 +16,7 @@ use reth_ecies::stream::ECIESStream; use reth_eth_wire::{ EthMessage, EthStream, HelloMessage, P2PStream, Status, UnauthedEthStream, UnauthedP2PStream, }; -use reth_network::config::rng_secret_key; +use reth_network::{config::rng_secret_key, EthNetworkPrimitives}; use reth_network_peers::{mainnet_nodes, pk2id, NodeRecord}; use reth_primitives::{EthereumHardfork, Head}; use secp256k1::{SecretKey, SECP256K1}; @@ -24,7 +24,7 @@ use std::sync::LazyLock; use tokio::net::TcpStream; type AuthedP2PStream = P2PStream>; -type AuthedEthStream = EthStream>>; +type AuthedEthStream = EthStream>, EthNetworkPrimitives>; pub static MAINNET_BOOT_NODES: LazyLock> = LazyLock::new(mainnet_nodes); From 8a00d2d25cb81bd0137d0fcab57133b78d95657b Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Wed, 4 Dec 2024 04:13:47 +0400 Subject: [PATCH 65/68] chore: relax rpc bounds (#13100) --- .../rpc-eth-api/src/helpers/transaction.rs | 31 +++++++++++++------ crates/rpc/rpc-eth-api/src/types.rs | 7 ++--- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/crates/rpc/rpc-eth-api/src/helpers/transaction.rs b/crates/rpc/rpc-eth-api/src/helpers/transaction.rs index 9d77e01193b1..3b4ecb9de273 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/transaction.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/transaction.rs @@ -8,7 +8,10 @@ use alloy_network::TransactionBuilder; use alloy_primitives::{Address, Bytes, TxHash, B256}; use alloy_rpc_types_eth::{transaction::TransactionRequest, BlockNumberOrTag, TransactionInfo}; use futures::Future; -use reth_primitives::{SealedBlockWithSenders, TransactionMeta, TransactionSigned}; +use reth_primitives::{ + transaction::SignedTransactionIntoRecoveredExt, SealedBlockWithSenders, TransactionMeta, + TransactionSigned, +}; use reth_provider::{ BlockNumReader, BlockReaderIdExt, ProviderReceipt, ProviderTx, ReceiptProvider, TransactionsProvider, @@ -120,10 +123,13 @@ pub trait EthTransactions: LoadTransaction { } /// Returns the _historical_ transaction and the block it was mined in + #[expect(clippy::type_complexity)] fn historical_transaction_by_hash_at( &self, hash: B256, - ) -> impl Future, Self::Error>> + Send { + ) -> impl Future< + Output = Result>, B256)>, Self::Error>, + > + Send { async move { match self.transaction_by_hash_at(hash).await? { None => Ok(None), @@ -475,11 +481,7 @@ pub trait EthTransactions: LoadTransaction { /// /// Behaviour shared by several `eth_` RPC methods, not exclusive to `eth_` transactions RPC /// methods. -pub trait LoadTransaction: - SpawnBlocking - + FullEthApiTypes - + RpcNodeCoreExt -{ +pub trait LoadTransaction: SpawnBlocking + FullEthApiTypes + RpcNodeCoreExt { /// Returns the transaction by hash. /// /// Checks the pool and state. @@ -539,11 +541,16 @@ pub trait LoadTransaction: /// Returns the transaction by including its corresponding [`BlockId`]. /// /// Note: this supports pending transactions + #[expect(clippy::type_complexity)] fn transaction_by_hash_at( &self, transaction_hash: B256, - ) -> impl Future, Self::Error>> + Send - { + ) -> impl Future< + Output = Result< + Option<(TransactionSource>, BlockId)>, + Self::Error, + >, + > + Send { async move { Ok(self.transaction_by_hash(transaction_hash).await?.map(|tx| match tx { tx @ TransactionSource::Pool(_) => (tx, BlockId::pending()), @@ -555,11 +562,15 @@ pub trait LoadTransaction: } /// Fetches the transaction and the transaction's block + #[expect(clippy::type_complexity)] fn transaction_and_block( &self, hash: B256, ) -> impl Future< - Output = Result)>, Self::Error>, + Output = Result< + Option<(TransactionSource>, Arc)>, + Self::Error, + >, > + Send { async move { let (transaction, at) = match self.transaction_by_hash_at(hash).await? { diff --git a/crates/rpc/rpc-eth-api/src/types.rs b/crates/rpc/rpc-eth-api/src/types.rs index 62af1432b11a..c97ea5735ee9 100644 --- a/crates/rpc/rpc-eth-api/src/types.rs +++ b/crates/rpc/rpc-eth-api/src/types.rs @@ -7,7 +7,6 @@ use std::{ use alloy_network::Network; use alloy_rpc_types_eth::Block; -use reth_primitives::TransactionSigned; use reth_provider::{ProviderTx, ReceiptProvider, TransactionsProvider}; use reth_rpc_types_compat::TransactionCompat; use reth_transaction_pool::{PoolTransaction, TransactionPool}; @@ -49,8 +48,7 @@ pub type RpcError = ::Error; pub trait FullEthApiTypes where Self: RpcNodeCore< - Provider: TransactionsProvider - + ReceiptProvider, + Provider: TransactionsProvider + ReceiptProvider, Pool: TransactionPool< Transaction: PoolTransaction>, >, @@ -66,8 +64,7 @@ where impl FullEthApiTypes for T where T: RpcNodeCore< - Provider: TransactionsProvider - + ReceiptProvider, + Provider: TransactionsProvider + ReceiptProvider, Pool: TransactionPool< Transaction: PoolTransaction>, >, From d164e3ec982593f5fc67f0d5d13e102562fc047e Mon Sep 17 00:00:00 2001 From: Dan Cline <6798349+Rjected@users.noreply.github.com> Date: Tue, 3 Dec 2024 19:14:25 -0500 Subject: [PATCH 66/68] chore: bound most NetworkBuilder methods by NetworkPrimitives generic (#13119) --- .../net/eth-wire/tests/pooled_transactions.rs | 4 +- crates/net/network/src/builder.rs | 40 ++++++++++--------- crates/net/network/src/config.rs | 2 +- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/crates/net/eth-wire/tests/pooled_transactions.rs b/crates/net/eth-wire/tests/pooled_transactions.rs index 3b17d04cba51..93a17f3b05ba 100644 --- a/crates/net/eth-wire/tests/pooled_transactions.rs +++ b/crates/net/eth-wire/tests/pooled_transactions.rs @@ -3,7 +3,7 @@ use alloy_eips::eip2718::Decodable2718; use alloy_primitives::hex; use alloy_rlp::{Decodable, Encodable}; -use reth_eth_wire::{EthVersion, PooledTransactions, ProtocolMessage}; +use reth_eth_wire::{EthNetworkPrimitives, EthVersion, PooledTransactions, ProtocolMessage}; use reth_primitives::PooledTransactionsElement; use std::{fs, path::PathBuf}; use test_fuzz::test_fuzz; @@ -51,7 +51,7 @@ fn decode_request_pair_pooled_blob_transactions() { .join("testdata/request_pair_pooled_blob_transactions"); let data = fs::read_to_string(network_data_path).expect("Unable to read file"); let hex_data = hex::decode(data.trim()).unwrap(); - let _txs: ProtocolMessage = + let _txs: ProtocolMessage = ProtocolMessage::decode_message(EthVersion::Eth68, &mut &hex_data[..]).unwrap(); } diff --git a/crates/net/network/src/builder.rs b/crates/net/network/src/builder.rs index da003a2e2907..13c932d46442 100644 --- a/crates/net/network/src/builder.rs +++ b/crates/net/network/src/builder.rs @@ -24,35 +24,50 @@ pub struct NetworkBuilder // === impl NetworkBuilder === -impl NetworkBuilder { +impl NetworkBuilder { /// Consumes the type and returns all fields. - pub fn split(self) -> (NetworkManager, Tx, Eth) { + pub fn split(self) -> (NetworkManager, Tx, Eth) { let Self { network, transactions, request_handler } = self; (network, transactions, request_handler) } /// Returns the network manager. - pub const fn network(&self) -> &NetworkManager { + pub const fn network(&self) -> &NetworkManager { &self.network } /// Returns the mutable network manager. - pub fn network_mut(&mut self) -> &mut NetworkManager { + pub fn network_mut(&mut self) -> &mut NetworkManager { &mut self.network } /// Returns the handle to the network. - pub fn handle(&self) -> NetworkHandle { + pub fn handle(&self) -> NetworkHandle { self.network.handle().clone() } /// Consumes the type and returns all fields and also return a [`NetworkHandle`]. - pub fn split_with_handle(self) -> (NetworkHandle, NetworkManager, Tx, Eth) { + pub fn split_with_handle(self) -> (NetworkHandle, NetworkManager, Tx, Eth) { let Self { network, transactions, request_handler } = self; let handle = network.handle().clone(); (handle, network, transactions, request_handler) } + /// Creates a new [`EthRequestHandler`] and wires it to the network. + pub fn request_handler( + self, + client: Client, + ) -> NetworkBuilder, N> { + let Self { mut network, transactions, .. } = self; + let (tx, rx) = mpsc::channel(ETH_REQUEST_CHANNEL_CAPACITY); + network.set_eth_request_handler(tx); + let peers = network.handle().peers_handle().clone(); + let request_handler = EthRequestHandler::new(client, peers, rx); + NetworkBuilder { network, request_handler, transactions } + } +} + +impl NetworkBuilder { /// Creates a new [`TransactionsManager`] and wires it to the network. pub fn transactions( self, @@ -66,17 +81,4 @@ impl NetworkBuilder { let transactions = TransactionsManager::new(handle, pool, rx, transactions_manager_config); NetworkBuilder { network, request_handler, transactions } } - - /// Creates a new [`EthRequestHandler`] and wires it to the network. - pub fn request_handler( - self, - client: Client, - ) -> NetworkBuilder> { - let Self { mut network, transactions, .. } = self; - let (tx, rx) = mpsc::channel(ETH_REQUEST_CHANNEL_CAPACITY); - network.set_eth_request_handler(tx); - let peers = network.handle().peers_handle().clone(); - let request_handler = EthRequestHandler::new(client, peers, rx); - NetworkBuilder { network, request_handler, transactions } - } } diff --git a/crates/net/network/src/config.rs b/crates/net/network/src/config.rs index 44f34c3a4b08..a9ce67821b98 100644 --- a/crates/net/network/src/config.rs +++ b/crates/net/network/src/config.rs @@ -94,7 +94,7 @@ impl NetworkConfig<(), N> { } /// Convenience method for creating the corresponding builder type with a random secret key. - pub fn builder_with_rng_secret_key() -> NetworkConfigBuilder { + pub fn builder_with_rng_secret_key() -> NetworkConfigBuilder { NetworkConfigBuilder::with_rng_secret_key() } } From 4e73bb04c252023fdce8cac6c3e3de90f9972834 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Wed, 4 Dec 2024 04:15:03 +0400 Subject: [PATCH 67/68] refactor: pending block construction (#13109) --- .../rpc-eth-api/src/helpers/pending_block.rs | 145 ++++++++---------- crates/rpc/rpc-eth-types/src/pending_block.rs | 30 ++-- 2 files changed, 72 insertions(+), 103 deletions(-) diff --git a/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs b/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs index c5bb0994607c..8a6e5c84be1a 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs @@ -8,17 +8,18 @@ use alloy_eips::{ eip4844::MAX_DATA_GAS_PER_BLOCK, eip7685::EMPTY_REQUESTS_HASH, merge::BEACON_NONCE, }; use alloy_primitives::{BlockNumber, B256, U256}; -use alloy_rpc_types_eth::BlockNumberOrTag; +use alloy_rpc_types_eth::{BlockNumberOrTag, Withdrawals}; use futures::Future; use reth_chainspec::{EthChainSpec, EthereumHardforks}; +use reth_errors::RethError; use reth_evm::{ state_change::post_block_withdrawals_balance_increments, system_calls::SystemCaller, - ConfigureEvm, ConfigureEvmEnv, + ConfigureEvm, ConfigureEvmEnv, NextBlockEnvAttributes, }; use reth_execution_types::ExecutionOutcome; use reth_primitives::{ proofs::calculate_transaction_root, Block, BlockBody, BlockExt, InvalidTransactionError, - Receipt, RecoveredTx, SealedBlockWithSenders, SealedHeader, + Receipt, RecoveredTx, SealedBlockWithSenders, }; use reth_provider::{ BlockReader, BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, ProviderError, @@ -27,7 +28,7 @@ use reth_provider::{ use reth_revm::{ database::StateProviderDatabase, primitives::{ - BlockEnv, CfgEnv, CfgEnvWithHandlerCfg, EVMError, Env, ExecutionResult, InvalidTransaction, + BlockEnv, CfgEnvWithHandlerCfg, EVMError, Env, ExecutionResult, InvalidTransaction, ResultAndState, SpecId, }, }; @@ -68,55 +69,56 @@ pub trait LoadPendingBlock: /// /// If no pending block is available, this will derive it from the `latest` block fn pending_block_env_and_cfg(&self) -> Result { - let origin: PendingBlockEnvOrigin = if let Some(pending) = + if let Some(block) = self.provider().pending_block_with_senders().map_err(Self::Error::from_eth_err)? { - PendingBlockEnvOrigin::ActualPending(pending) - } else { - // no pending block from the CL yet, so we use the latest block and modify the env - // values that we can - let latest = self + if let Some(receipts) = self .provider() - .latest_header() + .receipts_by_block(block.hash().into()) .map_err(Self::Error::from_eth_err)? - .ok_or(EthApiError::HeaderNotFound(BlockNumberOrTag::Latest.into()))?; - - let (mut latest_header, block_hash) = latest.split(); - // child block - latest_header.number += 1; - // assumed child block is in the next slot: 12s - latest_header.timestamp += 12; - // base fee of the child block - let chain_spec = self.provider().chain_spec(); - - latest_header.base_fee_per_gas = latest_header.next_block_base_fee( - chain_spec.base_fee_params_at_timestamp(latest_header.timestamp()), - ); - - // update excess blob gas consumed above target - latest_header.excess_blob_gas = latest_header.next_block_excess_blob_gas(); - - // we're reusing the same block hash because we need this to lookup the block's state - let latest = SealedHeader::new(latest_header, block_hash); - - PendingBlockEnvOrigin::DerivedFromLatest(latest) - }; + { + // Note: for the PENDING block we assume it is past the known merge block and + // thus this will not fail when looking up the total + // difficulty value for the blockenv. + let (cfg, block_env) = self + .provider() + .env_with_header(block.header(), self.evm_config().clone()) + .map_err(Self::Error::from_eth_err)?; + + return Ok(PendingBlockEnv::new( + cfg, + block_env, + PendingBlockEnvOrigin::ActualPending(block, receipts), + )); + } + } - let mut cfg = CfgEnvWithHandlerCfg::new_with_spec_id(CfgEnv::default(), SpecId::LATEST); - - let mut block_env = BlockEnv::default(); - // Note: for the PENDING block we assume it is past the known merge block and thus this will - // not fail when looking up the total difficulty value for the blockenv. - self.provider() - .fill_env_with_header( - &mut cfg, - &mut block_env, - origin.header(), - self.evm_config().clone(), + // no pending block from the CL yet, so we use the latest block and modify the env + // values that we can + let latest = self + .provider() + .latest_header() + .map_err(Self::Error::from_eth_err)? + .ok_or(EthApiError::HeaderNotFound(BlockNumberOrTag::Latest.into()))?; + + let (cfg, block_env) = self + .evm_config() + .next_cfg_and_block_env( + &latest, + NextBlockEnvAttributes { + timestamp: latest.timestamp() + 12, + suggested_fee_recipient: latest.beneficiary(), + prev_randao: B256::random(), + }, ) + .map_err(RethError::other) .map_err(Self::Error::from_eth_err)?; - Ok(PendingBlockEnv::new(cfg, block_env, origin)) + Ok(PendingBlockEnv::new( + cfg, + block_env, + PendingBlockEnvOrigin::DerivedFromLatest(latest.hash()), + )) } /// Returns the locally built pending block @@ -137,18 +139,12 @@ pub trait LoadPendingBlock: { async move { let pending = self.pending_block_env_and_cfg()?; - if pending.origin.is_actual_pending() { - if let Some(block) = pending.origin.clone().into_actual_pending() { - // we have the real pending block, so we should also have its receipts - if let Some(receipts) = self - .provider() - .receipts_by_block(block.hash().into()) - .map_err(Self::Error::from_eth_err)? - { - return Ok(Some((block, receipts))) - } + let parent_hash = match pending.origin { + PendingBlockEnvOrigin::ActualPending(block, receipts) => { + return Ok(Some((block, receipts))); } - } + PendingBlockEnvOrigin::DerivedFromLatest(parent_hash) => parent_hash, + }; // we couldn't find the real pending block, so we need to build it ourselves let mut lock = self.pending_block().lock().await; @@ -159,7 +155,7 @@ pub trait LoadPendingBlock: if let Some(pending_block) = lock.as_ref() { // this is guaranteed to be the `latest` header if pending.block_env.number.to::() == pending_block.block.number && - pending.origin.header().hash() == pending_block.block.parent_hash && + parent_hash == pending_block.block.parent_hash && now <= pending_block.expires_at { return Ok(Some((pending_block.block.clone(), pending_block.receipts.clone()))); @@ -170,7 +166,7 @@ pub trait LoadPendingBlock: let (sealed_block, receipts) = match self .spawn_blocking_io(move |this| { // we rebuild the block - this.build_block(pending) + this.build_block(pending.cfg, pending.block_env, parent_hash) }) .await { @@ -229,14 +225,13 @@ pub trait LoadPendingBlock: /// block contract call using the parent beacon block root received from the CL. fn build_block( &self, - env: PendingBlockEnv, + cfg: CfgEnvWithHandlerCfg, + block_env: BlockEnv, + parent_hash: B256, ) -> Result<(SealedBlockWithSenders, Vec), Self::Error> where EthApiError: From, { - let PendingBlockEnv { cfg, block_env, origin } = env; - - let parent_hash = origin.build_target_hash(); let state_provider = self .provider() .history_by_block_hash(parent_hash) @@ -258,34 +253,16 @@ pub trait LoadPendingBlock: block_env.get_blob_gasprice().map(|gasprice| gasprice as u64), )); - let (withdrawals, withdrawals_root) = match origin { - PendingBlockEnvOrigin::ActualPending(ref block) => { - (block.body.withdrawals.clone(), block.withdrawals_root) - } - PendingBlockEnvOrigin::DerivedFromLatest(_) => (None, None), - }; + let withdrawals: Option = None; + let withdrawals_root = None; let chain_spec = self.provider().chain_spec(); let mut system_caller = SystemCaller::new(self.evm_config().clone(), chain_spec.clone()); - let parent_beacon_block_root = if origin.is_actual_pending() { - // apply eip-4788 pre block contract call if we got the block from the CL with the real - // parent beacon block root - system_caller - .pre_block_beacon_root_contract_call( - &mut db, - &cfg, - &block_env, - origin.header().parent_beacon_block_root, - ) - .map_err(|err| EthApiError::Internal(err.into()))?; - origin.header().parent_beacon_block_root - } else { - None - }; + let parent_beacon_block_root = None; system_caller - .pre_block_blockhashes_contract_call(&mut db, &cfg, &block_env, origin.header().hash()) + .pre_block_blockhashes_contract_call(&mut db, &cfg, &block_env, parent_hash) .map_err(|err| EthApiError::Internal(err.into()))?; let mut receipts = Vec::new(); diff --git a/crates/rpc/rpc-eth-types/src/pending_block.rs b/crates/rpc/rpc-eth-types/src/pending_block.rs index 116026c2ddde..bd23e3f42abf 100644 --- a/crates/rpc/rpc-eth-types/src/pending_block.rs +++ b/crates/rpc/rpc-eth-types/src/pending_block.rs @@ -8,7 +8,7 @@ use alloy_consensus::BlockHeader; use alloy_eips::{BlockId, BlockNumberOrTag}; use alloy_primitives::B256; use derive_more::Constructor; -use reth_primitives::{Receipt, SealedBlockWithSenders, SealedHeader}; +use reth_primitives::{Receipt, SealedBlockWithSenders}; use reth_primitives_traits::Block; use revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg}; @@ -25,28 +25,28 @@ pub struct PendingBlockEnv { /// The origin for a configured [`PendingBlockEnv`] #[derive(Clone, Debug)] -pub enum PendingBlockEnvOrigin { +pub enum PendingBlockEnvOrigin { /// The pending block as received from the CL. - ActualPending(SealedBlockWithSenders), + ActualPending(SealedBlockWithSenders, Vec), /// The _modified_ header of the latest block. /// /// This derives the pending state based on the latest header by modifying: /// - the timestamp /// - the block number /// - fees - DerivedFromLatest(SealedHeader), + DerivedFromLatest(B256), } -impl PendingBlockEnvOrigin { +impl PendingBlockEnvOrigin { /// Returns true if the origin is the actual pending block as received from the CL. pub const fn is_actual_pending(&self) -> bool { - matches!(self, Self::ActualPending(_)) + matches!(self, Self::ActualPending(_, _)) } /// Consumes the type and returns the actual pending block. pub fn into_actual_pending(self) -> Option> { match self { - Self::ActualPending(block) => Some(block), + Self::ActualPending(block, _) => Some(block), _ => None, } } @@ -57,8 +57,8 @@ impl PendingBlockEnvOrigin { /// identify the block by its hash (latest block). pub fn state_block_id(&self) -> BlockId { match self { - Self::ActualPending(_) => BlockNumberOrTag::Pending.into(), - Self::DerivedFromLatest(header) => BlockId::Hash(header.hash().into()), + Self::ActualPending(_, _) => BlockNumberOrTag::Pending.into(), + Self::DerivedFromLatest(hash) => BlockId::Hash((*hash).into()), } } @@ -69,16 +69,8 @@ impl PendingBlockEnvOrigin { /// header. pub fn build_target_hash(&self) -> B256 { match self { - Self::ActualPending(block) => block.header().parent_hash(), - Self::DerivedFromLatest(header) => header.hash(), - } - } - - /// Returns the header this pending block is based on. - pub fn header(&self) -> &SealedHeader { - match self { - Self::ActualPending(block) => &block.header, - Self::DerivedFromLatest(header) => header, + Self::ActualPending(block, _) => block.header().parent_hash(), + Self::DerivedFromLatest(hash) => *hash, } } } From 5c07669ef6e1db8a1acc487fea92c1b6aa81cc67 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Wed, 4 Dec 2024 11:59:01 +0400 Subject: [PATCH 68/68] chore: remove `TransactionSignedNoHash` (#13120) --- .../cli/commands/src/test_vectors/compact.rs | 4 +- .../cli/commands/src/test_vectors/tables.rs | 4 +- crates/primitives/src/lib.rs | 2 +- crates/primitives/src/transaction/mod.rs | 304 +++++------------- crates/primitives/src/transaction/tx_type.rs | 2 +- .../stages/src/stages/hashing_storage.rs | 5 +- .../stages/stages/src/test_utils/test_db.rs | 2 +- crates/storage/db-api/src/models/mod.rs | 3 +- crates/storage/db/src/tables/mod.rs | 4 +- .../src/providers/blockchain_provider.rs | 6 +- .../src/providers/static_file/manager.rs | 4 +- docs/design/database.md | 2 +- 12 files changed, 96 insertions(+), 246 deletions(-) diff --git a/crates/cli/commands/src/test_vectors/compact.rs b/crates/cli/commands/src/test_vectors/compact.rs index 5490f568d3a8..c321e35be731 100644 --- a/crates/cli/commands/src/test_vectors/compact.rs +++ b/crates/cli/commands/src/test_vectors/compact.rs @@ -22,7 +22,7 @@ use reth_db::{ }; use reth_fs_util as fs; use reth_primitives::{ - Account, Log, LogData, Receipt, StorageEntry, Transaction, TransactionSignedNoHash, TxType, + Account, Log, LogData, Receipt, StorageEntry, Transaction, TransactionSigned, TxType, }; use reth_prune_types::{PruneCheckpoint, PruneMode}; use reth_stages_types::{ @@ -111,7 +111,7 @@ compact_types!( StoredBlockBodyIndices, StoredBlockWithdrawals, // Manual implementations - TransactionSignedNoHash, + TransactionSigned, // Bytecode, // todo revm arbitrary StorageEntry, // MerkleCheckpoint, // todo storedsubnode -> branchnodecompact arbitrary diff --git a/crates/cli/commands/src/test_vectors/tables.rs b/crates/cli/commands/src/test_vectors/tables.rs index acb811b75dfc..f845d2a66130 100644 --- a/crates/cli/commands/src/test_vectors/tables.rs +++ b/crates/cli/commands/src/test_vectors/tables.rs @@ -11,7 +11,7 @@ use proptest_arbitrary_interop::arb; use reth_db::tables; use reth_db_api::table::{DupSort, Table, TableRow}; use reth_fs_util as fs; -use reth_primitives::TransactionSignedNoHash; +use reth_primitives::TransactionSigned; use std::collections::HashSet; use tracing::error; @@ -74,7 +74,7 @@ pub fn generate_vectors(mut tables: Vec) -> Result<()> { (BlockBodyIndices, PER_TABLE, TABLE), (BlockOmmers
, 100, TABLE), (TransactionHashNumbers, PER_TABLE, TABLE), - (Transactions, 100, TABLE), + (Transactions, 100, TABLE), (PlainStorageState, PER_TABLE, DUPSORT), (PlainAccountState, PER_TABLE, TABLE) ]); diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index 97407ba610cf..2844c9397b83 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -53,7 +53,7 @@ pub use transaction::{ util::secp256k1::{public_key_to_address, recover_signer_unchecked, sign_message}, BlobTransaction, InvalidTransactionError, PooledTransactionsElement, PooledTransactionsElementEcRecovered, RecoveredTx, Transaction, TransactionMeta, - TransactionSigned, TransactionSignedEcRecovered, TransactionSignedNoHash, TxType, + TransactionSigned, TransactionSignedEcRecovered, TxType, }; // Re-exports diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index aaa6b82dc4ef..d0b88c4b179d 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -780,230 +780,6 @@ impl From for Transaction { } } -/// Signed transaction without its Hash. Used type for inserting into the DB. -/// -/// This can by converted to [`TransactionSigned`] by calling [`TransactionSignedNoHash::hash`]. -#[derive(Debug, Clone, PartialEq, Eq, Hash, AsRef, Deref, Serialize, Deserialize)] -#[cfg_attr(any(test, feature = "reth-codec"), reth_codecs::add_arbitrary_tests(compact))] -pub struct TransactionSignedNoHash { - /// The transaction signature values - pub signature: Signature, - /// Raw transaction info - #[deref] - #[as_ref] - pub transaction: Transaction, -} - -impl TransactionSignedNoHash { - /// Calculates the transaction hash. If used more than once, it's better to convert it to - /// [`TransactionSigned`] first. - pub fn hash(&self) -> B256 { - // pre-allocate buffer for the transaction - let mut buf = Vec::with_capacity(128 + self.transaction.input().len()); - self.transaction.eip2718_encode(&self.signature, &mut buf); - keccak256(&buf) - } - - /// Recover signer from signature and hash. - /// - /// Returns `None` if the transaction's signature is invalid, see also [`Self::recover_signer`]. - pub fn recover_signer(&self) -> Option
{ - // Optimism's Deposit transaction does not have a signature. Directly return the - // `from` address. - #[cfg(feature = "optimism")] - if let Transaction::Deposit(TxDeposit { from, .. }) = self.transaction { - return Some(from) - } - - let signature_hash = self.signature_hash(); - recover_signer(&self.signature, signature_hash) - } - - /// Recover signer from signature and hash _without ensuring that the signature has a low `s` - /// value_. - /// - /// Reuses a given buffer to avoid numerous reallocations when recovering batches. **Clears the - /// buffer before use.** - /// - /// Returns `None` if the transaction's signature is invalid, see also - /// [`recover_signer_unchecked`]. - /// - /// # Optimism - /// - /// For optimism this will return [`Address::ZERO`] if the Signature is empty, this is because pre bedrock (on OP mainnet), relay messages to the L2 Cross Domain Messenger were sent as legacy transactions from the zero address with an empty signature, e.g.: - /// This makes it possible to import pre bedrock transactions via the sender recovery stage. - pub fn encode_and_recover_unchecked(&self, buffer: &mut Vec) -> Option
{ - buffer.clear(); - self.transaction.encode_for_signing(buffer); - - // Optimism's Deposit transaction does not have a signature. Directly return the - // `from` address. - #[cfg(feature = "optimism")] - { - if let Transaction::Deposit(TxDeposit { from, .. }) = self.transaction { - return Some(from) - } - - // pre bedrock system transactions were sent from the zero address as legacy - // transactions with an empty signature - // - // NOTE: this is very hacky and only relevant for op-mainnet pre bedrock - if self.is_legacy() && self.signature == TxDeposit::signature() { - return Some(Address::ZERO) - } - } - - recover_signer_unchecked(&self.signature, keccak256(buffer)) - } - - /// Converts into a transaction type with its hash: [`TransactionSigned`]. - /// - /// Note: This will recalculate the hash of the transaction. - #[inline] - pub fn with_hash(self) -> TransactionSigned { - let Self { signature, transaction } = self; - TransactionSigned::new_unhashed(transaction, signature) - } - - /// Recovers a list of signers from a transaction list iterator - /// - /// Returns `None`, if some transaction's signature is invalid, see also - /// [`Self::recover_signer`]. - pub fn recover_signers<'a, T>(txes: T, num_txes: usize) -> Option> - where - T: IntoParallelIterator + IntoIterator + Send, - { - if num_txes < *PARALLEL_SENDER_RECOVERY_THRESHOLD { - txes.into_iter().map(|tx| tx.recover_signer()).collect() - } else { - txes.into_par_iter().map(|tx| tx.recover_signer()).collect() - } - } -} - -impl Default for TransactionSignedNoHash { - fn default() -> Self { - Self { signature: Signature::test_signature(), transaction: Default::default() } - } -} - -#[cfg(any(test, feature = "arbitrary"))] -impl<'a> arbitrary::Arbitrary<'a> for TransactionSignedNoHash { - fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { - let tx_signed = TransactionSigned::arbitrary(u)?; - - Ok(Self { signature: tx_signed.signature, transaction: tx_signed.transaction }) - } -} - -#[cfg(any(test, feature = "reth-codec"))] -impl reth_codecs::Compact for TransactionSignedNoHash { - fn to_compact(&self, buf: &mut B) -> usize - where - B: bytes::BufMut + AsMut<[u8]>, - { - let start = buf.as_mut().len(); - - // Placeholder for bitflags. - // The first byte uses 4 bits as flags: IsCompressed[1bit], TxType[2bits], Signature[1bit] - buf.put_u8(0); - - let sig_bit = self.signature.to_compact(buf) as u8; - let zstd_bit = self.transaction.input().len() >= 32; - - let tx_bits = if zstd_bit { - let mut tmp = Vec::with_capacity(256); - if cfg!(feature = "std") { - crate::compression::TRANSACTION_COMPRESSOR.with(|compressor| { - let mut compressor = compressor.borrow_mut(); - let tx_bits = self.transaction.to_compact(&mut tmp); - buf.put_slice(&compressor.compress(&tmp).expect("Failed to compress")); - tx_bits as u8 - }) - } else { - let mut compressor = crate::compression::create_tx_compressor(); - let tx_bits = self.transaction.to_compact(&mut tmp); - buf.put_slice(&compressor.compress(&tmp).expect("Failed to compress")); - tx_bits as u8 - } - } else { - self.transaction.to_compact(buf) as u8 - }; - - // Replace bitflags with the actual values - buf.as_mut()[start] = sig_bit | (tx_bits << 1) | ((zstd_bit as u8) << 3); - - buf.as_mut().len() - start - } - - fn from_compact(mut buf: &[u8], _len: usize) -> (Self, &[u8]) { - use bytes::Buf; - - // The first byte uses 4 bits as flags: IsCompressed[1], TxType[2], Signature[1] - let bitflags = buf.get_u8() as usize; - - let sig_bit = bitflags & 1; - let (signature, buf) = Signature::from_compact(buf, sig_bit); - - let zstd_bit = bitflags >> 3; - let (transaction, buf) = if zstd_bit != 0 { - if cfg!(feature = "std") { - crate::compression::TRANSACTION_DECOMPRESSOR.with(|decompressor| { - let mut decompressor = decompressor.borrow_mut(); - - // TODO: enforce that zstd is only present at a "top" level type - - let transaction_type = (bitflags & 0b110) >> 1; - let (transaction, _) = - Transaction::from_compact(decompressor.decompress(buf), transaction_type); - - (transaction, buf) - }) - } else { - let mut decompressor = crate::compression::create_tx_decompressor(); - let transaction_type = (bitflags & 0b110) >> 1; - let (transaction, _) = - Transaction::from_compact(decompressor.decompress(buf), transaction_type); - - (transaction, buf) - } - } else { - let transaction_type = bitflags >> 1; - Transaction::from_compact(buf, transaction_type) - }; - - (Self { signature, transaction }, buf) - } -} - -#[cfg(any(test, feature = "reth-codec"))] -impl reth_codecs::Compact for TransactionSigned { - fn to_compact(&self, buf: &mut B) -> usize - where - B: bytes::BufMut + AsMut<[u8]>, - { - let tx: TransactionSignedNoHash = self.clone().into(); - tx.to_compact(buf) - } - - fn from_compact(buf: &[u8], len: usize) -> (Self, &[u8]) { - let (tx, buf) = TransactionSignedNoHash::from_compact(buf, len); - (tx.into(), buf) - } -} - -impl From for TransactionSigned { - fn from(tx: TransactionSignedNoHash) -> Self { - tx.with_hash() - } -} - -impl From for TransactionSignedNoHash { - fn from(tx: TransactionSigned) -> Self { - Self { signature: tx.signature, transaction: tx.transaction } - } -} - /// Signed transaction. #[cfg_attr(any(test, feature = "reth-codec"), reth_codecs::add_arbitrary_tests(rlp))] #[derive(Debug, Clone, Eq, AsRef, Deref, Serialize, Deserialize)] @@ -1543,6 +1319,86 @@ impl Decodable2718 for TransactionSigned { } } +#[cfg(any(test, feature = "reth-codec"))] +impl reth_codecs::Compact for TransactionSigned { + fn to_compact(&self, buf: &mut B) -> usize + where + B: bytes::BufMut + AsMut<[u8]>, + { + let start = buf.as_mut().len(); + + // Placeholder for bitflags. + // The first byte uses 4 bits as flags: IsCompressed[1bit], TxType[2bits], Signature[1bit] + buf.put_u8(0); + + let sig_bit = self.signature.to_compact(buf) as u8; + let zstd_bit = self.transaction.input().len() >= 32; + + let tx_bits = if zstd_bit { + let mut tmp = Vec::with_capacity(256); + if cfg!(feature = "std") { + crate::compression::TRANSACTION_COMPRESSOR.with(|compressor| { + let mut compressor = compressor.borrow_mut(); + let tx_bits = self.transaction.to_compact(&mut tmp); + buf.put_slice(&compressor.compress(&tmp).expect("Failed to compress")); + tx_bits as u8 + }) + } else { + let mut compressor = crate::compression::create_tx_compressor(); + let tx_bits = self.transaction.to_compact(&mut tmp); + buf.put_slice(&compressor.compress(&tmp).expect("Failed to compress")); + tx_bits as u8 + } + } else { + self.transaction.to_compact(buf) as u8 + }; + + // Replace bitflags with the actual values + buf.as_mut()[start] = sig_bit | (tx_bits << 1) | ((zstd_bit as u8) << 3); + + buf.as_mut().len() - start + } + + fn from_compact(mut buf: &[u8], _len: usize) -> (Self, &[u8]) { + use bytes::Buf; + + // The first byte uses 4 bits as flags: IsCompressed[1], TxType[2], Signature[1] + let bitflags = buf.get_u8() as usize; + + let sig_bit = bitflags & 1; + let (signature, buf) = Signature::from_compact(buf, sig_bit); + + let zstd_bit = bitflags >> 3; + let (transaction, buf) = if zstd_bit != 0 { + if cfg!(feature = "std") { + crate::compression::TRANSACTION_DECOMPRESSOR.with(|decompressor| { + let mut decompressor = decompressor.borrow_mut(); + + // TODO: enforce that zstd is only present at a "top" level type + + let transaction_type = (bitflags & 0b110) >> 1; + let (transaction, _) = + Transaction::from_compact(decompressor.decompress(buf), transaction_type); + + (transaction, buf) + }) + } else { + let mut decompressor = crate::compression::create_tx_decompressor(); + let transaction_type = (bitflags & 0b110) >> 1; + let (transaction, _) = + Transaction::from_compact(decompressor.decompress(buf), transaction_type); + + (transaction, buf) + } + } else { + let transaction_type = bitflags >> 1; + Transaction::from_compact(buf, transaction_type) + }; + + (Self { signature, transaction, hash: Default::default() }, buf) + } +} + macro_rules! impl_from_signed { ($($tx:ident),*) => { $( diff --git a/crates/primitives/src/transaction/tx_type.rs b/crates/primitives/src/transaction/tx_type.rs index 784a976ab792..1d709b902b53 100644 --- a/crates/primitives/src/transaction/tx_type.rs +++ b/crates/primitives/src/transaction/tx_type.rs @@ -29,7 +29,7 @@ pub const COMPACT_EXTENDED_IDENTIFIER_FLAG: usize = 3; /// Transaction Type /// /// Currently being used as 2-bit type when encoding it to `reth_codecs::Compact` on -/// [`crate::TransactionSignedNoHash`]. Adding more transaction types will break the codec and +/// [`crate::TransactionSigned`]. Adding more transaction types will break the codec and /// database format. /// /// Other required changes when adding a new type can be seen on [PR#3953](https://github.com/paradigmxyz/reth/pull/3953/files). diff --git a/crates/stages/stages/src/stages/hashing_storage.rs b/crates/stages/stages/src/stages/hashing_storage.rs index dcabbe83ee64..0be84665bee1 100644 --- a/crates/stages/stages/src/stages/hashing_storage.rs +++ b/crates/stages/stages/src/stages/hashing_storage.rs @@ -359,10 +359,7 @@ mod tests { transaction.hash(), next_tx_num, )?; - tx.put::( - next_tx_num, - transaction.clone().into(), - )?; + tx.put::(next_tx_num, transaction.clone())?; let (addr, _) = accounts.get_mut(rng.gen::() % n_accounts as usize).unwrap(); diff --git a/crates/stages/stages/src/test_utils/test_db.rs b/crates/stages/stages/src/test_utils/test_db.rs index 2f9712f84364..5a6c12d8e00f 100644 --- a/crates/stages/stages/src/test_utils/test_db.rs +++ b/crates/stages/stages/src/test_utils/test_db.rs @@ -267,7 +267,7 @@ impl TestStageDB { if let Some(txs_writer) = &mut txs_writer { txs_writer.append_transaction(next_tx_num, body_tx)?; } else { - tx.put::(next_tx_num, body_tx.clone().into())? + tx.put::(next_tx_num, body_tx.clone())? } next_tx_num += 1; Ok::<(), ProviderError>(()) diff --git a/crates/storage/db-api/src/models/mod.rs b/crates/storage/db-api/src/models/mod.rs index 0a008bb88a5f..7ded84e17208 100644 --- a/crates/storage/db-api/src/models/mod.rs +++ b/crates/storage/db-api/src/models/mod.rs @@ -8,7 +8,7 @@ use alloy_consensus::Header; use alloy_genesis::GenesisAccount; use alloy_primitives::{Address, Bytes, Log, B256, U256}; use reth_codecs::{add_arbitrary_tests, Compact}; -use reth_primitives::{Receipt, StorageEntry, TransactionSigned, TransactionSignedNoHash, TxType}; +use reth_primitives::{Receipt, StorageEntry, TransactionSigned, TxType}; use reth_primitives_traits::{Account, Bytecode}; use reth_prune_types::{PruneCheckpoint, PruneSegment}; use reth_stages_types::StageCheckpoint; @@ -226,7 +226,6 @@ impl_compression_for_compact!( StoredBlockWithdrawals, Bytecode, AccountBeforeTx, - TransactionSignedNoHash, TransactionSigned, CompactU256, StageCheckpoint, diff --git a/crates/storage/db/src/tables/mod.rs b/crates/storage/db/src/tables/mod.rs index 8a11c4ac055d..88cfdde44aaf 100644 --- a/crates/storage/db/src/tables/mod.rs +++ b/crates/storage/db/src/tables/mod.rs @@ -31,7 +31,7 @@ use reth_db_api::{ }, table::{Decode, DupSort, Encode, Table}, }; -use reth_primitives::{Receipt, StorageEntry, TransactionSignedNoHash}; +use reth_primitives::{Receipt, StorageEntry, TransactionSigned}; use reth_primitives_traits::{Account, Bytecode}; use reth_prune_types::{PruneCheckpoint, PruneSegment}; use reth_stages_types::StageCheckpoint; @@ -348,7 +348,7 @@ tables! { } /// Canonical only Stores the transaction body for canonical transactions. - table Transactions { + table Transactions { type Key = TxNumber; type Value = T; } diff --git a/crates/storage/provider/src/providers/blockchain_provider.rs b/crates/storage/provider/src/providers/blockchain_provider.rs index 8330ef3a66e8..521e1d959b3c 100644 --- a/crates/storage/provider/src/providers/blockchain_provider.rs +++ b/crates/storage/provider/src/providers/blockchain_provider.rs @@ -29,7 +29,7 @@ use reth_node_types::{BlockTy, HeaderTy, NodeTypesWithDB, ReceiptTy, TxTy}; use reth_primitives::{ Account, Block, BlockWithSenders, EthPrimitives, NodePrimitives, Receipt, SealedBlock, SealedBlockFor, SealedBlockWithSenders, SealedHeader, StorageEntry, TransactionMeta, - TransactionSigned, TransactionSignedNoHash, + TransactionSigned, }; use reth_primitives_traits::BlockBody as _; use reth_prune_types::{PruneCheckpoint, PruneSegment}; @@ -850,9 +850,7 @@ mod tests { use reth_db_api::{cursor::DbCursorRO, transaction::DbTx}; use reth_errors::ProviderError; use reth_execution_types::{Chain, ExecutionOutcome}; - use reth_primitives::{ - BlockExt, Receipt, SealedBlock, StaticFileSegment, TransactionSignedNoHash, - }; + use reth_primitives::{BlockExt, Receipt, SealedBlock, StaticFileSegment}; use reth_primitives_traits::{BlockBody as _, SignedTransaction}; use reth_storage_api::{ BlockHashReader, BlockIdReader, BlockNumReader, BlockReader, BlockReaderIdExt, BlockSource, diff --git a/crates/storage/provider/src/providers/static_file/manager.rs b/crates/storage/provider/src/providers/static_file/manager.rs index eca382af76c7..7af071299cdf 100644 --- a/crates/storage/provider/src/providers/static_file/manager.rs +++ b/crates/storage/provider/src/providers/static_file/manager.rs @@ -39,7 +39,7 @@ use reth_primitives::{ }, transaction::recover_signers, BlockWithSenders, Receipt, SealedBlockFor, SealedBlockWithSenders, SealedHeader, - StaticFileSegment, TransactionMeta, TransactionSignedNoHash, + StaticFileSegment, TransactionMeta, TransactionSigned, }; use reth_primitives_traits::SignedTransaction; use reth_stages_types::{PipelineTarget, StageId}; @@ -1706,7 +1706,7 @@ impl StatsReader for StaticFileProvider { .get_highest_static_file_tx(StaticFileSegment::Receipts) .map(|receipts| receipts + 1) .unwrap_or_default() as usize), - tables::Transactions::::NAME => Ok(self + tables::Transactions::::NAME => Ok(self .get_highest_static_file_tx(StaticFileSegment::Transactions) .map(|txs| txs + 1) .unwrap_or_default() diff --git a/docs/design/database.md b/docs/design/database.md index cf2a6c8fcc10..48fc8612cbaa 100644 --- a/docs/design/database.md +++ b/docs/design/database.md @@ -56,7 +56,7 @@ BlockWithdrawals { } Transactions { u64 TxNumber "PK" - TransactionSignedNoHash Data + TransactionSigned Data } TransactionHashNumbers { B256 TxHash "PK"