diff --git a/.github/assets/check_rv32imac.sh b/.github/assets/check_rv32imac.sh index a8d348adb380..cf3466c18e8f 100755 --- a/.github/assets/check_rv32imac.sh +++ b/.github/assets/check_rv32imac.sh @@ -4,16 +4,18 @@ set +e # Disable immediate exit on error # Array of crates to check crates_to_check=( reth-codecs-derive - reth-ethereum-forks - reth-ethereum-primitives reth-primitives-traits - reth-optimism-forks reth-network-peers reth-trie-common reth-chainspec - # reth-evm - # reth-primitives - # reth-optimism-chainspec + + ## ethereum + reth-ethereum-forks + reth-ethereum-primitives + + ## optimism + reth-optimism-chainspec + reth-optimism-forks ) # Array to hold the results diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 38cca2fb1a9b..212246a4edaf 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -3,9 +3,7 @@ name: stale issues on: - workflow_dispatch: {} - schedule: - - cron: "30 1 * * *" + workflow_dispatch: jobs: close-issues: diff --git a/Cargo.lock b/Cargo.lock index 5ba9c2703948..a741aeaacda3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -106,9 +106,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "alloy-chains" -version = "0.1.51" +version = "0.1.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4e0f0136c085132939da6b753452ebed4efaa73fe523bb855b10c199c2ebfaf" +checksum = "da226340862e036ab26336dc99ca85311c6b662267c1440e1733890fd688802c" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -141,9 +141,9 @@ dependencies = [ [[package]] name = "alloy-consensus-any" -version = "0.9.0" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04519b5157de8a2166bddb07d84a63590100f1d3e2b3682144e787f1c27ccdac" +checksum = "0fa04e1882c31288ce1028fdf31b6ea94cfa9eafa2e497f903ded631c8c6a42c" dependencies = [ "alloy-consensus", "alloy-eips", @@ -175,9 +175,9 @@ dependencies = [ [[package]] name = "alloy-dyn-abi" -version = "0.8.15" +version = "0.8.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41056bde53ae10ffbbf11618efbe1e0290859e5eab0fe9ef82ebdb62f12a866f" +checksum = "44e3b98c37b3218924cd1d2a8570666b89662be54e5b182643855f783ea68b33" dependencies = [ "alloy-json-abi", "alloy-primitives", @@ -271,9 +271,9 @@ dependencies = [ [[package]] name = "alloy-json-abi" -version = "0.8.15" +version = "0.8.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c357da577dfb56998d01f574d81ad7a1958d248740a7981b205d69d65a7da404" +checksum = "731ea743b3d843bc657e120fb1d1e9cc94f5dab8107e35a82125a63e6420a102" dependencies = [ "alloy-primitives", "alloy-sol-type-parser", @@ -352,9 +352,9 @@ dependencies = [ [[package]] name = "alloy-primitives" -version = "0.8.15" +version = "0.8.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6259a506ab13e1d658796c31e6e39d2e2ee89243bcc505ddc613b35732e0a430" +checksum = "788bb18e8f61d5d9340b52143f27771daf7e1dccbaf2741621d2493f9debf52e" dependencies = [ "alloy-rlp", "arbitrary", @@ -366,7 +366,6 @@ dependencies = [ "foldhash", "getrandom 0.2.15", "hashbrown 0.15.2", - "hex-literal", "indexmap 2.7.0", "itoa", "k256", @@ -461,7 +460,7 @@ checksum = "5a833d97bf8a5f0f878daf2c8451fff7de7f9de38baa5a45d936ec718d81255a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -528,9 +527,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-any" -version = "0.9.0" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c64a83112b09bd293ef522bfa3800fa2d2df4d72f2bcd3a84b08490503b22e55" +checksum = "ca445cef0eb6c2cf51cfb4e214fbf1ebd00893ae2e6f3b944c8101b07990f988" dependencies = [ "alloy-consensus-any", "alloy-rpc-types-eth", @@ -692,23 +691,23 @@ dependencies = [ [[package]] name = "alloy-sol-macro" -version = "0.8.15" +version = "0.8.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9d64f851d95619233f74b310f12bcf16e0cbc27ee3762b6115c14a84809280a" +checksum = "a07b74d48661ab2e4b50bb5950d74dbff5e61dd8ed03bb822281b706d54ebacb" dependencies = [ "alloy-sol-macro-expander", "alloy-sol-macro-input", "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] name = "alloy-sol-macro-expander" -version = "0.8.15" +version = "0.8.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bf7ed1574b699f48bf17caab4e6e54c6d12bc3c006ab33d58b1e227c1c3559f" +checksum = "19cc9c7f20b90f9be1a8f71a3d8e283a43745137b0837b1a1cb13159d37cad72" dependencies = [ "alloy-sol-macro-input", "const-hex", @@ -717,31 +716,31 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", "syn-solidity", "tiny-keccak", ] [[package]] name = "alloy-sol-macro-input" -version = "0.8.15" +version = "0.8.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c02997ccef5f34f9c099277d4145f183b422938ed5322dc57a089fe9b9ad9ee" +checksum = "713b7e6dfe1cb2f55c80fb05fd22ed085a1b4e48217611365ed0ae598a74c6ac" dependencies = [ "const-hex", "dunce", "heck", "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", "syn-solidity", ] [[package]] name = "alloy-sol-type-parser" -version = "0.8.15" +version = "0.8.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce13ff37285b0870d0a0746992a4ae48efaf34b766ae4c2640fa15e5305f8e73" +checksum = "1eda2711ab2e1fb517fc6e2ffa9728c9a232e296d16810810e6957b781a1b8bc" dependencies = [ "serde", "winnow", @@ -749,9 +748,9 @@ dependencies = [ [[package]] name = "alloy-sol-types" -version = "0.8.15" +version = "0.8.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1174cafd6c6d810711b4e00383037bdb458efc4fe3dbafafa16567e0320c54d8" +checksum = "e3b478bc9c0c4737a04cd976accde4df7eba0bdc0d90ad6ff43d58bc93cf79c1" dependencies = [ "alloy-json-abi", "alloy-primitives", @@ -939,7 +938,7 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -1137,7 +1136,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -1173,18 +1172,18 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] name = "async-trait" -version = "0.1.83" +version = "0.1.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" +checksum = "3f934833b4b7233644e5848f235df3f57ed8c80f1528a26c3dfa13d2147fa056" dependencies = [ "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -1222,7 +1221,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -1328,7 +1327,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -1511,7 +1510,7 @@ checksum = "9fd3f870829131332587f607a7ff909f1af5fc523fd1b192db55fbbdf52e8d3c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", "synstructure", ] @@ -1595,9 +1594,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.11.1" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "786a307d683a5bf92e6fd5fd69a7eb613751668d1d8d67d802846dfe367c62c8" +checksum = "531a9155a481e2ee699d4f98f43c0ca4ff8ee1bfd55c31e9e98fb29d2b176fe0" dependencies = [ "memchr", "regex-automata 0.4.9", @@ -1633,7 +1632,7 @@ checksum = "3fa76293b4f7bb636ab88fd78228235b5248b4d05cc589aed610f954af5d7c7a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -1721,9 +1720,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.6" +version = "1.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d6dbb628b8f8555f86d0323c2eb39e3ec81901f4b83e091db8a6a76d316a333" +checksum = "a012a0df96dd6d06ba9a1b29d6402d1a5d77c6befd2566afdc26e10603dc93d7" dependencies = [ "jobserver", "libc", @@ -1851,7 +1850,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -1975,9 +1974,9 @@ dependencies = [ [[package]] name = "compact_str" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6050c3a16ddab2e412160b31f2c871015704239bca62f72f6e5f0be631d3f644" +checksum = "3b79c4069c6cad78e2e0cdfcbd26275770669fb39fd308a752dc110e83b9af32" dependencies = [ "castaway", "cfg-if", @@ -2318,7 +2317,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -2342,7 +2341,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -2353,7 +2352,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -2462,7 +2461,7 @@ checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" dependencies = [ "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -2483,7 +2482,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", "unicode-xid", ] @@ -2597,7 +2596,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -2606,12 +2605,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aac81fa3e28d21450aa4d2ac065992ba96a1d7303efbce51a95f4fd175b67562" -[[package]] -name = "downcast" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" - [[package]] name = "dunce" version = "1.0.5" @@ -2666,7 +2659,7 @@ dependencies = [ [[package]] name = "ef-tests" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -2749,7 +2742,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -2760,7 +2753,7 @@ checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38" dependencies = [ "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -2780,7 +2773,7 @@ checksum = "3bf679796c0322556351f287a51b49e48f7c4986e727b5dd78c972d30e2e16cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -2814,9 +2807,9 @@ dependencies = [ [[package]] name = "ethereum_ssz" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "036c84bd29bff35e29bbee3c8fc0e2fb95db12b6f2f3cae82a827fbc97256f3a" +checksum = "862e41ea8eea7508f70cfd8cd560f0c34bb0af37c719a8e06c2672f0f031d8e5" dependencies = [ "alloy-primitives", "ethereum_serde_utils", @@ -2829,14 +2822,14 @@ dependencies = [ [[package]] name = "ethereum_ssz_derive" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dc8e67e1f770f5aa4c2c2069aaaf9daee7ac21bed357a71b911b37a58966cfb" +checksum = "d31ecf6640112f61dc34b4d8359c081102969af0edd18381fed2052f6db6a410" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -3319,12 +3312,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "fragile" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" - [[package]] name = "fsevent-sys" version = "4.1.0" @@ -3411,7 +3398,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -3703,12 +3690,6 @@ dependencies = [ "serde", ] -[[package]] -name = "hex-literal" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" - [[package]] name = "hickory-proto" version = "0.25.0-alpha.4" @@ -4099,7 +4080,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -4156,7 +4137,7 @@ checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -4269,16 +4250,15 @@ dependencies = [ [[package]] name = "instability" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "898e106451f7335950c9cc64f8ec67b5f65698679ac67ed00619aeef14e1cf75" +checksum = "894813a444908c0c8c0e221b041771d107c4a21de1d317dc49bcc66e3c9e5b3f" dependencies = [ "darling", "indoc", - "pretty_assertions", "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -4527,7 +4507,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -4922,19 +4902,19 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] name = "metrics-exporter-prometheus" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b6f8152da6d7892ff1b7a1c0fa3f435e92b5918ad67035c3bb432111d9a29b" +checksum = "12779523996a67c13c84906a876ac6fe4d07a6e1adb54978378e13f199251a62" dependencies = [ "base64 0.22.1", "indexmap 2.7.0", "metrics", - "metrics-util", + "metrics-util 0.19.0", "quanta", "thiserror 1.0.69", ] @@ -4967,7 +4947,21 @@ dependencies = [ "indexmap 2.7.0", "metrics", "ordered-float", +] + +[[package]] +name = "metrics-util" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbd4884b1dd24f7d6628274a2f5ae22465c337c5ba065ec9b6edccddf8acc673" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", + "hashbrown 0.15.2", + "metrics", "quanta", + "rand 0.8.5", + "rand_xoshiro", "sketches-ddsketch", ] @@ -5046,32 +5040,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "mockall" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39a6bfcc6c8c7eed5ee98b9c3e33adc726054389233e201c95dab2d41a3839d2" -dependencies = [ - "cfg-if", - "downcast", - "fragile", - "mockall_derive", - "predicates", - "predicates-tree", -] - -[[package]] -name = "mockall_derive" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25ca3004c2efe9011bd4e461bd8256445052b9615405b4f7ea43fc8ca5c20898" -dependencies = [ - "cfg-if", - "proc-macro2", - "quote", - "syn 2.0.93", -] - [[package]] name = "modular-bitfield" version = "0.11.2" @@ -5095,21 +5063,20 @@ dependencies = [ [[package]] name = "moka" -version = "0.12.8" +version = "0.12.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32cf62eb4dd975d2dde76432fb1075c49e3ee2331cf36f1f8fd4b66550d32b6f" +checksum = "a9321642ca94a4282428e6ea4af8cc2ca4eac48ac7a6a4ea8f33f76d0ce70926" dependencies = [ "crossbeam-channel", "crossbeam-epoch", "crossbeam-utils", - "once_cell", + "loom", "parking_lot", - "quanta", + "portable-atomic", "rustc_version 0.4.1", "smallvec", "tagptr", "thiserror 1.0.69", - "triomphe", "uuid", ] @@ -5337,7 +5304,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -5351,9 +5318,9 @@ dependencies = [ [[package]] name = "nybbles" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3409fc85ac27b27d971ea7cd1aabafd2eefa6de7e481c8d4f707225c117e81a" +checksum = "8983bb634df7248924ee0c4c3a749609b5abcb082c28fffe3254b3eb3602b307" dependencies = [ "alloy-rlp", "arbitrary", @@ -5511,7 +5478,7 @@ dependencies = [ [[package]] name = "op-reth" -version = "1.1.4" +version = "1.1.5" dependencies = [ "clap", "reth-cli-util", @@ -5696,9 +5663,9 @@ dependencies = [ [[package]] name = "phf" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" dependencies = [ "phf_macros", "phf_shared", @@ -5706,9 +5673,9 @@ dependencies = [ [[package]] name = "phf_generator" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" dependencies = [ "phf_shared", "rand 0.8.5", @@ -5716,51 +5683,51 @@ dependencies = [ [[package]] name = "phf_macros" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" dependencies = [ "phf_generator", "phf_shared", "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] name = "phf_shared" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" dependencies = [ "siphasher", ] [[package]] name = "pin-project" -version = "1.1.7" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" +checksum = "1e2ec53ad785f4d35dac0adea7f7dc6f1bb277ad84a680c7afefeae05d1f5916" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.7" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" +checksum = "d56a66c0c55993aa927429d0f8a0abfd74f084e4d9c192cffed01e418d83eefb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] name = "pin-project-lite" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] name = "pin-utils" @@ -5883,32 +5850,6 @@ dependencies = [ "zerocopy", ] -[[package]] -name = "predicates" -version = "3.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5d19ee57562043d37e82899fade9a22ebab7be9cef5026b07fda9cdd4293573" -dependencies = [ - "anstyle", - "predicates-core", -] - -[[package]] -name = "predicates-core" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "727e462b119fe9c93fd0eb1429a5f7647394014cf3c04ab2c0350eeb09095ffa" - -[[package]] -name = "predicates-tree" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72dd2d6d381dfb73a193c7fca536518d7caee39fc8503f74e7dc0be0531b425c" -dependencies = [ - "predicates-core", - "termtree", -] - [[package]] name = "pretty_assertions" version = "1.4.1" @@ -5921,12 +5862,12 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.25" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" +checksum = "483f8c21f64f3ea09fe0f30f5d48c3e8eefe5dac9129f0075f76593b4c1da705" dependencies = [ "proc-macro2", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -5977,7 +5918,7 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -6075,14 +6016,14 @@ checksum = "4ee1c9ac207483d5e7db4940700de86a9aae46ef90c48b57f99fe7edb8345e49" dependencies = [ "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] name = "quanta" -version = "0.12.4" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773ce68d0bb9bc7ef20be3536ffe94e223e1f365bd374108b2659fac0c65cfe6" +checksum = "3bd1fe6824cea6538803de3ff1bc0cf3949024db3d43c9643024bfb33a807c0e" dependencies = [ "crossbeam-utils", "libc", @@ -6265,6 +6206,15 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand_xoshiro" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" +dependencies = [ + "rand_core 0.6.4", +] + [[package]] name = "ratatui" version = "0.28.1" @@ -6403,9 +6353,9 @@ checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" [[package]] name = "reqwest" -version = "0.12.11" +version = "0.12.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe060fe50f524be480214aba758c71f99f90ee8c83c5a36b5e9e1d568eb4eb3" +checksum = "43e734407157c3c2034e0258f5e4473ddb361b1e85f95a66690d67264d7cd1da" dependencies = [ "base64 0.22.1", "bytes", @@ -6459,7 +6409,7 @@ dependencies = [ [[package]] name = "reth" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -6532,7 +6482,7 @@ dependencies = [ [[package]] name = "reth-basic-payload-builder" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -6558,7 +6508,7 @@ dependencies = [ [[package]] name = "reth-beacon-consensus" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -6614,7 +6564,7 @@ dependencies = [ [[package]] name = "reth-bench" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-eips", "alloy-json-rpc", @@ -6650,7 +6600,7 @@ dependencies = [ [[package]] name = "reth-blockchain-tree" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -6688,7 +6638,7 @@ dependencies = [ [[package]] name = "reth-blockchain-tree-api" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -6703,7 +6653,7 @@ dependencies = [ [[package]] name = "reth-chain-state" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -6732,7 +6682,7 @@ dependencies = [ [[package]] name = "reth-chainspec" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-chains", "alloy-consensus", @@ -6743,17 +6693,15 @@ dependencies = [ "alloy-trie", "auto_impl", "derive_more", - "once_cell", "reth-ethereum-forks", "reth-network-peers", "reth-primitives-traits", - "reth-trie-common", "serde_json", ] [[package]] name = "reth-cli" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-genesis", "clap", @@ -6766,7 +6714,7 @@ dependencies = [ [[package]] name = "reth-cli-commands" -version = "1.1.4" +version = "1.1.5" dependencies = [ "ahash", "alloy-consensus", @@ -6834,7 +6782,7 @@ dependencies = [ [[package]] name = "reth-cli-runner" -version = "1.1.4" +version = "1.1.5" dependencies = [ "reth-tasks", "tokio", @@ -6843,7 +6791,7 @@ dependencies = [ [[package]] name = "reth-cli-util" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-eips", "alloy-primitives", @@ -6861,7 +6809,7 @@ dependencies = [ [[package]] name = "reth-codecs" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -6884,18 +6832,18 @@ dependencies = [ [[package]] name = "reth-codecs-derive" -version = "1.1.4" +version = "1.1.5" dependencies = [ "convert_case", "proc-macro2", "quote", "similar-asserts", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] name = "reth-config" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-primitives", "eyre", @@ -6911,7 +6859,7 @@ dependencies = [ [[package]] name = "reth-consensus" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -6924,23 +6872,21 @@ dependencies = [ [[package]] name = "reth-consensus-common" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", "alloy-primitives", - "mockall", "rand 0.8.5", "reth-chainspec", "reth-consensus", "reth-primitives", "reth-primitives-traits", - "reth-storage-api", ] [[package]] name = "reth-consensus-debug-client" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -6963,7 +6909,7 @@ dependencies = [ [[package]] name = "reth-db" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-primitives", @@ -7003,7 +6949,7 @@ dependencies = [ [[package]] name = "reth-db-api" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-genesis", @@ -7033,7 +6979,7 @@ dependencies = [ [[package]] name = "reth-db-common" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-genesis", @@ -7062,7 +7008,7 @@ dependencies = [ [[package]] name = "reth-db-models" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-eips", "alloy-primitives", @@ -7079,7 +7025,7 @@ dependencies = [ [[package]] name = "reth-discv4" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -7106,7 +7052,7 @@ dependencies = [ [[package]] name = "reth-discv5" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -7130,7 +7076,7 @@ dependencies = [ [[package]] name = "reth-dns-discovery" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-chains", "alloy-primitives", @@ -7158,7 +7104,7 @@ dependencies = [ [[package]] name = "reth-downloaders" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -7197,7 +7143,7 @@ dependencies = [ [[package]] name = "reth-e2e-test-utils" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -7226,7 +7172,6 @@ dependencies = [ "reth-payload-builder", "reth-payload-builder-primitives", "reth-payload-primitives", - "reth-primitives", "reth-provider", "reth-rpc-api", "reth-rpc-eth-api", @@ -7245,7 +7190,7 @@ dependencies = [ [[package]] name = "reth-ecies" -version = "1.1.4" +version = "1.1.5" dependencies = [ "aes", "alloy-primitives", @@ -7275,7 +7220,7 @@ dependencies = [ [[package]] name = "reth-engine-local" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-primitives", @@ -7306,7 +7251,7 @@ dependencies = [ [[package]] name = "reth-engine-primitives" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-primitives", @@ -7326,7 +7271,7 @@ dependencies = [ [[package]] name = "reth-engine-service" -version = "1.1.4" +version = "1.1.5" dependencies = [ "futures", "pin-project", @@ -7354,7 +7299,7 @@ dependencies = [ [[package]] name = "reth-engine-tree" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -7371,7 +7316,6 @@ dependencies = [ "rand 0.8.5", "rayon", "reth-beacon-consensus", - "reth-blockchain-tree", "reth-blockchain-tree-api", "reth-chain-state", "reth-chainspec", @@ -7383,6 +7327,7 @@ dependencies = [ "reth-evm", "reth-exex-types", "reth-metrics", + "reth-network", "reth-network-p2p", "reth-payload-builder", "reth-payload-builder-primitives", @@ -7411,7 +7356,7 @@ dependencies = [ [[package]] name = "reth-engine-util" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -7443,7 +7388,7 @@ dependencies = [ [[package]] name = "reth-errors" -version = "1.1.4" +version = "1.1.5" dependencies = [ "reth-blockchain-tree-api", "reth-consensus", @@ -7455,7 +7400,7 @@ dependencies = [ [[package]] name = "reth-eth-wire" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-chains", "alloy-eips", @@ -7492,7 +7437,7 @@ dependencies = [ [[package]] name = "reth-eth-wire-types" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-chains", "alloy-consensus", @@ -7517,7 +7462,7 @@ dependencies = [ [[package]] name = "reth-ethereum-cli" -version = "1.1.4" +version = "1.1.5" dependencies = [ "clap", "eyre", @@ -7528,7 +7473,7 @@ dependencies = [ [[package]] name = "reth-ethereum-consensus" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -7543,7 +7488,7 @@ dependencies = [ [[package]] name = "reth-ethereum-engine-primitives" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-eips", "alloy-primitives", @@ -7563,7 +7508,7 @@ dependencies = [ [[package]] name = "reth-ethereum-forks" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-chains", "alloy-eip2124", @@ -7578,7 +7523,7 @@ dependencies = [ [[package]] name = "reth-ethereum-payload-builder" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -7604,7 +7549,7 @@ dependencies = [ [[package]] name = "reth-ethereum-primitives" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -7627,7 +7572,7 @@ dependencies = [ [[package]] name = "reth-etl" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-primitives", "rayon", @@ -7637,7 +7582,7 @@ dependencies = [ [[package]] name = "reth-evm" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -7645,7 +7590,7 @@ dependencies = [ "auto_impl", "futures-util", "metrics", - "metrics-util", + "metrics-util 0.18.0", "parking_lot", "reth-chainspec", "reth-consensus", @@ -7666,7 +7611,7 @@ dependencies = [ [[package]] name = "reth-evm-ethereum" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -7691,7 +7636,7 @@ dependencies = [ [[package]] name = "reth-execution-errors" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-eips", "alloy-primitives", @@ -7706,7 +7651,7 @@ dependencies = [ [[package]] name = "reth-execution-types" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -7714,6 +7659,7 @@ dependencies = [ "arbitrary", "bincode", "rand 0.8.5", + "reth-ethereum-primitives", "reth-execution-errors", "reth-primitives", "reth-primitives-traits", @@ -7726,7 +7672,7 @@ dependencies = [ [[package]] name = "reth-exex" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -7738,7 +7684,6 @@ dependencies = [ "metrics", "parking_lot", "rand 0.8.5", - "reth-blockchain-tree", "reth-chain-state", "reth-chainspec", "reth-config", @@ -7769,13 +7714,12 @@ dependencies = [ [[package]] name = "reth-exex-test-utils" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-eips", "eyre", "futures-util", "rand 0.8.5", - "reth-blockchain-tree", "reth-chainspec", "reth-config", "reth-consensus", @@ -7802,7 +7746,7 @@ dependencies = [ [[package]] name = "reth-exex-types" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-eips", "alloy-primitives", @@ -7819,7 +7763,7 @@ dependencies = [ [[package]] name = "reth-fs-util" -version = "1.1.4" +version = "1.1.5" dependencies = [ "serde", "serde_json", @@ -7828,7 +7772,7 @@ dependencies = [ [[package]] name = "reth-invalid-block-hooks" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-primitives", @@ -7854,7 +7798,7 @@ dependencies = [ [[package]] name = "reth-ipc" -version = "1.1.4" +version = "1.1.5" dependencies = [ "async-trait", "bytes", @@ -7876,7 +7820,7 @@ dependencies = [ [[package]] name = "reth-libmdbx" -version = "1.1.4" +version = "1.1.5" dependencies = [ "bitflags 2.6.0", "byteorder", @@ -7897,7 +7841,7 @@ dependencies = [ [[package]] name = "reth-mdbx-sys" -version = "1.1.4" +version = "1.1.5" dependencies = [ "bindgen", "cc", @@ -7905,7 +7849,7 @@ dependencies = [ [[package]] name = "reth-metrics" -version = "1.1.4" +version = "1.1.5" dependencies = [ "futures", "metrics", @@ -7916,14 +7860,14 @@ dependencies = [ [[package]] name = "reth-net-banlist" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-primitives", ] [[package]] name = "reth-net-nat" -version = "1.1.4" +version = "1.1.5" dependencies = [ "futures-util", "if-addrs", @@ -7937,7 +7881,7 @@ dependencies = [ [[package]] name = "reth-network" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8000,7 +7944,7 @@ dependencies = [ [[package]] name = "reth-network-api" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-primitives", "alloy-rpc-types-admin", @@ -8022,7 +7966,7 @@ dependencies = [ [[package]] name = "reth-network-p2p" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8044,7 +7988,7 @@ dependencies = [ [[package]] name = "reth-network-peers" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -8060,7 +8004,7 @@ dependencies = [ [[package]] name = "reth-network-types" -version = "1.1.4" +version = "1.1.5" dependencies = [ "humantime-serde", "reth-ethereum-forks", @@ -8073,7 +8017,7 @@ dependencies = [ [[package]] name = "reth-nippy-jar" -version = "1.1.4" +version = "1.1.5" dependencies = [ "anyhow", "bincode", @@ -8091,7 +8035,7 @@ dependencies = [ [[package]] name = "reth-node-api" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-rpc-types-engine", "eyre", @@ -8112,7 +8056,7 @@ dependencies = [ [[package]] name = "reth-node-builder" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8177,7 +8121,7 @@ dependencies = [ [[package]] name = "reth-node-core" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8227,7 +8171,7 @@ dependencies = [ [[package]] name = "reth-node-ethereum" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-contract", @@ -8276,7 +8220,7 @@ dependencies = [ [[package]] name = "reth-node-events" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8300,7 +8244,7 @@ dependencies = [ [[package]] name = "reth-node-metrics" -version = "1.1.4" +version = "1.1.5" dependencies = [ "eyre", "http", @@ -8308,7 +8252,7 @@ dependencies = [ "metrics", "metrics-exporter-prometheus", "metrics-process", - "metrics-util", + "metrics-util 0.18.0", "procfs 0.16.0", "reqwest", "reth-metrics", @@ -8323,7 +8267,7 @@ dependencies = [ [[package]] name = "reth-node-types" -version = "1.1.4" +version = "1.1.5" dependencies = [ "reth-chainspec", "reth-db-api", @@ -8334,7 +8278,7 @@ dependencies = [ [[package]] name = "reth-optimism-chainspec" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-chains", "alloy-consensus", @@ -8356,7 +8300,7 @@ dependencies = [ [[package]] name = "reth-optimism-cli" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8403,7 +8347,7 @@ dependencies = [ [[package]] name = "reth-optimism-consensus" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-chains", "alloy-consensus", @@ -8437,7 +8381,7 @@ dependencies = [ [[package]] name = "reth-optimism-evm" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8469,7 +8413,7 @@ dependencies = [ [[package]] name = "reth-optimism-forks" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-chains", "alloy-primitives", @@ -8480,7 +8424,7 @@ dependencies = [ [[package]] name = "reth-optimism-node" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8537,7 +8481,7 @@ dependencies = [ [[package]] name = "reth-optimism-payload-builder" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8575,7 +8519,7 @@ dependencies = [ [[package]] name = "reth-optimism-primitives" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8591,7 +8535,6 @@ dependencies = [ "proptest-arbitrary-interop", "rand 0.8.5", "reth-codecs", - "reth-primitives", "reth-primitives-traits", "reth-zstd-compressors", "revm-primitives", @@ -8602,7 +8545,7 @@ dependencies = [ [[package]] name = "reth-optimism-rpc" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8648,7 +8591,7 @@ dependencies = [ [[package]] name = "reth-optimism-storage" -version = "1.1.4" +version = "1.1.5" dependencies = [ "reth-codecs", "reth-db-api", @@ -8659,7 +8602,7 @@ dependencies = [ [[package]] name = "reth-payload-builder" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-primitives", @@ -8682,7 +8625,7 @@ dependencies = [ [[package]] name = "reth-payload-builder-primitives" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-rpc-types-engine", "async-trait", @@ -8695,7 +8638,7 @@ dependencies = [ [[package]] name = "reth-payload-primitives" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-eips", "alloy-primitives", @@ -8713,7 +8656,7 @@ dependencies = [ [[package]] name = "reth-payload-util" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-primitives", @@ -8722,7 +8665,7 @@ dependencies = [ [[package]] name = "reth-payload-validator" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-rpc-types", "reth-chainspec", @@ -8732,7 +8675,7 @@ dependencies = [ [[package]] name = "reth-primitives" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8778,7 +8721,7 @@ dependencies = [ [[package]] name = "reth-primitives-traits" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8794,10 +8737,12 @@ dependencies = [ "derive_more", "k256", "modular-bitfield", + "once_cell", "op-alloy-consensus", "proptest", "proptest-arbitrary-interop", "rand 0.8.5", + "rayon", "reth-codecs", "revm-primitives", "secp256k1", @@ -8810,7 +8755,7 @@ dependencies = [ [[package]] name = "reth-provider" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8860,7 +8805,7 @@ dependencies = [ [[package]] name = "reth-prune" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8892,7 +8837,7 @@ dependencies = [ [[package]] name = "reth-prune-types" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-primitives", "arbitrary", @@ -8911,7 +8856,7 @@ dependencies = [ [[package]] name = "reth-revm" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8929,7 +8874,7 @@ dependencies = [ [[package]] name = "reth-rpc" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-dyn-abi", @@ -9000,7 +8945,7 @@ dependencies = [ [[package]] name = "reth-rpc-api" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-eips", "alloy-json-rpc", @@ -9024,7 +8969,7 @@ dependencies = [ [[package]] name = "reth-rpc-api-testing-util" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-eips", "alloy-primitives", @@ -9043,7 +8988,7 @@ dependencies = [ [[package]] name = "reth-rpc-builder" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-eips", "alloy-primitives", @@ -9093,7 +9038,7 @@ dependencies = [ [[package]] name = "reth-rpc-engine-api" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-eips", "alloy-primitives", @@ -9130,7 +9075,7 @@ dependencies = [ [[package]] name = "reth-rpc-eth-api" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-dyn-abi", @@ -9173,7 +9118,7 @@ dependencies = [ [[package]] name = "reth-rpc-eth-types" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -9215,7 +9160,7 @@ dependencies = [ [[package]] name = "reth-rpc-layer" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-rpc-types-engine", "http", @@ -9232,7 +9177,7 @@ dependencies = [ [[package]] name = "reth-rpc-server-types" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-eips", "alloy-primitives", @@ -9247,7 +9192,7 @@ dependencies = [ [[package]] name = "reth-rpc-types-compat" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -9263,7 +9208,7 @@ dependencies = [ [[package]] name = "reth-stages" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -9313,7 +9258,7 @@ dependencies = [ [[package]] name = "reth-stages-api" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-eips", "alloy-primitives", @@ -9342,7 +9287,7 @@ dependencies = [ [[package]] name = "reth-stages-types" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-primitives", "arbitrary", @@ -9359,7 +9304,7 @@ dependencies = [ [[package]] name = "reth-static-file" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-primitives", "assert_matches", @@ -9383,7 +9328,7 @@ dependencies = [ [[package]] name = "reth-static-file-types" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-primitives", "clap", @@ -9395,7 +9340,7 @@ dependencies = [ [[package]] name = "reth-storage-api" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -9419,7 +9364,7 @@ dependencies = [ [[package]] name = "reth-storage-errors" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-eips", "alloy-primitives", @@ -9433,7 +9378,7 @@ dependencies = [ [[package]] name = "reth-tasks" -version = "1.1.4" +version = "1.1.5" dependencies = [ "auto_impl", "dyn-clone", @@ -9450,7 +9395,7 @@ dependencies = [ [[package]] name = "reth-testing-utils" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -9464,7 +9409,7 @@ dependencies = [ [[package]] name = "reth-tokio-util" -version = "1.1.4" +version = "1.1.5" dependencies = [ "tokio", "tokio-stream", @@ -9473,7 +9418,7 @@ dependencies = [ [[package]] name = "reth-tracing" -version = "1.1.4" +version = "1.1.5" dependencies = [ "clap", "eyre", @@ -9487,7 +9432,7 @@ dependencies = [ [[package]] name = "reth-transaction-pool" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -9535,7 +9480,7 @@ dependencies = [ [[package]] name = "reth-trie" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-eips", @@ -9564,7 +9509,7 @@ dependencies = [ [[package]] name = "reth-trie-common" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-genesis", @@ -9593,7 +9538,7 @@ dependencies = [ [[package]] name = "reth-trie-db" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-consensus", "alloy-primitives", @@ -9622,7 +9567,7 @@ dependencies = [ [[package]] name = "reth-trie-parallel" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -9648,7 +9593,7 @@ dependencies = [ [[package]] name = "reth-trie-sparse" -version = "1.1.4" +version = "1.1.5" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -9672,16 +9617,16 @@ dependencies = [ [[package]] name = "reth-zstd-compressors" -version = "1.1.4" +version = "1.1.5" dependencies = [ "zstd", ] [[package]] name = "revm" -version = "19.0.0" +version = "19.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8905d0c5f10e767f13ea7cb8e502d315f144071a60fe2bd83977922dd3afa26" +checksum = "8b829dc9d6e62c5a540dfdceb0c4d2217e445bf5f6f5ed3866817e7a9637c019" dependencies = [ "auto_impl", "cfg-if", @@ -9903,7 +9848,7 @@ dependencies = [ "regex", "relative-path", "rustc_version 0.4.1", - "syn 2.0.93", + "syn 2.0.95", "unicode-ident", ] @@ -10035,7 +9980,7 @@ dependencies = [ "openssl-probe", "rustls-pki-types", "schannel", - "security-framework 3.1.0", + "security-framework 3.2.0", ] [[package]] @@ -10153,9 +10098,9 @@ dependencies = [ [[package]] name = "schnellru" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9a8ef13a93c54d20580de1e5c413e624e53121d42fc7e2c11d10ef7f8b02367" +checksum = "356285bbf17bea63d9e52e96bd18f039672ac92b55b8cb997d6162a2a37d1649" dependencies = [ "ahash", "cfg-if", @@ -10231,9 +10176,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "3.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81d3f8c9bfcc3cbb6b0179eb57042d75b1582bdc65c3cb95f3fa999509c03cbc" +checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316" dependencies = [ "bitflags 2.6.0", "core-foundation 0.10.0", @@ -10244,9 +10189,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.13.0" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1863fd3768cd83c56a7f60faa4dc0d403f1b6df0a38c3c25f44b7894e45370d5" +checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" dependencies = [ "core-foundation-sys", "libc", @@ -10308,14 +10253,14 @@ checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] name = "serde_json" -version = "1.0.134" +version = "1.0.135" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d" +checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9" dependencies = [ "indexmap 2.7.0", "itoa", @@ -10343,7 +10288,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -10394,7 +10339,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -10427,7 +10372,7 @@ checksum = "5d69265a08751de7844521fd15003ae0a888e035773ba05695c5c759a6f89eef" dependencies = [ "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -10584,9 +10529,9 @@ dependencies = [ [[package]] name = "siphasher" -version = "0.3.11" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" [[package]] name = "sketches-ddsketch" @@ -10710,7 +10655,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -10768,9 +10713,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.93" +version = "2.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c786062daee0d6db1132800e623df74274a0a87322d8e183338e01b3d98d058" +checksum = "46f71c0377baf4ef1cc3e3402ded576dccc315800fbc62dfc7fe04b009773b4a" dependencies = [ "proc-macro2", "quote", @@ -10779,14 +10724,14 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "0.8.15" +version = "0.8.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219389c1ebe89f8333df8bdfb871f6631c552ff399c23cac02480b6088aad8f0" +checksum = "31e89d8bf2768d277f40573c83a02a099e96d96dd3104e13ea676194e61ac4b0" dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -10806,7 +10751,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -10836,23 +10781,18 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.14.0" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" +checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704" dependencies = [ "cfg-if", "fastrand 2.3.0", + "getrandom 0.2.15", "once_cell", "rustix", "windows-sys 0.59.0", ] -[[package]] -name = "termtree" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" - [[package]] name = "test-fuzz" version = "6.0.0" @@ -10889,7 +10829,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -10937,7 +10877,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -10948,7 +10888,7 @@ checksum = "7b50fa271071aae2e6ee85f842e2e28ba8cd2c5fb67f11fcb1fd70b276f9e7d4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -11105,7 +11045,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -11306,7 +11246,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -11426,12 +11366,6 @@ dependencies = [ "rlp", ] -[[package]] -name = "triomphe" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859eb650cfee7434994602c3a68b25d77ad9e68c8a6cd491616ef86661382eb3" - [[package]] name = "try-lock" version = "0.2.5" @@ -11648,7 +11582,7 @@ checksum = "d674d135b4a8c1d7e813e2f8d1c9a58308aee4a680323066025e53132218bd91" dependencies = [ "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -11718,7 +11652,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", "wasm-bindgen-shared", ] @@ -11753,7 +11687,7 @@ checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -11919,7 +11853,7 @@ checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -11930,7 +11864,7 @@ checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -11941,7 +11875,7 @@ checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -11952,7 +11886,7 @@ checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -12144,9 +12078,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.20" +version = "0.6.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +checksum = "39281189af81c07ec09db316b302a3e67bf9bd7cbf6c820b50e35fee9c2fa980" dependencies = [ "memchr", ] @@ -12227,7 +12161,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", "synstructure", ] @@ -12249,7 +12183,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -12269,7 +12203,7 @@ checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", "synstructure", ] @@ -12290,7 +12224,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] @@ -12312,7 +12246,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.93", + "syn 2.0.95", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 66ddec61ccc3..0f0ea08e530f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace.package] -version = "1.1.4" +version = "1.1.5" edition = "2021" rust-version = "1.82" license = "MIT OR Apache-2.0" @@ -318,7 +318,7 @@ reth-codecs = { path = "crates/storage/codecs" } reth-codecs-derive = { path = "crates/storage/codecs/derive" } reth-config = { path = "crates/config" } reth-consensus = { path = "crates/consensus/consensus", default-features = false } -reth-consensus-common = { path = "crates/consensus/common" } +reth-consensus-common = { path = "crates/consensus/common", default-features = false } reth-consensus-debug-client = { path = "crates/consensus/debug-client" } reth-db = { path = "crates/storage/db", default-features = false } reth-db-api = { path = "crates/storage/db-api" } @@ -388,9 +388,7 @@ reth-payload-builder-primitives = { path = "crates/payload/builder-primitives" } reth-payload-primitives = { path = "crates/payload/primitives" } reth-payload-validator = { path = "crates/payload/validator" } reth-payload-util = { path = "crates/payload/util" } -reth-primitives = { path = "crates/primitives", default-features = false, features = [ - "std", -] } +reth-primitives = { path = "crates/primitives", default-features = false } reth-primitives-traits = { path = "crates/primitives-traits", default-features = false } reth-provider = { path = "crates/storage/provider" } reth-prune = { path = "crates/prune/prune" } @@ -426,7 +424,7 @@ reth-trie-sparse = { path = "crates/trie/sparse" } reth-zstd-compressors = { path = "crates/storage/zstd-compressors", default-features = false } # revm -revm = { version = "19.0.0", default-features = false } +revm = { version = "19.2.0", default-features = false } revm-primitives = { version = "15.1.0", default-features = false } revm-interpreter = { version = "15.0.0", default-features = false } revm-inspectors = "0.14.1" diff --git a/bin/reth/src/commands/debug_cmd/build_block.rs b/bin/reth/src/commands/debug_cmd/build_block.rs index 372a8712b211..a867a245903e 100644 --- a/bin/reth/src/commands/debug_cmd/build_block.rs +++ b/bin/reth/src/commands/debug_cmd/build_block.rs @@ -192,7 +192,7 @@ impl> Command { let pooled = transaction .clone() - .into_signed() + .into_tx() .try_into_pooled_eip4844(sidecar.clone()) .expect("should not fail to convert blob tx if it is already eip4844"); let encoded_length = pooled.encode_2718_len(); diff --git a/bin/reth/src/main.rs b/bin/reth/src/main.rs index e146912c06f9..f1f0a7d68cfb 100644 --- a/bin/reth/src/main.rs +++ b/bin/reth/src/main.rs @@ -39,6 +39,10 @@ pub struct EngineArgs { /// Configure the target number of blocks to keep in memory. #[arg(long = "engine.memory-block-buffer-target", conflicts_with = "legacy", default_value_t = DEFAULT_MEMORY_BLOCK_BUFFER_TARGET)] pub memory_block_buffer_target: u64, + + /// Enable state root task + #[arg(long = "engine.state-root-task", conflicts_with = "legacy")] + pub state_root_task_enabled: bool, } impl Default for EngineArgs { @@ -48,6 +52,7 @@ impl Default for EngineArgs { legacy: false, persistence_threshold: DEFAULT_PERSISTENCE_THRESHOLD, memory_block_buffer_target: DEFAULT_MEMORY_BLOCK_BUFFER_TARGET, + state_root_task_enabled: false, } } } @@ -71,7 +76,8 @@ fn main() { false => { let engine_tree_config = TreeConfig::default() .with_persistence_threshold(engine_args.persistence_threshold) - .with_memory_block_buffer_target(engine_args.memory_block_buffer_target); + .with_memory_block_buffer_target(engine_args.memory_block_buffer_target) + .with_state_root_task(engine_args.state_root_task_enabled); let handle = builder .with_types_and_provider::>() .with_components(EthereumNode::components()) diff --git a/book/cli/reth/node.md b/book/cli/reth/node.md index d8465d253fcf..c07585c44725 100644 --- a/book/cli/reth/node.md +++ b/book/cli/reth/node.md @@ -700,6 +700,9 @@ Engine: [default: 2] + --engine.state-root-task + Enable state root task + Logging: --log.stdout.format The format to use for logs written to stdout diff --git a/crates/blockchain-tree-api/src/error.rs b/crates/blockchain-tree-api/src/error.rs index 898b92dbd47c..ddd7cea7993c 100644 --- a/crates/blockchain-tree-api/src/error.rs +++ b/crates/blockchain-tree-api/src/error.rs @@ -55,7 +55,7 @@ pub enum BlockchainTreeError { } /// Canonical Errors -#[derive(thiserror::Error, Debug, Clone, PartialEq, Eq)] +#[derive(thiserror::Error, Debug, Clone)] pub enum CanonicalError { /// Error originating from validation operations. #[error(transparent)] @@ -167,7 +167,7 @@ impl std::fmt::Debug for InsertBlockError { } #[derive(thiserror::Error, Debug)] -#[error("Failed to insert block (hash={}, number={}, parent_hash={}): {kind}", +#[error("Failed to insert block (hash={}, number={}, parent_hash={}): {kind}", .block.hash(), .block.number, .block.parent_hash)] diff --git a/crates/blockchain-tree/src/blockchain_tree.rs b/crates/blockchain-tree/src/blockchain_tree.rs index b436c0dee350..3964ea53b7e2 100644 --- a/crates/blockchain-tree/src/blockchain_tree.rs +++ b/crates/blockchain-tree/src/blockchain_tree.rs @@ -1572,7 +1572,7 @@ mod tests { } let single_tx_cost = U256::from(INITIAL_BASE_FEE * MIN_TRANSACTION_GAS); - let mock_tx = |nonce: u64| -> RecoveredTx { + let mock_tx = |nonce: u64| -> RecoveredTx<_> { TransactionSigned::new_unhashed( Transaction::Eip1559(TxEip1559 { chain_id: chain_spec.chain.id(), @@ -1589,11 +1589,10 @@ mod tests { let mock_block = |number: u64, parent: Option, - body: Vec, + body: Vec>, num_of_signer_txs: u64| -> SealedBlockWithSenders { - let signed_body = - body.clone().into_iter().map(|tx| tx.into_signed()).collect::>(); + let signed_body = body.clone().into_iter().map(|tx| tx.into_tx()).collect::>(); let transactions_root = calculate_transaction_root(&signed_body); let receipts = body .iter() diff --git a/crates/chain-state/src/in_memory.rs b/crates/chain-state/src/in_memory.rs index 6133bc6a4b48..06d228a8f82e 100644 --- a/crates/chain-state/src/in_memory.rs +++ b/crates/chain-state/src/in_memory.rs @@ -18,7 +18,7 @@ use reth_primitives::{ use reth_primitives_traits::{Block, BlockBody as _, SignedTransaction}; use reth_storage_api::StateProviderBox; use reth_trie::{updates::TrieUpdates, HashedPostState}; -use std::{collections::BTreeMap, sync::Arc, time::Instant}; +use std::{collections::BTreeMap, ops::Deref, sync::Arc, time::Instant}; use tokio::sync::{broadcast, watch}; /// Size of the broadcast channel used to notify canonical state events. @@ -183,7 +183,7 @@ impl CanonicalInMemoryState { let in_memory_state = InMemoryState::new(blocks, numbers, pending); let header = in_memory_state .head_state() - .map_or_else(SealedHeader::default, |state| state.block_ref().block().header.clone()); + .map_or_else(SealedHeader::default, |state| state.block_ref().block().deref().clone()); let chain_info_tracker = ChainInfoTracker::new(header, finalized, safe); let (canon_state_notification_sender, _) = broadcast::channel(CANON_STATE_NOTIFICATION_CHANNEL_SIZE); @@ -462,7 +462,7 @@ impl CanonicalInMemoryState { /// Returns the `SealedHeader` corresponding to the pending state. pub fn pending_sealed_header(&self) -> Option> { - self.pending_state().map(|h| h.block_ref().block().header.clone()) + self.pending_state().map(|h| h.block_ref().block().deref().clone()) } /// Returns the `Header` corresponding to the pending state. @@ -584,7 +584,7 @@ impl CanonicalInMemoryState { index: index as u64, block_hash: block_state.hash(), block_number: block_state.block_ref().block.number(), - base_fee: block_state.block_ref().block.header.base_fee_per_gas(), + base_fee: block_state.block_ref().block.base_fee_per_gas(), timestamp: block_state.block_ref().block.timestamp(), excess_blob_gas: block_state.block_ref().block.excess_blob_gas(), }; @@ -664,7 +664,7 @@ impl BlockState { /// Returns the state root after applying the executed block that determines /// the state. pub fn state_root(&self) -> B256 { - self.block.block().header.state_root() + self.block.block().state_root() } /// Returns the `Receipts` of executed block that determines the state. @@ -789,7 +789,7 @@ impl BlockState { index: index as u64, block_hash: block_state.hash(), block_number: block_state.block_ref().block.number(), - base_fee: block_state.block_ref().block.header.base_fee_per_gas(), + base_fee: block_state.block_ref().block.base_fee_per_gas(), timestamp: block_state.block_ref().block.timestamp(), excess_blob_gas: block_state.block_ref().block.excess_blob_gas(), }; @@ -1318,7 +1318,7 @@ mod tests { ); // Check the pending header - assert_eq!(state.pending_header().unwrap(), block2.block().header.header().clone()); + assert_eq!(state.pending_header().unwrap(), block2.block().header().clone()); // Check the pending sealed header assert_eq!(state.pending_sealed_header().unwrap(), block2.block().header.clone()); diff --git a/crates/chain-state/src/test_utils.rs b/crates/chain-state/src/test_utils.rs index 292c21e54008..2ce18ea6d74c 100644 --- a/crates/chain-state/src/test_utils.rs +++ b/crates/chain-state/src/test_utils.rs @@ -94,7 +94,7 @@ impl TestBlockBuilder { ) -> SealedBlockWithSenders { let mut rng = thread_rng(); - let mock_tx = |nonce: u64| -> RecoveredTx { + let mock_tx = |nonce: u64| -> RecoveredTx<_> { let tx = Transaction::Eip1559(TxEip1559 { chain_id: self.chain_spec.chain.id(), nonce, @@ -112,7 +112,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; @@ -145,7 +145,7 @@ impl TestBlockBuilder { gas_limit: ETHEREUM_BLOCK_GAS_LIMIT, base_fee_per_gas: Some(INITIAL_BASE_FEE), transactions_root: calculate_transaction_root( - &transactions.clone().into_iter().map(|tx| tx.into_signed()).collect::>(), + &transactions.clone().into_iter().map(|tx| tx.into_tx()).collect::>(), ), receipts_root: calculate_receipt_root(&receipts), beneficiary: Address::random(), @@ -171,7 +171,7 @@ impl TestBlockBuilder { let block = SealedBlock::new( SealedHeader::seal(header), BlockBody { - transactions: transactions.into_iter().map(|tx| tx.into_signed()).collect(), + transactions: transactions.into_iter().map(|tx| tx.into_tx()).collect(), ommers: Vec::new(), withdrawals: Some(vec![].into()), }, diff --git a/crates/chainspec/Cargo.toml b/crates/chainspec/Cargo.toml index b050a0d909be..8e1d26f1a7d3 100644 --- a/crates/chainspec/Cargo.toml +++ b/crates/chainspec/Cargo.toml @@ -14,7 +14,7 @@ workspace = true # reth reth-ethereum-forks.workspace = true reth-network-peers.workspace = true -reth-trie-common.workspace = true +alloy-trie = { workspace = true, features = ["ethereum"] } reth-primitives-traits.workspace = true # ethereum @@ -26,7 +26,6 @@ alloy-consensus.workspace = true # misc auto_impl.workspace = true -once_cell.workspace = true serde_json.workspace = true derive_more.workspace = true @@ -47,19 +46,16 @@ std = [ "alloy-trie/std", "reth-primitives-traits/std", "alloy-consensus/std", - "once_cell/std", "alloy-rlp/std", "reth-ethereum-forks/std", "derive_more/std", "reth-network-peers/std", - "reth-trie-common/std", "serde_json/std" ] arbitrary = [ "alloy-chains/arbitrary", "reth-ethereum-forks/arbitrary", "reth-primitives-traits/arbitrary", - "reth-trie-common/arbitrary", "alloy-consensus/arbitrary", "alloy-eips/arbitrary", "alloy-primitives/arbitrary", @@ -67,5 +63,4 @@ arbitrary = [ ] test-utils = [ "reth-primitives-traits/test-utils", - "reth-trie-common/test-utils" ] diff --git a/crates/chainspec/src/lib.rs b/crates/chainspec/src/lib.rs index 2e97caba07cc..59950050722c 100644 --- a/crates/chainspec/src/lib.rs +++ b/crates/chainspec/src/lib.rs @@ -11,12 +11,6 @@ extern crate alloc; -use once_cell as _; -#[cfg(not(feature = "std"))] -pub(crate) use once_cell::sync::{Lazy as LazyLock, OnceCell as OnceLock}; -#[cfg(feature = "std")] -pub(crate) use std::sync::{LazyLock, OnceLock}; - /// Chain specific constants pub(crate) mod constants; pub use constants::MIN_TRANSACTION_GAS; @@ -40,6 +34,8 @@ pub use spec::{ DepositContract, ForkBaseFeeParams, DEV, HOLESKY, MAINNET, SEPOLIA, }; +use reth_primitives_traits::sync::OnceLock; + /// Simple utility to create a thread-safe sync cell with a value set. pub fn once_cell_set(value: T) -> OnceLock { let once = OnceLock::new(); diff --git a/crates/chainspec/src/spec.rs b/crates/chainspec/src/spec.rs index 755b892d976f..4307b0c6bee5 100644 --- a/crates/chainspec/src/spec.rs +++ b/crates/chainspec/src/spec.rs @@ -1,7 +1,7 @@ pub use alloy_eips::eip1559::BaseFeeParams; -use crate::{constants::MAINNET_DEPOSIT_CONTRACT, once_cell_set, EthChainSpec, LazyLock, OnceLock}; -use alloc::{boxed::Box, sync::Arc, vec::Vec}; +use crate::{constants::MAINNET_DEPOSIT_CONTRACT, once_cell_set, EthChainSpec}; +use alloc::{boxed::Box, collections::BTreeMap, string::String, sync::Arc, vec::Vec}; use alloy_chains::{Chain, NamedChain}; use alloy_consensus::{ constants::{ @@ -11,11 +11,14 @@ use alloy_consensus::{ Header, }; use alloy_eips::{ - eip1559::INITIAL_BASE_FEE, eip6110::MAINNET_DEPOSIT_CONTRACT_ADDRESS, + eip1559::INITIAL_BASE_FEE, + eip6110::MAINNET_DEPOSIT_CONTRACT_ADDRESS, eip7685::EMPTY_REQUESTS_HASH, + eip7840::{BlobParams, BlobScheduleItem}, }; use alloy_genesis::Genesis; use alloy_primitives::{address, b256, Address, BlockNumber, B256, U256}; +use alloy_trie::root::state_root_ref_unhashed; use derive_more::From; use reth_ethereum_forks::{ ChainHardforks, DisplayHardforks, EthereumHardfork, EthereumHardforks, ForkCondition, @@ -25,8 +28,10 @@ use reth_network_peers::{ base_nodes, base_testnet_nodes, holesky_nodes, mainnet_nodes, op_nodes, op_testnet_nodes, sepolia_nodes, NodeRecord, }; -use reth_primitives_traits::SealedHeader; -use reth_trie_common::root::state_root_ref_unhashed; +use reth_primitives_traits::{ + sync::{LazyLock, OnceLock}, + SealedHeader, +}; /// The Ethereum mainnet spec pub static MAINNET: LazyLock> = LazyLock::new(|| { @@ -50,6 +55,7 @@ pub static MAINNET: LazyLock> = LazyLock::new(|| { )), base_fee_params: BaseFeeParamsKind::Constant(BaseFeeParams::ethereum()), prune_delete_limit: 20000, + blob_params: HardforkBlobParams::default(), }; spec.genesis.config.dao_fork_support = true; spec.into() @@ -74,6 +80,7 @@ pub static SEPOLIA: LazyLock> = LazyLock::new(|| { )), base_fee_params: BaseFeeParamsKind::Constant(BaseFeeParams::ethereum()), prune_delete_limit: 10000, + blob_params: HardforkBlobParams::default(), }; spec.genesis.config.dao_fork_support = true; spec.into() @@ -96,6 +103,7 @@ pub static HOLESKY: LazyLock> = LazyLock::new(|| { )), base_fee_params: BaseFeeParamsKind::Constant(BaseFeeParams::ethereum()), prune_delete_limit: 10000, + blob_params: HardforkBlobParams::default(), }; spec.genesis.config.dao_fork_support = true; spec.into() @@ -154,6 +162,43 @@ impl From for BaseFeeParamsKind { #[derive(Clone, Debug, PartialEq, Eq, From)] pub struct ForkBaseFeeParams(Vec<(Box, BaseFeeParams)>); +/// A container for hardforks that use eip-7804 blobs. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct HardforkBlobParams { + /// Configuration for blob-related calculations for the Cancun hardfork. + pub cancun: BlobParams, + /// Configuration for blob-related calculations for the Prague hardfork. + pub prague: BlobParams, +} + +impl HardforkBlobParams { + /// Constructs params for chainspec from a provided blob schedule. + /// Falls back to defaults if the schedule is empty. + pub fn from_schedule(blob_schedule: &BTreeMap) -> Self { + let extract = |key: &str, default: fn() -> BlobParams| { + blob_schedule + .get(key) + .map(|item| BlobParams { + target_blob_count: item.target_blob_count, + max_blob_count: item.max_blob_count, + ..default() + }) + .unwrap_or_else(default) // Use default if key is missing + }; + + Self { + cancun: extract("cancun", BlobParams::cancun), + prague: extract("prague", BlobParams::prague), + } + } +} + +impl Default for HardforkBlobParams { + fn default() -> Self { + Self { cancun: BlobParams::cancun(), prague: BlobParams::prague() } + } +} + impl core::ops::Deref for ChainSpec { type Target = ChainHardforks; @@ -204,6 +249,9 @@ pub struct ChainSpec { /// The delete limit for pruner, per run. pub prune_delete_limit: usize, + + /// The settings passed for blob configurations for specific hardforks. + pub blob_params: HardforkBlobParams, } impl Default for ChainSpec { @@ -218,6 +266,7 @@ impl Default for ChainSpec { deposit_contract: Default::default(), base_fee_params: BaseFeeParamsKind::Constant(BaseFeeParams::ethereum()), prune_delete_limit: MAINNET.prune_delete_limit, + blob_params: Default::default(), } } } @@ -669,6 +718,9 @@ impl From for ChainSpec { // append the remaining unknown hardforks to ensure we don't filter any out ordered_hardforks.append(&mut hardforks); + // Extract blob parameters directly from blob_schedule + let blob_params = HardforkBlobParams::from_schedule(&genesis.config.blob_schedule); + // NOTE: in full node, we prune all receipts except the deposit contract's. We do not // have the deployment block in the genesis file, so we use block zero. We use the same // deposit topic as the mainnet contract if we have the deposit contract address in the @@ -684,6 +736,7 @@ impl From for ChainSpec { hardforks: ChainHardforks::new(ordered_hardforks), paris_block_and_final_difficulty, deposit_contract, + blob_params, ..Default::default() } } @@ -973,17 +1026,14 @@ pub fn test_fork_ids(spec: &ChainSpec, cases: &[(Head, ForkId)]) { #[cfg(test)] mod tests { - use core::ops::Deref; - use std::{collections::HashMap, str::FromStr}; - + use super::*; use alloy_chains::Chain; use alloy_genesis::{ChainConfig, GenesisAccount}; use alloy_primitives::{b256, hex}; - use alloy_trie::EMPTY_ROOT_HASH; + use alloy_trie::{TrieAccount, EMPTY_ROOT_HASH}; + use core::ops::Deref; use reth_ethereum_forks::{ForkCondition, ForkHash, ForkId, Head}; - use reth_trie_common::TrieAccount; - - use super::*; + use std::{collections::HashMap, str::FromStr}; fn test_hardfork_fork_ids(spec: &ChainSpec, cases: &[(EthereumHardfork, ForkId)]) { for (hardfork, expected_id) in cases { diff --git a/crates/consensus/common/Cargo.toml b/crates/consensus/common/Cargo.toml index bc7f80a515b9..448b3a16830f 100644 --- a/crates/consensus/common/Cargo.toml +++ b/crates/consensus/common/Cargo.toml @@ -24,7 +24,16 @@ alloy-eips.workspace = true [dev-dependencies] alloy-consensus.workspace = true -reth-storage-api.workspace = true rand.workspace = true -mockall = "0.13" +[features] +default = ["std"] +std = [ + "alloy-consensus/std", + "alloy-eips/std", + "alloy-primitives/std", + "reth-chainspec/std", + "reth-consensus/std", + "reth-primitives/std", + "reth-primitives-traits/std" +] diff --git a/crates/consensus/common/src/lib.rs b/crates/consensus/common/src/lib.rs index e3503656bb34..9e5eb2aaf0fd 100644 --- a/crates/consensus/common/src/lib.rs +++ b/crates/consensus/common/src/lib.rs @@ -7,6 +7,7 @@ )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +#![cfg_attr(not(feature = "std"), no_std)] /// Collection of consensus validation methods. pub mod validation; diff --git a/crates/consensus/common/src/validation.rs b/crates/consensus/common/src/validation.rs index d1131baee80c..67ecc886ea67 100644 --- a/crates/consensus/common/src/validation.rs +++ b/crates/consensus/common/src/validation.rs @@ -140,11 +140,11 @@ where { // Check ommers hash let ommers_hash = block.body().calculate_ommers_root(); - if Some(block.header.ommers_hash()) != ommers_hash { + if Some(block.ommers_hash()) != ommers_hash { return Err(ConsensusError::BodyOmmersHashDiff( GotExpected { got: ommers_hash.unwrap_or(EMPTY_OMMER_ROOT_HASH), - expected: block.header.ommers_hash(), + expected: block.ommers_hash(), } .into(), )) @@ -335,122 +335,12 @@ pub fn validate_against_parent_4844( #[cfg(test)] mod tests { use super::*; - use alloy_consensus::{Header, TxEip4844, EMPTY_OMMER_ROOT_HASH, EMPTY_ROOT_HASH}; - use alloy_eips::{ - eip4895::{Withdrawal, Withdrawals}, - BlockHashOrNumber, - }; - use alloy_primitives::{ - hex_literal::hex, Address, BlockHash, BlockNumber, Bytes, PrimitiveSignature as Signature, - U256, - }; - use mockall::mock; + use alloy_consensus::{Header, TxEip4844}; + use alloy_eips::eip4895::Withdrawals; + use alloy_primitives::{Address, Bytes, PrimitiveSignature as Signature, U256}; use rand::Rng; use reth_chainspec::ChainSpecBuilder; - use reth_primitives::{proofs, Account, BlockBody, Transaction, TransactionSigned}; - use reth_storage_api::{ - errors::provider::ProviderResult, AccountReader, HeaderProvider, WithdrawalsProvider, - }; - use std::ops::RangeBounds; - - mock! { - WithdrawalsProvider {} - - impl WithdrawalsProvider for WithdrawalsProvider { - fn latest_withdrawal(&self) -> ProviderResult> ; - - fn withdrawals_by_block( - &self, - _id: BlockHashOrNumber, - _timestamp: u64, - ) -> ProviderResult> ; - } - } - - struct Provider { - is_known: bool, - parent: Option
, - account: Option, - withdrawals_provider: MockWithdrawalsProvider, - } - - impl Provider { - /// New provider with parent - fn new(parent: Option
) -> Self { - Self { - is_known: false, - parent, - account: None, - withdrawals_provider: MockWithdrawalsProvider::new(), - } - } - } - - impl AccountReader for Provider { - fn basic_account(&self, _address: &Address) -> ProviderResult> { - Ok(self.account) - } - } - - impl HeaderProvider for Provider { - type Header = Header; - - fn is_known(&self, _block_hash: &BlockHash) -> ProviderResult { - Ok(self.is_known) - } - - fn header(&self, _block_number: &BlockHash) -> ProviderResult> { - Ok(self.parent.clone()) - } - - fn header_by_number(&self, _num: u64) -> ProviderResult> { - Ok(self.parent.clone()) - } - - 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, - _block_number: BlockNumber, - ) -> ProviderResult> { - Ok(None) - } - - fn sealed_headers_while( - &self, - _range: impl RangeBounds, - _predicate: impl FnMut(&SealedHeader) -> bool, - ) -> ProviderResult> { - Ok(vec![]) - } - } - - impl WithdrawalsProvider for Provider { - fn withdrawals_by_block( - &self, - _id: BlockHashOrNumber, - _timestamp: u64, - ) -> ProviderResult> { - self.withdrawals_provider.withdrawals_by_block(_id, _timestamp) - } - - fn latest_withdrawal(&self) -> ProviderResult> { - self.withdrawals_provider.latest_withdrawal() - } - } + use reth_primitives::{proofs, BlockBody, Transaction, TransactionSigned}; fn mock_blob_tx(nonce: u64, num_blobs: usize) -> TransactionSigned { let mut rng = rand::thread_rng(); @@ -473,97 +363,6 @@ mod tests { TransactionSigned::new_unhashed(request, signature) } - /// got test block - fn mock_block() -> (SealedBlock, Header) { - // https://etherscan.io/block/15867168 where transaction root and receipts root are cleared - // empty merkle tree: 0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 - - let header = Header { - parent_hash: hex!("859fad46e75d9be177c2584843501f2270c7e5231711e90848290d12d7c6dcdd").into(), - ommers_hash: EMPTY_OMMER_ROOT_HASH, - beneficiary: hex!("4675c7e5baafbffbca748158becba61ef3b0a263").into(), - state_root: hex!("8337403406e368b3e40411138f4868f79f6d835825d55fd0c2f6e17b1a3948e9").into(), - transactions_root: EMPTY_ROOT_HASH, - receipts_root: EMPTY_ROOT_HASH, - logs_bloom: hex!("002400000000004000220000800002000000000000000000000000000000100000000000000000100000000000000021020000000800000006000000002100040000000c0004000000000008000008200000000000000000000000008000000001040000020000020000002000000800000002000020000000022010000000000000010002001000000000020200000000000001000200880000004000000900020000000000020000000040000000000000000000000000000080000000000001000002000000000000012000200020000000000000001000000000000020000010321400000000100000000000000000000000000000400000000000000000").into(), - difficulty: U256::ZERO, // total difficulty: 0xc70d815d562d3cfa955).into(), - number: 0xf21d20, - gas_limit: 0x1c9c380, - gas_used: 0x6e813, - timestamp: 0x635f9657, - extra_data: hex!("")[..].into(), - mix_hash: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(), - nonce: 0x0000000000000000u64.into(), - base_fee_per_gas: 0x28f0001df.into(), - withdrawals_root: None, - blob_gas_used: None, - excess_blob_gas: None, - parent_beacon_block_root: None, - requests_hash: None, - }; - // size: 0x9b5 - - let mut parent = header.clone(); - parent.gas_used = 17763076; - parent.gas_limit = 30000000; - parent.base_fee_per_gas = Some(0x28041f7f5); - parent.number -= 1; - parent.timestamp -= 1; - - let ommers = Vec::new(); - let transactions = Vec::new(); - - ( - SealedBlock::new( - SealedHeader::seal(header), - BlockBody { transactions, ommers, withdrawals: None }, - ), - parent, - ) - } - - #[test] - fn valid_withdrawal_index() { - let chain_spec = ChainSpecBuilder::mainnet().shanghai_activated().build(); - - let create_block_with_withdrawals = |indexes: &[u64]| { - let withdrawals = Withdrawals::new( - indexes - .iter() - .map(|idx| Withdrawal { index: *idx, ..Default::default() }) - .collect(), - ); - - let header = Header { - withdrawals_root: Some(proofs::calculate_withdrawals_root(&withdrawals)), - ..Default::default() - }; - - SealedBlock::new( - SealedHeader::seal(header), - BlockBody { withdrawals: Some(withdrawals), ..Default::default() }, - ) - }; - - // Single withdrawal - let block: SealedBlock = create_block_with_withdrawals(&[1]); - assert_eq!(validate_block_pre_execution(&block, &chain_spec), Ok(())); - - // Multiple increasing withdrawals - let block = create_block_with_withdrawals(&[1, 2, 3]); - assert_eq!(validate_block_pre_execution(&block, &chain_spec), Ok(())); - let block = create_block_with_withdrawals(&[5, 6, 7, 8, 9]); - assert_eq!(validate_block_pre_execution(&block, &chain_spec), Ok(())); - let (_, parent) = mock_block(); - - // Withdrawal index should be the last withdrawal index + 1 - let mut provider = Provider::new(Some(parent)); - provider - .withdrawals_provider - .expect_latest_withdrawal() - .return_const(Ok(Some(Withdrawal { index: 2, ..Default::default() }))); - } - #[test] fn cancun_block_incorrect_blob_gas_used() { let chain_spec = ChainSpecBuilder::mainnet().cancun_activated().build(); diff --git a/crates/e2e-test-utils/Cargo.toml b/crates/e2e-test-utils/Cargo.toml index 7cb8516816b8..50784ddd5756 100644 --- a/crates/e2e-test-utils/Cargo.toml +++ b/crates/e2e-test-utils/Cargo.toml @@ -22,7 +22,6 @@ reth-rpc-api = { workspace = true, features = ["client"] } reth-payload-builder = { workspace = true, features = ["test-utils"] } reth-payload-builder-primitives.workspace = true reth-payload-primitives.workspace = true -reth-primitives.workspace = true reth-provider.workspace = true reth-network.workspace = true reth-node-api.workspace = true @@ -35,7 +34,7 @@ reth-engine-local.workspace = true reth-tasks.workspace = true # currently need to enable this for workspace level -reth-optimism-primitives = { workspace = true, features = ["arbitrary"] } +reth-optimism-primitives = { workspace = true, features = ["arbitrary", "serde"] } # rpc jsonrpsee.workspace = true diff --git a/crates/engine/tree/Cargo.toml b/crates/engine/tree/Cargo.toml index fb5da883f14c..4bf9663fedbb 100644 --- a/crates/engine/tree/Cargo.toml +++ b/crates/engine/tree/Cargo.toml @@ -14,7 +14,6 @@ workspace = true # reth reth-beacon-consensus.workspace = true reth-blockchain-tree-api.workspace = true -reth-blockchain-tree.workspace = true reth-chain-state.workspace = true reth-chainspec = { workspace = true, optional = true } reth-consensus.workspace = true @@ -31,9 +30,12 @@ reth-provider.workspace = true reth-prune.workspace = true reth-stages-api.workspace = true reth-tasks.workspace = true +reth-trie-db.workspace = true reth-trie-parallel.workspace = true reth-trie-sparse.workspace = true reth-trie.workspace = true +# TODO(mattsse): get rid of this by optimizing cache +reth-network.workspace = true # alloy alloy-consensus.workspace = true @@ -81,7 +83,6 @@ reth-static-file.workspace = true reth-testing-utils.workspace = true reth-tracing.workspace = true reth-trie-db.workspace = true -proptest.workspace = true # alloy alloy-rlp.workspace = true @@ -89,6 +90,7 @@ alloy-rlp.workspace = true assert_matches.workspace = true criterion.workspace = true crossbeam-channel = "0.5.13" +proptest.workspace = true rand.workspace = true [[bench]] @@ -101,26 +103,26 @@ harness = false [features] test-utils = [ - "reth-blockchain-tree/test-utils", - "reth-chain-state/test-utils", - "reth-chainspec/test-utils", - "reth-consensus/test-utils", - "reth-db/test-utils", - "reth-evm/test-utils", - "reth-network-p2p/test-utils", - "reth-payload-builder/test-utils", - "reth-primitives/test-utils", - "reth-primitives-traits/test-utils", - "reth-provider/test-utils", - "reth-prune-types", - "reth-prune-types?/test-utils", - "reth-stages-api/test-utils", - "reth-stages/test-utils", - "reth-static-file", - "reth-tracing", - "reth-trie/test-utils", - "reth-trie-sparse/test-utils", - "reth-prune-types?/test-utils", - "reth-trie-db/test-utils", - "reth-trie-parallel/test-utils", + "reth-chain-state/test-utils", + "reth-chainspec/test-utils", + "reth-consensus/test-utils", + "reth-db/test-utils", + "reth-evm/test-utils", + "reth-network-p2p/test-utils", + "reth-payload-builder/test-utils", + "reth-primitives/test-utils", + "reth-primitives-traits/test-utils", + "reth-provider/test-utils", + "reth-prune-types", + "reth-prune-types?/test-utils", + "reth-stages-api/test-utils", + "reth-stages/test-utils", + "reth-static-file", + "reth-tracing", + "reth-trie/test-utils", + "reth-trie-sparse/test-utils", + "reth-prune-types?/test-utils", + "reth-trie-db/test-utils", + "reth-trie-parallel/test-utils", + "reth-network/test-utils" ] diff --git a/crates/engine/tree/src/tree/block_buffer.rs b/crates/engine/tree/src/tree/block_buffer.rs new file mode 100644 index 000000000000..675e1b5c3255 --- /dev/null +++ b/crates/engine/tree/src/tree/block_buffer.rs @@ -0,0 +1,489 @@ +use crate::tree::metrics::BlockBufferMetrics; +use alloy_consensus::BlockHeader; +use alloy_primitives::{BlockHash, BlockNumber}; +use reth_network::cache::LruCache; +use reth_primitives::SealedBlockWithSenders; +use reth_primitives_traits::Block; +use std::collections::{BTreeMap, HashMap, HashSet}; + +/// Contains the tree of pending blocks that cannot be executed due to missing parent. +/// It allows to store unconnected blocks for potential future inclusion. +/// +/// The buffer has three main functionalities: +/// * [`BlockBuffer::insert_block`] for inserting blocks inside the buffer. +/// * [`BlockBuffer::remove_block_with_children`] for connecting blocks if the parent gets received +/// and inserted. +/// * [`BlockBuffer::remove_old_blocks`] to remove old blocks that precede the finalized number. +/// +/// Note: Buffer is limited by number of blocks that it can contain and eviction of the block +/// is done by last recently used block. +#[derive(Debug)] +pub(super) struct BlockBuffer { + /// All blocks in the buffer stored by their block hash. + pub(crate) blocks: HashMap>, + /// Map of any parent block hash (even the ones not currently in the buffer) + /// to the buffered children. + /// Allows connecting buffered blocks by parent. + pub(crate) parent_to_child: HashMap>, + /// `BTreeMap` tracking the earliest blocks by block number. + /// Used for removal of old blocks that precede finalization. + pub(crate) earliest_blocks: BTreeMap>, + /// LRU used for tracing oldest inserted blocks that are going to be + /// first in line for evicting if `max_blocks` limit is hit. + /// + /// Used as counter of amount of blocks inside buffer. + pub(crate) lru: LruCache, + /// Various metrics for the block buffer. + pub(crate) metrics: BlockBufferMetrics, +} + +impl BlockBuffer { + /// Create new buffer with max limit of blocks + pub(super) fn new(limit: u32) -> Self { + Self { + blocks: Default::default(), + parent_to_child: Default::default(), + earliest_blocks: Default::default(), + lru: LruCache::new(limit), + metrics: Default::default(), + } + } + + /// Return reference to the requested block. + pub(super) fn block(&self, hash: &BlockHash) -> Option<&SealedBlockWithSenders> { + self.blocks.get(hash) + } + + /// Return a reference to the lowest ancestor of the given block in the buffer. + pub(super) fn lowest_ancestor(&self, hash: &BlockHash) -> Option<&SealedBlockWithSenders> { + let mut current_block = self.blocks.get(hash)?; + while let Some(parent) = self.blocks.get(¤t_block.parent_hash()) { + current_block = parent; + } + Some(current_block) + } + + /// Insert a correct block inside the buffer. + pub(super) fn insert_block(&mut self, block: SealedBlockWithSenders) { + let hash = block.hash(); + + self.parent_to_child.entry(block.parent_hash()).or_default().insert(hash); + self.earliest_blocks.entry(block.number()).or_default().insert(hash); + self.blocks.insert(hash, block); + + if let (_, Some(evicted_hash)) = self.lru.insert_and_get_evicted(hash) { + // evict the block if limit is hit + if let Some(evicted_block) = self.remove_block(&evicted_hash) { + // evict the block if limit is hit + self.remove_from_parent(evicted_block.parent_hash(), &evicted_hash); + } + } + self.metrics.blocks.set(self.blocks.len() as f64); + } + + /// Removes the given block from the buffer and also all the children of the block. + /// + /// This is used to get all the blocks that are dependent on the block that is included. + /// + /// Note: that order of returned blocks is important and the blocks with lower block number + /// in the chain will come first so that they can be executed in the correct order. + pub(super) fn remove_block_with_children( + &mut self, + parent_hash: &BlockHash, + ) -> Vec> { + let removed = self + .remove_block(parent_hash) + .into_iter() + .chain(self.remove_children(vec![*parent_hash])) + .collect(); + self.metrics.blocks.set(self.blocks.len() as f64); + removed + } + + /// Discard all blocks that precede block number from the buffer. + pub(super) fn remove_old_blocks(&mut self, block_number: BlockNumber) { + let mut block_hashes_to_remove = Vec::new(); + + // discard all blocks that are before the finalized number. + while let Some(entry) = self.earliest_blocks.first_entry() { + if *entry.key() > block_number { + break + } + let block_hashes = entry.remove(); + block_hashes_to_remove.extend(block_hashes); + } + + // remove from other collections. + for block_hash in &block_hashes_to_remove { + // It's fine to call + self.remove_block(block_hash); + } + + self.remove_children(block_hashes_to_remove); + self.metrics.blocks.set(self.blocks.len() as f64); + } + + /// Remove block entry + fn remove_from_earliest_blocks(&mut self, number: BlockNumber, hash: &BlockHash) { + if let Some(entry) = self.earliest_blocks.get_mut(&number) { + entry.remove(hash); + if entry.is_empty() { + self.earliest_blocks.remove(&number); + } + } + } + + /// Remove from parent child connection. This method does not remove children. + fn remove_from_parent(&mut self, parent_hash: BlockHash, hash: &BlockHash) { + // remove from parent to child connection, but only for this block parent. + if let Some(entry) = self.parent_to_child.get_mut(&parent_hash) { + entry.remove(hash); + // if set is empty remove block entry. + if entry.is_empty() { + self.parent_to_child.remove(&parent_hash); + } + } + } + + /// Removes block from inner collections. + /// This method will only remove the block if it's present inside `self.blocks`. + /// The block might be missing from other collections, the method will only ensure that it has + /// been removed. + fn remove_block(&mut self, hash: &BlockHash) -> Option> { + let block = self.blocks.remove(hash)?; + self.remove_from_earliest_blocks(block.number(), hash); + self.remove_from_parent(block.parent_hash(), hash); + self.lru.remove(hash); + Some(block) + } + + /// Remove all children and their descendants for the given blocks and return them. + fn remove_children(&mut self, parent_hashes: Vec) -> Vec> { + // remove all parent child connection and all the child children blocks that are connected + // to the discarded parent blocks. + let mut remove_parent_children = parent_hashes; + let mut removed_blocks = Vec::new(); + while let Some(parent_hash) = remove_parent_children.pop() { + // get this child blocks children and add them to the remove list. + if let Some(parent_children) = self.parent_to_child.remove(&parent_hash) { + // remove child from buffer + for child_hash in &parent_children { + if let Some(block) = self.remove_block(child_hash) { + removed_blocks.push(block); + } + } + remove_parent_children.extend(parent_children); + } + } + removed_blocks + } +} + +#[cfg(test)] +mod tests { + use super::*; + use alloy_eips::BlockNumHash; + use alloy_primitives::BlockHash; + use reth_primitives::SealedBlockWithSenders; + use reth_testing_utils::generators::{self, random_block, BlockParams, Rng}; + use std::collections::HashMap; + + /// Create random block with specified number and parent hash. + fn create_block(rng: &mut R, number: u64, parent: BlockHash) -> SealedBlockWithSenders { + let block = + random_block(rng, number, BlockParams { parent: Some(parent), ..Default::default() }); + block.seal_with_senders().unwrap() + } + + /// Assert that all buffer collections have the same data length. + fn assert_buffer_lengths(buffer: &BlockBuffer, expected: usize) { + assert_eq!(buffer.blocks.len(), expected); + assert_eq!(buffer.lru.len(), expected); + assert_eq!( + buffer.parent_to_child.iter().fold(0, |acc, (_, hashes)| acc + hashes.len()), + expected + ); + assert_eq!( + buffer.earliest_blocks.iter().fold(0, |acc, (_, hashes)| acc + hashes.len()), + expected + ); + } + + /// Assert that the block was removed from all buffer collections. + fn assert_block_removal(buffer: &BlockBuffer, block: &SealedBlockWithSenders) { + assert!(!buffer.blocks.contains_key(&block.hash())); + assert!(buffer + .parent_to_child + .get(&block.parent_hash) + .and_then(|p| p.get(&block.hash())) + .is_none()); + assert!(buffer + .earliest_blocks + .get(&block.number) + .and_then(|hashes| hashes.get(&block.hash())) + .is_none()); + } + + #[test] + fn simple_insertion() { + let mut rng = generators::rng(); + let parent = rng.gen(); + let block1 = create_block(&mut rng, 10, parent); + let mut buffer = BlockBuffer::new(3); + + buffer.insert_block(block1.clone()); + assert_buffer_lengths(&buffer, 1); + assert_eq!(buffer.block(&block1.hash()), Some(&block1)); + } + + #[test] + fn take_entire_chain_of_children() { + let mut rng = generators::rng(); + + let main_parent_hash = rng.gen(); + let block1 = create_block(&mut rng, 10, main_parent_hash); + let block2 = create_block(&mut rng, 11, block1.hash()); + let block3 = create_block(&mut rng, 12, block2.hash()); + let parent4 = rng.gen(); + let block4 = create_block(&mut rng, 14, parent4); + + let mut buffer = BlockBuffer::new(5); + + buffer.insert_block(block1.clone()); + buffer.insert_block(block2.clone()); + buffer.insert_block(block3.clone()); + buffer.insert_block(block4.clone()); + + assert_buffer_lengths(&buffer, 4); + assert_eq!(buffer.block(&block4.hash()), Some(&block4)); + assert_eq!(buffer.block(&block2.hash()), Some(&block2)); + assert_eq!(buffer.block(&main_parent_hash), None); + + assert_eq!(buffer.lowest_ancestor(&block4.hash()), Some(&block4)); + assert_eq!(buffer.lowest_ancestor(&block3.hash()), Some(&block1)); + assert_eq!(buffer.lowest_ancestor(&block1.hash()), Some(&block1)); + assert_eq!( + buffer.remove_block_with_children(&main_parent_hash), + vec![block1, block2, block3] + ); + assert_buffer_lengths(&buffer, 1); + } + + #[test] + fn take_all_multi_level_children() { + let mut rng = generators::rng(); + + let main_parent_hash = rng.gen(); + let block1 = create_block(&mut rng, 10, main_parent_hash); + let block2 = create_block(&mut rng, 11, block1.hash()); + let block3 = create_block(&mut rng, 11, block1.hash()); + let block4 = create_block(&mut rng, 12, block2.hash()); + + let mut buffer = BlockBuffer::new(5); + + buffer.insert_block(block1.clone()); + buffer.insert_block(block2.clone()); + buffer.insert_block(block3.clone()); + buffer.insert_block(block4.clone()); + + assert_buffer_lengths(&buffer, 4); + assert_eq!( + buffer + .remove_block_with_children(&main_parent_hash) + .into_iter() + .map(|b| (b.hash(), b)) + .collect::>(), + HashMap::from([ + (block1.hash(), block1), + (block2.hash(), block2), + (block3.hash(), block3), + (block4.hash(), block4) + ]) + ); + assert_buffer_lengths(&buffer, 0); + } + + #[test] + fn take_block_with_children() { + let mut rng = generators::rng(); + + let main_parent = BlockNumHash::new(9, rng.gen()); + let block1 = create_block(&mut rng, 10, main_parent.hash); + let block2 = create_block(&mut rng, 11, block1.hash()); + let block3 = create_block(&mut rng, 11, block1.hash()); + let block4 = create_block(&mut rng, 12, block2.hash()); + + let mut buffer = BlockBuffer::new(5); + + buffer.insert_block(block1.clone()); + buffer.insert_block(block2.clone()); + buffer.insert_block(block3.clone()); + buffer.insert_block(block4.clone()); + + assert_buffer_lengths(&buffer, 4); + assert_eq!( + buffer + .remove_block_with_children(&block1.hash()) + .into_iter() + .map(|b| (b.hash(), b)) + .collect::>(), + HashMap::from([ + (block1.hash(), block1), + (block2.hash(), block2), + (block3.hash(), block3), + (block4.hash(), block4) + ]) + ); + assert_buffer_lengths(&buffer, 0); + } + + #[test] + fn remove_chain_of_children() { + let mut rng = generators::rng(); + + let main_parent = BlockNumHash::new(9, rng.gen()); + let block1 = create_block(&mut rng, 10, main_parent.hash); + let block2 = create_block(&mut rng, 11, block1.hash()); + let block3 = create_block(&mut rng, 12, block2.hash()); + let parent4 = rng.gen(); + let block4 = create_block(&mut rng, 14, parent4); + + let mut buffer = BlockBuffer::new(5); + + buffer.insert_block(block1.clone()); + buffer.insert_block(block2); + buffer.insert_block(block3); + buffer.insert_block(block4); + + assert_buffer_lengths(&buffer, 4); + buffer.remove_old_blocks(block1.number); + assert_buffer_lengths(&buffer, 1); + } + + #[test] + fn remove_all_multi_level_children() { + let mut rng = generators::rng(); + + let main_parent = BlockNumHash::new(9, rng.gen()); + let block1 = create_block(&mut rng, 10, main_parent.hash); + let block2 = create_block(&mut rng, 11, block1.hash()); + let block3 = create_block(&mut rng, 11, block1.hash()); + let block4 = create_block(&mut rng, 12, block2.hash()); + + let mut buffer = BlockBuffer::new(5); + + buffer.insert_block(block1.clone()); + buffer.insert_block(block2); + buffer.insert_block(block3); + buffer.insert_block(block4); + + assert_buffer_lengths(&buffer, 4); + buffer.remove_old_blocks(block1.number); + assert_buffer_lengths(&buffer, 0); + } + + #[test] + fn remove_multi_chains() { + let mut rng = generators::rng(); + + let main_parent = BlockNumHash::new(9, rng.gen()); + let block1 = create_block(&mut rng, 10, main_parent.hash); + let block1a = create_block(&mut rng, 10, main_parent.hash); + let block2 = create_block(&mut rng, 11, block1.hash()); + let block2a = create_block(&mut rng, 11, block1.hash()); + let random_parent1 = rng.gen(); + let random_block1 = create_block(&mut rng, 10, random_parent1); + let random_parent2 = rng.gen(); + let random_block2 = create_block(&mut rng, 11, random_parent2); + let random_parent3 = rng.gen(); + let random_block3 = create_block(&mut rng, 12, random_parent3); + + let mut buffer = BlockBuffer::new(10); + + buffer.insert_block(block1.clone()); + buffer.insert_block(block1a.clone()); + buffer.insert_block(block2.clone()); + buffer.insert_block(block2a.clone()); + buffer.insert_block(random_block1.clone()); + buffer.insert_block(random_block2.clone()); + buffer.insert_block(random_block3.clone()); + + // check that random blocks are their own ancestor, and that chains have proper ancestors + assert_eq!(buffer.lowest_ancestor(&random_block1.hash()), Some(&random_block1)); + assert_eq!(buffer.lowest_ancestor(&random_block2.hash()), Some(&random_block2)); + assert_eq!(buffer.lowest_ancestor(&random_block3.hash()), Some(&random_block3)); + + // descendants have ancestors + assert_eq!(buffer.lowest_ancestor(&block2a.hash()), Some(&block1)); + assert_eq!(buffer.lowest_ancestor(&block2.hash()), Some(&block1)); + + // roots are themselves + assert_eq!(buffer.lowest_ancestor(&block1a.hash()), Some(&block1a)); + assert_eq!(buffer.lowest_ancestor(&block1.hash()), Some(&block1)); + + assert_buffer_lengths(&buffer, 7); + buffer.remove_old_blocks(10); + assert_buffer_lengths(&buffer, 2); + } + + #[test] + fn evict_with_gap() { + let mut rng = generators::rng(); + + let main_parent = BlockNumHash::new(9, rng.gen()); + let block1 = create_block(&mut rng, 10, main_parent.hash); + let block2 = create_block(&mut rng, 11, block1.hash()); + let block3 = create_block(&mut rng, 12, block2.hash()); + let parent4 = rng.gen(); + let block4 = create_block(&mut rng, 13, parent4); + + let mut buffer = BlockBuffer::new(3); + + buffer.insert_block(block1.clone()); + buffer.insert_block(block2.clone()); + buffer.insert_block(block3.clone()); + + // pre-eviction block1 is the root + assert_eq!(buffer.lowest_ancestor(&block3.hash()), Some(&block1)); + assert_eq!(buffer.lowest_ancestor(&block2.hash()), Some(&block1)); + assert_eq!(buffer.lowest_ancestor(&block1.hash()), Some(&block1)); + + buffer.insert_block(block4.clone()); + + assert_eq!(buffer.lowest_ancestor(&block4.hash()), Some(&block4)); + + // block1 gets evicted + assert_block_removal(&buffer, &block1); + + // check lowest ancestor results post eviction + assert_eq!(buffer.lowest_ancestor(&block3.hash()), Some(&block2)); + assert_eq!(buffer.lowest_ancestor(&block2.hash()), Some(&block2)); + assert_eq!(buffer.lowest_ancestor(&block1.hash()), None); + + assert_buffer_lengths(&buffer, 3); + } + + #[test] + fn simple_eviction() { + let mut rng = generators::rng(); + + let main_parent = BlockNumHash::new(9, rng.gen()); + let block1 = create_block(&mut rng, 10, main_parent.hash); + let block2 = create_block(&mut rng, 11, block1.hash()); + let block3 = create_block(&mut rng, 12, block2.hash()); + let parent4 = rng.gen(); + let block4 = create_block(&mut rng, 13, parent4); + + let mut buffer = BlockBuffer::new(3); + + buffer.insert_block(block1.clone()); + buffer.insert_block(block2); + buffer.insert_block(block3); + buffer.insert_block(block4); + + // block3 gets evicted + assert_block_removal(&buffer, &block1); + + assert_buffer_lengths(&buffer, 3); + } +} diff --git a/crates/engine/tree/src/tree/config.rs b/crates/engine/tree/src/tree/config.rs index d252b65a8df5..34a6e4d0095f 100644 --- a/crates/engine/tree/src/tree/config.rs +++ b/crates/engine/tree/src/tree/config.rs @@ -32,6 +32,8 @@ pub struct TreeConfig { /// This is used as a cutoff to prevent long-running sequential block execution when we receive /// a batch of downloaded blocks. max_execute_block_batch_size: usize, + /// Whether to use the new state root task calculation method instead of parallel calculation + use_state_root_task: bool, } impl Default for TreeConfig { @@ -42,6 +44,7 @@ impl Default for TreeConfig { block_buffer_limit: DEFAULT_BLOCK_BUFFER_LIMIT, max_invalid_header_cache_length: DEFAULT_MAX_INVALID_HEADER_CACHE_LENGTH, max_execute_block_batch_size: DEFAULT_MAX_EXECUTE_BLOCK_BATCH_SIZE, + use_state_root_task: false, } } } @@ -54,6 +57,7 @@ impl TreeConfig { block_buffer_limit: u32, max_invalid_header_cache_length: u32, max_execute_block_batch_size: usize, + use_state_root_task: bool, ) -> Self { Self { persistence_threshold, @@ -61,6 +65,7 @@ impl TreeConfig { block_buffer_limit, max_invalid_header_cache_length, max_execute_block_batch_size, + use_state_root_task, } } @@ -89,6 +94,11 @@ impl TreeConfig { self.max_execute_block_batch_size } + /// Returns whether to use the state root task calculation method. + pub const fn use_state_root_task(&self) -> bool { + self.use_state_root_task + } + /// Setter for persistence threshold. pub const fn with_persistence_threshold(mut self, persistence_threshold: u64) -> Self { self.persistence_threshold = persistence_threshold; @@ -127,4 +137,10 @@ impl TreeConfig { self.max_execute_block_batch_size = max_execute_block_batch_size; self } + + /// Setter for whether to use the new state root task calculation method. + pub const fn with_state_root_task(mut self, use_state_root_task: bool) -> Self { + self.use_state_root_task = use_state_root_task; + self + } } diff --git a/crates/engine/tree/src/tree/metrics.rs b/crates/engine/tree/src/tree/metrics.rs index dba80a17914a..f05d132a496b 100644 --- a/crates/engine/tree/src/tree/metrics.rs +++ b/crates/engine/tree/src/tree/metrics.rs @@ -1,4 +1,3 @@ -use reth_blockchain_tree::metrics::TreeMetrics; use reth_evm::metrics::ExecutorMetrics; use reth_metrics::{ metrics::{Counter, Gauge, Histogram}, @@ -19,6 +18,18 @@ pub(crate) struct EngineApiMetrics { pub(crate) tree: TreeMetrics, } +/// Metrics for the entire blockchain tree +#[derive(Metrics)] +#[metrics(scope = "blockchain_tree")] +pub(super) struct TreeMetrics { + /// The highest block number in the canonical chain + pub canonical_chain_height: Gauge, + /// The number of reorgs + pub reorgs: Counter, + /// The latest reorg depth + pub latest_reorg_depth: Gauge, +} + /// Metrics for the `EngineApi`. #[derive(Metrics)] #[metrics(scope = "consensus.engine.beacon")] @@ -67,3 +78,11 @@ impl BlockValidationMetrics { self.state_root_histogram.record(elapsed_as_secs); } } + +/// Metrics for the blockchain tree block buffer +#[derive(Metrics)] +#[metrics(scope = "blockchain_tree.block_buffer")] +pub(super) struct BlockBufferMetrics { + /// Total blocks in the block buffer + pub blocks: Gauge, +} diff --git a/crates/engine/tree/src/tree/mod.rs b/crates/engine/tree/src/tree/mod.rs index e8218221dc5b..75cbfec411f6 100644 --- a/crates/engine/tree/src/tree/mod.rs +++ b/crates/engine/tree/src/tree/mod.rs @@ -15,12 +15,13 @@ use alloy_rpc_types_engine::{ ExecutionPayload, ExecutionPayloadSidecar, ForkchoiceState, PayloadStatus, PayloadStatusEnum, PayloadValidationError, }; +use block_buffer::BlockBuffer; use reth_beacon_consensus::{ BeaconConsensusEngineEvent, InvalidHeaderCache, MIN_BLOCKS_FOR_PIPELINE_RUN, }; -use reth_blockchain_tree::{ +use reth_blockchain_tree_api::{ error::{InsertBlockErrorKindTwo, InsertBlockErrorTwo, InsertBlockFatalError}, - BlockBuffer, BlockStatus2, InsertPayloadOk2, + BlockStatus2, InsertPayloadOk2, }; use reth_chain_state::{ CanonicalInMemoryState, ExecutedBlock, MemoryOverlayStateProvider, NewCanonicalChain, @@ -31,7 +32,7 @@ use reth_engine_primitives::{ EngineValidator, ForkchoiceStateTracker, OnForkChoiceUpdated, }; use reth_errors::{ConsensusError, ProviderResult}; -use reth_evm::execute::BlockExecutorProvider; +use reth_evm::{execute::BlockExecutorProvider, system_calls::OnStateHook}; use reth_payload_builder::PayloadBuilderHandle; use reth_payload_builder_primitives::PayloadBuilder; use reth_payload_primitives::PayloadBuilderAttributes; @@ -41,14 +42,23 @@ use reth_primitives::{ }; use reth_primitives_traits::Block; use reth_provider::{ - providers::ConsistentDbView, BlockReader, DatabaseProviderFactory, ExecutionOutcome, - HashedPostStateProvider, ProviderError, StateCommitmentProvider, StateProviderBox, - StateProviderFactory, StateReader, StateRootProvider, TransactionVariant, + providers::ConsistentDbView, BlockReader, DBProvider, DatabaseProviderFactory, + ExecutionOutcome, HashedPostStateProvider, ProviderError, StateCommitmentProvider, + StateProviderBox, StateProviderFactory, StateReader, StateRootProvider, TransactionVariant, }; use reth_stages_api::ControlFlow; -use reth_trie::{updates::TrieUpdates, HashedPostState, TrieInput}; +use reth_trie::{ + hashed_cursor::HashedPostStateCursorFactory, + prefix_set::TriePrefixSetsMut, + proof::ProofBlindedProviderFactory, + trie_cursor::InMemoryTrieCursorFactory, + updates::{TrieUpdates, TrieUpdatesSorted}, + HashedPostState, HashedPostStateSorted, TrieInput, +}; +use reth_trie_db::{DatabaseHashedCursorFactory, DatabaseTrieCursorFactory}; use reth_trie_parallel::root::{ParallelStateRoot, ParallelStateRootError}; use revm_primitives::EvmState; +use root::{StateRootComputeOutcome, StateRootConfig, StateRootTask}; use std::{ cmp::Ordering, collections::{btree_map, hash_map, BTreeMap, VecDeque}, @@ -66,6 +76,7 @@ use tokio::sync::{ }; use tracing::*; +mod block_buffer; pub mod config; mod invalid_block_hook; mod metrics; @@ -462,6 +473,15 @@ pub enum TreeAction { }, } +/// Context used to keep alive the required values when returning a state hook +/// from a scoped thread. +struct StateHookContext

{ + provider_ro: P, + nodes_sorted: Arc, + state_sorted: Arc, + prefix_sets: Arc, +} + /// The engine API tree handler implementation. /// /// This type is responsible for processing engine API requests, maintaining the canonical state and @@ -510,6 +530,8 @@ where invalid_block_hook: Box>, /// The engine API variant of this handler engine_kind: EngineApiKind, + /// state root task thread pool + state_root_task_pool: rayon::ThreadPool, } impl std::fmt::Debug @@ -573,6 +595,15 @@ where ) -> Self { let (incoming_tx, incoming) = std::sync::mpsc::channel(); + let num_threads = + std::thread::available_parallelism().map_or(1, |num| (num.get() / 2).max(1)); + + let state_root_task_pool = rayon::ThreadPoolBuilder::new() + .num_threads(num_threads) + .thread_name(|i| format!("srt-worker-{}", i)) + .build() + .expect("Failed to create proof worker thread pool"); + Self { provider, executor_provider, @@ -591,6 +622,7 @@ where incoming_tx, invalid_block_hook: Box::new(NoopInvalidBlockHook), engine_kind, + state_root_task_pool, } } @@ -2221,110 +2253,155 @@ where let sealed_block = Arc::new(block.block.clone()); let block = block.unseal(); - let exec_time = Instant::now(); - let persistence_not_in_progress = !self.persistence_state.in_progress(); - // TODO: uncomment to use StateRootTask + let state_root_result = std::thread::scope(|scope| { + let (state_root_handle, state_hook) = if persistence_not_in_progress && + self.config.use_state_root_task() + { + let consistent_view = ConsistentDbView::new_with_latest_tip(self.provider.clone())?; - // let (state_root_handle, state_hook) = if persistence_not_in_progress { - // let consistent_view = ConsistentDbView::new_with_latest_tip(self.provider.clone())?; - // - // let state_root_config = StateRootConfig::new_from_input( - // consistent_view.clone(), - // self.compute_trie_input(consistent_view, block.header().parent_hash()) - // .map_err(ParallelStateRootError::into)?, - // ); - // - // let provider_ro = consistent_view.provider_ro()?; - // let nodes_sorted = state_root_config.nodes_sorted.clone(); - // let state_sorted = state_root_config.state_sorted.clone(); - // let prefix_sets = state_root_config.prefix_sets.clone(); - // let blinded_provider_factory = ProofBlindedProviderFactory::new( - // InMemoryTrieCursorFactory::new( - // DatabaseTrieCursorFactory::new(provider_ro.tx_ref()), - // &nodes_sorted, - // ), - // HashedPostStateCursorFactory::new( - // DatabaseHashedCursorFactory::new(provider_ro.tx_ref()), - // &state_sorted, - // ), - // prefix_sets, - // ); - // - // let state_root_task = StateRootTask::new(state_root_config, - // blinded_provider_factory); let state_hook = state_root_task.state_hook(); - // (Some(state_root_task.spawn(scope)), Box::new(state_hook) as Box) - // } else { - // (None, Box::new(|_state: &EvmState| {}) as Box) - // }; - let state_hook = Box::new(|_state: &EvmState| {}); + let state_root_config = StateRootConfig::new_from_input( + consistent_view.clone(), + self.compute_trie_input(consistent_view.clone(), block.header().parent_hash()) + .map_err(|e| InsertBlockErrorKindTwo::Other(Box::new(e)))?, + ); - let output = self.metrics.executor.execute_metered(executor, &block, state_hook)?; + let provider_ro = consistent_view.provider_ro()?; + let nodes_sorted = state_root_config.nodes_sorted.clone(); + let state_sorted = state_root_config.state_sorted.clone(); + let prefix_sets = state_root_config.prefix_sets.clone(); + + // context will hold the values that need to be kept alive + let context = + StateHookContext { provider_ro, nodes_sorted, state_sorted, prefix_sets }; + + // it is ok to leak here because we are in a scoped thread, the + // memory will be freed when the thread completes + let context = Box::leak(Box::new(context)); + + let blinded_provider_factory = ProofBlindedProviderFactory::new( + InMemoryTrieCursorFactory::new( + DatabaseTrieCursorFactory::new(context.provider_ro.tx_ref()), + &context.nodes_sorted, + ), + HashedPostStateCursorFactory::new( + DatabaseHashedCursorFactory::new(context.provider_ro.tx_ref()), + &context.state_sorted, + ), + context.prefix_sets.clone(), + ); - trace!(target: "engine::tree", elapsed=?exec_time.elapsed(), ?block_number, "Executed block"); + let state_root_task = StateRootTask::new( + state_root_config, + blinded_provider_factory, + &self.state_root_task_pool, + ); + let state_hook = state_root_task.state_hook(); + (Some(state_root_task.spawn(scope)), Box::new(state_hook) as Box) + } else { + (None, Box::new(|_state: &EvmState| {}) as Box) + }; - if let Err(err) = self.consensus.validate_block_post_execution( - &block, - PostExecutionInput::new(&output.receipts, &output.requests), - ) { - // call post-block hook - self.invalid_block_hook.on_invalid_block( - &parent_block, - &block.seal_slow(), - &output, - None, - ); - return Err(err.into()) - } - - 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(); - - // We attempt to compute state root in parallel if we are currently not persisting anything - // to database. This is safe, because the database state cannot change until we - // finish parallel computation. It is important that nothing is being persisted as - // we are computing in parallel, because we initialize a different database transaction - // per thread and it might end up with a different view of the database. - let state_root_result = if persistence_not_in_progress { - // TODO: uncomment to use StateRootTask - - // if let Some(state_root_handle) = state_root_handle { - // match state_root_handle.wait_for_result() { - // Ok((task_state_root, task_trie_updates)) => { - // info!( - // target: "engine::tree", - // block = ?sealed_block.num_hash(), - // ?task_state_root, - // "State root task finished" - // ); - // } - // Err(error) => { - // info!(target: "engine::tree", ?error, "Failed to wait for state root task - // result"); } - // } - // } - - match self.compute_state_root_parallel(block.header().parent_hash(), &hashed_state) { - Ok(result) => Some(result), - Err(ParallelStateRootError::Provider(ProviderError::ConsistentView(error))) => { - debug!(target: "engine", %error, "Parallel state root computation failed consistency check, falling back"); - None - } - Err(error) => return Err(InsertBlockErrorKindTwo::Other(Box::new(error))), + let execution_start = Instant::now(); + let output = self.metrics.executor.execute_metered(executor, &block, state_hook)?; + let execution_time = execution_start.elapsed(); + trace!(target: "engine::tree", elapsed = ?execution_time, ?block_number, "Executed block"); + + if let Err(err) = self.consensus.validate_block_post_execution( + &block, + PostExecutionInput::new(&output.receipts, &output.requests), + ) { + // call post-block hook + self.invalid_block_hook.on_invalid_block( + &parent_block, + &block.clone().seal_slow(), + &output, + None, + ); + return Err(err.into()) } - } else { - None - }; - let (state_root, trie_output) = if let Some(result) = state_root_result { - result - } else { - debug!(target: "engine::tree", block=?sealed_block.num_hash(), ?persistence_not_in_progress, "Failed to compute state root in parallel"); - state_provider.state_root_with_updates(hashed_state.clone())? - }; + 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(); + + // We attempt to compute state root in parallel if we are currently not persisting + // anything to database. This is safe, because the database state cannot + // change until we finish parallel computation. It is important that nothing + // is being persisted as we are computing in parallel, because we initialize + // a different database transaction per thread and it might end up with a + // different view of the database. + let (state_root, trie_updates, root_elapsed) = if persistence_not_in_progress { + if self.config.use_state_root_task() { + match state_root_handle + .expect("state root handle must exist if use_state_root_task is true") + .wait_for_result() + { + Ok(StateRootComputeOutcome { + state_root: (task_state_root, task_trie_updates), + time_from_last_update, + .. + }) => { + info!( + target: "engine::tree", + block = ?sealed_block.num_hash(), + ?task_state_root, + task_elapsed = ?time_from_last_update, + "Task state root finished" + ); + (task_state_root, task_trie_updates, time_from_last_update) + } + Err(error) => { + info!(target: "engine::tree", ?error, "Failed to wait for state root task result"); + // Fall back to sequential calculation + let (root, updates) = + state_provider.state_root_with_updates(hashed_state.clone())?; + (root, updates, root_time.elapsed()) + } + } + } else { + match self + .compute_state_root_parallel(block.header().parent_hash(), &hashed_state) + { + Ok(result) => { + info!( + target: "engine::tree", + block = ?sealed_block.num_hash(), + regular_state_root = ?result.0, + "Regular root task finished" + ); + (result.0, result.1, root_time.elapsed()) + } + Err(ParallelStateRootError::Provider(ProviderError::ConsistentView( + error, + ))) => { + debug!(target: "engine", %error, "Parallel state root computation failed consistency check, falling back"); + let (root, updates) = + state_provider.state_root_with_updates(hashed_state.clone())?; + (root, updates, root_time.elapsed()) + } + Err(error) => return Err(InsertBlockErrorKindTwo::Other(Box::new(error))), + } + } + } else { + debug!(target: "engine::tree", block=?sealed_block.num_hash(), ?persistence_not_in_progress, "Failed to compute state root in parallel"); + let (root, updates) = + state_provider.state_root_with_updates(hashed_state.clone())?; + (root, updates, root_time.elapsed()) + }; + + Result::<_, InsertBlockErrorKindTwo>::Ok(( + state_root, + trie_updates, + hashed_state, + output, + root_elapsed, + )) + })?; + + let (state_root, trie_output, hashed_state, output, root_elapsed) = state_root_result; if state_root != block.header().state_root() { // call post-block hook @@ -2340,7 +2417,6 @@ where .into()) } - let root_elapsed = root_time.elapsed(); self.metrics.block_validation.record_state_root(&trie_output, root_elapsed.as_secs_f64()); debug!(target: "engine::tree", ?root_elapsed, block=?sealed_block.num_hash(), "Calculated state root"); diff --git a/crates/engine/tree/src/tree/root.rs b/crates/engine/tree/src/tree/root.rs index d5711c38a66c..660c304f75e5 100644 --- a/crates/engine/tree/src/tree/root.rs +++ b/crates/engine/tree/src/tree/root.rs @@ -403,7 +403,20 @@ where ) { // Dispatch proof gathering for this state update scope.spawn(move |_| { + trace!( + target: "engine::root", + proof_sequence_number, + ?proof_targets, + "Starting multiproof calculation", + ); + let start = Instant::now(); let result = calculate_multiproof(thread_pool, config, proof_targets.clone()); + trace!( + target: "engine::root", + proof_sequence_number, + elapsed = ?start.elapsed(), + "Multiproof calculated", + ); match result { Ok(proof) => { diff --git a/crates/ethereum-forks/Cargo.toml b/crates/ethereum-forks/Cargo.toml index 2d65949df452..938934d20e52 100644 --- a/crates/ethereum-forks/Cargo.toml +++ b/crates/ethereum-forks/Cargo.toml @@ -16,11 +16,11 @@ workspace = true alloy-chains.workspace = true alloy-eip2124.workspace = true alloy-primitives = { workspace = true, features = ["serde", "rlp"] } -once_cell.workspace = true # misc serde = { workspace = true, features = ["derive"], optional = true } dyn-clone.workspace = true +once_cell.workspace = true rustc-hash = { workspace = true, optional = true } # arbitrary utils @@ -48,8 +48,8 @@ std = [ "alloy-chains/std", "alloy-primitives/std", "rustc-hash/std", - "once_cell/std", "serde?/std", - "alloy-eip2124/std" + "alloy-eip2124/std", + "once_cell/std" ] rustc-hash = ["dep:rustc-hash"] diff --git a/crates/ethereum/evm/src/execute.rs b/crates/ethereum/evm/src/execute.rs index 5c7d63c6f0d0..54f30399e4fe 100644 --- a/crates/ethereum/evm/src/execute.rs +++ b/crates/ethereum/evm/src/execute.rs @@ -333,9 +333,8 @@ mod tests { BasicBlockExecutorProvider, BatchExecutor, BlockExecutorProvider, Executor, }; use reth_execution_types::BlockExecutionOutput; - use reth_primitives::{ - public_key_to_address, Account, Block, BlockBody, BlockExt, Transaction, - }; + use reth_primitives::{Account, Block, BlockBody, BlockExt, Transaction}; + use reth_primitives_traits::crypto::secp256k1::public_key_to_address; use reth_revm::{test_utils::StateProviderTest, Database, TransitionState}; use reth_testing_utils::generators::{self, sign_tx_with_key_pair}; use revm_primitives::{address, EvmState, BLOCKHASH_SERVE_WINDOW}; @@ -420,10 +419,10 @@ mod tests { "Executing cancun block without parent beacon block root field should fail", ); - assert_eq!( + assert!(matches!( err.as_validation().unwrap().clone(), BlockValidationError::MissingParentBeaconBlockRoot - ); + )); // fix header, set a gas limit header.parent_beacon_block_root = Some(B256::with_last_byte(0x69)); @@ -1097,13 +1096,13 @@ mod tests { // Check if the execution result is an error and assert the specific error type match exec_result { Ok(_) => panic!("Expected block gas limit error"), - Err(err) => assert_eq!( + Err(err) => assert!(matches!( *err.as_validation().unwrap(), BlockValidationError::TransactionGasLimitMoreThanAvailableBlockGas { transaction_gas_limit: 2_500_000, block_available_gas: 1_500_000, } - ), + )), } } diff --git a/crates/ethereum/payload/src/lib.rs b/crates/ethereum/payload/src/lib.rs index 144513856494..66ca1662b97e 100644 --- a/crates/ethereum/payload/src/lib.rs +++ b/crates/ethereum/payload/src/lib.rs @@ -285,7 +285,7 @@ where } // Configure the environment for the tx. - *evm.tx_mut() = evm_config.tx_env(tx.as_signed(), tx.signer()); + *evm.tx_mut() = evm_config.tx_env(tx.tx(), tx.signer()); let ResultAndState { result, state } = match evm.transact() { Ok(res) => res, @@ -354,7 +354,7 @@ where // append sender and transaction to the respective lists executed_senders.push(tx.signer()); - executed_txs.push(tx.into_signed()); + executed_txs.push(tx.into_tx()); } // check if we have a better block diff --git a/crates/ethereum/primitives/src/receipt.rs b/crates/ethereum/primitives/src/receipt.rs index c0a39fd33548..75ae92b447bd 100644 --- a/crates/ethereum/primitives/src/receipt.rs +++ b/crates/ethereum/primitives/src/receipt.rs @@ -20,7 +20,6 @@ use serde::{Deserialize, Serialize}; ))] pub struct Receipt { /// Receipt type. - #[serde(with = "tx_type_serde")] pub tx_type: TxType, /// If transaction is executed successfully. /// @@ -185,25 +184,3 @@ impl InMemorySize for Receipt { } impl reth_primitives_traits::Receipt for Receipt {} - -/// TODO: Remove once is released. -mod tx_type_serde { - use alloy_primitives::{U64, U8}; - - use super::*; - - pub(crate) fn serialize(tx_type: &TxType, serializer: S) -> Result - where - S: serde::Serializer, - { - let value: U8 = (*tx_type).into(); - value.serialize(serializer) - } - - pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - U64::deserialize(deserializer)?.try_into().map_err(serde::de::Error::custom) - } -} diff --git a/crates/ethereum/primitives/src/transaction.rs b/crates/ethereum/primitives/src/transaction.rs index 97e71f11edd0..b466ca3c3da8 100644 --- a/crates/ethereum/primitives/src/transaction.rs +++ b/crates/ethereum/primitives/src/transaction.rs @@ -290,6 +290,15 @@ impl PartialEq for TransactionSigned { } } +impl TransactionSigned { + /// 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: Transaction, signature: Signature) -> Self { + Self { hash: Default::default(), signature, transaction } + } +} + impl Typed2718 for TransactionSigned { fn ty(&self) -> u8 { self.transaction.ty() @@ -572,3 +581,32 @@ impl SignedTransaction for TransactionSigned { recover_signer_unchecked(&self.signature, signature_hash) } } + +#[cfg(test)] +mod tests { + use super::*; + use alloy_eips::eip7702::constants::SECP256K1N_HALF; + use alloy_primitives::hex; + + #[test] + fn eip_2_reject_high_s_value() { + // This pre-homestead transaction has a high `s` value and should be rejected by the + // `recover_signer` method: + // https://etherscan.io/getRawTx?tx=0x9e6e19637bb625a8ff3d052b7c2fe57dc78c55a15d258d77c43d5a9c160b0384 + // + // Block number: 46170 + let raw_tx = hex!("f86d8085746a52880082520894c93f2250589a6563f5359051c1ea25746549f0d889208686e75e903bc000801ba034b6fdc33ea520e8123cf5ac4a9ff476f639cab68980cd9366ccae7aef437ea0a0e517caa5f50e27ca0d1e9a92c503b4ccb039680c6d9d0c71203ed611ea4feb33"); + let tx = TransactionSigned::decode_2718(&mut &raw_tx[..]).unwrap(); + let signature = tx.signature(); + + // make sure we know it's greater than SECP256K1N_HALF + assert!(signature.s() > SECP256K1N_HALF); + + // recover signer, expect failure + let hash = *tx.tx_hash(); + assert!(recover_signer(signature, hash).is_none()); + + // use unchecked, ensure it succeeds (the signature is valid if not for EIP-2) + assert!(recover_signer_unchecked(signature, hash).is_some()); + } +} diff --git a/crates/evm/Cargo.toml b/crates/evm/Cargo.toml index b866194c1089..2b32185ce05b 100644 --- a/crates/evm/Cargo.toml +++ b/crates/evm/Cargo.toml @@ -59,7 +59,8 @@ std = [ "revm-primitives/std", "revm/std", "reth-ethereum-forks/std", - "reth-chainspec/std" + "reth-chainspec/std", + "reth-consensus-common/std" ] test-utils = [ "dep:parking_lot", diff --git a/crates/evm/execution-errors/src/lib.rs b/crates/evm/execution-errors/src/lib.rs index db7887d1b8d2..f49fa693f241 100644 --- a/crates/evm/execution-errors/src/lib.rs +++ b/crates/evm/execution-errors/src/lib.rs @@ -24,7 +24,7 @@ pub mod trie; pub use trie::*; /// Transaction validation errors -#[derive(Error, PartialEq, Eq, Clone, Debug)] +#[derive(Error, Clone, Debug)] pub enum BlockValidationError { /// EVM error with transaction hash and message #[error("EVM reported invalid transaction ({hash}): {error}")] diff --git a/crates/evm/execution-types/Cargo.toml b/crates/evm/execution-types/Cargo.toml index 5d872846a2fa..5a415f0b8892 100644 --- a/crates/evm/execution-types/Cargo.toml +++ b/crates/evm/execution-types/Cargo.toml @@ -32,6 +32,7 @@ arbitrary.workspace = true bincode.workspace = true rand.workspace = true reth-primitives = { workspace = true, features = ["arbitrary", "test-utils"] } +reth-ethereum-primitives.workspace = true [features] default = ["std"] @@ -65,5 +66,6 @@ std = [ "reth-primitives-traits/std", "alloy-consensus/std", "serde_with?/std", - "reth-trie-common?/std" + "reth-trie-common?/std", + "reth-ethereum-primitives/std" ] diff --git a/crates/evm/execution-types/src/chain.rs b/crates/evm/execution-types/src/chain.rs index aef0ced68e2a..91badacc187c 100644 --- a/crates/evm/execution-types/src/chain.rs +++ b/crates/evm/execution-types/src/chain.rs @@ -694,9 +694,26 @@ pub(super) mod serde_bincode_compat { #[cfg(test)] mod tests { use super::*; - use alloy_primitives::B256; + use alloy_consensus::TxType; + use alloy_primitives::{Address, B256}; + use reth_ethereum_primitives::Receipt; + use reth_primitives::Receipts; use revm::primitives::{AccountInfo, HashMap}; + // TODO: this is temporary, until we fully switch over to `reth_ethereum_primitives` for the + // `Receipt` type in `EthPrimitives`. + #[derive(Debug, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)] + #[non_exhaustive] + struct TestPrimitives; + + impl reth_primitives_traits::NodePrimitives for TestPrimitives { + type Block = reth_primitives::Block; + type BlockHeader = alloy_consensus::Header; + type BlockBody = reth_primitives::BlockBody; + type SignedTx = reth_primitives::TransactionSigned; + type Receipt = Receipt; + } + #[test] fn chain_append() { let block: SealedBlockWithSenders = Default::default(); @@ -710,10 +727,10 @@ mod tests { let mut block3 = block.clone(); let mut block4 = block; - block1.block.header.set_hash(block1_hash); - block2.block.header.set_hash(block2_hash); - block3.block.header.set_hash(block3_hash); - block4.block.header.set_hash(block4_hash); + block1.block.set_hash(block1_hash); + block2.block.set_hash(block2_hash); + block3.block.set_hash(block3_hash); + block4.block.set_hash(block4_hash); block3.set_parent_hash(block2_hash); @@ -828,10 +845,7 @@ mod tests { } #[test] - #[cfg(not(feature = "optimism"))] fn receipts_by_block_hash() { - use reth_primitives::{Receipt, Receipts, TxType}; - // Create a default SealedBlockWithSenders object let block: SealedBlockWithSenders = Default::default(); @@ -878,7 +892,7 @@ mod tests { // Create a Chain object with a BTreeMap of blocks mapped to their block numbers, // including block1_hash and block2_hash, and the execution_outcome - let chain: Chain = Chain { + let chain: Chain = Chain { blocks: BTreeMap::from([(10, block1), (11, block2)]), execution_outcome: execution_outcome.clone(), ..Default::default() diff --git a/crates/evm/execution-types/src/execution_outcome.rs b/crates/evm/execution-types/src/execution_outcome.rs index 43c78a5d9c4f..1a0f8a5c3902 100644 --- a/crates/evm/execution-types/src/execution_outcome.rs +++ b/crates/evm/execution-types/src/execution_outcome.rs @@ -1,6 +1,6 @@ use crate::BlockExecutionOutput; use alloy_eips::eip7685::Requests; -use alloy_primitives::{logs_bloom, Address, BlockNumber, Bloom, Log, B256, U256}; +use alloy_primitives::{logs_bloom, map::HashMap, Address, BlockNumber, Bloom, Log, B256, U256}; use reth_primitives::Receipts; use reth_primitives_traits::{Account, Bytecode, Receipt, StorageEntry}; use reth_trie::{HashedPostState, KeyHasher}; @@ -8,7 +8,6 @@ use revm::{ db::{states::BundleState, BundleAccount}, primitives::AccountInfo, }; -use std::collections::HashMap; /// Represents a changed account #[derive(Clone, Copy, Debug, PartialEq, Eq)] @@ -382,17 +381,11 @@ impl From<(BlockExecutionOutput, BlockNumber)> for ExecutionOutcome { #[cfg(test)] 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 alloy_consensus::TxType; + use alloy_primitives::{bytes, Address, LogData, B256}; use reth_primitives::Receipts; - #[cfg(not(feature = "optimism"))] - use reth_primitives::TxType; #[test] - #[cfg(not(feature = "optimism"))] fn test_initialisation() { // Create a new BundleState object with initial data let bundle = BundleState::new( @@ -403,7 +396,7 @@ mod tests { // Create a Receipts object with a vector of receipt vectors let receipts = Receipts { - receipt_vec: vec![vec![Some(reth_primitives::Receipt { + receipt_vec: vec![vec![Some(reth_ethereum_primitives::Receipt { tx_type: TxType::Legacy, cumulative_gas_used: 46913, logs: vec![], @@ -461,11 +454,10 @@ mod tests { } #[test] - #[cfg(not(feature = "optimism"))] fn test_block_number_to_index() { // Create a Receipts object with a vector of receipt vectors let receipts = Receipts { - receipt_vec: vec![vec![Some(reth_primitives::Receipt { + receipt_vec: vec![vec![Some(reth_ethereum_primitives::Receipt { tx_type: TxType::Legacy, cumulative_gas_used: 46913, logs: vec![], @@ -496,11 +488,10 @@ mod tests { } #[test] - #[cfg(not(feature = "optimism"))] fn test_get_logs() { // Create a Receipts object with a vector of receipt vectors let receipts = Receipts { - receipt_vec: vec![vec![Some(reth_primitives::Receipt { + receipt_vec: vec![vec![Some(reth_ethereum_primitives::Receipt { tx_type: TxType::Legacy, cumulative_gas_used: 46913, logs: vec![Log::::default()], @@ -528,11 +519,10 @@ mod tests { } #[test] - #[cfg(not(feature = "optimism"))] fn test_receipts_by_block() { // Create a Receipts object with a vector of receipt vectors let receipts = Receipts { - receipt_vec: vec![vec![Some(reth_primitives::Receipt { + receipt_vec: vec![vec![Some(reth_ethereum_primitives::Receipt { tx_type: TxType::Legacy, cumulative_gas_used: 46913, logs: vec![Log::::default()], @@ -558,7 +548,7 @@ mod tests { // Assert that the receipts for block number 123 match the expected receipts assert_eq!( receipts_by_block, - vec![&Some(reth_primitives::Receipt { + vec![&Some(reth_ethereum_primitives::Receipt { tx_type: TxType::Legacy, cumulative_gas_used: 46913, logs: vec![Log::::default()], @@ -568,11 +558,10 @@ mod tests { } #[test] - #[cfg(not(feature = "optimism"))] fn test_receipts_len() { // Create a Receipts object with a vector of receipt vectors let receipts = Receipts { - receipt_vec: vec![vec![Some(reth_primitives::Receipt { + receipt_vec: vec![vec![Some(reth_ethereum_primitives::Receipt { tx_type: TxType::Legacy, cumulative_gas_used: 46913, logs: vec![Log::::default()], @@ -617,10 +606,9 @@ mod tests { } #[test] - #[cfg(not(feature = "optimism"))] fn test_revert_to() { // Create a random receipt object - let receipt = reth_primitives::Receipt { + let receipt = reth_ethereum_primitives::Receipt { tx_type: TxType::Legacy, cumulative_gas_used: 46913, logs: vec![], @@ -666,10 +654,9 @@ mod tests { } #[test] - #[cfg(not(feature = "optimism"))] fn test_extend_execution_outcome() { // Create a Receipt object with specific attributes. - let receipt = reth_primitives::Receipt { + let receipt = reth_ethereum_primitives::Receipt { tx_type: TxType::Legacy, cumulative_gas_used: 46913, logs: vec![], @@ -710,10 +697,9 @@ mod tests { } #[test] - #[cfg(not(feature = "optimism"))] fn test_split_at_execution_outcome() { // Create a random receipt object - let receipt = reth_primitives::Receipt { + let receipt = reth_ethereum_primitives::Receipt { tx_type: TxType::Legacy, cumulative_gas_used: 46913, logs: vec![], diff --git a/crates/exex/exex/Cargo.toml b/crates/exex/exex/Cargo.toml index 0a59821bb96c..89297dcb6242 100644 --- a/crates/exex/exex/Cargo.toml +++ b/crates/exex/exex/Cargo.toml @@ -52,7 +52,6 @@ rmp-serde = "1.3" tracing.workspace = true [dev-dependencies] -reth-blockchain-tree.workspace = true reth-db-common.workspace = true reth-evm-ethereum.workspace = true reth-node-api.workspace = true diff --git a/crates/exex/exex/src/backfill/job.rs b/crates/exex/exex/src/backfill/job.rs index 9c1ebbbe38b5..8431f89c6992 100644 --- a/crates/exex/exex/src/backfill/job.rs +++ b/crates/exex/exex/src/backfill/job.rs @@ -226,18 +226,15 @@ impl From> for SingleBlockBackfillJob { #[cfg(test)] mod tests { - use std::sync::Arc; - use crate::{ backfill::test_utils::{blocks_and_execution_outputs, chain_spec, to_execution_outcome}, BackfillJobFactory, }; - use reth_blockchain_tree::noop::NoopBlockchainTree; use reth_db_common::init::init_genesis; use reth_evm_ethereum::execute::EthExecutorProvider; - use reth_primitives::public_key_to_address; + use reth_primitives_traits::crypto::secp256k1::public_key_to_address; use reth_provider::{ - providers::BlockchainProvider, test_utils::create_test_provider_factory_with_chain_spec, + providers::BlockchainProvider2, test_utils::create_test_provider_factory_with_chain_spec, }; use reth_testing_utils::generators; use secp256k1::Keypair; @@ -255,10 +252,7 @@ mod tests { let executor = EthExecutorProvider::ethereum(chain_spec.clone()); let provider_factory = create_test_provider_factory_with_chain_spec(chain_spec.clone()); init_genesis(&provider_factory)?; - let blockchain_db = BlockchainProvider::new( - provider_factory.clone(), - Arc::new(NoopBlockchainTree::default()), - )?; + let blockchain_db = BlockchainProvider2::new(provider_factory.clone())?; let blocks_and_execution_outputs = blocks_and_execution_outputs(provider_factory, chain_spec, key_pair)?; @@ -294,10 +288,7 @@ mod tests { let executor = EthExecutorProvider::ethereum(chain_spec.clone()); let provider_factory = create_test_provider_factory_with_chain_spec(chain_spec.clone()); init_genesis(&provider_factory)?; - let blockchain_db = BlockchainProvider::new( - provider_factory.clone(), - Arc::new(NoopBlockchainTree::default()), - )?; + let blockchain_db = BlockchainProvider2::new(provider_factory.clone())?; let blocks_and_execution_outcomes = blocks_and_execution_outputs(provider_factory, chain_spec, key_pair)?; diff --git a/crates/exex/exex/src/backfill/stream.rs b/crates/exex/exex/src/backfill/stream.rs index b36841540799..6111ae8fe4f9 100644 --- a/crates/exex/exex/src/backfill/stream.rs +++ b/crates/exex/exex/src/backfill/stream.rs @@ -235,8 +235,6 @@ where #[cfg(test)] mod tests { - use std::sync::Arc; - use crate::{ backfill::test_utils::{ blocks_and_execution_outcome, blocks_and_execution_outputs, chain_spec, @@ -244,12 +242,11 @@ mod tests { BackfillJobFactory, }; use futures::StreamExt; - use reth_blockchain_tree::noop::NoopBlockchainTree; use reth_db_common::init::init_genesis; use reth_evm_ethereum::execute::EthExecutorProvider; - use reth_primitives::public_key_to_address; + use reth_primitives_traits::crypto::secp256k1::public_key_to_address; use reth_provider::{ - providers::BlockchainProvider, test_utils::create_test_provider_factory_with_chain_spec, + providers::BlockchainProvider2, test_utils::create_test_provider_factory_with_chain_spec, }; use reth_stages_api::ExecutionStageThresholds; use reth_testing_utils::generators; @@ -268,10 +265,7 @@ mod tests { let executor = EthExecutorProvider::ethereum(chain_spec.clone()); let provider_factory = create_test_provider_factory_with_chain_spec(chain_spec.clone()); init_genesis(&provider_factory)?; - let blockchain_db = BlockchainProvider::new( - provider_factory.clone(), - Arc::new(NoopBlockchainTree::default()), - )?; + let blockchain_db = BlockchainProvider2::new(provider_factory.clone())?; // Create first 2 blocks let blocks_and_execution_outcomes = @@ -309,10 +303,7 @@ mod tests { let executor = EthExecutorProvider::ethereum(chain_spec.clone()); let provider_factory = create_test_provider_factory_with_chain_spec(chain_spec.clone()); init_genesis(&provider_factory)?; - let blockchain_db = BlockchainProvider::new( - provider_factory.clone(), - Arc::new(NoopBlockchainTree::default()), - )?; + let blockchain_db = BlockchainProvider2::new(provider_factory.clone())?; // Create first 2 blocks let (blocks, execution_outcome) = diff --git a/crates/exex/test-utils/Cargo.toml b/crates/exex/test-utils/Cargo.toml index 6e5af981b317..be3d40c7f2cf 100644 --- a/crates/exex/test-utils/Cargo.toml +++ b/crates/exex/test-utils/Cargo.toml @@ -13,7 +13,6 @@ workspace = true [dependencies] ## reth reth-chainspec.workspace = true -reth-blockchain-tree.workspace = true reth-config.workspace = true reth-consensus = { workspace = true, features = ["test-utils"] } reth-db = { workspace = true, features = ["test-utils"] } diff --git a/crates/exex/test-utils/src/lib.rs b/crates/exex/test-utils/src/lib.rs index be15828681c2..77289a73ca72 100644 --- a/crates/exex/test-utils/src/lib.rs +++ b/crates/exex/test-utils/src/lib.rs @@ -17,7 +17,6 @@ use std::{ use alloy_eips::BlockNumHash; use futures_util::FutureExt; -use reth_blockchain_tree::noop::NoopBlockchainTree; use reth_chainspec::{ChainSpec, MAINNET}; use reth_consensus::test_utils::TestConsensus; use reth_db::{ @@ -38,7 +37,7 @@ use reth_node_builder::{ Components, ComponentsBuilder, ConsensusBuilder, ExecutorBuilder, NodeComponentsBuilder, PoolBuilder, }, - BuilderContext, Node, NodeAdapter, RethFullAdapter, + BuilderContext, Node, NodeAdapter, RethFullAdapter2, }; use reth_node_core::node_config::NodeConfig; use reth_node_ethereum::{ @@ -47,13 +46,11 @@ use reth_node_ethereum::{ }; use reth_payload_builder::noop::NoopPayloadBuilderService; use reth_primitives::{BlockExt, EthPrimitives, Head, SealedBlockWithSenders, TransactionSigned}; -use reth_provider::{ - providers::{BlockchainProvider, StaticFileProvider}, - BlockReader, EthStorage, ProviderFactory, -}; +use reth_provider::{providers::StaticFileProvider, BlockReader, EthStorage, ProviderFactory}; use reth_tasks::TaskManager; use reth_transaction_pool::test_utils::{testing_pool, TestPool}; +use reth_provider::providers::BlockchainProvider2; use tempfile::TempDir; use thiserror::Error; use tokio::sync::mpsc::{Sender, UnboundedReceiver}; @@ -172,14 +169,14 @@ pub type TmpDB = Arc>; /// The [`NodeAdapter`] for the [`TestExExContext`]. Contains type necessary to /// boot the testing environment pub type Adapter = NodeAdapter< - RethFullAdapter, + RethFullAdapter2, <>, + BlockchainProvider2>, >, - >>::ComponentsBuilder as NodeComponentsBuilder>>::Components, + >>::ComponentsBuilder as NodeComponentsBuilder>>::Components, >; /// An [`ExExContext`] using the [`Adapter`] type. pub type TestExExContext = ExExContext; @@ -274,8 +271,7 @@ pub async fn test_exex_context_with_chain_spec( ); let genesis_hash = init_genesis(&provider_factory)?; - let provider = - BlockchainProvider::new(provider_factory.clone(), Arc::new(NoopBlockchainTree::default()))?; + let provider = BlockchainProvider2::new(provider_factory.clone())?; let network_manager = NetworkManager::new( NetworkConfigBuilder::new(SecretKey::new(&mut rand::thread_rng())) diff --git a/crates/net/network/benches/broadcast.rs b/crates/net/network/benches/broadcast.rs index 27a41278dbd7..bbbd00374968 100644 --- a/crates/net/network/benches/broadcast.rs +++ b/crates/net/network/benches/broadcast.rs @@ -64,7 +64,7 @@ pub fn broadcast_ingress_bench(c: &mut Criterion) { tx.sender(), ExtendedAccount::new(0, U256::from(100_000_000)), ); - txs.push(Arc::new(tx.transaction().clone().into_signed())); + txs.push(Arc::new(tx.transaction().clone().into_tx())); peer1.send_transactions(peer0_id, txs); } } diff --git a/crates/net/network/src/transactions/mod.rs b/crates/net/network/src/transactions/mod.rs index 67a033e70537..7c2a690877f0 100644 --- a/crates/net/network/src/transactions/mod.rs +++ b/crates/net/network/src/transactions/mod.rs @@ -1538,7 +1538,7 @@ impl PropagateTransaction { { let size = tx.encoded_length(); let transaction = tx.transaction.clone_into_consensus(); - let transaction = Arc::new(transaction.into_signed()); + let transaction = Arc::new(transaction.into_tx()); Self { size, transaction } } diff --git a/crates/net/network/tests/it/txgossip.rs b/crates/net/network/tests/it/txgossip.rs index c9911885ad87..f20ef6470833 100644 --- a/crates/net/network/tests/it/txgossip.rs +++ b/crates/net/network/tests/it/txgossip.rs @@ -80,7 +80,7 @@ async fn test_4844_tx_gossip_penalization() { } let signed_txs: Vec> = - txs.iter().map(|tx| Arc::new(tx.transaction().clone().into_signed())).collect(); + txs.iter().map(|tx| Arc::new(tx.transaction().clone().into_tx())).collect(); let network_handle = peer0.network(); diff --git a/crates/net/p2p/src/error.rs b/crates/net/p2p/src/error.rs index 45d34fc04ece..db765a9ab41b 100644 --- a/crates/net/p2p/src/error.rs +++ b/crates/net/p2p/src/error.rs @@ -131,7 +131,7 @@ impl From for RequestError { pub type DownloadResult = Result; /// The downloader error type -#[derive(Debug, Clone, PartialEq, Eq, Display, Error)] +#[derive(Debug, Clone, Display, Error)] pub enum DownloadError { /* ==================== HEADER ERRORS ==================== */ /// Header validation failed. diff --git a/crates/net/p2p/src/full_block.rs b/crates/net/p2p/src/full_block.rs index a966c01c933d..62981ad5d9ab 100644 --- a/crates/net/p2p/src/full_block.rs +++ b/crates/net/p2p/src/full_block.rs @@ -709,7 +709,7 @@ mod tests { assert_eq!(received.len(), 10); for (i, block) in received.iter().enumerate() { let expected_number = header.number - i as u64; - assert_eq!(block.header.number, expected_number); + assert_eq!(block.number, expected_number); } } @@ -728,7 +728,7 @@ mod tests { assert_eq!(received.len(), 50); for (i, block) in received.iter().enumerate() { let expected_number = header.number - i as u64; - assert_eq!(block.header.number, expected_number); + assert_eq!(block.number, expected_number); } } @@ -748,7 +748,7 @@ mod tests { assert_eq!(received.len(), range_length); for (i, block) in received.iter().enumerate() { let expected_number = header.number - i as u64; - assert_eq!(block.header.number, expected_number); + assert_eq!(block.number, expected_number); } } } diff --git a/crates/node/builder/src/builder/mod.rs b/crates/node/builder/src/builder/mod.rs index 8ffe357fd521..47d9a54572e9 100644 --- a/crates/node/builder/src/builder/mod.rs +++ b/crates/node/builder/src/builder/mod.rs @@ -34,7 +34,7 @@ use reth_node_core::{ primitives::Head, }; use reth_provider::{ - providers::{BlockchainProvider, NodeTypesForProvider}, + providers::{BlockchainProvider, BlockchainProvider2, NodeTypesForProvider}, ChainSpecProvider, FullProvider, }; use reth_tasks::TaskExecutor; @@ -53,6 +53,11 @@ pub use states::*; pub type RethFullAdapter = FullNodeTypesAdapter>>; +/// The adapter type for a reth node with the builtin provider type +// Note: we need to hardcode this because custom components might depend on it in associated types. +pub type RethFullAdapter2 = + FullNodeTypesAdapter>>; + #[allow(clippy::doc_markdown)] #[cfg_attr(doc, aquamarine::aquamarine)] /// Declaratively construct a node. diff --git a/crates/node/core/Cargo.toml b/crates/node/core/Cargo.toml index 96919b7de7e0..7d4a417bed80 100644 --- a/crates/node/core/Cargo.toml +++ b/crates/node/core/Cargo.toml @@ -15,7 +15,7 @@ workspace = true reth-chainspec.workspace = true reth-consensus.workspace = true reth-primitives.workspace = true -reth-primitives-traits.workspace = true +reth-primitives-traits = { workspace = true, features = ["rayon"] } reth-cli-util.workspace = true reth-db = { workspace = true, features = ["mdbx"] } reth-storage-errors.workspace = true diff --git a/crates/optimism/chainspec/src/lib.rs b/crates/optimism/chainspec/src/lib.rs index 47610bdfc416..6e24bdd50dae 100644 --- a/crates/optimism/chainspec/src/lib.rs +++ b/crates/optimism/chainspec/src/lib.rs @@ -26,8 +26,6 @@ pub use base::BASE_MAINNET; pub use base_sepolia::BASE_SEPOLIA; use derive_more::{Constructor, Deref, Display, From, Into}; pub use dev::OP_DEV; -#[cfg(not(feature = "std"))] -pub(crate) use once_cell::sync::Lazy as LazyLock; pub use op::OP_MAINNET; use op_alloy_consensus::{decode_holocene_extra_data, EIP1559ParamError}; pub use op_sepolia::OP_SEPOLIA; @@ -38,8 +36,7 @@ use reth_chainspec::{ use reth_ethereum_forks::{ChainHardforks, EthereumHardfork, ForkCondition, Hardfork}; use reth_network_peers::NodeRecord; use reth_optimism_forks::{OpHardfork, OpHardforks}; -#[cfg(feature = "std")] -pub(crate) use std::sync::LazyLock; +use reth_primitives_traits::sync::LazyLock; /// Chain spec builder for a OP stack chain. #[derive(Debug, Default, From)] diff --git a/crates/optimism/consensus/src/lib.rs b/crates/optimism/consensus/src/lib.rs index d892609e919f..8620de3a7b47 100644 --- a/crates/optimism/consensus/src/lib.rs +++ b/crates/optimism/consensus/src/lib.rs @@ -79,9 +79,9 @@ impl Consensus for OpBeaconConsensus { ) -> Result<(), ConsensusError> { // Check ommers hash let ommers_hash = block.body().calculate_ommers_root(); - if block.header.ommers_hash != ommers_hash { + if block.ommers_hash != ommers_hash { return Err(ConsensusError::BodyOmmersHashDiff( - GotExpected { got: ommers_hash, expected: block.header.ommers_hash }.into(), + GotExpected { got: ommers_hash, expected: block.ommers_hash }.into(), )) } diff --git a/crates/optimism/evm/Cargo.toml b/crates/optimism/evm/Cargo.toml index 66472c5ebd0d..1d8e844dcd2d 100644 --- a/crates/optimism/evm/Cargo.toml +++ b/crates/optimism/evm/Cargo.toml @@ -74,7 +74,8 @@ std = [ "reth-optimism-forks/std", "thiserror/std", "op-alloy-consensus/std", - "reth-chainspec/std" + "reth-chainspec/std", + "reth-consensus-common/std" ] optimism = [ "reth-primitives/optimism", diff --git a/crates/optimism/evm/src/l1.rs b/crates/optimism/evm/src/l1.rs index 1a092b831a56..033d632b505d 100644 --- a/crates/optimism/evm/src/l1.rs +++ b/crates/optimism/evm/src/l1.rs @@ -196,7 +196,7 @@ pub trait RethL1BlockInfo { /// - `input`: The calldata of the transaction. /// - `is_deposit`: Whether or not the transaction is a deposit. fn l1_tx_data_fee( - &self, + &mut self, chain_spec: &ChainSpec, timestamp: u64, input: &[u8], @@ -219,7 +219,7 @@ pub trait RethL1BlockInfo { impl RethL1BlockInfo for L1BlockInfo { fn l1_tx_data_fee( - &self, + &mut self, chain_spec: &ChainSpec, timestamp: u64, input: &[u8], diff --git a/crates/optimism/evm/src/lib.rs b/crates/optimism/evm/src/lib.rs index ec2a56389782..37c3fd548be6 100644 --- a/crates/optimism/evm/src/lib.rs +++ b/crates/optimism/evm/src/lib.rs @@ -194,7 +194,11 @@ mod tests { use alloy_consensus::{constants::KECCAK_EMPTY, Header, Receipt}; use alloy_eips::eip7685::Requests; use alloy_genesis::Genesis; - use alloy_primitives::{bytes, Address, LogData, B256, U256}; + use alloy_primitives::{ + bytes, + map::{HashMap, HashSet}, + Address, LogData, B256, U256, + }; use reth_chainspec::ChainSpec; use reth_evm::execute::ProviderError; use reth_execution_types::{ @@ -210,10 +214,7 @@ mod tests { JournaledState, }; use revm_primitives::{EnvWithHandlerCfg, HandlerCfg}; - use std::{ - collections::{HashMap, HashSet}, - sync::Arc, - }; + use std::sync::Arc; fn test_evm_config() -> OpEvmConfig { OpEvmConfig::new(BASE_MAINNET.clone()) @@ -543,11 +544,11 @@ mod tests { let mut block2 = block; // Set the hashes of block1 and block2 - block1.block.header.set_block_number(10); - block1.block.header.set_hash(block1_hash); + block1.block.set_block_number(10); + block1.block.set_hash(block1_hash); - block2.block.header.set_block_number(11); - block2.block.header.set_hash(block2_hash); + block2.block.set_block_number(11); + block2.block.set_hash(block2_hash); // Create a random receipt object, receipt1 let receipt1 = OpReceipt::Legacy(Receipt { diff --git a/crates/optimism/node/src/txpool.rs b/crates/optimism/node/src/txpool.rs index 9692e8cdb136..752a78405c31 100644 --- a/crates/optimism/node/src/txpool.rs +++ b/crates/optimism/node/src/txpool.rs @@ -58,9 +58,9 @@ impl TryFrom> for OpPooledTransaction { type Error = TransactionConversionError; fn try_from(value: RecoveredTx) -> Result { - let (tx, signer) = value.to_components(); + let (tx, signer) = value.into_parts(); let pooled: RecoveredTx = - RecoveredTx::from_signed_transaction(tx.try_into()?, signer); + RecoveredTx::new_unchecked(tx.try_into()?, signer); Ok(pooled.into()) } } @@ -83,8 +83,8 @@ impl PoolTransaction for OpPooledTransaction { fn try_consensus_into_pooled( tx: RecoveredTx, ) -> Result, Self::TryFromConsensusError> { - let (tx, signer) = tx.to_components(); - Ok(RecoveredTx::from_signed_transaction(tx.try_into()?, signer)) + let (tx, signer) = tx.into_parts(); + Ok(RecoveredTx::new_unchecked(tx.try_into()?, signer)) } fn hash(&self) -> &TxHash { @@ -324,7 +324,7 @@ where propagate, } = outcome { - let l1_block_info = self.block_info.l1_block_info.read().clone(); + let mut l1_block_info = self.block_info.l1_block_info.read().clone(); let mut encoded = Vec::with_capacity(valid_tx.transaction().encoded_length()); let tx = valid_tx.transaction().clone_into_consensus(); @@ -459,7 +459,7 @@ mod tests { }); let signature = Signature::test_signature(); let signed_tx = OpTransactionSigned::new_unhashed(deposit_tx, signature); - let signed_recovered = RecoveredTx::from_signed_transaction(signed_tx, signer); + let signed_recovered = RecoveredTx::new_unchecked(signed_tx, signer); let len = signed_recovered.encode_2718_len(); let pooled_tx = OpPooledTransaction::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 510cd5cdb20b..d34dac483672 100644 --- a/crates/optimism/node/tests/it/priority.rs +++ b/crates/optimism/node/tests/it/priority.rs @@ -67,7 +67,7 @@ impl OpPayloadTransactions for CustomTxPriority { ..Default::default() }; let signature = sender.sign_transaction_sync(&mut end_of_block_tx).unwrap(); - let end_of_block_tx = RecoveredTx::from_signed_transaction( + let end_of_block_tx = RecoveredTx::new_unchecked( OpTransactionSigned::new_unhashed( OpTypedTransaction::Eip1559(end_of_block_tx), signature, diff --git a/crates/optimism/payload/src/builder.rs b/crates/optimism/payload/src/builder.rs index 2a3f63880923..b87b01b37b2b 100644 --- a/crates/optimism/payload/src/builder.rs +++ b/crates/optimism/payload/src/builder.rs @@ -790,7 +790,7 @@ where )) })?; - *evm.tx_mut() = self.evm_config.tx_env(sequencer_tx.as_signed(), sequencer_tx.signer()); + *evm.tx_mut() = self.evm_config.tx_env(sequencer_tx.tx(), sequencer_tx.signer()); let ResultAndState { result, state } = match evm.transact() { Ok(res) => res, @@ -841,7 +841,7 @@ where // append sender and transaction to the respective lists info.executed_senders.push(sequencer_tx.signer()); - info.executed_transactions.push(sequencer_tx.into_signed()); + info.executed_transactions.push(sequencer_tx.into_tx()); } Ok(info) @@ -891,7 +891,7 @@ where } // Configure the environment for the tx. - *evm.tx_mut() = self.evm_config.tx_env(tx.as_signed(), tx.signer()); + *evm.tx_mut() = self.evm_config.tx_env(tx.tx(), tx.signer()); let ResultAndState { result, state } = match evm.transact() { Ok(res) => res, @@ -954,7 +954,7 @@ where // append sender and transaction to the respective lists info.executed_senders.push(tx.signer()); - info.executed_transactions.push(tx.into_signed()); + info.executed_transactions.push(tx.into_tx()); } Ok(None) diff --git a/crates/optimism/primitives/Cargo.toml b/crates/optimism/primitives/Cargo.toml index f0c35fb52e5e..5e1fd17311a8 100644 --- a/crates/optimism/primitives/Cargo.toml +++ b/crates/optimism/primitives/Cargo.toml @@ -13,7 +13,6 @@ workspace = true [dependencies] # reth -reth-primitives.workspace = true reth-primitives-traits = { workspace = true, features = ["op"] } reth-codecs = { workspace = true, optional = true, features = ["op"] } reth-zstd-compressors = { workspace = true, optional = true } @@ -48,13 +47,13 @@ proptest-arbitrary-interop.workspace = true reth-codecs = { workspace = true, features = ["test-utils", "op"] } rstest.workspace = true arbitrary.workspace = true +secp256k1 = { workspace = true, features = ["rand"] } proptest.workspace = true [features] -default = ["std", "serde"] +default = ["std"] std = [ "reth-primitives-traits/std", - "reth-primitives/std", "reth-codecs?/std", "alloy-consensus/std", "alloy-eips/std", @@ -74,10 +73,8 @@ reth-codec = [ "std", "dep:proptest", "dep:arbitrary", - "reth-primitives/reth-codec", "reth-primitives-traits/reth-codec", "reth-codecs?/op", - "reth-primitives/reth-codec", "dep:bytes", "dep:modular-bitfield", "dep:reth-zstd-compressors" @@ -99,14 +96,13 @@ serde-bincode-compat = [ "alloy-consensus/serde-bincode-compat", "alloy-eips/serde-bincode-compat", "op-alloy-consensus/serde-bincode-compat", - "reth-primitives/serde-bincode-compat", "reth-primitives-traits/serde-bincode-compat" ] arbitrary = [ "dep:arbitrary", "dep:secp256k1", + "secp256k1?/rand", "reth-primitives-traits/arbitrary", - "reth-primitives/arbitrary", "reth-codecs?/arbitrary", "op-alloy-consensus/arbitrary", "alloy-consensus/arbitrary", @@ -118,5 +114,4 @@ arbitrary = [ optimism = [ "dep:revm-primitives", "revm-primitives/optimism", - "reth-primitives/optimism" ] diff --git a/crates/optimism/primitives/src/lib.rs b/crates/optimism/primitives/src/lib.rs index 1ccc6f886bd0..1cf4a0390d75 100644 --- a/crates/optimism/primitives/src/lib.rs +++ b/crates/optimism/primitives/src/lib.rs @@ -23,7 +23,7 @@ mod receipt; pub use receipt::OpReceipt; /// Optimism-specific block type. -pub type OpBlock = reth_primitives::Block; +pub type OpBlock = alloy_consensus::Block; /// Optimism-specific block body type. pub type OpBlockBody = ::Body; @@ -33,7 +33,7 @@ pub type OpBlockBody = ::Body; pub struct OpPrimitives; #[cfg(feature = "optimism")] -impl reth_primitives::NodePrimitives for OpPrimitives { +impl reth_primitives_traits::NodePrimitives for OpPrimitives { type Block = OpBlock; type BlockHeader = alloy_consensus::Header; type BlockBody = OpBlockBody; diff --git a/crates/optimism/primitives/src/transaction/signed.rs b/crates/optimism/primitives/src/transaction/signed.rs index 5ebb4b7f6151..6600922617f5 100644 --- a/crates/optimism/primitives/src/transaction/signed.rs +++ b/crates/optimism/primitives/src/transaction/signed.rs @@ -519,7 +519,7 @@ impl<'a> arbitrary::Arbitrary<'a> for OpTransactionSigned { 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( + let signature = reth_primitives_traits::crypto::secp256k1::sign_message( B256::from_slice(&key_pair.secret_bytes()[..]), signature_hash(&transaction), ) diff --git a/crates/optimism/rpc/src/eth/receipt.rs b/crates/optimism/rpc/src/eth/receipt.rs index cc37dbbb5320..d83cb7a5e844 100644 --- a/crates/optimism/rpc/src/eth/receipt.rs +++ b/crates/optimism/rpc/src/eth/receipt.rs @@ -107,7 +107,7 @@ impl OpReceiptFieldsBuilder { mut self, chain_spec: &OpChainSpec, tx: &OpTransactionSigned, - l1_block_info: revm::L1BlockInfo, + mut l1_block_info: revm::L1BlockInfo, ) -> Result { let raw_tx = tx.encoded_2718(); let timestamp = self.block_timestamp; diff --git a/crates/optimism/rpc/src/eth/transaction.rs b/crates/optimism/rpc/src/eth/transaction.rs index 05fbb0a95349..ba3b43d071f6 100644 --- a/crates/optimism/rpc/src/eth/transaction.rs +++ b/crates/optimism/rpc/src/eth/transaction.rs @@ -89,7 +89,7 @@ where ) -> Result { let from = tx.signer(); let hash = *tx.tx_hash(); - let OpTransactionSigned { transaction, signature, .. } = tx.into_signed(); + let OpTransactionSigned { transaction, signature, .. } = tx.into_tx(); let mut deposit_receipt_version = None; let mut deposit_nonce = None; diff --git a/crates/payload/basic/src/lib.rs b/crates/payload/basic/src/lib.rs index 1b8bc6ba7c0b..b8cec6dacedc 100644 --- a/crates/payload/basic/src/lib.rs +++ b/crates/payload/basic/src/lib.rs @@ -295,6 +295,15 @@ impl Default for BasicPayloadJobGeneratorConfig { } /// A basic payload job that continuously builds a payload with the best transactions from the pool. +/// +/// This type is a [`PayloadJob`] and [`Future`] that terminates when the deadline is reached or +/// when the job is resolved: [`PayloadJob::resolve`]. +/// +/// This basic job implementation will trigger new payload build task continuously until the job is +/// resolved or the deadline is reached, or until the built payload is marked as frozen: +/// [`BuildOutcome::Freeze`]. Once a frozen payload is returned, no additional payloads will be +/// built and this future will wait to be resolved: [`PayloadJob::resolve`] or terminated if the +/// deadline is reached.. #[derive(Debug)] pub struct BasicPayloadJob where diff --git a/crates/payload/builder/src/traits.rs b/crates/payload/builder/src/traits.rs index 34a756e6059b..807bfa186ec1 100644 --- a/crates/payload/builder/src/traits.rs +++ b/crates/payload/builder/src/traits.rs @@ -67,6 +67,8 @@ pub trait PayloadJob: Future> + Send + ) -> (Self::ResolvePayloadFuture, KeepPayloadJobAlive); /// Resolves the payload as fast as possible. + /// + /// See also [`PayloadJob::resolve_kind`] fn resolve(&mut self) -> (Self::ResolvePayloadFuture, KeepPayloadJobAlive) { self.resolve_kind(PayloadKind::Earliest) } diff --git a/crates/payload/util/src/transaction.rs b/crates/payload/util/src/transaction.rs index 71387946aef1..e6e41d7b1e9a 100644 --- a/crates/payload/util/src/transaction.rs +++ b/crates/payload/util/src/transaction.rs @@ -99,12 +99,12 @@ where 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.as_signed().gas_limit() <= before_max_gas { - self.before_gas += tx.as_signed().gas_limit(); + if self.before_gas + tx.tx().gas_limit() <= before_max_gas { + self.before_gas += tx.tx().gas_limit(); return Some(tx); } - self.before.mark_invalid(tx.signer(), tx.as_signed().nonce()); - self.after.mark_invalid(tx.signer(), tx.as_signed().nonce()); + self.before.mark_invalid(tx.signer(), tx.tx().nonce()); + self.after.mark_invalid(tx.signer(), tx.tx().nonce()); } else { return Some(tx); } @@ -112,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.as_signed().gas_limit() <= after_max_gas { - self.after_gas += tx.as_signed().gas_limit(); + if self.after_gas + tx.tx().gas_limit() <= after_max_gas { + self.after_gas += tx.tx().gas_limit(); return Some(tx); } - self.after.mark_invalid(tx.signer(), tx.as_signed().nonce()); + self.after.mark_invalid(tx.signer(), tx.tx().nonce()); } else { return Some(tx); } diff --git a/crates/payload/validator/src/lib.rs b/crates/payload/validator/src/lib.rs index 6a75463c6923..e696e557afa0 100644 --- a/crates/payload/validator/src/lib.rs +++ b/crates/payload/validator/src/lib.rs @@ -131,11 +131,11 @@ impl ExecutionPayloadValidator { } if self.is_cancun_active_at_timestamp(sealed_block.timestamp) { - if sealed_block.header.blob_gas_used.is_none() { + if sealed_block.blob_gas_used.is_none() { // cancun active but blob gas used not present return Err(PayloadError::PostCancunBlockWithoutBlobGasUsed) } - if sealed_block.header.excess_blob_gas.is_none() { + if sealed_block.excess_blob_gas.is_none() { // cancun active but excess blob gas not present return Err(PayloadError::PostCancunBlockWithoutExcessBlobGas) } @@ -148,11 +148,11 @@ impl ExecutionPayloadValidator { // cancun not active but blob transactions present return Err(PayloadError::PreCancunBlockWithBlobTransactions) } - if sealed_block.header.blob_gas_used.is_some() { + if sealed_block.blob_gas_used.is_some() { // cancun not active but blob gas used present return Err(PayloadError::PreCancunBlockWithBlobGasUsed) } - if sealed_block.header.excess_blob_gas.is_some() { + if sealed_block.excess_blob_gas.is_some() { // cancun not active but excess blob gas present return Err(PayloadError::PreCancunBlockWithExcessBlobGas) } diff --git a/crates/primitives-traits/Cargo.toml b/crates/primitives-traits/Cargo.toml index a84394033704..d017ea650e4a 100644 --- a/crates/primitives-traits/Cargo.toml +++ b/crates/primitives-traits/Cargo.toml @@ -34,11 +34,12 @@ secp256k1 = { workspace = true, features = [ k256.workspace = true # misc +auto_impl.workspace = true byteorder = { workspace = true, optional = true } bytes.workspace = true derive_more.workspace = true +once_cell.workspace = true serde_with = { workspace = true, optional = true } -auto_impl.workspace = true thiserror.workspace = true # required by reth-codecs @@ -49,6 +50,7 @@ serde = { workspace = true, optional = true} arbitrary = { workspace = true, features = ["derive"], optional = true } proptest = { workspace = true, optional = true } proptest-arbitrary-interop = { workspace = true, optional = true } +rayon = { workspace = true, optional = true } [dev-dependencies] reth-codecs.workspace = true @@ -86,6 +88,7 @@ std = [ "bytes/std", "derive_more/std", "k256/std", + "once_cell/std", "secp256k1?/std", "thiserror/std", "alloy-trie/std", @@ -142,3 +145,6 @@ reth-codec = [ op = [ "dep:op-alloy-consensus", ] +rayon = [ + "dep:rayon", +] diff --git a/crates/primitives-traits/src/block/body.rs b/crates/primitives-traits/src/block/body.rs index 37342733b4c9..58fe3c4b43e9 100644 --- a/crates/primitives-traits/src/block/body.rs +++ b/crates/primitives-traits/src/block/body.rs @@ -6,13 +6,16 @@ use crate::{ use alloc::{fmt, vec::Vec}; use alloy_consensus::{Header, Transaction}; use alloy_eips::{eip2718::Encodable2718, eip4895::Withdrawals}; -use alloy_primitives::{Bytes, B256}; +use alloy_primitives::{Address, Bytes, B256}; /// Helper trait that unifies all behaviour required by transaction to support full node operations. pub trait FullBlockBody: BlockBody + MaybeSerdeBincodeCompat {} impl FullBlockBody for T where T: BlockBody + MaybeSerdeBincodeCompat {} +#[cfg(feature = "rayon")] +use rayon::prelude::*; + /// Abstraction for block's body. pub trait BlockBody: Send @@ -38,6 +41,15 @@ pub trait BlockBody: /// Returns reference to transactions in block. fn transactions(&self) -> &[Self::Transaction]; + /// Returns an iterator over all transaction hashes in the block body. + fn transaction_hashes_iter(&self) -> impl Iterator + '_ { + self.transactions().iter().map(|tx| tx.tx_hash()) + } + + /// Returns the number of the transactions in the block. + fn transaction_count(&self) -> usize { + self.transactions().len() + } /// Consume the block body and return a [`Vec`] of transactions. fn into_transactions(self) -> Vec; @@ -97,6 +109,39 @@ pub trait BlockBody: fn encoded_2718_transactions(&self) -> Vec { self.encoded_2718_transactions_iter().map(Into::into).collect() } + + /// Recover signer addresses for all transactions in the block body. + fn recover_signers(&self) -> Option> + where + Self::Transaction: SignedTransaction, + { + #[cfg(feature = "rayon")] + { + self.transactions().into_par_iter().map(|tx| tx.recover_signer()).collect() + } + #[cfg(not(feature = "rayon"))] + { + self.transactions().iter().map(|tx| tx.recover_signer()).collect() + } + } + + /// Recover signer addresses for all transactions in the block body _without ensuring that the + /// signature has a low `s` value_. + /// + /// Returns `None`, if some transaction's signature is invalid. + fn recover_signers_unchecked(&self) -> Option> + where + Self::Transaction: SignedTransaction, + { + #[cfg(feature = "rayon")] + { + self.transactions().into_par_iter().map(|tx| tx.recover_signer_unchecked()).collect() + } + #[cfg(not(feature = "rayon"))] + { + self.transactions().iter().map(|tx| tx.recover_signer_unchecked()).collect() + } + } } impl BlockBody for alloy_consensus::BlockBody diff --git a/crates/primitives-traits/src/lib.rs b/crates/primitives-traits/src/lib.rs index 74d10fc3c84f..322ed33edae3 100644 --- a/crates/primitives-traits/src/lib.rs +++ b/crates/primitives-traits/src/lib.rs @@ -69,6 +69,8 @@ pub use alloy_primitives::{logs_bloom, Log, LogData}; mod storage; pub use storage::StorageEntry; +pub mod sync; + /// Common header types pub mod header; #[cfg(any(test, feature = "arbitrary", feature = "test-utils"))] diff --git a/crates/primitives-traits/src/sync.rs b/crates/primitives-traits/src/sync.rs new file mode 100644 index 000000000000..353278da7499 --- /dev/null +++ b/crates/primitives-traits/src/sync.rs @@ -0,0 +1,9 @@ +//! Lock synchronization primitives + +use once_cell as _; + +#[cfg(not(feature = "std"))] +pub use once_cell::sync::{Lazy as LazyLock, OnceCell as OnceLock}; + +#[cfg(feature = "std")] +pub use std::sync::{LazyLock, OnceLock}; diff --git a/crates/primitives/src/transaction/access_list.rs b/crates/primitives-traits/src/transaction/access_list.rs similarity index 100% rename from crates/primitives/src/transaction/access_list.rs rename to crates/primitives-traits/src/transaction/access_list.rs diff --git a/crates/primitives-traits/src/transaction/mod.rs b/crates/primitives-traits/src/transaction/mod.rs index e474c8993c55..15b3df7fdb8b 100644 --- a/crates/primitives-traits/src/transaction/mod.rs +++ b/crates/primitives-traits/src/transaction/mod.rs @@ -11,6 +11,9 @@ pub use alloy_consensus::transaction::{TransactionInfo, TransactionMeta}; use crate::{InMemorySize, MaybeCompact, MaybeSerde}; use core::{fmt, hash::Hash}; +#[cfg(test)] +mod access_list; + /// Helper trait that unifies all behaviour required by transaction to support full node operations. pub trait FullTransaction: Transaction + MaybeCompact {} diff --git a/crates/primitives-traits/src/transaction/signature.rs b/crates/primitives-traits/src/transaction/signature.rs index 1ff56671bf77..06bbb6db14dd 100644 --- a/crates/primitives-traits/src/transaction/signature.rs +++ b/crates/primitives-traits/src/transaction/signature.rs @@ -2,3 +2,31 @@ /// Re-exported signature type pub use alloy_primitives::PrimitiveSignature as Signature; + +#[cfg(test)] +mod tests { + use crate::crypto::secp256k1::recover_signer; + use alloy_primitives::{Address, PrimitiveSignature as Signature, B256, U256}; + use std::str::FromStr; + + #[test] + fn test_recover_signer() { + let signature = Signature::new( + U256::from_str( + "18515461264373351373200002665853028612451056578545711640558177340181847433846", + ) + .unwrap(), + U256::from_str( + "46948507304638947509940763649030358759909902576025900602547168820602576006531", + ) + .unwrap(), + false, + ); + let hash = + B256::from_str("daf5a779ae972f972197303d7b574746c7ef83eadac0f2791ad23db92e4c8e53") + .unwrap(); + let signer = recover_signer(&signature, hash).unwrap(); + let expected = Address::from_str("0x9d8a62f656a8d1615c1294fd71e9cfb3e4855a4f").unwrap(); + assert_eq!(expected, signer); + } +} diff --git a/crates/primitives-traits/src/transaction/signed.rs b/crates/primitives-traits/src/transaction/signed.rs index 53338dc4dcf7..ddc79829ad1c 100644 --- a/crates/primitives-traits/src/transaction/signed.rs +++ b/crates/primitives-traits/src/transaction/signed.rs @@ -5,7 +5,10 @@ use crate::{ FillTxEnv, InMemorySize, MaybeCompact, MaybeSerde, }; use alloc::{fmt, vec::Vec}; -use alloy_consensus::{transaction::PooledTransaction, SignableTransaction}; +use alloy_consensus::{ + transaction::{PooledTransaction, Recovered}, + SignableTransaction, +}; use alloy_eips::eip2718::{Decodable2718, Encodable2718}; use alloy_primitives::{keccak256, Address, PrimitiveSignature as Signature, TxHash, B256}; use core::hash::Hash; @@ -156,3 +159,39 @@ impl SignedTransaction for op_alloy_consensus::OpPooledTransaction { recover_signer_unchecked(self.signature(), signature_hash) } } + +/// Extension trait for [`SignedTransaction`] to convert it into [`Recovered`]. +pub trait SignedTransactionIntoRecoveredExt: SignedTransaction { + /// Tries to recover signer and return [`Recovered`] by cloning the type. + fn try_ecrecovered(&self) -> Option> { + let signer = self.recover_signer()?; + Some(Recovered::new_unchecked(self.clone(), signer)) + } + + /// Tries to recover signer and return [`Recovered`]. + /// + /// 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(Recovered::new_unchecked(self, signer)), + } + } + + /// Consumes the type, recover signer and return [`Recovered`] _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> { + let signer = self.recover_signer_unchecked()?; + Some(Recovered::new_unchecked(self, signer)) + } + + /// Returns the [`Recovered`] transaction with the given sender. + fn with_signer(self, signer: Address) -> Recovered { + Recovered::new_unchecked(self, signer) + } +} + +impl SignedTransactionIntoRecoveredExt for T where T: SignedTransaction {} diff --git a/crates/primitives/src/alloy_compat.rs b/crates/primitives/src/alloy_compat.rs index fc83e6622e11..888876520830 100644 --- a/crates/primitives/src/alloy_compat.rs +++ b/crates/primitives/src/alloy_compat.rs @@ -2,13 +2,16 @@ use crate::{BlockBody, SealedBlock, Transaction, TransactionSigned}; use alloc::string::ToString; -use alloy_consensus::TxEnvelope; +use alloy_consensus::{Header, TxEnvelope}; use alloy_network::{AnyRpcBlock, AnyRpcTransaction, AnyTxEnvelope}; use alloy_serde::WithOtherFields; use op_alloy_rpc_types as _; use reth_primitives_traits::SealedHeader; -impl TryFrom for SealedBlock { +impl TryFrom for SealedBlock> +where + T: TryFrom, +{ type Error = alloy_rpc_types::ConversionError; fn try_from(block: AnyRpcBlock) -> Result { diff --git a/crates/primitives/src/block.rs b/crates/primitives/src/block.rs index ff3d5ed704b9..3cff1646e435 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, - RecoveredTx, SealedHeader, TransactionSigned, + traits::BlockExt, transaction::SignedTransactionIntoRecoveredExt, GotExpected, RecoveredTx, + SealedHeader, TransactionSigned, }; use alloc::vec::Vec; use alloy_consensus::Header; @@ -232,6 +232,17 @@ where } } +impl SealedBlock +where + B: reth_primitives_traits::BlockBody, +{ + /// Returns the number of transactions in the block. + #[inline] + pub fn transaction_count(&self) -> usize { + self.body.transaction_count() + } +} + impl SealedBlock where H: alloy_consensus::BlockHeader, @@ -918,4 +929,14 @@ mod tests { let decoded = BlockBody::decode(&mut buf.as_slice()).unwrap(); assert_eq!(body, decoded); } + + #[test] + fn test_transaction_count() { + let mut block = Block::default(); + assert_eq!(block.body.transaction_count(), 0); + block.body.transactions.push(TransactionSigned::default()); + assert_eq!(block.body.transaction_count(), 1); + block.body.transactions.push(TransactionSigned::default()); + assert_eq!(block.body.transaction_count(), 2); + } } diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index d44391de7cd9..4667689aebf4 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -44,13 +44,13 @@ pub use reth_primitives_traits::{ pub use static_file::StaticFileSegment; pub use alloy_consensus::{ - transaction::{PooledTransaction, TransactionMeta}, + transaction::{PooledTransaction, Recovered as RecoveredTx, TransactionMeta}, ReceiptWithBloom, }; pub use transaction::{ util::secp256k1::{public_key_to_address, recover_signer_unchecked, sign_message}, - InvalidTransactionError, PooledTransactionsElementEcRecovered, RecoveredTx, Transaction, - TransactionSigned, TransactionSignedEcRecovered, TxType, + InvalidTransactionError, PooledTransactionsElementEcRecovered, Transaction, TransactionSigned, + TransactionSignedEcRecovered, TxType, }; // Re-exports diff --git a/crates/primitives/src/traits.rs b/crates/primitives/src/traits.rs index d0d9c211b539..08a8ab3e665a 100644 --- a/crates/primitives/src/traits.rs +++ b/crates/primitives/src/traits.rs @@ -1,7 +1,4 @@ -use crate::{ - transaction::{recover_signers, recover_signers_unchecked}, - BlockWithSenders, SealedBlock, -}; +use crate::{BlockWithSenders, SealedBlock}; use alloc::vec::Vec; use reth_primitives_traits::{Block, BlockBody, SealedHeader, SignedTransaction}; use revm_primitives::{Address, B256}; @@ -52,7 +49,6 @@ pub trait BlockExt: Block { /// /// If the number of senders does not match the number of transactions in the block, this falls /// back to manually recovery, but _without ensuring that the signature has a low `s` value_. - /// See also [`recover_signers_unchecked`] /// /// Returns an error if a signature is invalid. #[track_caller] @@ -87,28 +83,3 @@ pub trait BlockExt: Block { } impl BlockExt for T {} - -/// Extension trait for [`BlockBody`] adding helper methods operating with transactions. -pub trait BlockBodyTxExt: BlockBody { - /// Recover signer addresses for all transactions in the block body. - fn recover_signers(&self) -> Option> - where - Self::Transaction: SignedTransaction, - { - recover_signers(self.transactions(), self.transactions().len()) - } - - /// Recover signer addresses for all transactions in the block body _without ensuring that the - /// signature has a low `s` value_. - /// - /// Returns `None`, if some transaction's signature is invalid, see also - /// [`recover_signers_unchecked`]. - fn recover_signers_unchecked(&self) -> Option> - where - Self::Transaction: SignedTransaction, - { - recover_signers_unchecked(self.transactions(), self.transactions().len()) - } -} - -impl BlockBodyTxExt for T {} diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index d3717586923a..64531d29ad39 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -1,5 +1,6 @@ //! Transaction types. +use crate::RecoveredTx; use alloc::vec::Vec; pub use alloy_consensus::transaction::PooledTransaction; use alloy_consensus::{ @@ -16,12 +17,10 @@ use alloy_eips::{ use alloy_primitives::{ keccak256, Address, Bytes, ChainId, PrimitiveSignature as Signature, TxHash, TxKind, B256, U256, }; -use alloy_rlp::{Decodable, Encodable, Error as RlpError, Header}; +use alloy_rlp::{Decodable, Encodable, Header}; use core::hash::{Hash, Hasher}; use derive_more::{AsRef, Deref}; use once_cell as _; -#[cfg(not(feature = "std"))] -use once_cell::sync::{Lazy as LazyLock, OnceCell as OnceLock}; #[cfg(feature = "optimism")] use op_alloy_consensus::DepositTransaction; #[cfg(feature = "optimism")] @@ -29,8 +28,12 @@ use op_alloy_consensus::TxDeposit; pub use pooled::PooledTransactionsElementEcRecovered; use rayon::prelude::{IntoParallelIterator, ParallelIterator}; pub use reth_primitives_traits::{ - transaction::error::{ - InvalidTransactionError, TransactionConversionError, TryFromRecoveredTransactionError, + sync::{LazyLock, OnceLock}, + transaction::{ + error::{ + InvalidTransactionError, TransactionConversionError, TryFromRecoveredTransactionError, + }, + signed::SignedTransactionIntoRecoveredExt, }, FillTxEnv, WithEncoded, }; @@ -38,8 +41,6 @@ use reth_primitives_traits::{InMemorySize, SignedTransaction}; use revm_primitives::{AuthorizationList, TxEnv}; use serde::{Deserialize, Serialize}; pub use signature::{recover_signer, recover_signer_unchecked}; -#[cfg(feature = "std")] -use std::sync::{LazyLock, OnceLock}; pub use tx_type::TxType; /// Handling transaction signature operations, including signature recovery, @@ -47,16 +48,9 @@ pub use tx_type::TxType; pub mod signature; pub mod util; -pub(crate) mod access_list; mod pooled; mod tx_type; -#[cfg(any(test, feature = "reth-codec"))] -pub use tx_type::{ - COMPACT_EXTENDED_IDENTIFIER_FLAG, COMPACT_IDENTIFIER_EIP1559, COMPACT_IDENTIFIER_EIP2930, - COMPACT_IDENTIFIER_LEGACY, -}; - /// Expected number of transactions where we can expect a speed-up by recovering the senders in /// parallel. pub static PARALLEL_SENDER_RECOVERY_THRESHOLD: LazyLock = @@ -878,8 +872,7 @@ impl TransactionSigned { } } - /// Converts from an EIP-4844 [`RecoveredTx`] to a - /// [`PooledTransactionsElementEcRecovered`] with the given sidecar. + /// Converts from an EIP-4844 transaction to a [`PooledTransaction`] with the given sidecar. /// /// Returns an `Err` containing the original `TransactionSigned` if the transaction is not /// EIP-4844. @@ -909,49 +902,18 @@ impl TransactionSigned { *self.tx_hash() } - /// 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() - } - } - - /// Recovers a list of signers from a transaction list iterator _without ensuring that the - /// signature has a low `s` value_. - /// - /// Returns `None`, if some transaction's signature is invalid, see also - /// [`Self::recover_signer_unchecked`]. - pub fn recover_signers_unchecked<'a, T>(txes: T, num_txes: usize) -> Option> - where - T: IntoParallelIterator + IntoIterator, - { - if num_txes < *PARALLEL_SENDER_RECOVERY_THRESHOLD { - txes.into_iter().map(|tx| tx.recover_signer_unchecked()).collect() - } else { - txes.into_par_iter().map(|tx| tx.recover_signer_unchecked()).collect() - } - } - /// Returns the [`RecoveredTx`] transaction with the given sender. #[inline] - pub const fn with_signer(self, signer: Address) -> RecoveredTx { - RecoveredTx::from_signed_transaction(self, signer) + pub const fn with_signer(self, signer: Address) -> RecoveredTx { + RecoveredTx::new_unchecked(self, signer) } /// 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(RecoveredTx { signed_transaction: self, signer }) + Some(RecoveredTx::new_unchecked(self, signer)) } /// Consumes the type, recover signer and return [`RecoveredTx`] _without @@ -959,9 +921,9 @@ impl TransactionSigned { /// /// 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(RecoveredTx { signed_transaction: self, signer }) + Some(RecoveredTx::new_unchecked(self, signer)) } /// Tries to recover signer and return [`RecoveredTx`]. _without ensuring that @@ -969,10 +931,10 @@ impl TransactionSigned { /// /// 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, Self> { match self.recover_signer_unchecked() { None => Err(self), - Some(signer) => Ok(RecoveredTx { signed_transaction: self, signer }), + Some(signer) => Ok(RecoveredTx::new_unchecked(self, signer)), } } @@ -1213,15 +1175,15 @@ impl alloy_consensus::Transaction for TransactionSigned { } } -impl From for TransactionSigned { - fn from(recovered: RecoveredTx) -> Self { - recovered.signed_transaction +impl From> for TransactionSigned { + fn from(recovered: RecoveredTx) -> Self { + recovered.into_tx() } } impl From> for TransactionSigned { fn from(recovered: RecoveredTx) -> Self { - recovered.signed_transaction.into() + recovered.into_tx().into() } } @@ -1527,7 +1489,7 @@ impl<'a> arbitrary::Arbitrary<'a> for TransactionSigned { let secp = secp256k1::Secp256k1::new(); let key_pair = secp256k1::Keypair::new(&secp, &mut rand::thread_rng()); - let signature = crate::sign_message( + let signature = reth_primitives_traits::crypto::secp256k1::sign_message( B256::from_slice(&key_pair.secret_bytes()[..]), transaction.signature_hash(), ) @@ -1552,135 +1514,6 @@ 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 RecoveredTx { - /// Signer of the transaction - signer: Address, - /// Signed transaction - #[deref] - #[as_ref] - signed_transaction: T, -} - -// === impl RecoveredTx === - -impl RecoveredTx { - /// Signer of transaction recovered from signature - pub const fn signer(&self) -> Address { - 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 - } - - /// Transform back to [`TransactionSigned`] - pub fn into_signed(self) -> T { - self.signed_transaction - } - - /// Dissolve Self to its component - pub fn to_components(self) -> (T, Address) { - (self.signed_transaction, self.signer) - } - - /// Create [`RecoveredTx`] from [`TransactionSigned`] and [`Address`] of the - /// signer. - #[inline] - pub const fn from_signed_transaction(signed_transaction: T, signer: Address) -> Self { - Self { signed_transaction, signer } - } - - /// Applies the given closure to the inner transactions. - pub fn map_transaction(self, f: impl FnOnce(T) -> Tx) -> RecoveredTx { - RecoveredTx::from_signed_transaction(f(self.signed_transaction), self.signer) - } -} - -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. - fn encode(&self, out: &mut dyn bytes::BufMut) { - self.signed_transaction.encode(out) - } - - fn length(&self) -> usize { - self.signed_transaction.length() - } -} - -impl Decodable for RecoveredTx { - fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { - let signed_transaction = T::decode(buf)?; - let signer = signed_transaction - .recover_signer() - .ok_or(RlpError::Custom("Unable to recover decoded transaction signer."))?; - Ok(Self { signer, signed_transaction }) - } -} - -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 { - /// 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). - /// - /// Returns `None` if the transaction's signature is invalid. - fn into_ecrecovered_unchecked(self) -> Option> { - let signer = self.recover_signer_unchecked()?; - Some(RecoveredTx::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) - } -} - -impl SignedTransactionIntoRecoveredExt for T where T: SignedTransaction {} - /// Bincode-compatible transaction type serde implementations. #[cfg(feature = "serde-bincode-compat")] pub mod serde_bincode_compat { @@ -1926,7 +1759,7 @@ where mod tests { use crate::{ transaction::{TxEip1559, TxKind, TxLegacy}, - RecoveredTx, Transaction, TransactionSigned, + Transaction, TransactionSigned, }; use alloy_consensus::Transaction as _; use alloy_eips::eip2718::{Decodable2718, Encodable2718}; @@ -2179,17 +2012,6 @@ mod tests { assert_eq!(encoded, input); } - #[test] - fn test_decode_signed_ec_recovered_transaction() { - // random tx: - let input = hex!("02f871018302a90f808504890aef60826b6c94ddf4c5025d1a5742cf12f74eec246d4432c295e487e09c3bbcc12b2b80c080a0f21a4eacd0bf8fea9c5105c543be5a1d8c796516875710fafafdf16d16d8ee23a001280915021bb446d1973501a67f93d2b38894a514b976e7b46dc2fe54598d76"); - let tx = TransactionSigned::decode(&mut &input[..]).unwrap(); - let recovered = tx.into_ecrecovered().unwrap(); - - let decoded = RecoveredTx::decode(&mut &alloy_rlp::encode(&recovered)[..]).unwrap(); - assert_eq!(recovered, decoded) - } - #[test] fn test_decode_tx() { // some random transactions pulled from hive tests @@ -2206,38 +2028,6 @@ mod tests { assert_eq!(data.as_slice(), b.as_slice()); } - #[cfg(feature = "secp256k1")] - proptest::proptest! { - #![proptest_config(proptest::prelude::ProptestConfig::with_cases(1))] - - #[test] - fn test_parallel_recovery_order(txes in proptest::collection::vec( - proptest_arbitrary_interop::arb::(), - *crate::transaction::PARALLEL_SENDER_RECOVERY_THRESHOLD * 5 - )) { - let mut rng =rand::thread_rng(); - let secp = secp256k1::Secp256k1::new(); - let txes: Vec = txes.into_iter().map(|mut tx| { - if let Some(chain_id) = tx.chain_id() { - // Otherwise we might overflow when calculating `v` on `recalculate_hash` - tx.set_chain_id(chain_id % (u64::MAX / 2 - 36)); - } - - let key_pair = secp256k1::Keypair::new(&secp, &mut rng); - - let signature = - crate::sign_message(B256::from_slice(&key_pair.secret_bytes()[..]), tx.signature_hash()).unwrap(); - - TransactionSigned::new_unhashed(tx, signature) - }).collect(); - - let parallel_senders = TransactionSigned::recover_signers(&txes, txes.len()).unwrap(); - let seq_senders = txes.iter().map(|tx| tx.recover_signer()).collect::>>().unwrap(); - - assert_eq!(parallel_senders, seq_senders); - } - } - // #[test] fn recover_legacy_singer() { diff --git a/crates/primitives/src/transaction/pooled.rs b/crates/primitives/src/transaction/pooled.rs index a01eb7142037..183d0af07ee3 100644 --- a/crates/primitives/src/transaction/pooled.rs +++ b/crates/primitives/src/transaction/pooled.rs @@ -3,49 +3,10 @@ use crate::RecoveredTx; use alloy_consensus::transaction::PooledTransaction; -use alloy_eips::eip4844::BlobTransactionSidecar; -use reth_primitives_traits::transaction::error::TransactionConversionError; /// A signed pooled transaction with recovered signer. pub type PooledTransactionsElementEcRecovered = RecoveredTx; -impl PooledTransactionsElementEcRecovered { - /// Transform back to [`RecoveredTx`] - pub fn into_ecrecovered_transaction(self) -> RecoveredTx { - let (tx, signer) = self.to_components(); - RecoveredTx::from_signed_transaction(tx.into(), signer) - } - - /// 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: RecoveredTx, - sidecar: BlobTransactionSidecar, - ) -> Result { - let RecoveredTx { signer, signed_transaction } = tx; - let transaction = signed_transaction - .try_into_pooled_eip4844(sidecar) - .map_err(|tx| RecoveredTx { signer, signed_transaction: tx })?; - Ok(Self::from_signed_transaction(transaction, signer)) - } -} - -/// Converts a `Recovered` into a `PooledTransactionsElementEcRecovered`. -impl TryFrom for PooledTransactionsElementEcRecovered { - type Error = TransactionConversionError; - - fn try_from(tx: RecoveredTx) -> Result { - match PooledTransaction::try_from(tx.signed_transaction) { - Ok(pooled_transaction) => { - Ok(Self::from_signed_transaction(pooled_transaction, tx.signer)) - } - Err(_) => Err(TransactionConversionError::UnsupportedForP2P), - } - } -} - #[cfg(test)] mod tests { use super::*; diff --git a/crates/primitives/src/transaction/signature.rs b/crates/primitives/src/transaction/signature.rs index 03b6327df2e9..cc5df1d74ca2 100644 --- a/crates/primitives/src/transaction/signature.rs +++ b/crates/primitives/src/transaction/signature.rs @@ -1,53 +1 @@ pub use reth_primitives_traits::crypto::secp256k1::{recover_signer, recover_signer_unchecked}; - -#[cfg(test)] -mod tests { - use crate::transaction::signature::{recover_signer, recover_signer_unchecked}; - use alloy_eips::{eip2718::Decodable2718, eip7702::constants::SECP256K1N_HALF}; - use alloy_primitives::{hex, Address, PrimitiveSignature as Signature, B256, U256}; - use reth_primitives_traits::SignedTransaction; - use std::str::FromStr; - - #[test] - fn test_recover_signer() { - let signature = Signature::new( - U256::from_str( - "18515461264373351373200002665853028612451056578545711640558177340181847433846", - ) - .unwrap(), - U256::from_str( - "46948507304638947509940763649030358759909902576025900602547168820602576006531", - ) - .unwrap(), - false, - ); - let hash = - B256::from_str("daf5a779ae972f972197303d7b574746c7ef83eadac0f2791ad23db92e4c8e53") - .unwrap(); - let signer = recover_signer(&signature, hash).unwrap(); - let expected = Address::from_str("0x9d8a62f656a8d1615c1294fd71e9cfb3e4855a4f").unwrap(); - assert_eq!(expected, signer); - } - - #[test] - fn eip_2_reject_high_s_value() { - // This pre-homestead transaction has a high `s` value and should be rejected by the - // `recover_signer` method: - // https://etherscan.io/getRawTx?tx=0x9e6e19637bb625a8ff3d052b7c2fe57dc78c55a15d258d77c43d5a9c160b0384 - // - // Block number: 46170 - let raw_tx = hex!("f86d8085746a52880082520894c93f2250589a6563f5359051c1ea25746549f0d889208686e75e903bc000801ba034b6fdc33ea520e8123cf5ac4a9ff476f639cab68980cd9366ccae7aef437ea0a0e517caa5f50e27ca0d1e9a92c503b4ccb039680c6d9d0c71203ed611ea4feb33"); - let tx = crate::transaction::TransactionSigned::decode_2718(&mut &raw_tx[..]).unwrap(); - let signature = tx.signature(); - - // make sure we know it's greater than SECP256K1N_HALF - assert!(signature.s() > SECP256K1N_HALF); - - // recover signer, expect failure - let hash = tx.hash(); - assert!(recover_signer(signature, hash).is_none()); - - // use unchecked, ensure it succeeds (the signature is valid if not for EIP-2) - assert!(recover_signer_unchecked(signature, hash).is_some()); - } -} diff --git a/crates/primitives/src/transaction/tx_type.rs b/crates/primitives/src/transaction/tx_type.rs index 83f954387692..cbd7f1c1e317 100644 --- a/crates/primitives/src/transaction/tx_type.rs +++ b/crates/primitives/src/transaction/tx_type.rs @@ -11,24 +11,6 @@ use derive_more::Display; use reth_primitives_traits::InMemorySize; use serde::{Deserialize, Serialize}; -/// Identifier parameter for legacy transaction -#[cfg(any(test, feature = "reth-codec"))] -pub const COMPACT_IDENTIFIER_LEGACY: usize = 0; - -/// Identifier parameter for EIP-2930 transaction -#[cfg(any(test, feature = "reth-codec"))] -pub const COMPACT_IDENTIFIER_EIP2930: usize = 1; - -/// Identifier parameter for EIP-1559 transaction -#[cfg(any(test, feature = "reth-codec"))] -pub const COMPACT_IDENTIFIER_EIP1559: usize = 2; - -/// 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. -#[cfg(any(test, feature = "reth-codec"))] -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 @@ -256,7 +238,7 @@ impl Decodable for TxType { mod tests { use super::*; use alloy_primitives::hex; - use reth_codecs::Compact; + use reth_codecs::{txtype::*, Compact}; use rstest::rstest; #[rstest] diff --git a/crates/prune/prune/src/segments/mod.rs b/crates/prune/prune/src/segments/mod.rs index 25f4b39cbb93..9f9e989dc06a 100644 --- a/crates/prune/prune/src/segments/mod.rs +++ b/crates/prune/prune/src/segments/mod.rs @@ -242,8 +242,7 @@ mod tests { let range = input.get_next_tx_num_range(&provider).expect("Expected range").unwrap(); // Calculate the total number of transactions - let num_txs = - blocks.iter().map(|block| block.body().transactions.len() as u64).sum::(); + let num_txs = blocks.iter().map(|block| block.transaction_count() as u64).sum::(); assert_eq!(range, 0..=num_txs - 1); } @@ -289,8 +288,7 @@ mod tests { let range = input.get_next_tx_num_range(&provider).expect("Expected range").unwrap(); // Calculate the total number of transactions - let num_txs = - blocks.iter().map(|block| block.body().transactions.len() as u64).sum::(); + let num_txs = blocks.iter().map(|block| block.transaction_count() as u64).sum::(); assert_eq!(range, 0..=num_txs - 1,); } @@ -324,8 +322,7 @@ mod tests { // Get the last tx number // Calculate the total number of transactions - let num_txs = - blocks.iter().map(|block| block.body().transactions.len() as u64).sum::(); + let num_txs = blocks.iter().map(|block| block.transaction_count() as u64).sum::(); let max_range = num_txs - 1; // Create a prune input with a previous checkpoint that is the last tx number diff --git a/crates/prune/prune/src/segments/receipts.rs b/crates/prune/prune/src/segments/receipts.rs index 922d11e83a64..50a21031f9ba 100644 --- a/crates/prune/prune/src/segments/receipts.rs +++ b/crates/prune/prune/src/segments/receipts.rs @@ -113,7 +113,7 @@ mod tests { let mut receipts = Vec::new(); for block in &blocks { - receipts.reserve_exact(block.body().transactions.len()); + receipts.reserve_exact(block.transaction_count()); for transaction in &block.body().transactions { receipts .push((receipts.len() as u64, random_receipt(&mut rng, transaction, Some(0)))); @@ -124,7 +124,7 @@ mod tests { assert_eq!( db.table::().unwrap().len(), - blocks.iter().map(|block| block.body().transactions.len()).sum::() + blocks.iter().map(|block| block.transaction_count()).sum::() ); assert_eq!( db.table::().unwrap().len(), @@ -158,7 +158,7 @@ mod tests { let last_pruned_tx_number = blocks .iter() .take(to_block as usize) - .map(|block| block.body().transactions.len()) + .map(|block| block.transaction_count()) .sum::() .min( next_tx_number_to_prune as usize + @@ -186,7 +186,7 @@ mod tests { let last_pruned_block_number = blocks .iter() .fold_while((0, 0), |(_, mut tx_count), block| { - tx_count += block.body().transactions.len(); + tx_count += block.transaction_count(); if tx_count > last_pruned_tx_number { Done((block.number, tx_count)) diff --git a/crates/prune/prune/src/segments/static_file/transactions.rs b/crates/prune/prune/src/segments/static_file/transactions.rs index 19a6fd06d0e7..f3e5c3ffa972 100644 --- a/crates/prune/prune/src/segments/static_file/transactions.rs +++ b/crates/prune/prune/src/segments/static_file/transactions.rs @@ -174,7 +174,7 @@ mod tests { let last_pruned_tx_number = blocks .iter() .take(to_block as usize) - .map(|block| block.body().transactions.len()) + .map(|block| block.transaction_count()) .sum::() .min( next_tx_number_to_prune as usize + @@ -185,7 +185,7 @@ mod tests { let last_pruned_block_number = blocks .iter() .fold_while((0, 0), |(_, mut tx_count), block| { - tx_count += block.body().transactions.len(); + tx_count += block.transaction_count(); if tx_count > last_pruned_tx_number { Done((block.number, tx_count)) diff --git a/crates/prune/prune/src/segments/user/receipts_by_logs.rs b/crates/prune/prune/src/segments/user/receipts_by_logs.rs index b82f38e5f1a8..4706b560bd31 100644 --- a/crates/prune/prune/src/segments/user/receipts_by_logs.rs +++ b/crates/prune/prune/src/segments/user/receipts_by_logs.rs @@ -278,7 +278,7 @@ mod tests { let mut receipt = random_receipt(&mut rng, transaction, Some(1)); receipt.logs.push(random_log( &mut rng, - (txi == (block.body().transactions.len() - 1)).then_some(deposit_contract_addr), + (txi == (block.transaction_count() - 1)).then_some(deposit_contract_addr), Some(1), )); receipts.push((receipts.len() as u64, receipt)); @@ -288,7 +288,7 @@ mod tests { assert_eq!( db.table::().unwrap().len(), - blocks.iter().map(|block| block.body().transactions.len()).sum::() + blocks.iter().map(|block| block.transaction_count()).sum::() ); assert_eq!( db.table::().unwrap().len(), @@ -337,7 +337,7 @@ mod tests { assert_eq!( db.table::().unwrap().len(), - blocks.iter().map(|block| block.body().transactions.len()).sum::() - + blocks.iter().map(|block| block.transaction_count()).sum::() - ((pruned_tx + 1) - unprunable) as usize ); diff --git a/crates/prune/prune/src/segments/user/sender_recovery.rs b/crates/prune/prune/src/segments/user/sender_recovery.rs index a119b8ca8fd1..be5a7842c58b 100644 --- a/crates/prune/prune/src/segments/user/sender_recovery.rs +++ b/crates/prune/prune/src/segments/user/sender_recovery.rs @@ -111,7 +111,7 @@ mod tests { let mut transaction_senders = Vec::new(); for block in &blocks { - transaction_senders.reserve_exact(block.body().transactions.len()); + transaction_senders.reserve_exact(block.transaction_count()); for transaction in &block.body().transactions { transaction_senders.push(( transaction_senders.len() as u64, @@ -124,7 +124,7 @@ mod tests { assert_eq!( db.table::().unwrap().len(), - blocks.iter().map(|block| block.body().transactions.len()).sum::() + blocks.iter().map(|block| block.transaction_count()).sum::() ); assert_eq!( db.table::().unwrap().len(), @@ -159,7 +159,7 @@ mod tests { let last_pruned_tx_number = blocks .iter() .take(to_block as usize) - .map(|block| block.body().transactions.len()) + .map(|block| block.transaction_count()) .sum::() .min( next_tx_number_to_prune as usize + @@ -170,7 +170,7 @@ mod tests { let last_pruned_block_number = blocks .iter() .fold_while((0, 0), |(_, mut tx_count), block| { - tx_count += block.body().transactions.len(); + tx_count += block.transaction_count(); if tx_count > last_pruned_tx_number { Done((block.number, tx_count)) diff --git a/crates/prune/prune/src/segments/user/transaction_lookup.rs b/crates/prune/prune/src/segments/user/transaction_lookup.rs index f1637123ad02..2629c217f0d0 100644 --- a/crates/prune/prune/src/segments/user/transaction_lookup.rs +++ b/crates/prune/prune/src/segments/user/transaction_lookup.rs @@ -139,7 +139,7 @@ mod tests { let mut tx_hash_numbers = Vec::new(); for block in &blocks { - tx_hash_numbers.reserve_exact(block.body().transactions.len()); + tx_hash_numbers.reserve_exact(block.transaction_count()); for transaction in &block.body().transactions { tx_hash_numbers.push((transaction.hash(), tx_hash_numbers.len() as u64)); } @@ -149,7 +149,7 @@ mod tests { assert_eq!( db.table::().unwrap().len(), - blocks.iter().map(|block| block.body().transactions.len()).sum::() + blocks.iter().map(|block| block.transaction_count()).sum::() ); assert_eq!( db.table::().unwrap().len(), @@ -184,7 +184,7 @@ mod tests { let last_pruned_tx_number = blocks .iter() .take(to_block as usize) - .map(|block| block.body().transactions.len()) + .map(|block| block.transaction_count()) .sum::() .min( next_tx_number_to_prune as usize + @@ -195,7 +195,7 @@ mod tests { let last_pruned_block_number = blocks .iter() .fold_while((0, 0), |(_, mut tx_count), block| { - tx_count += block.body().transactions.len(); + tx_count += block.transaction_count(); if tx_count > last_pruned_tx_number { Done((block.number, tx_count)) diff --git a/crates/rpc/rpc-engine-api/src/engine_api.rs b/crates/rpc/rpc-engine-api/src/engine_api.rs index f26f90f87614..db27d8a1e35d 100644 --- a/crates/rpc/rpc-engine-api/src/engine_api.rs +++ b/crates/rpc/rpc-engine-api/src/engine_api.rs @@ -1029,9 +1029,8 @@ mod tests { use reth_engine_primitives::BeaconEngineMessage; use reth_ethereum_engine_primitives::{EthEngineTypes, EthereumEngineValidator}; use reth_payload_builder::test_utils::spawn_test_payload_service; - use reth_primitives::{Block, SealedBlock}; + use reth_primitives::{Block, TransactionSigned}; use reth_provider::test_utils::MockEthProvider; - use reth_rpc_types_compat::engine::payload::execution_payload_from_sealed_block; use reth_tasks::TokioTaskExecutor; use reth_testing_utils::generators::random_block; use reth_transaction_pool::noop::NoopTransactionPool; @@ -1098,9 +1097,11 @@ mod tests { let (mut handle, api) = setup_engine_api(); tokio::spawn(async move { - api.new_payload_v1(execution_payload_from_sealed_block(SealedBlock::default())) - .await - .unwrap(); + api.new_payload_v1(ExecutionPayloadV1::from_block_slow( + &Block::::default(), + )) + .await + .unwrap(); }); assert_matches!(handle.from_api.recv().await, Some(BeaconEngineMessage::NewPayload { .. })); } diff --git a/crates/rpc/rpc-eth-api/src/helpers/call.rs b/crates/rpc/rpc-eth-api/src/helpers/call.rs index 1b20dd9d9fc2..2aecb500dd5e 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/call.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/call.rs @@ -682,7 +682,7 @@ pub trait Call: let env = EnvWithHandlerCfg::new_with_cfg_env( cfg_env_with_handler_cfg, block_env, - RpcNodeCore::evm_config(&this).tx_env(tx.as_signed(), tx.signer()), + RpcNodeCore::evm_config(&this).tx_env(tx.tx(), tx.signer()), ); let (res, _) = this.transact(&mut db, env)?; 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 5f0512e3e76e..fd69422da68b 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs @@ -341,7 +341,7 @@ pub trait LoadPendingBlock: let env = Env::boxed( cfg.cfg_env.clone(), block_env.clone(), - Self::evm_config(self).tx_env(tx.as_signed(), tx.signer()), + Self::evm_config(self).tx_env(tx.tx(), tx.signer()), ); let mut evm = revm::Evm::builder().with_env(env).with_db(&mut db).build(); @@ -393,7 +393,7 @@ pub trait LoadPendingBlock: cumulative_gas_used += gas_used; // append transaction to the list of executed transactions - let (tx, sender) = tx.to_components(); + let (tx, sender) = tx.into_parts(); executed_txs.push(tx); senders.push(sender); results.push(result); diff --git a/crates/rpc/rpc-eth-api/src/helpers/trace.rs b/crates/rpc/rpc-eth-api/src/helpers/trace.rs index a5808b04ccbe..66c6b5a27a92 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/trace.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/trace.rs @@ -226,7 +226,7 @@ pub trait Trace: let env = EnvWithHandlerCfg::new_with_cfg_env( cfg_env_with_handler_cfg, block_env, - RpcNodeCore::evm_config(&this).tx_env(tx.as_signed(), tx.signer()), + RpcNodeCore::evm_config(&this).tx_env(tx.tx(), tx.signer()), ); let (res, _) = this.inspect(StateCacheDbRefMutWrapper(&mut db), env, &mut inspector)?; diff --git a/crates/rpc/rpc-eth-api/src/helpers/transaction.rs b/crates/rpc/rpc-eth-api/src/helpers/transaction.rs index 6096cb3579ff..6da59a98b24c 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/transaction.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/transaction.rs @@ -21,7 +21,7 @@ use reth_provider::{ TransactionsProvider, }; use reth_rpc_eth_types::{utils::binary_search, EthApiError, SignError, TransactionSource}; -use reth_rpc_types_compat::transaction::{from_recovered, from_recovered_with_block_context}; +use reth_rpc_types_compat::transaction::TransactionCompat; use reth_transaction_pool::{PoolTransaction, TransactionOrigin, TransactionPool}; use std::sync::Arc; @@ -221,11 +221,9 @@ pub trait EthTransactions: LoadTransaction { index: Some(index as u64), }; - return Ok(Some(from_recovered_with_block_context( - tx.clone().with_signer(*signer), - tx_info, - self.tx_resp_builder(), - )?)) + return Ok(Some( + self.tx_resp_builder().fill(tx.clone().with_signer(*signer), tx_info)?, + )) } } @@ -250,7 +248,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, self.tx_resp_builder())?)); + return Ok(Some(self.tx_resp_builder().fill_pending(transaction)?)); } } @@ -301,11 +299,7 @@ pub trait EthTransactions: LoadTransaction { base_fee: base_fee_per_gas.map(u128::from), index: Some(index as u64), }; - from_recovered_with_block_context( - tx.clone().with_signer(*signer), - tx_info, - self.tx_resp_builder(), - ) + self.tx_resp_builder().fill(tx.clone().with_signer(*signer), tx_info) }) }) .ok_or(EthApiError::HeaderNotFound(block_id))? diff --git a/crates/rpc/rpc-eth-types/src/transaction.rs b/crates/rpc/rpc-eth-types/src/transaction.rs index f994638d3af8..549ca0e8bb9e 100644 --- a/crates/rpc/rpc-eth-types/src/transaction.rs +++ b/crates/rpc/rpc-eth-types/src/transaction.rs @@ -6,10 +6,7 @@ use alloy_primitives::B256; use alloy_rpc_types_eth::TransactionInfo; use reth_primitives::{RecoveredTx, TransactionSigned}; use reth_primitives_traits::SignedTransaction; -use reth_rpc_types_compat::{ - transaction::{from_recovered, from_recovered_with_block_context}, - TransactionCompat, -}; +use reth_rpc_types_compat::TransactionCompat; /// Represents from where a transaction was fetched. #[derive(Debug, Clone, Eq, PartialEq)] @@ -47,7 +44,7 @@ impl TransactionSource { resp_builder: &Builder, ) -> Result { match self { - Self::Pool(tx) => from_recovered(tx, resp_builder), + Self::Pool(tx) => resp_builder.fill_pending(tx), Self::Block { transaction, index, block_hash, block_number, base_fee } => { let tx_info = TransactionInfo { hash: Some(transaction.trie_hash()), @@ -57,7 +54,7 @@ impl TransactionSource { base_fee: base_fee.map(u128::from), }; - from_recovered_with_block_context(transaction, tx_info, resp_builder) + resp_builder.fill(transaction, tx_info) } } } diff --git a/crates/rpc/rpc-types-compat/src/block.rs b/crates/rpc/rpc-types-compat/src/block.rs index 7d8c1480033a..5eac699e12a5 100644 --- a/crates/rpc/rpc-types-compat/src/block.rs +++ b/crates/rpc/rpc-types-compat/src/block.rs @@ -9,7 +9,7 @@ use alloy_rpc_types_eth::{ use reth_primitives::{transaction::SignedTransactionIntoRecoveredExt, BlockWithSenders}; use reth_primitives_traits::{Block as BlockTrait, BlockBody, SignedTransaction}; -use crate::{transaction::from_recovered_with_block_context, TransactionCompat}; +use crate::transaction::TransactionCompat; /// Converts the given primitive block into a [`Block`] response with the given /// [`BlockTransactionsKind`] @@ -47,7 +47,7 @@ where B: BlockTrait, { let block_hash = block_hash.unwrap_or_else(|| block.header().hash_slow()); - let transactions = block.body().transactions().iter().map(|tx| *tx.tx_hash()).collect(); + let transactions = block.body().transaction_hashes_iter().copied().collect(); from_block_with_transactions( block.length(), @@ -94,11 +94,7 @@ where index: Some(idx as u64), }; - from_recovered_with_block_context::<_, T>( - signed_tx_ec_recovered, - tx_info, - tx_resp_builder, - ) + tx_resp_builder.fill(signed_tx_ec_recovered, tx_info) }) .collect::, T::Error>>()?; diff --git a/crates/rpc/rpc-types-compat/src/engine/payload.rs b/crates/rpc/rpc-types-compat/src/engine/payload.rs index 2ce20865bd1b..6645188f3177 100644 --- a/crates/rpc/rpc-types-compat/src/engine/payload.rs +++ b/crates/rpc/rpc-types-compat/src/engine/payload.rs @@ -32,7 +32,7 @@ pub fn block_to_payload( _ => ExecutionPayloadSidecar::none(), }; - let execution_payload = if value.header.parent_beacon_block_root.is_some() { + let execution_payload = if value.parent_beacon_block_root.is_some() { // block with parent beacon block root: V3 ExecutionPayload::V3(block_to_payload_v3(value)) } else if value.body().withdrawals.is_some() { @@ -114,27 +114,6 @@ pub fn convert_to_payload_body_v1( } } -/// Transforms a [`SealedBlock`] into a [`ExecutionPayloadV1`] -pub fn execution_payload_from_sealed_block(value: SealedBlock) -> ExecutionPayloadV1 { - let transactions = value.encoded_2718_transactions(); - ExecutionPayloadV1 { - parent_hash: value.parent_hash, - fee_recipient: value.beneficiary, - state_root: value.state_root, - receipts_root: value.receipts_root, - logs_bloom: value.logs_bloom, - prev_randao: value.mix_hash, - block_number: value.number, - gas_limit: value.gas_limit, - gas_used: value.gas_used, - timestamp: value.timestamp, - extra_data: value.extra_data.clone(), - base_fee_per_gas: U256::from(value.base_fee_per_gas.unwrap_or_default()), - block_hash: value.hash(), - transactions, - } -} - #[cfg(test)] mod tests { use super::block_to_payload_v3; diff --git a/crates/rpc/rpc-types-compat/src/transaction.rs b/crates/rpc/rpc-types-compat/src/transaction.rs index b5515ce9e23d..f2c641d2ffcf 100644 --- a/crates/rpc/rpc-types-compat/src/transaction.rs +++ b/crates/rpc/rpc-types-compat/src/transaction.rs @@ -7,28 +7,6 @@ use alloy_rpc_types_eth::{request::TransactionRequest, TransactionInfo}; use reth_primitives::{RecoveredTx, TransactionSigned}; use serde::{Deserialize, Serialize}; -/// Create a new rpc transaction result for a mined transaction, using the given block hash, -/// number, and tx index fields to populate the corresponding fields in the rpc result. -/// -/// 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: RecoveredTx, - tx_info: TransactionInfo, - resp_builder: &T, -) -> Result { - resp_builder.fill(tx, tx_info) -} - -/// Create a new rpc transaction result for a _pending_ signed transaction, setting block -/// environment related fields to `None`. -pub fn from_recovered>( - tx: RecoveredTx, - resp_builder: &T, -) -> Result { - resp_builder.fill(tx, TransactionInfo::default()) -} - /// Builds RPC transaction w.r.t. network. pub trait TransactionCompat: Send + Sync + Unpin + Clone + fmt::Debug @@ -45,8 +23,18 @@ pub trait TransactionCompat: /// RPC transaction error type. type Error: error::Error + Into>; + /// Wrapper for `fill()` with default `TransactionInfo` /// Create a new rpc transaction result for a _pending_ signed transaction, setting block /// environment related fields to `None`. + fn fill_pending(&self, tx: RecoveredTx) -> Result { + self.fill(tx, TransactionInfo::default()) + } + + /// Create a new rpc transaction result for a mined transaction, using the given block hash, + /// number, and tx index fields to populate the corresponding fields in the rpc result. + /// + /// The block hash, number, and tx index fields should be from the original block where the + /// transaction was mined. fn fill( &self, tx: RecoveredTx, @@ -68,5 +56,5 @@ pub fn transaction_to_call_request( tx: RecoveredTx, ) -> TransactionRequest { let from = tx.signer(); - TransactionRequest::from_transaction_with_sender(tx.into_signed(), from) + TransactionRequest::from_transaction_with_sender(tx.into_tx(), from) } diff --git a/crates/rpc/rpc/src/debug.rs b/crates/rpc/rpc/src/debug.rs index 68192d160caf..5ddd1f49f69c 100644 --- a/crates/rpc/rpc/src/debug.rs +++ b/crates/rpc/rpc/src/debug.rs @@ -273,7 +273,7 @@ where env: Env::boxed( cfg_env_with_handler_cfg.cfg_env.clone(), block_env, - this.eth_api().evm_config().tx_env(tx.as_signed(), tx.signer()), + this.eth_api().evm_config().tx_env(tx.tx(), tx.signer()), ), handler_cfg: cfg_env_with_handler_cfg.handler_cfg, }; diff --git a/crates/rpc/rpc/src/eth/filter.rs b/crates/rpc/rpc/src/eth/filter.rs index 6441db70459a..337fbb91e06d 100644 --- a/crates/rpc/rpc/src/eth/filter.rs +++ b/crates/rpc/rpc/src/eth/filter.rs @@ -23,7 +23,6 @@ use reth_rpc_eth_types::{ EthApiError, EthFilterConfig, EthStateCache, EthSubscriptionIdProvider, }; 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::{ @@ -637,7 +636,7 @@ where let mut prepared_stream = self.txs_stream.lock().await; while let Ok(tx) = prepared_stream.try_recv() { - match from_recovered(tx.transaction.to_consensus(), &self.tx_resp_builder) { + match self.tx_resp_builder.fill_pending(tx.transaction.to_consensus()) { Ok(tx) => pending_txs.push(tx), Err(err) => { error!(target: "rpc", diff --git a/crates/rpc/rpc/src/eth/helpers/types.rs b/crates/rpc/rpc/src/eth/helpers/types.rs index 91e9f7875576..48a6d0d8ab6c 100644 --- a/crates/rpc/rpc/src/eth/helpers/types.rs +++ b/crates/rpc/rpc/src/eth/helpers/types.rs @@ -39,12 +39,12 @@ where fn fill( &self, - tx: RecoveredTx, + tx: RecoveredTx, tx_info: TransactionInfo, ) -> Result { let from = tx.signer(); let hash = tx.hash(); - let TransactionSigned { transaction, signature, .. } = tx.into_signed(); + let TransactionSigned { transaction, signature, .. } = tx.into_tx(); let inner: TxEnvelope = match transaction { reth_primitives::Transaction::Legacy(tx) => { diff --git a/crates/rpc/rpc/src/eth/pubsub.rs b/crates/rpc/rpc/src/eth/pubsub.rs index fc02b0da0671..c38028a33e2e 100644 --- a/crates/rpc/rpc/src/eth/pubsub.rs +++ b/crates/rpc/rpc/src/eth/pubsub.rs @@ -19,7 +19,6 @@ use reth_rpc_eth_api::{ }; 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, PoolConsensusTx, TransactionPool}; use serde::Serialize; @@ -119,10 +118,11 @@ where Params::Bool(true) => { // full transaction objects requested let stream = pubsub.full_pending_transaction_stream().filter_map(|tx| { - let tx_value = match from_recovered( - tx.transaction.to_consensus(), - pubsub.eth_api.tx_resp_builder(), - ) { + let tx_value = match pubsub + .eth_api + .tx_resp_builder() + .fill_pending(tx.transaction.to_consensus()) + { Ok(tx) => Some(tx), Err(err) => { error!(target = "rpc", diff --git a/crates/rpc/rpc/src/eth/sim_bundle.rs b/crates/rpc/rpc/src/eth/sim_bundle.rs index a9a6a17f50ee..de2597b64a3f 100644 --- a/crates/rpc/rpc/src/eth/sim_bundle.rs +++ b/crates/rpc/rpc/src/eth/sim_bundle.rs @@ -172,7 +172,7 @@ where match &body[idx] { BundleItem::Tx { tx, can_revert } => { let recovered_tx = recover_raw_transaction::>(tx)?; - let (tx, signer) = recovered_tx.to_components(); + let (tx, signer) = recovered_tx.into_parts(); let tx: PoolConsensusTx = ::Transaction::pooled_into_consensus(tx); diff --git a/crates/rpc/rpc/src/trace.rs b/crates/rpc/rpc/src/trace.rs index aaf8539ab454..33e32aec0281 100644 --- a/crates/rpc/rpc/src/trace.rs +++ b/crates/rpc/rpc/src/trace.rs @@ -121,7 +121,7 @@ where let env = EnvWithHandlerCfg::new_with_cfg_env( cfg_env_with_handler_cfg, block_env, - self.eth_api().evm_config().tx_env(tx.as_signed(), tx.signer()), + self.eth_api().evm_config().tx_env(tx.tx(), tx.signer()), ); let config = TracingInspectorConfig::from_parity_config(&trace_types); diff --git a/crates/rpc/rpc/src/txpool.rs b/crates/rpc/rpc/src/txpool.rs index a8d783406773..7d0414ed3c7d 100644 --- a/crates/rpc/rpc/src/txpool.rs +++ b/crates/rpc/rpc/src/txpool.rs @@ -9,7 +9,7 @@ use alloy_rpc_types_txpool::{ use async_trait::async_trait; use jsonrpsee::core::RpcResult; use reth_rpc_api::TxPoolApiServer; -use reth_rpc_types_compat::{transaction::from_recovered, TransactionCompat}; +use reth_rpc_types_compat::TransactionCompat; use reth_transaction_pool::{ AllPoolTransactions, PoolConsensusTx, PoolTransaction, TransactionPool, }; @@ -50,7 +50,7 @@ where { content.entry(tx.sender()).or_default().insert( tx.nonce().to_string(), - from_recovered(tx.clone_into_consensus(), resp_builder)?, + resp_builder.fill_pending(tx.clone_into_consensus())?, ); Ok(()) @@ -103,7 +103,7 @@ where ) { let entry = inspect.entry(tx.sender()).or_default(); let tx = tx.clone_into_consensus(); - entry.insert(tx.nonce().to_string(), tx.into_signed().into()); + entry.insert(tx.nonce().to_string(), tx.into_tx().into()); } let AllPoolTransactions { pending, queued } = self.pool.all_transactions(); diff --git a/crates/stages/stages/src/stages/bodies.rs b/crates/stages/stages/src/stages/bodies.rs index 9bc1bcc45ca0..b17ad3562a09 100644 --- a/crates/stages/stages/src/stages/bodies.rs +++ b/crates/stages/stages/src/stages/bodies.rs @@ -592,7 +592,7 @@ mod tests { let body = StoredBlockBodyIndices { first_tx_num: 0, - tx_count: progress.body().transactions.len() as u64, + tx_count: progress.transaction_count() as u64, }; static_file_producer.set_block_range(0..=progress.number); diff --git a/crates/stages/stages/src/stages/execution.rs b/crates/stages/stages/src/stages/execution.rs index a2d8378673f1..0aef24caf4f9 100644 --- a/crates/stages/stages/src/stages/execution.rs +++ b/crates/stages/stages/src/stages/execution.rs @@ -701,7 +701,9 @@ mod tests { previous_checkpoint, ); - assert_eq!(stage_checkpoint, Ok(previous_stage_checkpoint)); + assert!( + matches!(stage_checkpoint, Ok(checkpoint) if checkpoint == previous_stage_checkpoint) + ); } #[test] @@ -937,28 +939,21 @@ mod tests { }; // assert accounts - assert_eq!( - provider.basic_account(&account1), - Ok(Some(account1_info)), - "Post changed of a account" + assert!( + matches!(provider.basic_account(&account1), Ok(Some(acc)) if acc == account1_info) ); - assert_eq!( - provider.basic_account(&account2), - Ok(Some(account2_info)), - "Post changed of a account" + assert!( + matches!(provider.basic_account(&account2), Ok(Some(acc)) if acc == account2_info) ); - assert_eq!( - provider.basic_account(&account3), - Ok(Some(account3_info)), - "Post changed of a account" + assert!( + matches!(provider.basic_account(&account3), Ok(Some(acc)) if acc == account3_info) ); // assert storage // Get on dupsort would return only first value. This is good enough for this test. - assert_eq!( + assert!(matches!( provider.tx_ref().get::(account1), - Ok(Some(StorageEntry { key: B256::with_last_byte(1), value: U256::from(2) })), - "Post changed of a account" - ); + Ok(Some(entry)) if entry.key == B256::with_last_byte(1) && entry.value == U256::from(2) + )); let mut provider = factory.database_provider_rw().unwrap(); let mut stage = stage(); @@ -1073,25 +1068,13 @@ mod tests { } if total == block.gas_used); // assert unwind stage - assert_eq!( - provider.basic_account(&acc1), - Ok(Some(acc1_info)), - "Pre changed of a account" - ); - assert_eq!( - provider.basic_account(&acc2), - Ok(Some(acc2_info)), - "Post changed of a account" - ); + assert!(matches!(provider.basic_account(&acc1), Ok(Some(acc)) if acc == acc1_info)); + assert!(matches!(provider.basic_account(&acc2), Ok(Some(acc)) if acc == acc2_info)); let miner_acc = address!("2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"); - assert_eq!( - provider.basic_account(&miner_acc), - Ok(None), - "Third account should be unwound" - ); + assert!(matches!(provider.basic_account(&miner_acc), Ok(None))); - assert_eq!(provider.receipt(0), Ok(None), "First receipt should be unwound"); + assert!(matches!(provider.receipt(0), Ok(None))); } } @@ -1172,13 +1155,12 @@ mod tests { // assert unwind stage let provider = test_db.factory.database_provider_rw().unwrap(); - assert_eq!(provider.basic_account(&destroyed_address), Ok(None), "Account was destroyed"); + assert!(matches!(provider.basic_account(&destroyed_address), Ok(None))); - assert_eq!( + assert!(matches!( provider.tx_ref().get::(destroyed_address), - Ok(None), - "There is storage for destroyed account" - ); + Ok(None) + )); // drops tx so that it returns write privilege to test_tx drop(provider); let plain_accounts = test_db.table::().unwrap(); diff --git a/crates/stages/stages/src/stages/hashing_storage.rs b/crates/stages/stages/src/stages/hashing_storage.rs index 6110d2101704..6075e62158fd 100644 --- a/crates/stages/stages/src/stages/hashing_storage.rs +++ b/crates/stages/stages/src/stages/hashing_storage.rs @@ -398,7 +398,7 @@ mod tests { let body = StoredBlockBodyIndices { first_tx_num, - tx_count: progress.body().transactions.len() as u64, + tx_count: progress.transaction_count() as u64, }; first_tx_num = next_tx_num; diff --git a/crates/stages/stages/src/stages/mod.rs b/crates/stages/stages/src/stages/mod.rs index 6ef5b26590c8..e5cf6d525c28 100644 --- a/crates/stages/stages/src/stages/mod.rs +++ b/crates/stages/stages/src/stages/mod.rs @@ -267,7 +267,7 @@ mod tests { let mut receipts = Vec::with_capacity(blocks.len()); let mut tx_num = 0u64; for block in &blocks { - let mut block_receipts = Vec::with_capacity(block.body().transactions.len()); + let mut block_receipts = Vec::with_capacity(block.transaction_count()); for transaction in &block.body().transactions { block_receipts.push((tx_num, random_receipt(&mut rng, transaction, Some(0)))); tx_num += 1; @@ -317,11 +317,11 @@ mod tests { // writer for the first time. let mut static_file_provider = db.factory.static_file_provider(); static_file_provider = StaticFileProvider::read_write(static_file_provider.path()).unwrap(); - assert_eq!( + assert!(matches!( static_file_provider .check_consistency(&db.factory.database_provider_ro().unwrap(), is_full_node,), - Ok(expected) - ); + Ok(e) if e == expected + )); } /// Saves a checkpoint with `checkpoint_block_number` and compare the check consistency result @@ -338,12 +338,12 @@ mod tests { .unwrap(); provider_rw.commit().unwrap(); - assert_eq!( + assert!(matches!( db.factory .static_file_provider() .check_consistency(&db.factory.database_provider_ro().unwrap(), false,), - Ok(expected) - ); + Ok(e) if e == expected + )); } /// Inserts a dummy value at key and compare the check consistency result against the expected @@ -360,12 +360,12 @@ mod tests { cursor.insert(key, Default::default()).unwrap(); provider_rw.commit().unwrap(); - assert_eq!( + assert!(matches!( db.factory .static_file_provider() .check_consistency(&db.factory.database_provider_ro().unwrap(), false), - Ok(expected) - ); + Ok(e) if e == expected + )); } #[test] @@ -373,10 +373,10 @@ mod tests { let db = seed_data(90).unwrap(); let db_provider = db.factory.database_provider_ro().unwrap(); - assert_eq!( + assert!(matches!( db.factory.static_file_provider().check_consistency(&db_provider, false), Ok(None) - ); + )); } #[test] diff --git a/crates/stages/stages/src/stages/sender_recovery.rs b/crates/stages/stages/src/stages/sender_recovery.rs index f832df7ffeb7..8d768265465f 100644 --- a/crates/stages/stages/src/stages/sender_recovery.rs +++ b/crates/stages/stages/src/stages/sender_recovery.rs @@ -477,7 +477,7 @@ mod tests { let expected_progress = seed .iter() .find(|x| { - tx_count += x.body().transactions.len(); + tx_count += x.transaction_count(); tx_count as u64 > threshold }) .map(|x| x.number) @@ -555,7 +555,7 @@ mod tests { tx_number: Some( blocks[..=max_pruned_block as usize] .iter() - .map(|block| block.body().transactions.len() as u64) + .map(|block| block.transaction_count() as u64) .sum(), ), prune_mode: PruneMode::Full, @@ -570,9 +570,9 @@ mod tests { EntitiesCheckpoint { processed: blocks[..=max_processed_block] .iter() - .map(|block| block.body().transactions.len() as u64) + .map(|block| block.transaction_count() as u64) .sum(), - total: blocks.iter().map(|block| block.body().transactions.len() as u64).sum() + total: blocks.iter().map(|block| block.transaction_count() as u64).sum() } ); } diff --git a/crates/stages/stages/src/stages/tx_lookup.rs b/crates/stages/stages/src/stages/tx_lookup.rs index 04542e1e08bf..dd15c4f43fca 100644 --- a/crates/stages/stages/src/stages/tx_lookup.rs +++ b/crates/stages/stages/src/stages/tx_lookup.rs @@ -403,7 +403,7 @@ mod tests { tx_number: Some( blocks[..=max_pruned_block as usize] .iter() - .map(|block| block.body().transactions.len() as u64) + .map(|block| block.transaction_count() as u64) .sum::() .sub(1), // `TxNumber` is 0-indexed ), @@ -419,9 +419,9 @@ mod tests { EntitiesCheckpoint { processed: blocks[..=max_processed_block] .iter() - .map(|block| block.body().transactions.len() as u64) + .map(|block| block.transaction_count() as u64) .sum(), - total: blocks.iter().map(|block| block.body().transactions.len() as u64).sum() + total: blocks.iter().map(|block| block.transaction_count() as u64).sum() } ); } diff --git a/crates/stages/stages/src/test_utils/test_db.rs b/crates/stages/stages/src/test_utils/test_db.rs index 18680c8ec78a..5e4c61b6fd36 100644 --- a/crates/stages/stages/src/test_utils/test_db.rs +++ b/crates/stages/stages/src/test_utils/test_db.rs @@ -252,7 +252,7 @@ impl TestStageDB { // Insert into body tables. let block_body_indices = StoredBlockBodyIndices { first_tx_num: next_tx_num, - tx_count: block.body().transactions.len() as u64, + tx_count: block.transaction_count() as u64, }; if !block.body().transactions.is_empty() { @@ -489,7 +489,7 @@ impl StorageKind { fn tx_offset(&self) -> u64 { if let Self::Database(offset) = self { - return offset.unwrap_or_default() + return offset.unwrap_or_default(); } 0 } diff --git a/crates/storage/db-common/src/init.rs b/crates/storage/db-common/src/init.rs index 1c5ce30ce97f..30b5bd2c885c 100644 --- a/crates/storage/db-common/src/init.rs +++ b/crates/storage/db-common/src/init.rs @@ -2,7 +2,7 @@ use alloy_consensus::BlockHeader; use alloy_genesis::GenesisAccount; -use alloy_primitives::{Address, B256, U256}; +use alloy_primitives::{map::HashMap, Address, B256, U256}; use reth_chainspec::EthChainSpec; use reth_codecs::Compact; use reth_config::config::EtlConfig; @@ -23,7 +23,7 @@ use reth_stages_types::{StageCheckpoint, StageId}; use reth_trie::{IntermediateStateRootState, StateRoot as StateRootComputer, StateRootProgress}; use reth_trie_db::DatabaseStateRoot; use serde::{Deserialize, Serialize}; -use std::{collections::HashMap, io::BufRead}; +use std::io::BufRead; use tracing::{debug, error, info, trace}; /// Default soft limit for number of bytes to read from state dump file, before inserting into @@ -44,7 +44,7 @@ pub const AVERAGE_COUNT_ACCOUNTS_PER_GB_STATE_DUMP: usize = 285_228; const SOFT_LIMIT_COUNT_FLUSHED_UPDATES: usize = 1_000_000; /// Storage initialization error type. -#[derive(Debug, thiserror::Error, PartialEq, Eq, Clone)] +#[derive(Debug, thiserror::Error, Clone)] pub enum InitStorageError { /// Genesis header found on static files but the database is empty. #[error("static files found, but the database is uninitialized. If attempting to re-syncing, delete both.")] @@ -186,9 +186,11 @@ where + AsRef, { let capacity = alloc.size_hint().1.unwrap_or(0); - let mut state_init: BundleStateInit = HashMap::with_capacity(capacity); - let mut reverts_init = HashMap::with_capacity(capacity); - let mut contracts: HashMap = HashMap::with_capacity(capacity); + let mut state_init: BundleStateInit = + HashMap::with_capacity_and_hasher(capacity, Default::default()); + let mut reverts_init = HashMap::with_capacity_and_hasher(capacity, Default::default()); + let mut contracts: HashMap = + HashMap::with_capacity_and_hasher(capacity, Default::default()); for (address, account) in alloc { let bytecode_hash = if let Some(code) = &account.code { @@ -239,7 +241,7 @@ where ), ); } - let all_reverts_init: RevertsInit = HashMap::from([(block, reverts_init)]); + let all_reverts_init: RevertsInit = HashMap::from_iter([(block, reverts_init)]); let execution_outcome = ExecutionOutcome::new_init( state_init, @@ -686,13 +688,13 @@ mod tests { static_file_provider, )); - assert_eq!( + assert!(matches!( genesis_hash.unwrap_err(), InitStorageError::GenesisHashMismatch { chainspec_hash: MAINNET_GENESIS_HASH, storage_hash: SEPOLIA_GENESIS_HASH } - ) + )) } #[test] diff --git a/crates/storage/errors/src/provider.rs b/crates/storage/errors/src/provider.rs index 149c3288a1b2..772844ab7f00 100644 --- a/crates/storage/errors/src/provider.rs +++ b/crates/storage/errors/src/provider.rs @@ -10,7 +10,7 @@ use reth_static_file_types::StaticFileSegment; pub type ProviderResult = Result; /// Bundled errors variants thrown by various providers. -#[derive(Clone, Debug, PartialEq, Eq, thiserror::Error)] +#[derive(Clone, PartialEq, Eq, Debug, thiserror::Error)] pub enum ProviderError { /// Database error. #[error(transparent)] diff --git a/crates/storage/provider/src/providers/blockchain_provider.rs b/crates/storage/provider/src/providers/blockchain_provider.rs index 7c8648fe8451..20c371cdf1c5 100644 --- a/crates/storage/provider/src/providers/blockchain_provider.rs +++ b/crates/storage/provider/src/providers/blockchain_provider.rs @@ -461,10 +461,6 @@ impl WithdrawalsProvider for BlockchainProvider2 { ) -> ProviderResult> { self.consistent_provider()?.withdrawals_by_block(id, timestamp) } - - fn latest_withdrawal(&self) -> ProviderResult> { - self.consistent_provider()?.latest_withdrawal() - } } impl OmmersProvider for BlockchainProvider2 { @@ -1459,7 +1455,7 @@ mod tests { "Expected withdrawals_by_block to return empty list if block does not exist" ); - for block in blocks.clone() { + for block in blocks { assert_eq!( provider .withdrawals_by_block( @@ -1472,15 +1468,6 @@ mod tests { ); } - let canonical_block_num = provider.best_block_number().unwrap(); - let canonical_block = blocks.get(canonical_block_num as usize).unwrap(); - - assert_eq!( - Some(provider.latest_withdrawal()?.unwrap()), - canonical_block.body().withdrawals.clone().unwrap().pop(), - "Expected latest withdrawal to be equal to last withdrawal entry in canonical block" - ); - Ok(()) } @@ -2167,9 +2154,9 @@ mod tests { $( // Since data moves for each tried method, need to recalculate everything let db_tx_count = - database_blocks.iter().map(|b| b.body().transactions.len()).sum::() as u64; + database_blocks.iter().map(|b| b.transaction_count()).sum::() as u64; let in_mem_tx_count = - in_memory_blocks.iter().map(|b| b.body().transactions.len()).sum::() as u64; + in_memory_blocks.iter().map(|b| b.transaction_count()).sum::() as u64; let db_range = 0..=(db_tx_count - 1); let in_mem_range = db_tx_count..=(in_mem_tx_count + db_range.end()); @@ -2410,7 +2397,7 @@ mod tests { .iter() .chain(in_memory_blocks.iter()) .take_while(|b| b.number < block.number) - .map(|b| b.body().transactions.len()) + .map(|b| b.transaction_count()) .sum::() as u64 }; @@ -2431,7 +2418,7 @@ mod tests { .iter() .chain(in_memory_blocks.iter()) .take_while(|b| b.number < block.number) - .map(|b| b.body().transactions.len()) + .map(|b| b.transaction_count()) .sum::() as u64 }; @@ -2527,7 +2514,7 @@ mod tests { block.number, Some(StoredBlockBodyIndices { first_tx_num: tx_num, - tx_count: block.body().transactions.len() as u64 + tx_count: block.transaction_count() as u64 }) ), u64::MAX @@ -2725,7 +2712,7 @@ mod tests { canonical_in_memory_state: CanonicalInMemoryState, _factory: ProviderFactory| { if let Some(tx) = canonical_in_memory_state.transaction_by_hash(hash) { - return Ok::<_, ProviderError>(Some(tx)) + return Ok::<_, ProviderError>(Some(tx)); } panic!("should not be in database"); // _factory.transaction_by_hash(hash) @@ -2740,14 +2727,14 @@ mod tests { // Even though the block exists, given the order of provider queries done in the method // above, we do not see it. - assert_eq!( + assert!(matches!( old_transaction_hash_fn( to_be_persisted_tx.hash(), provider.canonical_in_memory_state(), provider.database.clone() ), Ok(None) - ); + )); } // CORRECT BEHAVIOUR @@ -2757,14 +2744,14 @@ mod tests { persist_block_after_db_tx_creation(provider.clone(), in_memory_blocks[1].number); let to_be_persisted_tx = in_memory_blocks[1].body().transactions[0].clone(); - assert_eq!( + assert!(matches!( correct_transaction_hash_fn( to_be_persisted_tx.hash(), provider.canonical_in_memory_state(), provider.database ), Ok(Some(to_be_persisted_tx)) - ); + )); } Ok(()) diff --git a/crates/storage/provider/src/providers/consistent.rs b/crates/storage/provider/src/providers/consistent.rs index c12324c541c4..f2872352b8f3 100644 --- a/crates/storage/provider/src/providers/consistent.rs +++ b/crates/storage/provider/src/providers/consistent.rs @@ -8,11 +8,13 @@ use crate::{ }; use alloy_consensus::{transaction::TransactionMeta, BlockHeader}; use alloy_eips::{ - eip2718::Encodable2718, - eip4895::{Withdrawal, Withdrawals}, - BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag, HashOrNumber, + eip2718::Encodable2718, eip4895::Withdrawals, BlockHashOrNumber, BlockId, BlockNumHash, + BlockNumberOrTag, HashOrNumber, +}; +use alloy_primitives::{ + map::{hash_map, HashMap}, + Address, BlockHash, BlockNumber, TxHash, TxNumber, B256, U256, }; -use alloy_primitives::{Address, BlockHash, BlockNumber, TxHash, TxNumber, B256, U256}; use reth_chain_state::{BlockState, CanonicalInMemoryState, MemoryOverlayStateProviderRef}; use reth_chainspec::{ChainInfo, EthereumHardforks}; use reth_db::models::BlockNumberAddress; @@ -32,7 +34,6 @@ use reth_storage_api::{ use reth_storage_errors::provider::ProviderResult; use revm::db::states::PlainStorageRevert; use std::{ - collections::{hash_map, HashMap}, ops::{Add, Bound, RangeBounds, RangeInclusive, Sub}, sync::Arc, }; @@ -224,8 +225,8 @@ impl ConsistentProvider { storage_changeset: Vec<(BlockNumberAddress, StorageEntry)>, block_range_end: BlockNumber, ) -> ProviderResult<(BundleStateInit, RevertsInit)> { - let mut state: BundleStateInit = HashMap::new(); - let mut reverts: RevertsInit = HashMap::new(); + let mut state: BundleStateInit = HashMap::default(); + let mut reverts: RevertsInit = HashMap::default(); let state_provider = self.state_by_block_number_ref(block_range_end)?; // add account changeset changes @@ -234,7 +235,7 @@ impl ConsistentProvider { match state.entry(address) { hash_map::Entry::Vacant(entry) => { let new_info = state_provider.basic_account(&address)?; - entry.insert((old_info, new_info, HashMap::new())); + entry.insert((old_info, new_info, HashMap::default())); } hash_map::Entry::Occupied(mut entry) => { // overwrite old account state. @@ -252,7 +253,7 @@ impl ConsistentProvider { let account_state = match state.entry(address) { hash_map::Entry::Vacant(entry) => { let present_info = state_provider.basic_account(&address)?; - entry.insert((present_info, present_info, HashMap::new())) + entry.insert((present_info, present_info, HashMap::default())) } hash_map::Entry::Occupied(entry) => entry.into_mut(), }; @@ -1130,24 +1131,6 @@ impl WithdrawalsProvider for ConsistentProvider { |block_state| Ok(block_state.block_ref().block().body().withdrawals().cloned()), ) } - - fn latest_withdrawal(&self) -> ProviderResult> { - let best_block_num = self.best_block_number()?; - - self.get_in_memory_or_storage_by_block( - best_block_num.into(), - |db_provider| db_provider.latest_withdrawal(), - |block_state| { - Ok(block_state - .block_ref() - .block() - .body() - .withdrawals() - .cloned() - .and_then(|mut w| w.pop())) - }, - ) - } } impl OmmersProvider for ConsistentProvider { diff --git a/crates/storage/provider/src/providers/database/mod.rs b/crates/storage/provider/src/providers/database/mod.rs index 075b9174d223..57ec9c059708 100644 --- a/crates/storage/provider/src/providers/database/mod.rs +++ b/crates/storage/provider/src/providers/database/mod.rs @@ -8,10 +8,7 @@ use crate::{ TransactionVariant, TransactionsProvider, WithdrawalsProvider, }; use alloy_consensus::transaction::TransactionMeta; -use alloy_eips::{ - eip4895::{Withdrawal, Withdrawals}, - BlockHashOrNumber, -}; +use alloy_eips::{eip4895::Withdrawals, BlockHashOrNumber}; use alloy_primitives::{Address, BlockHash, BlockNumber, TxHash, TxNumber, B256, U256}; use core::fmt; use reth_chainspec::{ChainInfo, EthereumHardforks}; @@ -556,10 +553,6 @@ impl WithdrawalsProvider for ProviderFactory { ) -> ProviderResult> { self.provider()?.withdrawals_by_block(id, timestamp) } - - fn latest_withdrawal(&self) -> ProviderResult> { - self.provider()?.latest_withdrawal() - } } impl OmmersProvider for ProviderFactory { @@ -778,7 +771,7 @@ mod tests { ); let db_senders = provider.senders_by_tx_range(range); - assert_eq!(db_senders, Ok(vec![])); + assert!(matches!(db_senders, Ok(ref v) if v.is_empty())); } } diff --git a/crates/storage/provider/src/providers/database/provider.rs b/crates/storage/provider/src/providers/database/provider.rs index 16c62f7c367e..89b2ae5b6001 100644 --- a/crates/storage/provider/src/providers/database/provider.rs +++ b/crates/storage/provider/src/providers/database/provider.rs @@ -20,11 +20,7 @@ use crate::{ TransactionsProviderExt, TrieWriter, WithdrawalsProvider, }; use alloy_consensus::{transaction::TransactionMeta, BlockHeader, Header}; -use alloy_eips::{ - eip2718::Encodable2718, - eip4895::{Withdrawal, Withdrawals}, - BlockHashOrNumber, -}; +use alloy_eips::{eip2718::Encodable2718, eip4895::Withdrawals, BlockHashOrNumber}; use alloy_primitives::{ keccak256, map::{hash_map, B256HashMap, HashMap, HashSet}, @@ -1593,12 +1589,6 @@ impl> Withdrawals } Ok(None) } - - fn latest_withdrawal(&self) -> ProviderResult> { - let latest_block_withdrawal = self.tx.cursor_read::()?.last()?; - Ok(latest_block_withdrawal - .and_then(|(_, mut block_withdrawal)| block_withdrawal.withdrawals.pop())) - } } impl OmmersProvider for DatabaseProvider { diff --git a/crates/storage/provider/src/providers/mod.rs b/crates/storage/provider/src/providers/mod.rs index 0d37f11434a6..b8c7ce0c8b81 100644 --- a/crates/storage/provider/src/providers/mod.rs +++ b/crates/storage/provider/src/providers/mod.rs @@ -11,8 +11,7 @@ use crate::{ }; use alloy_consensus::{transaction::TransactionMeta, Header}; use alloy_eips::{ - eip4895::{Withdrawal, Withdrawals}, - BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag, + eip4895::Withdrawals, BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag, }; use alloy_primitives::{Address, BlockHash, BlockNumber, TxHash, TxNumber, B256, U256}; use alloy_rpc_types_engine::ForkchoiceState; @@ -570,10 +569,6 @@ impl WithdrawalsProvider for BlockchainProvider { ) -> ProviderResult> { self.database.withdrawals_by_block(id, timestamp) } - - fn latest_withdrawal(&self) -> ProviderResult> { - self.database.latest_withdrawal() - } } impl OmmersProvider for BlockchainProvider { diff --git a/crates/storage/provider/src/providers/state/historical.rs b/crates/storage/provider/src/providers/state/historical.rs index 140c9a8b44e4..64a8570499c7 100644 --- a/crates/storage/provider/src/providers/state/historical.rs +++ b/crates/storage/provider/src/providers/state/historical.rs @@ -633,48 +633,51 @@ mod tests { let db = factory.provider().unwrap(); // run - assert_eq!(HistoricalStateProviderRef::new(&db, 1).basic_account(&ADDRESS), Ok(None)); - assert_eq!( + assert!(matches!( + HistoricalStateProviderRef::new(&db, 1).basic_account(&ADDRESS), + Ok(None) + )); + assert!(matches!( HistoricalStateProviderRef::new(&db, 2).basic_account(&ADDRESS), - Ok(Some(acc_at3)) - ); - assert_eq!( + Ok(Some(acc)) if acc == acc_at3 + )); + assert!(matches!( HistoricalStateProviderRef::new(&db, 3).basic_account(&ADDRESS), - Ok(Some(acc_at3)) - ); - assert_eq!( + Ok(Some(acc)) if acc == acc_at3 + )); + assert!(matches!( HistoricalStateProviderRef::new(&db, 4).basic_account(&ADDRESS), - Ok(Some(acc_at7)) - ); - assert_eq!( + Ok(Some(acc)) if acc == acc_at7 + )); + assert!(matches!( HistoricalStateProviderRef::new(&db, 7).basic_account(&ADDRESS), - Ok(Some(acc_at7)) - ); - assert_eq!( + Ok(Some(acc)) if acc == acc_at7 + )); + assert!(matches!( HistoricalStateProviderRef::new(&db, 9).basic_account(&ADDRESS), - Ok(Some(acc_at10)) - ); - assert_eq!( + Ok(Some(acc)) if acc == acc_at10 + )); + assert!(matches!( HistoricalStateProviderRef::new(&db, 10).basic_account(&ADDRESS), - Ok(Some(acc_at10)) - ); - assert_eq!( + Ok(Some(acc)) if acc == acc_at10 + )); + assert!(matches!( HistoricalStateProviderRef::new(&db, 11).basic_account(&ADDRESS), - Ok(Some(acc_at15)) - ); - assert_eq!( + Ok(Some(acc)) if acc == acc_at15 + )); + assert!(matches!( HistoricalStateProviderRef::new(&db, 16).basic_account(&ADDRESS), - Ok(Some(acc_plain)) - ); + Ok(Some(acc)) if acc == acc_plain + )); - assert_eq!( + assert!(matches!( HistoricalStateProviderRef::new(&db, 1).basic_account(&HIGHER_ADDRESS), Ok(None) - ); - assert_eq!( + )); + assert!(matches!( HistoricalStateProviderRef::new(&db, 1000).basic_account(&HIGHER_ADDRESS), - Ok(Some(higher_acc_plain)) - ); + Ok(Some(acc)) if acc == higher_acc_plain + )); } #[test] @@ -730,43 +733,46 @@ mod tests { let db = factory.provider().unwrap(); // run - assert_eq!(HistoricalStateProviderRef::new(&db, 0).storage(ADDRESS, STORAGE), Ok(None)); - assert_eq!( + assert!(matches!( + HistoricalStateProviderRef::new(&db, 0).storage(ADDRESS, STORAGE), + Ok(None) + )); + assert!(matches!( HistoricalStateProviderRef::new(&db, 3).storage(ADDRESS, STORAGE), Ok(Some(U256::ZERO)) - ); - assert_eq!( + )); + assert!(matches!( HistoricalStateProviderRef::new(&db, 4).storage(ADDRESS, STORAGE), - Ok(Some(entry_at7.value)) - ); - assert_eq!( + Ok(Some(expected_value)) if expected_value == entry_at7.value + )); + assert!(matches!( HistoricalStateProviderRef::new(&db, 7).storage(ADDRESS, STORAGE), - Ok(Some(entry_at7.value)) - ); - assert_eq!( + Ok(Some(expected_value)) if expected_value == entry_at7.value + )); + assert!(matches!( HistoricalStateProviderRef::new(&db, 9).storage(ADDRESS, STORAGE), - Ok(Some(entry_at10.value)) - ); - assert_eq!( + Ok(Some(expected_value)) if expected_value == entry_at10.value + )); + assert!(matches!( HistoricalStateProviderRef::new(&db, 10).storage(ADDRESS, STORAGE), - Ok(Some(entry_at10.value)) - ); - assert_eq!( + Ok(Some(expected_value)) if expected_value == entry_at10.value + )); + assert!(matches!( HistoricalStateProviderRef::new(&db, 11).storage(ADDRESS, STORAGE), - Ok(Some(entry_at15.value)) - ); - assert_eq!( + Ok(Some(expected_value)) if expected_value == entry_at15.value + )); + assert!(matches!( HistoricalStateProviderRef::new(&db, 16).storage(ADDRESS, STORAGE), - Ok(Some(entry_plain.value)) - ); - assert_eq!( + Ok(Some(expected_value)) if expected_value == entry_plain.value + )); + assert!(matches!( HistoricalStateProviderRef::new(&db, 1).storage(HIGHER_ADDRESS, STORAGE), Ok(None) - ); - assert_eq!( + )); + assert!(matches!( HistoricalStateProviderRef::new(&db, 1000).storage(HIGHER_ADDRESS, STORAGE), - Ok(Some(higher_entry_plain.value)) - ); + Ok(Some(expected_value)) if expected_value == higher_entry_plain.value + )); } #[test] @@ -784,14 +790,14 @@ mod tests { storage_history_block_number: Some(3), }, ); - assert_eq!( + assert!(matches!( provider.account_history_lookup(ADDRESS), - Err(ProviderError::StateAtBlockPruned(provider.block_number)) - ); - assert_eq!( + Err(ProviderError::StateAtBlockPruned(number)) if number == provider.block_number + )); + assert!(matches!( provider.storage_history_lookup(ADDRESS, STORAGE), - Err(ProviderError::StateAtBlockPruned(provider.block_number)) - ); + Err(ProviderError::StateAtBlockPruned(number)) if number == provider.block_number + )); // provider block_number == lowest available block number, // i.e. state at provider block is available @@ -803,11 +809,14 @@ mod tests { storage_history_block_number: Some(2), }, ); - assert_eq!(provider.account_history_lookup(ADDRESS), Ok(HistoryInfo::MaybeInPlainState)); - assert_eq!( + assert!(matches!( + provider.account_history_lookup(ADDRESS), + Ok(HistoryInfo::MaybeInPlainState) + )); + assert!(matches!( provider.storage_history_lookup(ADDRESS, STORAGE), Ok(HistoryInfo::MaybeInPlainState) - ); + )); // provider block_number == lowest available block number, // i.e. state at provider block is available @@ -819,10 +828,13 @@ mod tests { storage_history_block_number: Some(1), }, ); - assert_eq!(provider.account_history_lookup(ADDRESS), Ok(HistoryInfo::MaybeInPlainState)); - assert_eq!( + assert!(matches!( + provider.account_history_lookup(ADDRESS), + Ok(HistoryInfo::MaybeInPlainState) + )); + assert!(matches!( provider.storage_history_lookup(ADDRESS, STORAGE), Ok(HistoryInfo::MaybeInPlainState) - ); + )); } } diff --git a/crates/storage/provider/src/providers/static_file/manager.rs b/crates/storage/provider/src/providers/static_file/manager.rs index 7f8b3e1b97fa..cb8be0f922fc 100644 --- a/crates/storage/provider/src/providers/static_file/manager.rs +++ b/crates/storage/provider/src/providers/static_file/manager.rs @@ -8,11 +8,7 @@ use crate::{ TransactionsProviderExt, WithdrawalsProvider, }; use alloy_consensus::{transaction::TransactionMeta, Header}; -use alloy_eips::{ - eip2718::Encodable2718, - eip4895::{Withdrawal, Withdrawals}, - BlockHashOrNumber, -}; +use alloy_eips::{eip2718::Encodable2718, eip4895::Withdrawals, BlockHashOrNumber}; use alloy_primitives::{keccak256, Address, BlockHash, BlockNumber, TxHash, TxNumber, B256, U256}; use dashmap::DashMap; use notify::{RecommendedWatcher, RecursiveMode, Watcher}; @@ -1675,11 +1671,6 @@ impl WithdrawalsProvider for StaticFileProvider { // Required data not present in static_files Err(ProviderError::UnsupportedProvider) } - - fn latest_withdrawal(&self) -> ProviderResult> { - // Required data not present in static_files - Err(ProviderError::UnsupportedProvider) - } } impl> OmmersProvider for StaticFileProvider { diff --git a/crates/storage/provider/src/test_utils/mock.rs b/crates/storage/provider/src/test_utils/mock.rs index d3196b8195d0..362bbc32dfab 100644 --- a/crates/storage/provider/src/test_utils/mock.rs +++ b/crates/storage/provider/src/test_utils/mock.rs @@ -6,10 +6,7 @@ use crate::{ StateRootProvider, TransactionVariant, TransactionsProvider, WithdrawalsProvider, }; use alloy_consensus::{constants::EMPTY_ROOT_HASH, transaction::TransactionMeta, Header}; -use alloy_eips::{ - eip4895::{Withdrawal, Withdrawals}, - BlockHashOrNumber, BlockId, BlockNumberOrTag, -}; +use alloy_eips::{eip4895::Withdrawals, BlockHashOrNumber, BlockId, BlockNumberOrTag}; use alloy_primitives::{ keccak256, map::{B256HashMap, HashMap}, @@ -766,9 +763,6 @@ impl WithdrawalsProvider for MockEthProvider { ) -> ProviderResult> { Ok(None) } - fn latest_withdrawal(&self) -> ProviderResult> { - Ok(None) - } } impl OmmersProvider for MockEthProvider { diff --git a/crates/storage/provider/src/writer/mod.rs b/crates/storage/provider/src/writer/mod.rs index f507afabba21..c1ce33978fd0 100644 --- a/crates/storage/provider/src/writer/mod.rs +++ b/crates/storage/provider/src/writer/mod.rs @@ -287,7 +287,7 @@ mod tests { hashed_state.storages.insert(destroyed_address_hashed, HashedStorage::new(true)); let provider_rw = provider_factory.provider_rw().unwrap(); - assert_eq!(provider_rw.write_hashed_state(&hashed_state.into_sorted()), Ok(())); + assert!(matches!(provider_rw.write_hashed_state(&hashed_state.into_sorted()), Ok(()))); provider_rw.commit().unwrap(); let provider = provider_factory.provider().unwrap(); diff --git a/crates/storage/storage-api/src/noop.rs b/crates/storage/storage-api/src/noop.rs index f58c1e176ef4..3e6ed7dbd52c 100644 --- a/crates/storage/storage-api/src/noop.rs +++ b/crates/storage/storage-api/src/noop.rs @@ -9,10 +9,7 @@ use crate::{ TransactionVariant, TransactionsProvider, WithdrawalsProvider, }; use alloy_consensus::transaction::TransactionMeta; -use alloy_eips::{ - eip4895::{Withdrawal, Withdrawals}, - BlockHashOrNumber, BlockId, BlockNumberOrTag, -}; +use alloy_eips::{eip4895::Withdrawals, BlockHashOrNumber, BlockId, BlockNumberOrTag}; use alloy_primitives::{ map::{B256HashMap, HashMap}, Address, BlockHash, BlockNumber, Bytes, StorageKey, StorageValue, TxHash, TxNumber, B256, U256, @@ -543,9 +540,6 @@ impl WithdrawalsProvider for NoopProvider ProviderResult> { Ok(None) } - fn latest_withdrawal(&self) -> ProviderResult> { - Ok(None) - } } impl OmmersProvider for NoopProvider { diff --git a/crates/storage/storage-api/src/withdrawals.rs b/crates/storage/storage-api/src/withdrawals.rs index 47aa4944410d..fdfb27aa7072 100644 --- a/crates/storage/storage-api/src/withdrawals.rs +++ b/crates/storage/storage-api/src/withdrawals.rs @@ -1,10 +1,7 @@ -use alloy_eips::{ - eip4895::{Withdrawal, Withdrawals}, - BlockHashOrNumber, -}; +use alloy_eips::{eip4895::Withdrawals, BlockHashOrNumber}; use reth_storage_errors::provider::ProviderResult; -/// Client trait for fetching [Withdrawal] related data. +/// Client trait for fetching [`alloy_eips::eip4895::Withdrawal`] related data. #[auto_impl::auto_impl(&, Arc)] pub trait WithdrawalsProvider: Send + Sync { /// Get withdrawals by block id. @@ -13,7 +10,4 @@ pub trait WithdrawalsProvider: Send + Sync { id: BlockHashOrNumber, timestamp: u64, ) -> ProviderResult>; - - /// Get latest withdrawal from this block or earlier . - fn latest_withdrawal(&self) -> ProviderResult>; } diff --git a/crates/transaction-pool/src/maintain.rs b/crates/transaction-pool/src/maintain.rs index 6ccd479c2b83..583b291685d5 100644 --- a/crates/transaction-pool/src/maintain.rs +++ b/crates/transaction-pool/src/maintain.rs @@ -600,7 +600,7 @@ where let local_transactions = local_transactions .into_iter() - .map(|tx| tx.transaction.clone_into_consensus().into_signed()) + .map(|tx| tx.transaction.clone_into_consensus().into_tx()) .collect::>(); let num_txs = local_transactions.len(); diff --git a/crates/transaction-pool/src/pool/mod.rs b/crates/transaction-pool/src/pool/mod.rs index 088fbe59bb65..a7c16d05aa8e 100644 --- a/crates/transaction-pool/src/pool/mod.rs +++ b/crates/transaction-pool/src/pool/mod.rs @@ -357,7 +357,7 @@ where }; size += encoded_len; - elements.push(pooled.into_signed()); + elements.push(pooled.into_tx()); if limit.exceeds(size) { break diff --git a/crates/transaction-pool/src/test_utils/gen.rs b/crates/transaction-pool/src/test_utils/gen.rs index 95a179aec814..3110997d692d 100644 --- a/crates/transaction-pool/src/test_utils/gen.rs +++ b/crates/transaction-pool/src/test_utils/gen.rs @@ -4,7 +4,8 @@ use alloy_eips::{eip1559::MIN_PROTOCOL_BASE_FEE, eip2718::Encodable2718, eip2930 use alloy_primitives::{Address, Bytes, TxKind, B256, U256}; use rand::Rng; use reth_chainspec::MAINNET; -use reth_primitives::{sign_message, Transaction, TransactionSigned}; +use reth_primitives::{Transaction, TransactionSigned}; +use reth_primitives_traits::crypto::secp256k1::sign_message; /// A generator for transactions for testing purposes. #[derive(Debug)] diff --git a/crates/transaction-pool/src/test_utils/mock.rs b/crates/transaction-pool/src/test_utils/mock.rs index 999c4d9c8e15..98fa167f014c 100644 --- a/crates/transaction-pool/src/test_utils/mock.rs +++ b/crates/transaction-pool/src/test_utils/mock.rs @@ -30,8 +30,7 @@ use rand::{ }; use reth_primitives::{ transaction::{SignedTransactionIntoRecoveredExt, TryFromRecoveredTransactionError}, - PooledTransaction, PooledTransactionsElementEcRecovered, RecoveredTx, Transaction, - TransactionSigned, TxType, + PooledTransaction, RecoveredTx, Transaction, TransactionSigned, TxType, }; use reth_primitives_traits::InMemorySize; use std::{ops::Range, sync::Arc, time::Instant, vec::IntoIter}; @@ -685,7 +684,7 @@ impl PoolTransaction for MockTransaction { fn try_consensus_into_pooled( tx: RecoveredTx, ) -> Result, Self::TryFromConsensusError> { - let (tx, signer) = tx.to_components(); + let (tx, signer) = tx.into_parts(); Self::Pooled::try_from(tx) .map(|tx| tx.with_signer(signer)) .map_err(|_| TryFromRecoveredTransactionError::BlobSidecarMissing) @@ -871,7 +870,7 @@ impl EthPoolTransaction for MockTransaction { self, sidecar: Arc, ) -> Option> { - let (tx, signer) = self.into_consensus().to_components(); + let (tx, signer) = self.into_consensus().into_parts(); tx.try_into_pooled_eip4844(Arc::unwrap_or_clone(sidecar)) .map(|tx| tx.with_signer(signer)) .ok() @@ -881,7 +880,7 @@ impl EthPoolTransaction for MockTransaction { tx: RecoveredTx, sidecar: BlobTransactionSidecar, ) -> Option { - let (tx, signer) = tx.to_components(); + let (tx, signer) = tx.into_parts(); tx.try_into_pooled_eip4844(sidecar) .map(|tx| tx.with_signer(signer)) .ok() @@ -904,12 +903,12 @@ impl EthPoolTransaction for MockTransaction { } } -impl TryFrom for MockTransaction { +impl TryFrom> for MockTransaction { type Error = TryFromRecoveredTransactionError; - fn try_from(tx: RecoveredTx) -> Result { + fn try_from(tx: RecoveredTx) -> Result { let sender = tx.signer(); - let transaction = tx.into_signed(); + let transaction = tx.into_tx(); let hash = transaction.hash(); let size = transaction.size(); @@ -1045,20 +1044,21 @@ impl TryFrom for MockTransaction { } } -impl From for MockTransaction { - fn from(tx: PooledTransactionsElementEcRecovered) -> Self { - tx.into_ecrecovered_transaction().try_into().expect( +impl From> for MockTransaction { + fn from(tx: RecoveredTx) -> Self { + let (tx, signer) = tx.into_parts(); + RecoveredTx::::new_unchecked(tx.into(), signer).try_into().expect( "Failed to convert from PooledTransactionsElementEcRecovered to MockTransaction", ) } } -impl From for RecoveredTx { +impl From for RecoveredTx { fn from(tx: MockTransaction) -> Self { let signed_tx = TransactionSigned::new(tx.clone().into(), Signature::test_signature(), *tx.hash()); - Self::from_signed_transaction(signed_tx, tx.sender()) + Self::new_unchecked(signed_tx, tx.sender()) } } @@ -1180,7 +1180,7 @@ impl proptest::arbitrary::Arbitrary for MockTransaction { arb::<(TransactionSigned, Address)>() .prop_map(|(signed_transaction, signer)| { - RecoveredTx::from_signed_transaction(signed_transaction, signer) + RecoveredTx::new_unchecked(signed_transaction, signer) .try_into() .expect("Failed to create an Arbitrary MockTransaction via RecoveredTx") }) diff --git a/crates/transaction-pool/src/traits.rs b/crates/transaction-pool/src/traits.rs index 3ce92576d134..862ecc15a7bf 100644 --- a/crates/transaction-pool/src/traits.rs +++ b/crates/transaction-pool/src/traits.rs @@ -21,8 +21,7 @@ use reth_execution_types::ChangedAccount; use reth_primitives::{ kzg::KzgSettings, transaction::{SignedTransactionIntoRecoveredExt, TryFromRecoveredTransactionError}, - PooledTransaction, PooledTransactionsElementEcRecovered, RecoveredTx, SealedBlock, Transaction, - TransactionSigned, + PooledTransaction, RecoveredTx, SealedBlock, Transaction, TransactionSigned, }; use reth_primitives_traits::{BlockBody, SignedTransaction}; #[cfg(feature = "serde")] @@ -1242,24 +1241,24 @@ impl EthPooledTransaction { } /// Conversion from the network transaction type to the pool transaction type. -impl From for EthPooledTransaction { - fn from(tx: PooledTransactionsElementEcRecovered) -> Self { +impl From> for EthPooledTransaction { + fn from(tx: RecoveredTx) -> Self { let encoded_length = tx.encode_2718_len(); - let (tx, signer) = tx.to_components(); + let (tx, signer) = tx.into_parts(); match tx { PooledTransaction::Eip4844(tx) => { // include the blob sidecar let (tx, sig, hash) = tx.into_parts(); let (tx, blob) = tx.into_parts(); let tx = TransactionSigned::new(tx.into(), sig, hash); - let tx = RecoveredTx::from_signed_transaction(tx, signer); + let tx = RecoveredTx::new_unchecked(tx, signer); let mut pooled = Self::new(tx, encoded_length); pooled.blob_sidecar = EthBlobTransactionSidecar::Present(blob); pooled } tx => { // no blob sidecar - let tx = RecoveredTx::from_signed_transaction(tx.into(), signer); + let tx = RecoveredTx::new_unchecked(tx.into(), signer); Self::new(tx, encoded_length) } } @@ -1280,11 +1279,11 @@ impl PoolTransaction for EthPooledTransaction { fn try_consensus_into_pooled( tx: RecoveredTx, ) -> Result, Self::TryFromConsensusError> { - let (tx, signer) = tx.to_components(); + let (tx, signer) = tx.into_parts(); let pooled = tx .try_into_pooled() .map_err(|_| TryFromRecoveredTransactionError::BlobSidecarMissing)?; - Ok(RecoveredTx::from_signed_transaction(pooled, signer)) + Ok(RecoveredTx::new_unchecked(pooled, signer)) } /// Returns hash of the transaction. @@ -1416,18 +1415,18 @@ impl EthPoolTransaction for EthPooledTransaction { self, sidecar: Arc, ) -> Option> { - PooledTransactionsElementEcRecovered::try_from_blob_transaction( - self.into_consensus(), - Arc::unwrap_or_clone(sidecar), - ) - .ok() + let (signed_transaction, signer) = self.into_consensus().into_parts(); + let pooled_transaction = + signed_transaction.try_into_pooled_eip4844(Arc::unwrap_or_clone(sidecar)).ok()?; + + Some(RecoveredTx::new_unchecked(pooled_transaction, signer)) } fn try_from_eip4844( tx: RecoveredTx, sidecar: BlobTransactionSidecar, ) -> Option { - let (tx, signer) = tx.to_components(); + let (tx, signer) = tx.into_parts(); tx.try_into_pooled_eip4844(sidecar) .ok() .map(|tx| tx.with_signer(signer)) @@ -1453,10 +1452,10 @@ impl EthPoolTransaction for EthPooledTransaction { } } -impl TryFrom for EthPooledTransaction { +impl TryFrom> for EthPooledTransaction { type Error = TryFromRecoveredTransactionError; - fn try_from(tx: RecoveredTx) -> Result { + fn try_from(tx: RecoveredTx) -> Result { // ensure we can handle the transaction type and its format match tx.ty() { 0..=EIP1559_TX_TYPE_ID | EIP7702_TX_TYPE_ID => { @@ -1480,7 +1479,7 @@ impl TryFrom for EthPooledTransaction { } } -impl From for RecoveredTx { +impl From for RecoveredTx { fn from(tx: EthPooledTransaction) -> Self { tx.transaction } @@ -1692,7 +1691,7 @@ mod tests { }); let signature = Signature::test_signature(); let signed_tx = TransactionSigned::new_unhashed(tx, signature); - let transaction = RecoveredTx::from_signed_transaction(signed_tx, Default::default()); + let transaction = RecoveredTx::new_unchecked(signed_tx, Default::default()); let pooled_tx = EthPooledTransaction::new(transaction.clone(), 200); // Check that the pooled transaction is created correctly @@ -1713,7 +1712,7 @@ mod tests { }); let signature = Signature::test_signature(); let signed_tx = TransactionSigned::new_unhashed(tx, signature); - let transaction = RecoveredTx::from_signed_transaction(signed_tx, Default::default()); + let transaction = RecoveredTx::new_unchecked(signed_tx, Default::default()); let pooled_tx = EthPooledTransaction::new(transaction.clone(), 200); // Check that the pooled transaction is created correctly @@ -1734,7 +1733,7 @@ mod tests { }); let signature = Signature::test_signature(); let signed_tx = TransactionSigned::new_unhashed(tx, signature); - let transaction = RecoveredTx::from_signed_transaction(signed_tx, Default::default()); + let transaction = RecoveredTx::new_unchecked(signed_tx, Default::default()); let pooled_tx = EthPooledTransaction::new(transaction.clone(), 200); // Check that the pooled transaction is created correctly @@ -1757,7 +1756,7 @@ mod tests { }); let signature = Signature::test_signature(); let signed_tx = TransactionSigned::new_unhashed(tx, signature); - let transaction = RecoveredTx::from_signed_transaction(signed_tx, Default::default()); + let transaction = RecoveredTx::new_unchecked(signed_tx, Default::default()); let pooled_tx = EthPooledTransaction::new(transaction.clone(), 300); // Check that the pooled transaction is created correctly @@ -1780,7 +1779,7 @@ mod tests { }); let signature = Signature::test_signature(); let signed_tx = TransactionSigned::new_unhashed(tx, signature); - let transaction = RecoveredTx::from_signed_transaction(signed_tx, Default::default()); + let transaction = RecoveredTx::new_unchecked(signed_tx, Default::default()); let pooled_tx = EthPooledTransaction::new(transaction.clone(), 200); // Check that the pooled transaction is created correctly diff --git a/crates/trie/parallel/src/proof.rs b/crates/trie/parallel/src/proof.rs index ef7e34b1970a..ce0c185e1aa3 100644 --- a/crates/trie/parallel/src/proof.rs +++ b/crates/trie/parallel/src/proof.rs @@ -25,7 +25,7 @@ use reth_trie::{ use reth_trie_common::proof::ProofRetainer; use reth_trie_db::{DatabaseHashedCursorFactory, DatabaseTrieCursorFactory}; use std::{sync::Arc, time::Instant}; -use tracing::{debug, error, trace}; +use tracing::{debug, trace}; #[cfg(feature = "metrics")] use crate::metrics::ParallelStateRootMetrics; @@ -196,8 +196,11 @@ where proof_result })(); + // We can have the receiver dropped before we send, because we still calculate + // storage proofs for deleted accounts, but do not actually walk over them in + // `account_node_iter` below. if let Err(e) = tx.send(result) { - error!( + debug!( target: "trie::parallel", ?hashed_address, error = ?e, diff --git a/crates/trie/sparse/src/trie.rs b/crates/trie/sparse/src/trie.rs index 04f034e1c8a5..8f54d9454022 100644 --- a/crates/trie/sparse/src/trie.rs +++ b/crates/trie/sparse/src/trie.rs @@ -282,6 +282,11 @@ impl

RevealedSparseTrie

{ node: TrieNode, hash_mask: Option, ) -> SparseTrieResult<()> { + // If the node is already revealed and it's not a hash node, do nothing. + if self.nodes.get(&path).is_some_and(|node| !node.is_hash()) { + return Ok(()) + } + if let Some(hash_mask) = hash_mask { self.branch_node_hash_masks.insert(path.clone(), hash_mask); } diff --git a/crates/trie/trie/src/trie_cursor/in_memory.rs b/crates/trie/trie/src/trie_cursor/in_memory.rs index fa59b70d1fd9..0e394fcf77f3 100644 --- a/crates/trie/trie/src/trie_cursor/in_memory.rs +++ b/crates/trie/trie/src/trie_cursor/in_memory.rs @@ -78,7 +78,7 @@ impl<'a, C: TrieCursor> InMemoryAccountTrieCursor<'a, C> { exact: bool, ) -> Result, DatabaseError> { let in_memory = self.in_memory_cursor.seek(&key); - if exact && in_memory.as_ref().is_some_and(|entry| entry.0 == key) { + if in_memory.as_ref().is_some_and(|entry| entry.0 == key) { return Ok(in_memory) } @@ -202,9 +202,7 @@ impl InMemoryStorageTrieCursor<'_, C> { exact: bool, ) -> Result, DatabaseError> { let in_memory = self.in_memory_cursor.as_mut().and_then(|c| c.seek(&key)); - if self.storage_trie_cleared || - (exact && in_memory.as_ref().is_some_and(|entry| entry.0 == key)) - { + if self.storage_trie_cleared || in_memory.as_ref().is_some_and(|entry| entry.0 == key) { return Ok(in_memory.filter(|(nibbles, _)| !exact || nibbles == &key)) } diff --git a/docs/crates/network.md b/docs/crates/network.md index 7e38ac5d6014..281f0105b09c 100644 --- a/docs/crates/network.md +++ b/docs/crates/network.md @@ -909,7 +909,7 @@ fn on_new_transactions(&mut self, hashes: impl IntoIterator) { .get_all(hashes) .into_iter() .map(|tx| { - (*tx.hash(), Arc::new(tx.transaction.to_recovered_transaction().into_signed())) + (*tx.hash(), Arc::new(tx.transaction.to_recovered_transaction().into_tx())) }) .collect(), ); @@ -1098,7 +1098,7 @@ fn on_get_pooled_transactions( .pool .get_all(request.0) .into_iter() - .map(|tx| tx.transaction.to_recovered_transaction().into_signed()) + .map(|tx| tx.transaction.to_recovered_transaction().into_tx()) .collect::>(); // we sent a response at which point we assume that the peer is aware of the transaction diff --git a/docs/repo/ci.md b/docs/repo/ci.md index 863a18f9c383..afc2d24a17bc 100644 --- a/docs/repo/ci.md +++ b/docs/repo/ci.md @@ -15,8 +15,6 @@ The CI runs a couple of workflows: - **[book]**: Builds, tests, and deploys the book. ### Meta - -- **[deny]**: Runs `cargo deny` to check for license conflicts and security advisories in our dependencies - **[release]**: Runs the release workflow - **[release-dist]**: Publishes Reth to external package managers - **[dependencies]**: Runs `cargo update` periodically to keep dependencies current @@ -40,7 +38,6 @@ The CI runs a couple of workflows: [sync]: https://github.com/paradigmxyz/reth/blob/main/.github/workflows/sync.yml [stage]: https://github.com/paradigmxyz/reth/blob/main/.github/workflows/stage.yml [book]: https://github.com/paradigmxyz/reth/blob/main/.github/workflows/book.yml -[deny]: https://github.com/paradigmxyz/reth/blob/main/.github/workflows/deny.yml [release]: https://github.com/paradigmxyz/reth/blob/main/.github/workflows/release.yml [release-dist]: https://github.com/paradigmxyz/reth/blob/main/.github/workflows/release-dist.yml [dependencies]: https://github.com/paradigmxyz/reth/blob/main/.github/workflows/dependencies.yml diff --git a/examples/bsc-p2p/src/chainspec.rs b/examples/bsc-p2p/src/chainspec.rs index 588175734ff9..acf9f4dff062 100644 --- a/examples/bsc-p2p/src/chainspec.rs +++ b/examples/bsc-p2p/src/chainspec.rs @@ -24,6 +24,7 @@ pub(crate) fn bsc_chain_spec() -> Arc { deposit_contract: None, base_fee_params: reth_chainspec::BaseFeeParamsKind::Constant(BaseFeeParams::ethereum()), prune_delete_limit: 0, + blob_params: Default::default(), } .into() } diff --git a/examples/polygon-p2p/src/chain_cfg.rs b/examples/polygon-p2p/src/chain_cfg.rs index 229e4301b8c2..d87bbccb2836 100644 --- a/examples/polygon-p2p/src/chain_cfg.rs +++ b/examples/polygon-p2p/src/chain_cfg.rs @@ -30,6 +30,7 @@ pub(crate) fn polygon_chain_spec() -> Arc { deposit_contract: None, base_fee_params: reth_chainspec::BaseFeeParamsKind::Constant(BaseFeeParams::ethereum()), prune_delete_limit: 0, + blob_params: Default::default(), } .into() } diff --git a/testing/testing-utils/Cargo.toml b/testing/testing-utils/Cargo.toml index a6197d7e0cf7..8dc438170e8e 100644 --- a/testing/testing-utils/Cargo.toml +++ b/testing/testing-utils/Cargo.toml @@ -13,6 +13,7 @@ workspace = true [dependencies] reth-primitives = { workspace = true, features = ["secp256k1", "arbitrary"] } +reth-primitives-traits = { workspace = true, features = ["secp256k1", "arbitrary"] } alloy-genesis.workspace = true alloy-primitives.workspace = true diff --git a/testing/testing-utils/src/generators.rs b/testing/testing-utils/src/generators.rs index 529c0a49f1e3..9cf6515eb6ce 100644 --- a/testing/testing-utils/src/generators.rs +++ b/testing/testing-utils/src/generators.rs @@ -12,9 +12,11 @@ use rand::{ distributions::uniform::SampleRange, rngs::StdRng, seq::SliceRandom, thread_rng, SeedableRng, }; use reth_primitives::{ - proofs, sign_message, Account, BlockBody, Log, Receipt, SealedBlock, SealedHeader, - StorageEntry, Transaction, TransactionSigned, + proofs, Account, BlockBody, Log, Receipt, SealedBlock, SealedHeader, StorageEntry, Transaction, + TransactionSigned, }; + +use reth_primitives_traits::crypto::secp256k1::sign_message; use secp256k1::{Keypair, Secp256k1}; use std::{ cmp::{max, min}, @@ -263,7 +265,7 @@ pub fn random_block_range( idx, BlockParams { parent: Some( - blocks.last().map(|block: &SealedBlock| block.header.hash()).unwrap_or(parent), + blocks.last().map(|block: &SealedBlock| block.hash()).unwrap_or(parent), ), tx_count: Some(tx_count), ommers_count: None, @@ -469,8 +471,10 @@ mod tests { use alloy_consensus::TxEip1559; use alloy_eips::eip2930::AccessList; use alloy_primitives::{hex, PrimitiveSignature as Signature}; - use reth_primitives::public_key_to_address; - use reth_primitives_traits::SignedTransaction; + use reth_primitives_traits::{ + crypto::secp256k1::{public_key_to_address, sign_message}, + SignedTransaction, + }; use std::str::FromStr; #[test] diff --git a/testing/testing-utils/src/genesis_allocator.rs b/testing/testing-utils/src/genesis_allocator.rs index acf5e091cba3..e486f884a89e 100644 --- a/testing/testing-utils/src/genesis_allocator.rs +++ b/testing/testing-utils/src/genesis_allocator.rs @@ -3,7 +3,7 @@ use alloy_genesis::GenesisAccount; use alloy_primitives::{Address, Bytes, B256, U256}; -use reth_primitives::public_key_to_address; +use reth_primitives_traits::crypto::secp256k1::public_key_to_address; use secp256k1::{ rand::{thread_rng, RngCore}, Keypair, Secp256k1,