diff --git a/Cargo.lock b/Cargo.lock index 8cae6fe6a8..7f095efdb8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -106,9 +106,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "alloy-chains" -version = "0.1.55" +version = "0.1.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e39f295f876b61a1222d937e1dd31f965e4a1acc3bba98e448dd7e84b1a4566" +checksum = "da226340862e036ab26336dc99ca85311c6b662267c1440e1733890fd688802c" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -170,7 +170,7 @@ dependencies = [ "alloy-transport", "futures", "futures-util", - "thiserror 2.0.11", + "thiserror 2.0.9", ] [[package]] @@ -203,7 +203,7 @@ dependencies = [ "crc", "rand 0.8.5", "serde", - "thiserror 2.0.11", + "thiserror 2.0.9", ] [[package]] @@ -291,7 +291,7 @@ dependencies = [ "alloy-sol-types", "serde", "serde_json", - "thiserror 2.0.11", + "thiserror 2.0.9", "tracing", ] @@ -317,7 +317,7 @@ dependencies = [ "futures-utils-wasm", "serde", "serde_json", - "thiserror 2.0.11", + "thiserror 2.0.9", ] [[package]] @@ -345,7 +345,7 @@ dependencies = [ "rand 0.8.5", "serde_json", "tempfile", - "thiserror 2.0.11", + "thiserror 2.0.9", "tracing", "url", ] @@ -415,7 +415,7 @@ dependencies = [ "schnellru", "serde", "serde_json", - "thiserror 2.0.11", + "thiserror 2.0.9", "tokio", "tracing", "url", @@ -460,7 +460,7 @@ checksum = "5a833d97bf8a5f0f878daf2c8451fff7de7f9de38baa5a45d936ec718d81255a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -549,7 +549,7 @@ dependencies = [ "ethereum_ssz_derive", "serde", "serde_with", - "thiserror 2.0.11", + "thiserror 2.0.9", ] [[package]] @@ -602,7 +602,7 @@ dependencies = [ "jsonrpsee-types", "serde", "serde_json", - "thiserror 2.0.11", + "thiserror 2.0.9", ] [[package]] @@ -630,7 +630,7 @@ dependencies = [ "alloy-serde", "serde", "serde_json", - "thiserror 2.0.11", + "thiserror 2.0.9", ] [[package]] @@ -668,7 +668,7 @@ dependencies = [ "auto_impl", "elliptic-curve", "k256", - "thiserror 2.0.11", + "thiserror 2.0.9", ] [[package]] @@ -686,7 +686,7 @@ dependencies = [ "coins-bip39", "k256", "rand 0.8.5", - "thiserror 2.0.11", + "thiserror 2.0.9", ] [[package]] @@ -700,7 +700,7 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -716,7 +716,7 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", "syn-solidity", "tiny-keccak", ] @@ -732,7 +732,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", "syn-solidity", ] @@ -771,7 +771,7 @@ dependencies = [ "futures-utils-wasm", "serde", "serde_json", - "thiserror 2.0.11", + "thiserror 2.0.9", "tokio", "tower 0.5.2", "tracing", @@ -938,7 +938,7 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -1136,7 +1136,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -1172,7 +1172,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -1183,7 +1183,7 @@ checksum = "3f934833b4b7233644e5848f235df3f57ed8c80f1528a26c3dfa13d2147fa056" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -1221,7 +1221,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -1318,7 +1318,7 @@ version = "0.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" dependencies = [ - "bitflags 2.7.0", + "bitflags 2.6.0", "cexpr", "clang-sys", "itertools 0.13.0", @@ -1327,7 +1327,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -1353,9 +1353,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.7.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1be3f42a67d6d345ecd59f675f3f012d6974981560836e938c22b424b85ce1be" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" dependencies = [ "arbitrary", "serde", @@ -1419,7 +1419,7 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c340fe0f0b267787095cbe35240c6786ff19da63ec7b69367ba338eace8169b" dependencies = [ - "bitflags 2.7.0", + "bitflags 2.6.0", "boa_interner", "boa_macros", "boa_string", @@ -1435,7 +1435,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f620c3f06f51e65c0504ddf04978be1b814ac6586f0b45f6019801ab5efd37f9" dependencies = [ "arrayvec", - "bitflags 2.7.0", + "bitflags 2.6.0", "boa_ast", "boa_gc", "boa_interner", @@ -1469,7 +1469,7 @@ dependencies = [ "static_assertions", "tap", "thin-vec", - "thiserror 2.0.11", + "thiserror 2.0.9", "time", ] @@ -1510,7 +1510,7 @@ checksum = "9fd3f870829131332587f607a7ff909f1af5fc523fd1b192db55fbbdf52e8d3c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", "synstructure", ] @@ -1520,7 +1520,7 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9cc142dac798cdc6e2dbccfddeb50f36d2523bb977a976e19bdb3ae19b740804" dependencies = [ - "bitflags 2.7.0", + "bitflags 2.6.0", "boa_ast", "boa_interner", "boa_macros", @@ -1632,7 +1632,7 @@ checksum = "3fa76293b4f7bb636ab88fd78228235b5248b4d05cc589aed610f954af5d7c7a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -1720,9 +1720,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.8" +version = "1.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0cf6e91fde44c773c6ee7ec6bba798504641a8bc2eb7e37a04ffbf4dfaa55a" +checksum = "a012a0df96dd6d06ba9a1b29d6402d1a5d77c6befd2566afdc26e10603dc93d7" dependencies = [ "jobserver", "libc", @@ -1821,9 +1821,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.26" +version = "4.5.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8eb5e908ef3a6efbe1ed62520fb7287959888c88485abe072543190ecc66783" +checksum = "9560b07a799281c7e0958b9296854d6fafd4c5f31444a7e5bb1ad6dde5ccf1bd" dependencies = [ "clap_builder", "clap_derive", @@ -1831,9 +1831,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.26" +version = "4.5.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b01801b5fc6a0a232407abc821660c9c6d25a1cafc0d4f85f29fb8d9afc121" +checksum = "874e0dd3eb68bf99058751ac9712f622e61e6f393a94f7128fa26e3f02f5c7cd" dependencies = [ "anstream", "anstyle", @@ -1850,7 +1850,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -2214,7 +2214,7 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" dependencies = [ - "bitflags 2.7.0", + "bitflags 2.6.0", "crossterm_winapi", "mio 1.0.3", "parking_lot", @@ -2326,7 +2326,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -2350,7 +2350,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -2361,7 +2361,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -2470,7 +2470,7 @@ checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -2491,7 +2491,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", "unicode-xid", ] @@ -2605,7 +2605,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -2686,7 +2686,7 @@ dependencies = [ "revm", "serde", "serde_json", - "thiserror 2.0.11", + "thiserror 2.0.9", "walkdir", ] @@ -2751,7 +2751,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -2762,7 +2762,7 @@ checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -2782,7 +2782,7 @@ checksum = "3bf679796c0322556351f287a51b49e48f7c4986e727b5dd78c972d30e2e16cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -2838,7 +2838,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -2862,7 +2862,7 @@ dependencies = [ "reth-node-ethereum", "serde", "serde_json", - "thiserror 2.0.11", + "thiserror 2.0.9", ] [[package]] @@ -2951,7 +2951,7 @@ dependencies = [ "reth-tracing", "reth-trie-db", "serde", - "thiserror 2.0.11", + "thiserror 2.0.9", "tokio", ] @@ -3408,7 +3408,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -3719,7 +3719,7 @@ dependencies = [ "once_cell", "rand 0.8.5", "serde", - "thiserror 2.0.11", + "thiserror 2.0.9", "tinyvec", "tokio", "tracing", @@ -3743,7 +3743,7 @@ dependencies = [ "resolv-conf", "serde", "smallvec", - "thiserror 2.0.11", + "thiserror 2.0.9", "tokio", "tracing", ] @@ -4090,7 +4090,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -4147,7 +4147,7 @@ checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -4260,15 +4260,15 @@ dependencies = [ [[package]] name = "instability" -version = "0.3.7" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf9fed6d91cfb734e7476a06bde8300a1b94e217e1b523b6f0cd1a01998c71d" +checksum = "894813a444908c0c8c0e221b041771d107c4a21de1d317dc49bcc66e3c9e5b3f" dependencies = [ "darling", "indoc", "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -4517,7 +4517,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -4719,7 +4719,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.7.0", + "bitflags 2.6.0", "libc", "redox_syscall", ] @@ -4790,9 +4790,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.15" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "litemap" @@ -4854,32 +4854,6 @@ dependencies = [ "libc", ] -[[package]] -name = "maili-protocol" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "428caa534dd054a449e64d8007d0fd0a15519d1033b272d37d02b74a29cf69f7" -dependencies = [ - "alloc-no-stdlib", - "alloy-consensus", - "alloy-eips", - "alloy-primitives", - "alloy-rlp", - "alloy-serde", - "alloy-sol-types", - "async-trait", - "brotli", - "derive_more", - "miniz_oxide", - "op-alloy-consensus", - "op-alloy-genesis", - "rand 0.8.5", - "serde", - "thiserror 2.0.11", - "tracing", - "unsigned-varint", -] - [[package]] name = "match_cfg" version = "0.1.0" @@ -4938,7 +4912,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -5177,7 +5151,7 @@ version = "6.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d" dependencies = [ - "bitflags 2.7.0", + "bitflags 2.6.0", "filetime", "fsevent-sys", "inotify", @@ -5328,7 +5302,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -5381,9 +5355,9 @@ checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" [[package]] name = "op-alloy-consensus" -version = "0.9.2" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "442518bf0ef88f4d79409527565b8cdee235c891f2e2a829497caec5ed9d8d1c" +checksum = "250244eadaf1a25e0e2ad263110ad2d1b43c2e57ddf4c025e71552d98196a8d3" dependencies = [ "alloy-consensus", "alloy-eips", @@ -5394,14 +5368,14 @@ dependencies = [ "derive_more", "serde", "serde_with", - "thiserror 2.0.11", + "thiserror 2.0.9", ] [[package]] name = "op-alloy-genesis" -version = "0.9.2" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a2af7fee1fa297569199b524493e50355eab3f1bff75cef492036eb4a3ffb5e" +checksum = "98334a9cdccc5878e9d5c48afc9cc1b84da58dbc68d41f9488d8f71688b495d3" dependencies = [ "alloy-consensus", "alloy-eips", @@ -5409,14 +5383,14 @@ dependencies = [ "alloy-sol-types", "serde", "serde_repr", - "thiserror 2.0.11", + "thiserror 2.0.9", ] [[package]] name = "op-alloy-network" -version = "0.9.2" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9e7e9fc656dfa8cc3b6e799da23e100b3d47e31ec6b5a4ed9d44e11f0967ad8" +checksum = "1dd588157ac14db601d6497b81ae738b2581c60886fc592976fab6c282619604" dependencies = [ "alloy-consensus", "alloy-network", @@ -5429,32 +5403,47 @@ dependencies = [ [[package]] name = "op-alloy-protocol" -version = "0.9.2" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a144b1ed079913b11c0640f4eaa3d2ac1bdb6cc35e3658a1640e88b241e0c32" +checksum = "753762429c31f838b59c886b31456c9bf02fd38fb890621665523a9087ae06ae" dependencies = [ - "maili-protocol", + "alloc-no-stdlib", + "alloy-consensus", + "alloy-eips", + "alloy-primitives", + "alloy-rlp", + "alloy-serde", + "alloy-sol-types", + "async-trait", + "brotli", + "derive_more", + "miniz_oxide", + "op-alloy-consensus", + "op-alloy-genesis", + "serde", + "thiserror 2.0.9", + "tracing", + "unsigned-varint", ] [[package]] name = "op-alloy-rpc-jsonrpsee" -version = "0.9.2" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ff030fa1051bb38a0b526727aec511c0172d6f074a0d63cfedf522b11cc8b09" +checksum = "1f483fb052ef807682ae5b5729c3a61a092ee4f7334e6e6055de67e9f28ef880" dependencies = [ "alloy-eips", "alloy-primitives", "jsonrpsee", - "op-alloy-protocol", "op-alloy-rpc-types", "op-alloy-rpc-types-engine", ] [[package]] name = "op-alloy-rpc-types" -version = "0.9.2" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50223d61cad040db6721bcc2d489c924c1691ce3f5e674d4d8776131dab786a0" +checksum = "37b1d3872021aa28b10fc6cf8252e792e802d89e8b2cdaa57dcb9243c461b286" dependencies = [ "alloy-consensus", "alloy-eips", @@ -5471,9 +5460,9 @@ dependencies = [ [[package]] name = "op-alloy-rpc-types-engine" -version = "0.9.2" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5e2419373bae23ea3f6cf5a49c624d9b644061e2e929d4f9629cbcbffa4964d" +checksum = "c43f00d4060a6a38f5bf0a8182b4cc4c7071e2bc96942f414619251b522169eb" dependencies = [ "alloy-eips", "alloy-primitives", @@ -5483,7 +5472,7 @@ dependencies = [ "op-alloy-consensus", "op-alloy-protocol", "serde", - "thiserror 2.0.11", + "thiserror 2.0.9", ] [[package]] @@ -5657,7 +5646,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc" dependencies = [ "memchr", - "thiserror 2.0.11", + "thiserror 2.0.9", "ucd-trie", ] @@ -5701,7 +5690,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -5730,7 +5719,7 @@ checksum = "d56a66c0c55993aa927429d0f8a0abfd74f084e4d9c192cffed01e418d83eefb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -5877,7 +5866,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "483f8c21f64f3ea09fe0f30f5d48c3e8eefe5dac9129f0075f76593b4c1da705" dependencies = [ "proc-macro2", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -5928,14 +5917,14 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] name = "proc-macro2" -version = "1.0.93" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] @@ -5946,7 +5935,7 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "731e0d9356b0c25f16f33b5be79b1c57b562f141ebfcdb0ad8ac2c13a24293b4" dependencies = [ - "bitflags 2.7.0", + "bitflags 2.6.0", "chrono", "flate2", "hex", @@ -5961,7 +5950,7 @@ version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc5b72d8145275d844d4b5f6d4e1eef00c8cd889edb6035c21675d1bb1f45c9f" dependencies = [ - "bitflags 2.7.0", + "bitflags 2.6.0", "hex", "procfs-core 0.17.0", "rustix", @@ -5973,7 +5962,7 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d3554923a69f4ce04c4a754260c338f505ce22642d3830e049a399fc2059a29" dependencies = [ - "bitflags 2.7.0", + "bitflags 2.6.0", "chrono", "hex", ] @@ -5984,7 +5973,7 @@ version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "239df02d8349b06fc07398a3a1697b06418223b1c7725085e801e7c0fc6a12ec" dependencies = [ - "bitflags 2.7.0", + "bitflags 2.6.0", "hex", ] @@ -5996,7 +5985,7 @@ checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d" dependencies = [ "bit-set", "bit-vec", - "bitflags 2.7.0", + "bitflags 2.6.0", "lazy_static", "num-traits", "rand 0.8.5", @@ -6026,7 +6015,7 @@ checksum = "4ee1c9ac207483d5e7db4940700de86a9aae46ef90c48b57f99fe7edb8345e49" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -6081,7 +6070,7 @@ dependencies = [ "rustc-hash 2.1.0", "rustls", "socket2", - "thiserror 2.0.11", + "thiserror 2.0.9", "tokio", "tracing", ] @@ -6100,7 +6089,7 @@ dependencies = [ "rustls", "rustls-pki-types", "slab", - "thiserror 2.0.11", + "thiserror 2.0.9", "tinyvec", "tracing", "web-time", @@ -6231,7 +6220,7 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdef7f9be5c0122f890d58bdf4d964349ba6a6161f705907526d891efabba57d" dependencies = [ - "bitflags 2.7.0", + "bitflags 2.6.0", "cassowary", "compact_str", "crossterm", @@ -6252,7 +6241,7 @@ version = "11.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ab240315c661615f2ee9f0f2cd32d5a7343a84d5ebcccb99d46e6637565e7b0" dependencies = [ - "bitflags 2.7.0", + "bitflags 2.6.0", ] [[package]] @@ -6287,7 +6276,7 @@ version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" dependencies = [ - "bitflags 2.7.0", + "bitflags 2.6.0", ] [[package]] @@ -6543,7 +6532,7 @@ dependencies = [ "reth-rpc-types-compat", "reth-tracing", "serde", - "thiserror 2.0.11", + "thiserror 2.0.9", "tokio", "tower 0.4.13", "tracing", @@ -6701,7 +6690,7 @@ dependencies = [ "secp256k1", "serde", "snmalloc-rs", - "thiserror 2.0.11", + "thiserror 2.0.9", "tikv-jemallocator", "tracy-client", ] @@ -6737,7 +6726,7 @@ dependencies = [ "proc-macro2", "quote", "similar-asserts", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -6843,7 +6832,7 @@ dependencies = [ "sysinfo", "tempfile", "test-fuzz", - "thiserror 2.0.11", + "thiserror 2.0.9", ] [[package]] @@ -6901,7 +6890,7 @@ dependencies = [ "reth-trie-db", "serde", "serde_json", - "thiserror 2.0.11", + "thiserror 2.0.9", "tracing", ] @@ -6943,7 +6932,7 @@ dependencies = [ "schnellru", "secp256k1", "serde", - "thiserror 2.0.11", + "thiserror 2.0.9", "tokio", "tokio-stream", "tracing", @@ -6968,7 +6957,7 @@ dependencies = [ "reth-network-peers", "reth-tracing", "secp256k1", - "thiserror 2.0.11", + "thiserror 2.0.9", "tokio", "tracing", ] @@ -6995,7 +6984,7 @@ dependencies = [ "secp256k1", "serde", "serde_with", - "thiserror 2.0.11", + "thiserror 2.0.9", "tokio", "tokio-stream", "tracing", @@ -7033,7 +7022,7 @@ dependencies = [ "reth-testing-utils", "reth-tracing", "tempfile", - "thiserror 2.0.11", + "thiserror 2.0.9", "tokio", "tokio-stream", "tokio-util", @@ -7109,7 +7098,7 @@ dependencies = [ "secp256k1", "sha2 0.10.8", "sha3", - "thiserror 2.0.11", + "thiserror 2.0.9", "tokio", "tokio-stream", "tokio-util", @@ -7163,7 +7152,7 @@ dependencies = [ "reth-primitives-traits", "reth-trie", "serde", - "thiserror 2.0.11", + "thiserror 2.0.9", "tokio", ] @@ -7190,7 +7179,7 @@ dependencies = [ "reth-prune", "reth-stages-api", "reth-tasks", - "thiserror 2.0.11", + "thiserror 2.0.9", "tokio", "tokio-stream", ] @@ -7249,7 +7238,7 @@ dependencies = [ "reth-trie-sparse", "revm-primitives", "schnellru", - "thiserror 2.0.11", + "thiserror 2.0.9", "tokio", "tracing", ] @@ -7274,6 +7263,7 @@ dependencies = [ "reth-fs-util", "reth-payload-validator", "reth-primitives", + "reth-primitives-traits", "reth-provider", "reth-revm", "reth-rpc-types-compat", @@ -7294,7 +7284,7 @@ dependencies = [ "reth-execution-errors", "reth-fs-util", "reth-storage-errors", - "thiserror 2.0.11", + "thiserror 2.0.9", ] [[package]] @@ -7327,7 +7317,7 @@ dependencies = [ "serde", "snap", "test-fuzz", - "thiserror 2.0.11", + "thiserror 2.0.9", "tokio", "tokio-stream", "tokio-util", @@ -7356,7 +7346,7 @@ dependencies = [ "reth-primitives", "reth-primitives-traits", "serde", - "thiserror 2.0.11", + "thiserror 2.0.9", ] [[package]] @@ -7543,7 +7533,7 @@ dependencies = [ "reth-prune-types", "reth-storage-errors", "revm-primitives", - "thiserror 2.0.11", + "thiserror 2.0.9", ] [[package]] @@ -7632,12 +7622,13 @@ dependencies = [ "reth-node-ethereum", "reth-payload-builder", "reth-primitives", + "reth-primitives-traits", "reth-provider", "reth-tasks", "reth-transaction-pool", "reth-trie-db", "tempfile", - "thiserror 2.0.11", + "thiserror 2.0.9", "tokio", ] @@ -7664,7 +7655,7 @@ version = "1.1.5" dependencies = [ "serde", "serde_json", - "thiserror 2.0.11", + "thiserror 2.0.9", ] [[package]] @@ -7707,7 +7698,7 @@ dependencies = [ "rand 0.8.5", "reth-tracing", "serde_json", - "thiserror 2.0.11", + "thiserror 2.0.9", "tokio", "tokio-stream", "tokio-util", @@ -7719,7 +7710,7 @@ dependencies = [ name = "reth-libmdbx" version = "1.1.5" dependencies = [ - "bitflags 2.7.0", + "bitflags 2.6.0", "byteorder", "codspeed-criterion-compat", "dashmap", @@ -7732,7 +7723,7 @@ dependencies = [ "reth-mdbx-sys", "smallvec", "tempfile", - "thiserror 2.0.11", + "thiserror 2.0.9", "tracing", ] @@ -7771,7 +7762,7 @@ dependencies = [ "reqwest", "reth-tracing", "serde_with", - "thiserror 2.0.11", + "thiserror 2.0.9", "tokio", "tracing", ] @@ -7831,7 +7822,7 @@ dependencies = [ "serial_test", "smallvec", "tempfile", - "thiserror 2.0.11", + "thiserror 2.0.9", "tokio", "tokio-stream", "tokio-util", @@ -7856,7 +7847,7 @@ dependencies = [ "reth-network-types", "reth-tokio-util", "serde", - "thiserror 2.0.11", + "thiserror 2.0.9", "tokio", "tokio-stream", ] @@ -7894,7 +7885,7 @@ dependencies = [ "secp256k1", "serde_json", "serde_with", - "thiserror 2.0.11", + "thiserror 2.0.9", "tokio", "url", ] @@ -7925,7 +7916,7 @@ dependencies = [ "reth-fs-util", "serde", "tempfile", - "thiserror 2.0.11", + "thiserror 2.0.9", "tracing", "zstd", ] @@ -8055,7 +8046,7 @@ dependencies = [ "serde", "shellexpand", "strum", - "thiserror 2.0.11", + "thiserror 2.0.9", "tokio", "toml", "tracing", @@ -8187,7 +8178,7 @@ dependencies = [ "reth-optimism-forks", "reth-primitives-traits", "serde_json", - "thiserror 2.0.11", + "thiserror 2.0.9", ] [[package]] @@ -8284,7 +8275,7 @@ dependencies = [ "reth-revm", "revm", "revm-primitives", - "thiserror 2.0.11", + "thiserror 2.0.9", "tracing", ] @@ -8384,13 +8375,14 @@ dependencies = [ "reth-payload-primitives", "reth-payload-util", "reth-primitives", + "reth-primitives-traits", "reth-provider", "reth-revm", "reth-rpc-types-compat", "reth-transaction-pool", "revm", "sha2 0.10.8", - "thiserror 2.0.11", + "thiserror 2.0.9", "tracing", ] @@ -8461,7 +8453,7 @@ dependencies = [ "reth-transaction-pool", "revm", "serde_json", - "thiserror 2.0.11", + "thiserror 2.0.9", "tokio", "tracing", ] @@ -8528,7 +8520,7 @@ dependencies = [ "reth-primitives", "revm-primitives", "serde", - "thiserror 2.0.11", + "thiserror 2.0.9", "tokio", ] @@ -8627,7 +8619,7 @@ dependencies = [ "serde_json", "serde_with", "test-fuzz", - "thiserror 2.0.11", + "thiserror 2.0.9", ] [[package]] @@ -8706,7 +8698,7 @@ dependencies = [ "reth-tokio-util", "reth-tracing", "rustc-hash 2.1.0", - "thiserror 2.0.11", + "thiserror 2.0.9", "tokio", "tracing", ] @@ -8726,7 +8718,7 @@ dependencies = [ "serde", "serde_json", "test-fuzz", - "thiserror 2.0.11", + "thiserror 2.0.9", "toml", ] @@ -8811,7 +8803,7 @@ dependencies = [ "revm-primitives", "serde", "serde_json", - "thiserror 2.0.11", + "thiserror 2.0.9", "tokio", "tokio-stream", "tower 0.4.13", @@ -8889,6 +8881,7 @@ dependencies = [ "reth-node-core", "reth-payload-builder", "reth-primitives", + "reth-primitives-traits", "reth-provider", "reth-rpc", "reth-rpc-api", @@ -8903,7 +8896,7 @@ dependencies = [ "reth-transaction-pool", "serde", "serde_json", - "thiserror 2.0.11", + "thiserror 2.0.9", "tokio", "tokio-util", "tower 0.4.13", @@ -8942,7 +8935,7 @@ dependencies = [ "reth-tokio-util", "reth-transaction-pool", "serde", - "thiserror 2.0.11", + "thiserror 2.0.9", "tokio", "tracing", ] @@ -9026,7 +9019,7 @@ dependencies = [ "schnellru", "serde", "serde_json", - "thiserror 2.0.11", + "thiserror 2.0.9", "tokio", "tokio-stream", "tracing", @@ -9126,7 +9119,7 @@ dependencies = [ "reth-trie", "reth-trie-db", "tempfile", - "thiserror 2.0.11", + "thiserror 2.0.9", "tokio", "tracing", ] @@ -9154,7 +9147,7 @@ dependencies = [ "reth-static-file-types", "reth-testing-utils", "reth-tokio-util", - "thiserror 2.0.11", + "thiserror 2.0.9", "tokio", "tokio-stream", "tracing", @@ -9248,7 +9241,7 @@ dependencies = [ "reth-fs-util", "reth-primitives-traits", "reth-static-file-types", - "thiserror 2.0.11", + "thiserror 2.0.9", ] [[package]] @@ -9262,7 +9255,7 @@ dependencies = [ "pin-project", "rayon", "reth-metrics", - "thiserror 2.0.11", + "thiserror 2.0.9", "tokio", "tracing", "tracing-futures", @@ -9316,7 +9309,7 @@ dependencies = [ "aquamarine", "assert_matches", "auto_impl", - "bitflags 2.7.0", + "bitflags 2.6.0", "codspeed-criterion-compat", "futures-util", "metrics", @@ -9347,7 +9340,7 @@ dependencies = [ "serde_json", "smallvec", "tempfile", - "thiserror 2.0.11", + "thiserror 2.0.9", "tokio", "tokio-stream", "tracing", @@ -9462,7 +9455,7 @@ dependencies = [ "reth-trie", "reth-trie-common", "reth-trie-db", - "thiserror 2.0.11", + "thiserror 2.0.9", "tracing", ] @@ -9487,7 +9480,7 @@ dependencies = [ "reth-trie", "reth-trie-common", "smallvec", - "thiserror 2.0.11", + "thiserror 2.0.9", ] [[package]] @@ -9529,7 +9522,7 @@ dependencies = [ "colorchoice", "revm", "serde_json", - "thiserror 2.0.11", + "thiserror 2.0.9", ] [[package]] @@ -9572,7 +9565,7 @@ dependencies = [ "alloy-eip7702", "alloy-primitives", "auto_impl", - "bitflags 2.7.0", + "bitflags 2.6.0", "bitvec", "c-kzg", "cfg-if", @@ -9674,9 +9667,9 @@ dependencies = [ [[package]] name = "roaring" -version = "0.10.10" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a652edd001c53df0b3f96a36a8dc93fce6866988efc16808235653c6bcac8bf2" +checksum = "41589aba99537475bf697f2118357cad1c31590c5a1b9f6d9fc4ad6d07503661" dependencies = [ "bytemuck", "byteorder", @@ -9723,7 +9716,7 @@ dependencies = [ "regex", "relative-path", "rustc_version 0.4.1", - "syn 2.0.96", + "syn 2.0.95", "unicode-ident", ] @@ -9811,7 +9804,7 @@ version = "0.38.43" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6" dependencies = [ - "bitflags 2.7.0", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", @@ -9820,9 +9813,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.21" +version = "0.23.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f287924602bf649d949c63dc8ac8b235fa5387d394020705b80c4eb597ce5b8" +checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b" dependencies = [ "log", "once_cell", @@ -10041,7 +10034,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.7.0", + "bitflags 2.6.0", "core-foundation 0.9.4", "core-foundation-sys", "libc", @@ -10055,7 +10048,7 @@ version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316" dependencies = [ - "bitflags 2.7.0", + "bitflags 2.6.0", "core-foundation 0.10.0", "core-foundation-sys", "libc", @@ -10128,7 +10121,7 @@ checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -10163,7 +10156,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -10214,7 +10207,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -10247,7 +10240,7 @@ checksum = "5d69265a08751de7844521fd15003ae0a888e035773ba05695c5c759a6f89eef" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -10549,7 +10542,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -10573,9 +10566,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "symbolic-common" -version = "12.13.1" +version = "12.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf08b42a6f9469bd8584daee39a1352c8133ccabc5151ccccb15896ef047d99a" +checksum = "cd33e73f154e36ec223c18013f7064a2c120f1162fc086ac9933542def186b00" dependencies = [ "debugid", "memmap2", @@ -10585,9 +10578,9 @@ dependencies = [ [[package]] name = "symbolic-demangle" -version = "12.13.1" +version = "12.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f73b5a5bd4da72720c45756a2d11edf110116b87f998bda59b97be8c2c7cf1" +checksum = "89e51191290147f071777e37fe111800bb82a9059f9c95b19d2dd41bfeddf477" dependencies = [ "cpp_demangle", "rustc-demangle", @@ -10607,9 +10600,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.96" +version = "2.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" +checksum = "46f71c0377baf4ef1cc3e3402ded576dccc315800fbc62dfc7fe04b009773b4a" dependencies = [ "proc-macro2", "quote", @@ -10625,7 +10618,7 @@ dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -10645,7 +10638,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -10723,7 +10716,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -10756,11 +10749,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.11" +version = "2.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" +checksum = "f072643fd0190df67a8bab670c20ef5d8737177d6ac6b2e9a236cb096206b2cc" dependencies = [ - "thiserror-impl 2.0.11", + "thiserror-impl 2.0.9", ] [[package]] @@ -10771,18 +10764,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] name = "thiserror-impl" -version = "2.0.11" +version = "2.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" +checksum = "7b50fa271071aae2e6ee85f842e2e28ba8cd2c5fb67f11fcb1fd70b276f9e7d4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -10915,9 +10908,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.43.0" +version = "1.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" +checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551" dependencies = [ "backtrace", "bytes", @@ -10933,13 +10926,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.5.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -11073,7 +11066,7 @@ checksum = "403fa3b783d4b626a8ad51d766ab03cb6d2dbfc46b1c5d4448395e6628dc9697" dependencies = [ "async-compression", "base64 0.22.1", - "bitflags 2.7.0", + "bitflags 2.6.0", "bytes", "futures-core", "futures-util", @@ -11140,7 +11133,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -11435,9 +11428,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.11.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b913a3b5fe84142e269d63cc62b64319ccaf89b748fc31fe025177f767a756c4" +checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" dependencies = [ "getrandom 0.2.15", ] @@ -11476,7 +11469,7 @@ checksum = "d674d135b4a8c1d7e813e2f8d1c9a58308aee4a680323066025e53132218bd91" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -11546,7 +11539,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", "wasm-bindgen-shared", ] @@ -11581,7 +11574,7 @@ checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -11747,7 +11740,7 @@ checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -11758,7 +11751,7 @@ checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -11769,7 +11762,7 @@ checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -11780,7 +11773,7 @@ checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -11972,9 +11965,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.24" +version = "0.6.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8d71a593cc5c42ad7876e2c1fda56f314f3754c084128833e64f1345ff8a03a" +checksum = "39281189af81c07ec09db316b302a3e67bf9bd7cbf6c820b50e35fee9c2fa980" dependencies = [ "memchr", ] @@ -12055,7 +12048,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", "synstructure", ] @@ -12077,7 +12070,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -12097,7 +12090,7 @@ checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", "synstructure", ] @@ -12118,7 +12111,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] @@ -12140,7 +12133,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.95", ] [[package]] diff --git a/bin/reth-bench/src/bench/new_payload_fcu.rs b/bin/reth-bench/src/bench/new_payload_fcu.rs index 2866cf8fb4..12caecbd03 100644 --- a/bin/reth-bench/src/bench/new_payload_fcu.rs +++ b/bin/reth-bench/src/bench/new_payload_fcu.rs @@ -12,13 +12,14 @@ use crate::{ valid_payload::{call_forkchoice_updated, call_new_payload}, }; use alloy_primitives::B256; -use alloy_provider::Provider; +use alloy_provider::{network::AnyRpcBlock, Provider}; use alloy_rpc_types_engine::ForkchoiceState; use clap::Parser; use csv::Writer; use reth_cli_runner::CliContext; use reth_node_core::args::BenchmarkArgs; use reth_primitives::SealedBlock; +use reth_primitives_traits::SealedHeader; use reth_rpc_types_compat::engine::payload::block_to_payload; use std::time::Instant; use tracing::{debug, info}; @@ -46,7 +47,7 @@ impl Command { let block_res = block_provider.get_block_by_number(next_block.into(), true.into()).await; let block = block_res.unwrap().unwrap(); - let block: SealedBlock = block.try_into().unwrap(); + let block = from_any_rpc_block(block); let head_block_hash = block.hash(); let safe_block_hash = block_provider .get_block_by_number(block.number.saturating_sub(32).into(), false.into()); @@ -161,3 +162,19 @@ impl Command { Ok(()) } } + +// TODO(mattsse): integrate in alloy +pub(crate) fn from_any_rpc_block(block: AnyRpcBlock) -> SealedBlock { + let block = block.inner; + let block_hash = block.header.hash; + let block = block.try_map_transactions(|tx| tx.try_into()).unwrap(); + + SealedBlock::from_sealed_parts( + SealedHeader::new(block.header.inner.into_header_with_defaults(), block_hash), + reth_primitives::BlockBody { + transactions: block.transactions.into_transactions().collect(), + ommers: Default::default(), + withdrawals: block.withdrawals.map(|w| w.into_inner().into()), + }, + ) +} diff --git a/bin/reth-bench/src/bench/new_payload_only.rs b/bin/reth-bench/src/bench/new_payload_only.rs index 4485e3fa79..f72b9f2d5d 100644 --- a/bin/reth-bench/src/bench/new_payload_only.rs +++ b/bin/reth-bench/src/bench/new_payload_only.rs @@ -3,6 +3,7 @@ use crate::{ bench::{ context::BenchContext, + new_payload_fcu::from_any_rpc_block, output::{ NewPayloadResult, TotalGasOutput, TotalGasRow, GAS_OUTPUT_SUFFIX, NEW_PAYLOAD_OUTPUT_SUFFIX, @@ -16,7 +17,6 @@ use clap::Parser; use csv::Writer; use reth_cli_runner::CliContext; use reth_node_core::args::BenchmarkArgs; -use reth_primitives::SealedBlock; use reth_rpc_types_compat::engine::payload::block_to_payload; use std::time::Instant; use tracing::{debug, info}; @@ -46,7 +46,7 @@ impl Command { let block_res = block_provider.get_block_by_number(next_block.into(), true.into()).await; let block = block_res.unwrap().unwrap(); - let block: SealedBlock = block.try_into().unwrap(); + let block = from_any_rpc_block(block); next_block += 1; sender.send(block).await.unwrap(); diff --git a/bin/reth/src/commands/debug_cmd/build_block.rs b/bin/reth/src/commands/debug_cmd/build_block.rs index 40110fe849..396fe62145 100644 --- a/bin/reth/src/commands/debug_cmd/build_block.rs +++ b/bin/reth/src/commands/debug_cmd/build_block.rs @@ -1,5 +1,5 @@ //! Command for debugging block building. -use alloy_consensus::TxEip4844; +use alloy_consensus::{BlockHeader, TxEip4844}; use alloy_eips::{ eip2718::Encodable2718, eip4844::{env_settings::EnvKzgSettings, BlobTransactionSidecar}, @@ -24,10 +24,8 @@ use reth_execution_types::ExecutionOutcome; use reth_fs_util as fs; use reth_node_api::{BlockTy, EngineApiMessageVersion, PayloadBuilderAttributes}; use reth_node_ethereum::{consensus::EthBeaconConsensus, EthEvmConfig, EthExecutorProvider}; -use reth_primitives::{ - BlockExt, EthPrimitives, SealedBlockFor, SealedBlockWithSenders, SealedHeader, Transaction, - TransactionSigned, -}; +use reth_primitives::{EthPrimitives, SealedBlock, SealedHeader, Transaction, TransactionSigned}; +use reth_primitives_traits::Block as _; use reth_provider::{ providers::{BlockchainProvider, ProviderNodeTypes}, BlockHashReader, BlockReader, BlockWriter, ChainSpecProvider, ProviderFactory, @@ -86,7 +84,7 @@ impl> Command { fn lookup_best_block>( &self, factory: ProviderFactory, - ) -> RethResult>>> { + ) -> RethResult>>> { let provider = factory.provider()?; let best_number = @@ -241,17 +239,14 @@ impl> Command { consensus.validate_header(block.sealed_header())?; consensus.validate_block_pre_execution(block)?; - let senders = block.senders().expect("sender recovery failed"); - let block_with_senders = - SealedBlockWithSenders::>::new(block.clone(), senders).unwrap(); + let block_with_senders = block.clone().try_recover().unwrap(); let state_provider = blockchain_db.latest()?; let db = StateProviderDatabase::new(&state_provider); let executor = EthExecutorProvider::ethereum(provider_factory.chain_spec()).executor(db); - let block_execution_output = - executor.execute(&block_with_senders.clone().unseal())?; + let block_execution_output = executor.execute(&block_with_senders)?; let execution_outcome = ExecutionOutcome::from((block_execution_output, block.number)); debug!(target: "reth::cli", ?execution_outcome, "Executed block"); @@ -262,7 +257,7 @@ impl> Command { hashed_post_state.clone(), )?; - if state_root != block_with_senders.state_root { + if state_root != block_with_senders.state_root() { eyre::bail!( "state root mismatch. expected: {}. got: {}", block_with_senders.state_root, diff --git a/bin/reth/src/commands/debug_cmd/execution.rs b/bin/reth/src/commands/debug_cmd/execution.rs index cc0c701067..ef21f144a3 100644 --- a/bin/reth/src/commands/debug_cmd/execution.rs +++ b/bin/reth/src/commands/debug_cmd/execution.rs @@ -1,6 +1,6 @@ //! Command for debugging execution. -use crate::{args::NetworkArgs, utils::get_single_header}; +use crate::{api::BlockTy, args::NetworkArgs, utils::get_single_header}; use alloy_eips::BlockHashOrNumber; use alloy_primitives::{BlockNumber, B256}; use clap::Parser; @@ -64,7 +64,7 @@ impl> Command { &self, config: &Config, client: Client, - consensus: Arc>, + consensus: Arc, Error = ConsensusError>>, provider_factory: ProviderFactory, task_executor: &TaskExecutor, static_file_producer: StaticFileProducer>, @@ -172,7 +172,7 @@ impl> Command { let Environment { provider_factory, config, data_dir } = self.env.init::(AccessRights::RW)?; - let consensus: Arc> = + let consensus: Arc, Error = ConsensusError>> = Arc::new(EthBeaconConsensus::new(provider_factory.chain_spec())); // Configure and build network diff --git a/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs b/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs index d4c0f3c6c4..30ba4ec907 100644 --- a/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs +++ b/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs @@ -1,9 +1,11 @@ //! Command for debugging in-memory merkle trie calculation. use crate::{ + api::BlockTy, args::NetworkArgs, utils::{get_single_body, get_single_header}, }; +use alloy_consensus::BlockHeader; use alloy_eips::BlockHashOrNumber; use backon::{ConstantBuilder, Retryable}; use clap::Parser; @@ -18,9 +20,9 @@ use reth_evm::execute::{BlockExecutorProvider, Executor}; use reth_execution_types::ExecutionOutcome; use reth_network::{BlockDownloaderProvider, NetworkHandle}; use reth_network_api::NetworkInfo; -use reth_node_api::{BlockTy, NodePrimitives}; +use reth_node_api::NodePrimitives; use reth_node_ethereum::{consensus::EthBeaconConsensus, EthExecutorProvider}; -use reth_primitives::{BlockExt, EthPrimitives}; +use reth_primitives::{EthPrimitives, SealedBlock}; use reth_provider::{ providers::ProviderNodeTypes, AccountExtReader, ChainSpecProvider, DatabaseProviderFactory, HashedPostStateProvider, HashingWriter, LatestStateProviderRef, OriginalValuesKnown, @@ -135,25 +137,19 @@ impl> Command { let client = fetch_client.clone(); let chain = provider_factory.chain_spec(); let consensus = Arc::new(EthBeaconConsensus::new(chain.clone())); - let block = (move || get_single_body(client.clone(), header.clone(), consensus.clone())) - .retry(backoff) - .notify( - |err, _| warn!(target: "reth::cli", "Error requesting body: {err}. Retrying..."), - ) - .await?; + let block: SealedBlock> = (move || { + get_single_body(client.clone(), header.clone(), consensus.clone()) + }) + .retry(backoff) + .notify(|err, _| warn!(target: "reth::cli", "Error requesting body: {err}. Retrying...")) + .await?; let state_provider = LatestStateProviderRef::new(&provider); let db = StateProviderDatabase::new(&state_provider); let executor = EthExecutorProvider::ethereum(provider_factory.chain_spec()).executor(db); - let block_execution_output = executor.execute( - &block - .clone() - .unseal::>() - .with_recovered_senders() - .ok_or(BlockValidationError::SenderRecoveryError)?, - )?; - let execution_outcome = ExecutionOutcome::from((block_execution_output, block.number)); + let block_execution_output = executor.execute(&block.clone().try_recover()?)?; + let execution_outcome = ExecutionOutcome::from((block_execution_output, block.number())); // Unpacked `BundleState::state_root_slow` function let (in_memory_state_root, in_memory_updates) = StateRoot::overlay_root_with_updates( @@ -161,7 +157,7 @@ impl> Command { state_provider.hashed_post_state(execution_outcome.state()), )?; - if in_memory_state_root == block.state_root { + if in_memory_state_root == block.state_root() { info!(target: "reth::cli", state_root = ?in_memory_state_root, "Computed in-memory state root matches"); return Ok(()) } @@ -170,28 +166,27 @@ impl> Command { // Insert block, state and hashes provider_rw.insert_historical_block( - block - .clone() - .try_seal_with_senders() - .map_err(|_| BlockValidationError::SenderRecoveryError)?, + block.clone().try_recover().map_err(|_| BlockValidationError::SenderRecoveryError)?, )?; provider_rw.write_state( &execution_outcome, OriginalValuesKnown::No, StorageLocation::Database, )?; - let storage_lists = provider_rw.changed_storages_with_range(block.number..=block.number)?; + let storage_lists = + provider_rw.changed_storages_with_range(block.number..=block.number())?; let storages = provider_rw.plain_state_storages(storage_lists)?; provider_rw.insert_storage_for_hashing(storages)?; - let account_lists = provider_rw.changed_accounts_with_range(block.number..=block.number)?; + let account_lists = + provider_rw.changed_accounts_with_range(block.number..=block.number())?; let accounts = provider_rw.basic_accounts(account_lists)?; provider_rw.insert_account_for_hashing(accounts)?; let (state_root, incremental_trie_updates) = StateRoot::incremental_root_with_updates( provider_rw.tx_ref(), - block.number..=block.number, + block.number..=block.number(), )?; - if state_root != block.state_root { + if state_root != block.state_root() { eyre::bail!( "Computed incremental state root mismatch. Expected: {:?}. Got: {:?}", block.state_root, diff --git a/bin/reth/src/commands/debug_cmd/merkle.rs b/bin/reth/src/commands/debug_cmd/merkle.rs index acc346d9e3..d7f3516500 100644 --- a/bin/reth/src/commands/debug_cmd/merkle.rs +++ b/bin/reth/src/commands/debug_cmd/merkle.rs @@ -1,5 +1,6 @@ //! Command for debugging merkle tree calculation. use crate::{args::NetworkArgs, utils::get_single_header}; +use alloy_consensus::BlockHeader; use alloy_eips::BlockHashOrNumber; use backon::{ConstantBuilder, Retryable}; use clap::Parser; @@ -128,7 +129,7 @@ impl> Command { info!(target: "reth::cli", target_block_number=self.to, "Finished downloading tip of block range"); // build the full block client - let consensus: Arc> = + let consensus: Arc, Error = ConsensusError>> = Arc::new(EthBeaconConsensus::new(provider_factory.chain_spec())); let block_range_client = FullBlockClient::new(fetch_client, consensus); @@ -153,18 +154,17 @@ impl> Command { for block in blocks.into_iter().rev() { let block_number = block.number; - let sealed_block = block - .try_seal_with_senders::>() - .map_err(|block| eyre::eyre!("Error sealing block with senders: {block:?}"))?; + let sealed_block = + block.try_recover().map_err(|_| eyre::eyre!("Error sealing block with senders"))?; trace!(target: "reth::cli", block_number, "Executing block"); provider_rw.insert_block(sealed_block.clone(), StorageLocation::Database)?; - td += sealed_block.difficulty; + td += sealed_block.difficulty(); let mut executor = executor_provider.batch_executor(StateProviderDatabase::new( LatestStateProviderRef::new(&provider_rw), )); - executor.execute_and_verify_one(&sealed_block.clone().unseal())?; + executor.execute_and_verify_one(&sealed_block)?; let execution_outcome = executor.finalize(); provider_rw.write_state( diff --git a/book/sources/exex/tracking-state/src/bin/2.rs b/book/sources/exex/tracking-state/src/bin/2.rs index 44b023967a..dba9714c52 100644 --- a/book/sources/exex/tracking-state/src/bin/2.rs +++ b/book/sources/exex/tracking-state/src/bin/2.rs @@ -6,7 +6,11 @@ use std::{ use alloy_primitives::BlockNumber; use futures_util::{FutureExt, TryStreamExt}; -use reth::{api::FullNodeComponents, builder::NodeTypes, primitives::EthPrimitives}; +use reth::{ + api::{BlockBody, FullNodeComponents}, + builder::NodeTypes, + primitives::EthPrimitives, +}; use reth_exex::{ExExContext, ExExEvent}; use reth_node_ethereum::EthereumNode; use reth_tracing::tracing::info; @@ -36,7 +40,7 @@ impl>> Fut while let Some(notification) = ready!(this.ctx.notifications.try_next().poll_unpin(cx))? { if let Some(reverted_chain) = notification.reverted_chain() { this.transactions = this.transactions.saturating_sub( - reverted_chain.blocks_iter().map(|b| b.body().transactions.len() as u64).sum(), + reverted_chain.blocks_iter().map(|b| b.body().transaction_count() as u64).sum(), ); } @@ -45,7 +49,7 @@ impl>> Fut this.transactions += committed_chain .blocks_iter() - .map(|b| b.body().transactions.len() as u64) + .map(|b| b.body().transaction_count() as u64) .sum::(); this.ctx diff --git a/crates/chain-state/Cargo.toml b/crates/chain-state/Cargo.toml index 2b06bd9370..639b211d54 100644 --- a/crates/chain-state/Cargo.toml +++ b/crates/chain-state/Cargo.toml @@ -47,6 +47,7 @@ alloy-signer-local = { workspace = true, optional = true } rand = { workspace = true, optional = true } [dev-dependencies] +reth-primitives-traits = { workspace = true, features = ["test-utils"] } reth-testing-utils.workspace = true alloy-signer.workspace = true alloy-signer-local.workspace = true diff --git a/crates/chain-state/src/in_memory.rs b/crates/chain-state/src/in_memory.rs index fac148d4a7..59e01055f7 100644 --- a/crates/chain-state/src/in_memory.rs +++ b/crates/chain-state/src/in_memory.rs @@ -12,10 +12,9 @@ use reth_chainspec::ChainInfo; use reth_execution_types::{Chain, ExecutionOutcome}; use reth_metrics::{metrics::Gauge, Metrics}; use reth_primitives::{ - BlockWithSenders, EthPrimitives, NodePrimitives, Receipts, SealedBlock, SealedBlockFor, - SealedBlockWithSenders, SealedHeader, + EthPrimitives, NodePrimitives, Receipts, RecoveredBlock, SealedBlock, SealedHeader, }; -use reth_primitives_traits::{Block, BlockBody as _, SignedTransaction}; +use reth_primitives_traits::{BlockBody as _, SignedTransaction}; use reth_storage_api::StateProviderBox; use reth_trie::{updates::TrieUpdates, HashedPostState}; use std::{collections::BTreeMap, sync::Arc, time::Instant}; @@ -160,7 +159,7 @@ impl CanonicalInMemoryStateInner { } type PendingBlockAndReceipts = - (SealedBlockFor<::Block>, Vec>); + (SealedBlock<::Block>, Vec>); /// This type is responsible for providing the blocks, receipts, and state for /// all canonical blocks not on disk yet and keeps track of the block range that @@ -471,17 +470,17 @@ impl CanonicalInMemoryState { } /// Returns the `SealedBlock` corresponding to the pending state. - pub fn pending_block(&self) -> Option> { + pub fn pending_block(&self) -> Option> { self.pending_state().map(|block_state| block_state.block_ref().block().clone()) } - /// Returns the `SealedBlockWithSenders` corresponding to the pending state. - pub fn pending_block_with_senders(&self) -> Option> + /// Returns the `RecoveredBlock` corresponding to the pending state. + pub fn pending_recovered_block(&self) -> Option> where N::SignedTx: SignedTransaction, { self.pending_state() - .and_then(|block_state| block_state.block_ref().block().clone().seal_with_senders()) + .and_then(|block_state| block_state.block_ref().block().clone().try_recover().ok()) } /// Returns a tuple with the `SealedBlock` corresponding to the pending @@ -636,19 +635,11 @@ impl BlockState { &self.block } - /// Returns the block with senders for the state. - pub fn block_with_senders(&self) -> BlockWithSenders { + /// Returns a clone of the block with recovered senders for the state. + pub fn clone_recovered_block(&self) -> RecoveredBlock { let block = self.block.block().clone(); let senders = self.block.senders().clone(); - let (header, body) = block.split(); - BlockWithSenders::new_unchecked(N::Block::new(header.unseal(), body), senders) - } - - /// Returns the sealed block with senders for the state. - pub fn sealed_block_with_senders(&self) -> SealedBlockWithSenders { - let block = self.block.block().clone(); - let senders = self.block.senders().clone(); - SealedBlockWithSenders::new_unchecked(block, senders) + RecoveredBlock::new_sealed(block, senders) } /// Returns the hash of executed block that determines the state. @@ -803,7 +794,7 @@ impl BlockState { #[derive(Clone, Debug, PartialEq, Eq, Default)] pub struct ExecutedBlock { /// Sealed block the rest of fields refer to. - pub block: Arc>, + pub block: Arc>, /// Block's senders. pub senders: Arc>, /// Block's execution outcome. @@ -817,7 +808,7 @@ pub struct ExecutedBlock { impl ExecutedBlock { /// [`ExecutedBlock`] constructor. pub const fn new( - block: Arc>, + block: Arc>, senders: Arc>, execution_output: Arc>, hashed_state: Arc, @@ -827,7 +818,7 @@ impl ExecutedBlock { } /// Returns a reference to the executed block. - pub fn block(&self) -> &SealedBlockFor { + pub fn block(&self) -> &SealedBlock { &self.block } @@ -836,11 +827,11 @@ impl ExecutedBlock { &self.senders } - /// Returns a [`SealedBlockWithSenders`] + /// Returns a [`RecoveredBlock`] /// /// Note: this clones the block and senders. - pub fn sealed_block_with_senders(&self) -> SealedBlockWithSenders { - SealedBlockWithSenders::new_unchecked((*self.block).clone(), (*self.senders).clone()) + pub fn clone_recovered_block(&self) -> RecoveredBlock { + RecoveredBlock::new_sealed((*self.block).clone(), (*self.senders).clone()) } /// Returns a reference to the block's execution outcome @@ -899,7 +890,7 @@ impl> NewCanonicalChain { Self::Commit { new } => { let new = Arc::new(new.iter().fold(Chain::default(), |mut chain, exec| { chain.append_block( - exec.sealed_block_with_senders(), + exec.clone_recovered_block(), exec.execution_outcome().clone(), ); chain @@ -909,14 +900,14 @@ impl> NewCanonicalChain { Self::Reorg { new, old } => { let new = Arc::new(new.iter().fold(Chain::default(), |mut chain, exec| { chain.append_block( - exec.sealed_block_with_senders(), + exec.clone_recovered_block(), exec.execution_outcome().clone(), ); chain })); let old = Arc::new(old.iter().fold(Chain::default(), |mut chain, exec| { chain.append_block( - exec.sealed_block_with_senders(), + exec.clone_recovered_block(), exec.execution_outcome().clone(), ); chain @@ -930,7 +921,7 @@ impl> NewCanonicalChain { /// /// Returns the new tip for [`Self::Reorg`] and [`Self::Commit`] variants which commit at least /// 1 new block. - pub fn tip(&self) -> &SealedBlockFor { + pub fn tip(&self) -> &SealedBlock { match self { Self::Commit { new } | Self::Reorg { new, .. } => { new.last().expect("non empty blocks").block() @@ -1325,8 +1316,8 @@ mod tests { // Check the pending block with senders assert_eq!( - state.pending_block_with_senders().unwrap(), - block2.block().clone().seal_with_senders().unwrap() + state.pending_recovered_block().unwrap(), + block2.block().clone().try_recover().unwrap() ); // Check the pending block and receipts @@ -1529,7 +1520,7 @@ mod tests { chain_commit.to_chain_notification(), CanonStateNotification::Commit { new: Arc::new(Chain::new( - vec![block0.sealed_block_with_senders(), block1.sealed_block_with_senders()], + vec![block0.clone_recovered_block(), block1.clone_recovered_block()], sample_execution_outcome.clone(), None )) @@ -1546,12 +1537,12 @@ mod tests { chain_reorg.to_chain_notification(), CanonStateNotification::Reorg { old: Arc::new(Chain::new( - vec![block1.sealed_block_with_senders(), block2.sealed_block_with_senders()], + vec![block1.clone_recovered_block(), block2.clone_recovered_block()], sample_execution_outcome.clone(), None )), new: Arc::new(Chain::new( - vec![block1a.sealed_block_with_senders(), block2a.sealed_block_with_senders()], + vec![block1a.clone_recovered_block(), block2a.clone_recovered_block()], sample_execution_outcome, None )) diff --git a/crates/chain-state/src/notifications.rs b/crates/chain-state/src/notifications.rs index 808b6b42f8..97a4faaefa 100644 --- a/crates/chain-state/src/notifications.rs +++ b/crates/chain-state/src/notifications.rs @@ -3,7 +3,7 @@ use alloy_eips::eip2718::Encodable2718; use derive_more::{Deref, DerefMut}; use reth_execution_types::{BlockReceipts, Chain}; -use reth_primitives::{NodePrimitives, SealedBlockWithSenders, SealedHeader}; +use reth_primitives::{NodePrimitives, RecoveredBlock, SealedHeader}; use reth_storage_api::NodePrimitivesProvider; use std::{ pin::Pin, @@ -123,7 +123,7 @@ impl CanonStateNotification { /// /// Returns the new tip for [`Self::Reorg`] and [`Self::Commit`] variants which commit at least /// 1 new block. - pub fn tip(&self) -> &SealedBlockWithSenders { + pub fn tip(&self) -> &RecoveredBlock { match self { Self::Commit { new } | Self::Reorg { new, .. } => new.tip(), } @@ -221,7 +221,7 @@ mod tests { #[test] fn test_commit_notification() { - let block: SealedBlockWithSenders = Default::default(); + let block: RecoveredBlock = Default::default(); let block1_hash = B256::new([0x01; 32]); let block2_hash = B256::new([0x02; 32]); @@ -254,7 +254,7 @@ mod tests { #[test] fn test_reorg_notification() { - let block: SealedBlockWithSenders = Default::default(); + let block: RecoveredBlock = Default::default(); let block1_hash = B256::new([0x01; 32]); let block2_hash = B256::new([0x02; 32]); let block3_hash = B256::new([0x03; 32]); @@ -306,10 +306,12 @@ mod tests { let tx = TransactionSigned::default(); body.transactions.push(tx); - let block: SealedBlockWithSenders = - SealedBlock::new(SealedHeader::seal(alloy_consensus::Header::default()), body) - .seal_with_senders() - .unwrap(); + let block = SealedBlock::>::from_sealed_parts( + SealedHeader::seal_slow(alloy_consensus::Header::default()), + body, + ) + .try_recover() + .unwrap(); // Create a clone of the default block and customize it to act as block1. let mut block1 = block.clone(); @@ -372,10 +374,13 @@ mod tests { // Define block1 for the old chain segment, which will be reverted. let mut body = BlockBody::::default(); body.transactions.push(TransactionSigned::default()); - let mut old_block1: SealedBlockWithSenders = - SealedBlock::new(SealedHeader::seal(alloy_consensus::Header::default()), body) - .seal_with_senders() - .unwrap(); + let mut old_block1 = + SealedBlock::>::from_sealed_parts( + SealedHeader::seal_slow(alloy_consensus::Header::default()), + body, + ) + .try_recover() + .unwrap(); old_block1.set_block_number(1); old_block1.set_hash(B256::new([0x01; 32])); @@ -400,10 +405,13 @@ mod tests { // Define block2 for the new chain segment, which will be committed. let mut body = BlockBody::::default(); body.transactions.push(TransactionSigned::default()); - let mut new_block1: SealedBlockWithSenders = - SealedBlock::new(SealedHeader::seal(alloy_consensus::Header::default()), body) - .seal_with_senders() - .unwrap(); + let mut new_block1 = + SealedBlock::>::from_sealed_parts( + SealedHeader::seal_slow(alloy_consensus::Header::default()), + body, + ) + .try_recover() + .unwrap(); new_block1.set_block_number(2); new_block1.set_hash(B256::new([0x02; 32])); diff --git a/crates/chain-state/src/test_utils.rs b/crates/chain-state/src/test_utils.rs index a0ddeb8d0f..cce88d7136 100644 --- a/crates/chain-state/src/test_utils.rs +++ b/crates/chain-state/src/test_utils.rs @@ -17,8 +17,8 @@ use reth_chainspec::{ChainSpec, EthereumHardfork, MIN_TRANSACTION_GAS}; use reth_execution_types::{Chain, ExecutionOutcome}; use reth_primitives::{ proofs::{calculate_receipt_root, calculate_transaction_root, calculate_withdrawals_root}, - BlockBody, EthPrimitives, NodePrimitives, Receipt, Receipts, RecoveredTx, SealedBlock, - SealedBlockWithSenders, SealedHeader, Transaction, TransactionSigned, + BlockBody, EthPrimitives, NodePrimitives, Receipt, Receipts, RecoveredBlock, RecoveredTx, + SealedBlock, SealedHeader, Transaction, TransactionSigned, }; use reth_primitives_traits::Account; use reth_storage_api::NodePrimitivesProvider; @@ -86,12 +86,12 @@ impl TestBlockBuilder { U256::from(INITIAL_BASE_FEE * MIN_TRANSACTION_GAS) } - /// Generates a random [`SealedBlockWithSenders`]. + /// Generates a random [`RecoveredBlock`]. pub fn generate_random_block( &mut self, number: BlockNumber, parent_hash: B256, - ) -> SealedBlockWithSenders { + ) -> RecoveredBlock { let mut rng = thread_rng(); let mock_tx = |nonce: u64| -> RecoveredTx<_> { @@ -168,8 +168,8 @@ impl TestBlockBuilder { ..Default::default() }; - let block = SealedBlock::new( - SealedHeader::seal(header), + let block = SealedBlock::from_sealed_parts( + SealedHeader::seal_slow(header), BlockBody { transactions: transactions.into_iter().map(|tx| tx.into_tx()).collect(), ommers: Vec::new(), @@ -177,7 +177,8 @@ impl TestBlockBuilder { }, ); - SealedBlockWithSenders::new(block, vec![self.signer; num_txs as usize]).unwrap() + RecoveredBlock::try_recover_sealed_with_senders(block, vec![self.signer; num_txs as usize]) + .unwrap() } /// Creates a fork chain with the given base block. @@ -185,13 +186,13 @@ impl TestBlockBuilder { &mut self, base_block: &SealedBlock, length: u64, - ) -> Vec { + ) -> Vec> { let mut fork = Vec::with_capacity(length as usize); let mut parent = base_block.clone(); for _ in 0..length { let block = self.generate_random_block(parent.number + 1, parent.hash()); - parent = block.block.clone(); + parent = block.clone_sealed_block(); fork.push(block); } @@ -207,7 +208,7 @@ impl TestBlockBuilder { ) -> ExecutedBlock { let block_with_senders = self.generate_random_block(block_number, parent_hash); - let (block, senders) = block_with_senders.split(); + let (block, senders) = block_with_senders.split_sealed(); ExecutedBlock::new( Arc::new(block), Arc::new(senders), @@ -258,7 +259,10 @@ impl TestBlockBuilder { /// Returns the execution outcome for a block created with this builder. /// In order to properly include the bundle state, the signer balance is /// updated. - pub fn get_execution_outcome(&mut self, block: SealedBlockWithSenders) -> ExecutionOutcome { + pub fn get_execution_outcome( + &mut self, + block: RecoveredBlock, + ) -> ExecutionOutcome { let receipts = block .body() .transactions diff --git a/crates/cli/commands/src/import.rs b/crates/cli/commands/src/import.rs index 7f5fd2d2f1..1f297ad33b 100644 --- a/crates/cli/commands/src/import.rs +++ b/crates/cli/commands/src/import.rs @@ -20,7 +20,7 @@ use reth_network_p2p::{ bodies::downloader::BodyDownloader, headers::downloader::{HeaderDownloader, SyncTarget}, }; -use reth_node_api::{BlockTy, BodyTy, HeaderTy}; +use reth_node_api::BlockTy; use reth_node_core::version::SHORT_VERSION; use reth_node_events::node::NodeEvent; use reth_provider::{ @@ -169,7 +169,7 @@ pub fn build_import_pipeline( ) -> eyre::Result<(Pipeline, impl Stream>)> where N: ProviderNodeTypes + CliNodeTypes, - C: Consensus, BodyTy, Error = ConsensusError> + 'static, + C: Consensus, Error = ConsensusError> + 'static, E: BlockExecutorProvider, { if !file_client.has_canonical_blocks() { diff --git a/crates/cli/commands/src/init_state/without_evm.rs b/crates/cli/commands/src/init_state/without_evm.rs index f8f72709a7..7f94a8168e 100644 --- a/crates/cli/commands/src/init_state/without_evm.rs +++ b/crates/cli/commands/src/init_state/without_evm.rs @@ -1,16 +1,14 @@ +use alloy_consensus::{BlockHeader, Header}; use alloy_primitives::{BlockNumber, B256, U256}; use alloy_rlp::Decodable; - -use alloy_consensus::{BlockHeader, Header}; use reth_codecs::Compact; use reth_node_builder::NodePrimitives; -use reth_primitives::{SealedBlock, SealedBlockWithSenders, SealedHeader, StaticFileSegment}; +use reth_primitives::{SealedBlock, SealedHeader, StaticFileSegment}; use reth_provider::{ providers::StaticFileProvider, BlockWriter, StageCheckpointWriter, StaticFileProviderFactory, StaticFileWriter, StorageLocation, }; use reth_stages::{StageCheckpoint, StageId}; - use std::{fs::File, io::Read, path::PathBuf}; use tracing::info; @@ -69,8 +67,12 @@ where + StaticFileProviderFactory>, { provider_rw.insert_block( - SealedBlockWithSenders::new(SealedBlock::new(header.clone(), Default::default()), vec![]) - .expect("no senders or txes"), + SealedBlock::<::Block>::from_sealed_parts( + header.clone(), + Default::default(), + ) + .try_recover() + .expect("no senders or txes"), StorageLocation::Database, )?; diff --git a/crates/consensus/common/Cargo.toml b/crates/consensus/common/Cargo.toml index 448b3a1683..75dc4c00cf 100644 --- a/crates/consensus/common/Cargo.toml +++ b/crates/consensus/common/Cargo.toml @@ -14,7 +14,6 @@ workspace = true # reth reth-chainspec.workspace = true reth-consensus.workspace = true -reth-primitives.workspace = true # ethereum alloy-primitives.workspace = true @@ -23,6 +22,7 @@ alloy-consensus.workspace = true alloy-eips.workspace = true [dev-dependencies] +reth-primitives.workspace = true alloy-consensus.workspace = true rand.workspace = true @@ -34,6 +34,6 @@ std = [ "alloy-primitives/std", "reth-chainspec/std", "reth-consensus/std", - "reth-primitives/std", - "reth-primitives-traits/std" + "reth-primitives-traits/std", + "reth-primitives/std" ] diff --git a/crates/consensus/common/src/validation.rs b/crates/consensus/common/src/validation.rs index 9e6a2ad901..530c508766 100644 --- a/crates/consensus/common/src/validation.rs +++ b/crates/consensus/common/src/validation.rs @@ -1,11 +1,14 @@ //! Collection of methods for block validation. -use alloy_consensus::{constants::MAXIMUM_EXTRA_DATA_SIZE, BlockHeader, EMPTY_OMMER_ROOT_HASH}; +use alloy_consensus::{ + constants::MAXIMUM_EXTRA_DATA_SIZE, BlockHeader as _, EMPTY_OMMER_ROOT_HASH, +}; use alloy_eips::{calc_next_block_base_fee, eip4844::DATA_GAS_PER_BLOB, eip7840::BlobParams}; use reth_chainspec::{EthChainSpec, EthereumHardfork, EthereumHardforks}; use reth_consensus::ConsensusError; -use reth_primitives::SealedBlock; -use reth_primitives_traits::{BlockBody, GotExpected, SealedHeader}; +use reth_primitives_traits::{ + Block, BlockBody, BlockHeader, GotExpected, SealedBlock, SealedHeader, +}; /// Gas used needs to be less than gas limit. Gas used is going to be checked after execution. #[inline] @@ -38,8 +41,8 @@ pub fn validate_header_base_fee( /// /// [EIP-4895]: https://eips.ethereum.org/EIPS/eip-4895 #[inline] -pub fn validate_shanghai_withdrawals( - block: &SealedBlock, +pub fn validate_shanghai_withdrawals( + block: &SealedBlock, ) -> Result<(), ConsensusError> { let withdrawals = block.body().withdrawals().ok_or(ConsensusError::BodyWithdrawalsMissing)?; let withdrawals_root = alloy_consensus::proofs::calculate_withdrawals_root(withdrawals); @@ -59,9 +62,7 @@ pub fn validate_shanghai_withdrawals( /// /// [EIP-4844]: https://eips.ethereum.org/EIPS/eip-4844 #[inline] -pub fn validate_cancun_gas( - block: &SealedBlock, -) -> Result<(), ConsensusError> { +pub fn validate_cancun_gas(block: &SealedBlock) -> Result<(), ConsensusError> { // Check that the blob gas used in the header matches the sum of the blob gas used by each // blob tx let header_blob_gas_used = block.blob_gas_used().ok_or(ConsensusError::BlobGasUsedMissing)?; @@ -127,13 +128,12 @@ where /// - Compares the transactions root in the block header to the block body /// - Pre-execution transaction validation /// - (Optionally) Compares the receipts root in the block header to the block body -pub fn validate_block_pre_execution( - block: &SealedBlock, +pub fn validate_block_pre_execution( + block: &SealedBlock, chain_spec: &ChainSpec, ) -> Result<(), ConsensusError> where - H: BlockHeader, - B: BlockBody, + B: Block, ChainSpec: EthereumHardforks, { // Check ommers hash @@ -377,15 +377,13 @@ mod tests { transactions_root: proofs::calculate_transaction_root(&[transaction.clone()]), ..Default::default() }; - let header = SealedHeader::seal(header); - let body = BlockBody { transactions: vec![transaction], ommers: vec![], withdrawals: Some(Withdrawals::default()), }; - let block = SealedBlock::new(header, body); + let block = SealedBlock::seal_slow(alloy_consensus::Block { header, body }); // 10 blobs times the blob gas per blob. let expected_blob_gas_used = 10 * DATA_GAS_PER_BLOB; diff --git a/crates/consensus/consensus/src/lib.rs b/crates/consensus/consensus/src/lib.rs index 1de99d8278..aa14806e43 100644 --- a/crates/consensus/consensus/src/lib.rs +++ b/crates/consensus/consensus/src/lib.rs @@ -16,10 +16,10 @@ use alloy_consensus::Header; use alloy_eips::eip7685::Requests; use alloy_primitives::{BlockHash, BlockNumber, Bloom, B256, U256}; use reth_primitives::{ - BlockBody, BlockWithSenders, EthPrimitives, GotExpected, GotExpectedBoxed, - InvalidTransactionError, NodePrimitives, Receipt, SealedBlock, SealedHeader, + EthPrimitives, GotExpected, GotExpectedBoxed, InvalidTransactionError, NodePrimitives, Receipt, + RecoveredBlock, SealedBlock, SealedHeader, }; -use reth_primitives_traits::constants::MINIMUM_GAS_LIMIT; +use reth_primitives_traits::{constants::MINIMUM_GAS_LIMIT, Block}; /// A consensus implementation that does nothing. pub mod noop; @@ -47,9 +47,7 @@ impl<'a, R> PostExecutionInput<'a, R> { /// [`Consensus`] implementation which knows full node primitives and is able to validation block's /// execution outcome. #[auto_impl::auto_impl(&, Arc)] -pub trait FullConsensus: - AsConsensus -{ +pub trait FullConsensus: AsConsensus { /// Validate a block considering world state, i.e. things that can not be checked before /// execution. /// @@ -58,22 +56,22 @@ pub trait FullConsensus: /// Note: validating blocks does not include other validations of the Consensus fn validate_block_post_execution( &self, - block: &BlockWithSenders, + block: &RecoveredBlock, input: PostExecutionInput<'_, N::Receipt>, ) -> Result<(), ConsensusError>; } /// Consensus is a protocol that chooses canonical chain. #[auto_impl::auto_impl(&, Arc)] -pub trait Consensus: AsHeaderValidator { +pub trait Consensus: AsHeaderValidator { /// The error type related to consensus. type Error; /// Ensures that body field values match the header. fn validate_body_against_header( &self, - body: &B, - header: &SealedHeader, + body: &B::Body, + header: &SealedHeader, ) -> Result<(), Self::Error>; /// Validate a block disregarding world state, i.e. things that can be checked before sender @@ -85,7 +83,7 @@ pub trait Consensus: AsHeaderValidator { /// **This should not be called for the genesis block**. /// /// Note: validating blocks does not include other validations of the Consensus - fn validate_block_pre_execution(&self, block: &SealedBlock) -> Result<(), Self::Error>; + fn validate_block_pre_execution(&self, block: &SealedBlock) -> Result<(), Self::Error>; } /// HeaderValidator is a protocol that validates headers and their relationships. @@ -170,15 +168,15 @@ impl, H> AsHeaderValidator for T { } /// Helper trait to cast `Arc` to `Arc` -pub trait AsConsensus: Consensus { +pub trait AsConsensus: Consensus { /// Converts the [`Arc`] of self to [`Arc`] of [`HeaderValidator`] - fn as_consensus<'a>(self: Arc) -> Arc + 'a> + fn as_consensus<'a>(self: Arc) -> Arc + 'a> where Self: 'a; } -impl, H, B> AsConsensus for T { - fn as_consensus<'a>(self: Arc) -> Arc + 'a> +impl, B: Block> AsConsensus for T { + fn as_consensus<'a>(self: Arc) -> Arc + 'a> where Self: 'a, { diff --git a/crates/consensus/consensus/src/noop.rs b/crates/consensus/consensus/src/noop.rs index ea269c07da..3df809ebe1 100644 --- a/crates/consensus/consensus/src/noop.rs +++ b/crates/consensus/consensus/src/noop.rs @@ -1,6 +1,7 @@ use crate::{Consensus, ConsensusError, FullConsensus, HeaderValidator, PostExecutionInput}; use alloy_primitives::U256; -use reth_primitives::{BlockWithSenders, NodePrimitives, SealedBlock, SealedHeader}; +use reth_primitives::{NodePrimitives, RecoveredBlock, SealedBlock, SealedHeader}; +use reth_primitives_traits::Block; /// A Consensus implementation that does nothing. #[derive(Debug, Copy, Clone, Default)] @@ -29,18 +30,18 @@ impl HeaderValidator for NoopConsensus { } } -impl Consensus for NoopConsensus { +impl Consensus for NoopConsensus { type Error = ConsensusError; fn validate_body_against_header( &self, - _body: &B, - _header: &SealedHeader, + _body: &B::Body, + _header: &SealedHeader, ) -> Result<(), Self::Error> { Ok(()) } - fn validate_block_pre_execution(&self, _block: &SealedBlock) -> Result<(), Self::Error> { + fn validate_block_pre_execution(&self, _block: &SealedBlock) -> Result<(), Self::Error> { Ok(()) } } @@ -48,7 +49,7 @@ impl Consensus for NoopConsensus { impl FullConsensus for NoopConsensus { fn validate_block_post_execution( &self, - _block: &BlockWithSenders, + _block: &RecoveredBlock, _input: PostExecutionInput<'_, N::Receipt>, ) -> Result<(), Self::Error> { Ok(()) diff --git a/crates/consensus/consensus/src/test_utils.rs b/crates/consensus/consensus/src/test_utils.rs index 3f26222c4b..d8a94d270a 100644 --- a/crates/consensus/consensus/src/test_utils.rs +++ b/crates/consensus/consensus/src/test_utils.rs @@ -1,7 +1,8 @@ use crate::{Consensus, ConsensusError, FullConsensus, HeaderValidator, PostExecutionInput}; use alloy_primitives::U256; use core::sync::atomic::{AtomicBool, Ordering}; -use reth_primitives::{BlockWithSenders, NodePrimitives, SealedBlock, SealedHeader}; +use reth_primitives::{NodePrimitives, RecoveredBlock, SealedBlock, SealedHeader}; +use reth_primitives_traits::Block; /// Consensus engine implementation for testing #[derive(Debug)] @@ -49,7 +50,7 @@ impl TestConsensus { impl FullConsensus for TestConsensus { fn validate_block_post_execution( &self, - _block: &BlockWithSenders, + _block: &RecoveredBlock, _input: PostExecutionInput<'_, N::Receipt>, ) -> Result<(), ConsensusError> { if self.fail_validation() { @@ -60,13 +61,13 @@ impl FullConsensus for TestConsensus { } } -impl Consensus for TestConsensus { +impl Consensus for TestConsensus { type Error = ConsensusError; fn validate_body_against_header( &self, - _body: &B, - _header: &SealedHeader, + _body: &B::Body, + _header: &SealedHeader, ) -> Result<(), Self::Error> { if self.fail_body_against_header() { Err(ConsensusError::BaseFeeMissing) @@ -75,7 +76,7 @@ impl Consensus for TestConsensus { } } - fn validate_block_pre_execution(&self, _block: &SealedBlock) -> Result<(), Self::Error> { + fn validate_block_pre_execution(&self, _block: &SealedBlock) -> Result<(), Self::Error> { if self.fail_validation() { Err(ConsensusError::BaseFeeMissing) } else { diff --git a/crates/e2e-test-utils/src/node.rs b/crates/e2e-test-utils/src/node.rs index 29dbc92745..e21b85e78a 100644 --- a/crates/e2e-test-utils/src/node.rs +++ b/crates/e2e-test-utils/src/node.rs @@ -11,7 +11,7 @@ use eyre::Ok; use futures_util::Future; use reth_chainspec::EthereumHardforks; use reth_network_api::test_utils::PeersHandleProvider; -use reth_node_api::{Block, BlockTy, EngineTypes, FullNodeComponents}; +use reth_node_api::{Block, BlockBody, BlockTy, EngineTypes, FullNodeComponents}; use reth_node_builder::{rpc::RethRpcAddOns, FullNode, NodeTypes, NodeTypesWithEngine}; use reth_node_core::primitives::SignedTransaction; use reth_payload_primitives::{BuiltPayload, PayloadBuilderAttributes}; @@ -232,7 +232,7 @@ where // get head block from notifications stream and verify the tx has been pushed to the // pool is actually present in the canonical block let head = self.engine_api.canonical_stream.next().await.unwrap(); - let tx = head.tip().transactions().first(); + let tx = head.tip().body().transactions().first(); assert_eq!(tx.unwrap().tx_hash().as_slice(), tip_tx_hash.as_slice()); loop { diff --git a/crates/engine/invalid-block-hooks/src/witness.rs b/crates/engine/invalid-block-hooks/src/witness.rs index b7a06951fb..b7e3b4f191 100644 --- a/crates/engine/invalid-block-hooks/src/witness.rs +++ b/crates/engine/invalid-block-hooks/src/witness.rs @@ -8,8 +8,8 @@ use reth_engine_primitives::InvalidBlockHook; use reth_evm::{ state_change::post_block_balance_increments, system_calls::SystemCaller, ConfigureEvm, }; -use reth_primitives::{NodePrimitives, SealedBlockWithSenders, SealedHeader}; -use reth_primitives_traits::SignedTransaction; +use reth_primitives::{NodePrimitives, RecoveredBlock, SealedHeader}; +use reth_primitives_traits::{BlockBody, SignedTransaction}; use reth_provider::{BlockExecutionOutput, ChainSpecProvider, StateProviderFactory}; use reth_revm::{ database::StateProviderDatabase, db::states::bundle_state::BundleRetention, DatabaseCommit, @@ -58,7 +58,7 @@ where fn on_invalid_block( &self, parent_header: &SealedHeader, - block: &SealedBlockWithSenders, + block: &RecoveredBlock, output: &BlockExecutionOutput, trie_updates: Option<(&TrieUpdates, B256)>, ) -> eyre::Result<()> @@ -87,7 +87,7 @@ where // Re-execute all of the transactions in the block to load all touched accounts into // the cache DB. - for tx in block.transactions() { + for tx in block.body().transactions() { self.evm_config.fill_tx_env( evm.tx_mut(), tx, @@ -101,10 +101,8 @@ where // use U256::MAX here for difficulty, because fetching it is annoying // NOTE: This is not mut because we are not doing the DAO irregular state change here - let balance_increments = post_block_balance_increments( - self.provider.chain_spec().as_ref(), - &block.clone().unseal().block, - ); + let balance_increments = + post_block_balance_increments(self.provider.chain_spec().as_ref(), block); // increment balances db.increment_balances(balance_increments)?; @@ -302,7 +300,7 @@ where fn on_invalid_block( &self, parent_header: &SealedHeader, - block: &SealedBlockWithSenders, + block: &RecoveredBlock, output: &BlockExecutionOutput, trie_updates: Option<(&TrieUpdates, B256)>, ) { diff --git a/crates/engine/primitives/src/event.rs b/crates/engine/primitives/src/event.rs index fdf5b73f1e..20b41d4140 100644 --- a/crates/engine/primitives/src/event.rs +++ b/crates/engine/primitives/src/event.rs @@ -4,7 +4,7 @@ use crate::ForkchoiceStatus; use alloy_consensus::BlockHeader; use alloy_primitives::B256; use alloy_rpc_types_engine::ForkchoiceState; -use reth_primitives::{EthPrimitives, SealedBlockFor}; +use reth_primitives::{EthPrimitives, SealedBlock}; use reth_primitives_traits::{NodePrimitives, SealedHeader}; use std::{ fmt::{Display, Formatter, Result}, @@ -18,9 +18,9 @@ pub enum BeaconConsensusEngineEvent { /// The fork choice state was updated, and the current fork choice status ForkchoiceUpdated(ForkchoiceState, ForkchoiceStatus), /// A block was added to the fork chain. - ForkBlockAdded(Arc>, Duration), + ForkBlockAdded(Arc>, Duration), /// A block was added to the canonical chain, and the elapsed time validating the block - CanonicalBlockAdded(Arc>, Duration), + CanonicalBlockAdded(Arc>, Duration), /// A canonical chain was committed, and the elapsed time committing the data CanonicalChainCommitted(Box>, Duration), /// The consensus engine is involved in live sync, and has specific progress diff --git a/crates/engine/primitives/src/invalid_block_hook.rs b/crates/engine/primitives/src/invalid_block_hook.rs index cfd127ae6f..c407df2ef4 100644 --- a/crates/engine/primitives/src/invalid_block_hook.rs +++ b/crates/engine/primitives/src/invalid_block_hook.rs @@ -1,6 +1,6 @@ use alloy_primitives::B256; use reth_execution_types::BlockExecutionOutput; -use reth_primitives::{NodePrimitives, SealedBlockWithSenders, SealedHeader}; +use reth_primitives::{NodePrimitives, RecoveredBlock, SealedHeader}; use reth_trie::updates::TrieUpdates; /// An invalid block hook. @@ -9,7 +9,7 @@ pub trait InvalidBlockHook: Send + Sync { fn on_invalid_block( &self, parent_header: &SealedHeader, - block: &SealedBlockWithSenders, + block: &RecoveredBlock, output: &BlockExecutionOutput, trie_updates: Option<(&TrieUpdates, B256)>, ); @@ -20,7 +20,7 @@ where N: NodePrimitives, F: Fn( &SealedHeader, - &SealedBlockWithSenders, + &RecoveredBlock, &BlockExecutionOutput, Option<(&TrieUpdates, B256)>, ) + Send @@ -29,7 +29,7 @@ where fn on_invalid_block( &self, parent_header: &SealedHeader, - block: &SealedBlockWithSenders, + block: &RecoveredBlock, output: &BlockExecutionOutput, trie_updates: Option<(&TrieUpdates, B256)>, ) { diff --git a/crates/engine/primitives/src/lib.rs b/crates/engine/primitives/src/lib.rs index e0b465e985..1def1a67e2 100644 --- a/crates/engine/primitives/src/lib.rs +++ b/crates/engine/primitives/src/lib.rs @@ -33,7 +33,7 @@ pub use reth_payload_primitives::{ PayloadTypes, }; use reth_payload_primitives::{InvalidPayloadAttributesError, PayloadAttributes}; -use reth_primitives::{NodePrimitives, SealedBlockFor}; +use reth_primitives::{NodePrimitives, SealedBlock}; use reth_primitives_traits::Block; use serde::{de::DeserializeOwned, ser::Serialize}; @@ -86,7 +86,7 @@ pub trait EngineTypes: /// Converts a [`BuiltPayload`] into an [`ExecutionPayload`] and [`ExecutionPayloadSidecar`]. fn block_to_payload( - block: SealedBlockFor< + block: SealedBlock< <::Primitives as NodePrimitives>::Block, >, ) -> (ExecutionPayload, ExecutionPayloadSidecar); @@ -109,7 +109,7 @@ pub trait PayloadValidator: fmt::Debug + Send + Sync + Unpin + 'static { &self, payload: ExecutionPayload, sidecar: ExecutionPayloadSidecar, - ) -> Result, PayloadError>; + ) -> Result, PayloadError>; } /// Type that validates the payloads processed by the engine. diff --git a/crates/engine/service/src/service.rs b/crates/engine/service/src/service.rs index b099e56ae0..81c5ca5ad7 100644 --- a/crates/engine/service/src/service.rs +++ b/crates/engine/service/src/service.rs @@ -16,7 +16,7 @@ pub use reth_engine_tree::{ }; use reth_evm::execute::BlockExecutorProvider; use reth_network_p2p::BlockClient; -use reth_node_types::{BlockTy, BodyTy, HeaderTy, NodeTypes, NodeTypesWithEngine}; +use reth_node_types::{BlockTy, NodeTypes, NodeTypesWithEngine}; use reth_payload_builder::PayloadBuilderHandle; use reth_primitives::EthPrimitives; use reth_provider::{ @@ -52,10 +52,13 @@ type EngineServiceType = ChainOrchestrator< /// The type that drives the chain forward and communicates progress. #[pin_project] #[allow(missing_debug_implementations)] +// TODO(mattsse): remove hidde once fixed : +// otherwise rustdoc fails to resolve the alias +#[doc(hidden)] pub struct EngineService where N: EngineNodeTypes, - Client: BlockClient
, Body = BodyTy> + 'static, + Client: BlockClient> + 'static, E: BlockExecutorProvider + 'static, { orchestrator: EngineServiceType, @@ -65,7 +68,7 @@ where impl EngineService where N: EngineNodeTypes, - Client: BlockClient
, Body = BodyTy> + 'static, + Client: BlockClient> + 'static, E: BlockExecutorProvider + 'static, { /// Constructor for `EngineService`. @@ -133,7 +136,7 @@ where impl Stream for EngineService where N: EngineNodeTypes, - Client: BlockClient
, Body = BodyTy> + 'static, + Client: BlockClient> + 'static, E: BlockExecutorProvider + 'static, { type Item = ChainEvent>; diff --git a/crates/engine/tree/src/backfill.rs b/crates/engine/tree/src/backfill.rs index a0eb8dd957..370ca7e52e 100644 --- a/crates/engine/tree/src/backfill.rs +++ b/crates/engine/tree/src/backfill.rs @@ -274,7 +274,7 @@ mod tests { gas_limit: ETHEREUM_BLOCK_GAS_LIMIT, ..Default::default() }; - let header = SealedHeader::seal(header); + let header = SealedHeader::seal_slow(header); insert_headers_into_client(&client, header, 0..total_blocks); let tip = client.highest_block().expect("there should be blocks here").hash(); diff --git a/crates/engine/tree/src/download.rs b/crates/engine/tree/src/download.rs index 1359843c0a..f365b87018 100644 --- a/crates/engine/tree/src/download.rs +++ b/crates/engine/tree/src/download.rs @@ -9,7 +9,7 @@ use reth_network_p2p::{ full_block::{FetchFullBlockFuture, FetchFullBlockRangeFuture, FullBlockClient}, BlockClient, }; -use reth_primitives::{SealedBlockFor, SealedBlockWithSenders}; +use reth_primitives::{RecoveredBlock, SealedBlock}; use reth_primitives_traits::Block; use std::{ cmp::{Ordering, Reverse}, @@ -45,7 +45,7 @@ pub enum DownloadAction { #[derive(Debug)] pub enum DownloadOutcome { /// Downloaded blocks. - Blocks(Vec>), + Blocks(Vec>), /// New download started. NewDownloadStarted { /// How many blocks are pending in this download. @@ -69,7 +69,7 @@ where inflight_block_range_requests: Vec>, /// Buffered blocks from downloads - this is a min-heap of blocks, using the block number for /// ordering. This means the blocks will be popped from the heap with ascending block numbers. - set_buffered_blocks: BinaryHeap>>, + set_buffered_blocks: BinaryHeap>>, /// Engine download metrics. metrics: BlockDownloaderMetrics, /// Pending events to be emitted. @@ -78,14 +78,11 @@ where impl BasicBlockDownloader where - Client: BlockClient
+ 'static, + Client: BlockClient + 'static, B: Block, { /// Create a new instance - pub fn new( - client: Client, - consensus: Arc>, - ) -> Self { + pub fn new(client: Client, consensus: Arc>) -> Self { Self { full_block_client: FullBlockClient::new(client, consensus), inflight_full_block_requests: Vec::new(), @@ -192,7 +189,7 @@ where impl BlockDownloader for BasicBlockDownloader where - Client: BlockClient
, + Client: BlockClient, B: Block, { type Block = B; @@ -233,9 +230,7 @@ where .into_iter() .map(|b| { let senders = b.senders().unwrap_or_default(); - OrderedSealedBlockWithSenders(SealedBlockWithSenders::new_unchecked( - b, senders, - )) + OrderedRecoveredBlock(RecoveredBlock::new_sealed(b, senders)) }) .map(Reverse), ); @@ -252,7 +247,7 @@ where } // drain all unique element of the block buffer if there are any - let mut downloaded_blocks: Vec> = + let mut downloaded_blocks: Vec> = Vec::with_capacity(self.set_buffered_blocks.len()); while let Some(block) = self.set_buffered_blocks.pop() { // peek ahead and pop duplicates @@ -269,32 +264,32 @@ where } } -/// A wrapper type around [`SealedBlockWithSenders`] that implements the [Ord] +/// A wrapper type around [`RecoveredBlock`] that implements the [Ord] /// trait by block number. #[derive(Debug, Clone, PartialEq, Eq)] -struct OrderedSealedBlockWithSenders(SealedBlockWithSenders); +struct OrderedRecoveredBlock(RecoveredBlock); -impl PartialOrd for OrderedSealedBlockWithSenders { +impl PartialOrd for OrderedRecoveredBlock { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } -impl Ord for OrderedSealedBlockWithSenders { +impl Ord for OrderedRecoveredBlock { fn cmp(&self, other: &Self) -> Ordering { self.0.number().cmp(&other.0.number()) } } -impl From> for OrderedSealedBlockWithSenders { - fn from(block: SealedBlockFor) -> Self { +impl From> for OrderedRecoveredBlock { + fn from(block: SealedBlock) -> Self { let senders = block.senders().unwrap_or_default(); - Self(SealedBlockWithSenders::new_unchecked(block, senders)) + Self(RecoveredBlock::new_sealed(block, senders)) } } -impl From> for SealedBlockWithSenders { - fn from(value: OrderedSealedBlockWithSenders) -> Self { +impl From> for RecoveredBlock { + fn from(value: OrderedRecoveredBlock) -> Self { value.0 } } @@ -348,7 +343,7 @@ mod tests { gas_limit: ETHEREUM_BLOCK_GAS_LIMIT, ..Default::default() }; - let header = SealedHeader::seal(header); + let header = SealedHeader::seal_slow(header); insert_headers_into_client(&client, header, 0..total_blocks); let consensus = Arc::new(EthBeaconConsensus::new(chain_spec)); diff --git a/crates/engine/tree/src/engine.rs b/crates/engine/tree/src/engine.rs index fa92cba28f..238846d4f0 100644 --- a/crates/engine/tree/src/engine.rs +++ b/crates/engine/tree/src/engine.rs @@ -9,7 +9,7 @@ use alloy_primitives::B256; use futures::{Stream, StreamExt}; use reth_chain_state::ExecutedBlock; use reth_engine_primitives::{BeaconConsensusEngineEvent, BeaconEngineMessage, EngineTypes}; -use reth_primitives::{NodePrimitives, SealedBlockWithSenders}; +use reth_primitives::{NodePrimitives, RecoveredBlock}; use reth_primitives_traits::Block; use std::{ collections::HashSet, @@ -306,7 +306,7 @@ pub enum FromEngine { /// Request from the engine. Request(Req), /// Downloaded blocks from the network. - DownloadedBlocks(Vec>), + DownloadedBlocks(Vec>), } impl Display for FromEngine { diff --git a/crates/engine/tree/src/test_utils.rs b/crates/engine/tree/src/test_utils.rs index c1b534ebf5..de6485ce9c 100644 --- a/crates/engine/tree/src/test_utils.rs +++ b/crates/engine/tree/src/test_utils.rs @@ -76,7 +76,7 @@ pub fn insert_headers_into_client( header.parent_hash = hash; header.number += 1; header.timestamp += 1; - sealed_header = SealedHeader::seal(header); + sealed_header = SealedHeader::seal_slow(header); client.insert(sealed_header.clone(), body.clone()); } } diff --git a/crates/engine/tree/src/tree/block_buffer.rs b/crates/engine/tree/src/tree/block_buffer.rs index 675e1b5c32..0d022f32de 100644 --- a/crates/engine/tree/src/tree/block_buffer.rs +++ b/crates/engine/tree/src/tree/block_buffer.rs @@ -2,7 +2,7 @@ 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::RecoveredBlock; use reth_primitives_traits::Block; use std::collections::{BTreeMap, HashMap, HashSet}; @@ -20,7 +20,7 @@ use std::collections::{BTreeMap, HashMap, HashSet}; #[derive(Debug)] pub(super) struct BlockBuffer { /// All blocks in the buffer stored by their block hash. - pub(crate) blocks: HashMap>, + 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. @@ -50,12 +50,12 @@ impl BlockBuffer { } /// Return reference to the requested block. - pub(super) fn block(&self, hash: &BlockHash) -> Option<&SealedBlockWithSenders> { + pub(super) fn block(&self, hash: &BlockHash) -> Option<&RecoveredBlock> { 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> { + pub(super) fn lowest_ancestor(&self, hash: &BlockHash) -> Option<&RecoveredBlock> { let mut current_block = self.blocks.get(hash)?; while let Some(parent) = self.blocks.get(¤t_block.parent_hash()) { current_block = parent; @@ -64,7 +64,7 @@ impl BlockBuffer { } /// Insert a correct block inside the buffer. - pub(super) fn insert_block(&mut self, block: SealedBlockWithSenders) { + pub(super) fn insert_block(&mut self, block: RecoveredBlock) { let hash = block.hash(); self.parent_to_child.entry(block.parent_hash()).or_default().insert(hash); @@ -90,7 +90,7 @@ impl BlockBuffer { pub(super) fn remove_block_with_children( &mut self, parent_hash: &BlockHash, - ) -> Vec> { + ) -> Vec> { let removed = self .remove_block(parent_hash) .into_iter() @@ -149,7 +149,7 @@ impl BlockBuffer { /// 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> { + 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); @@ -158,7 +158,7 @@ impl BlockBuffer { } /// Remove all children and their descendants for the given blocks and return them. - fn remove_children(&mut self, parent_hashes: Vec) -> Vec> { + 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; @@ -184,15 +184,19 @@ mod tests { use super::*; use alloy_eips::BlockNumHash; use alloy_primitives::BlockHash; - use reth_primitives::SealedBlockWithSenders; + use reth_primitives::RecoveredBlock; 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 { + fn create_block( + rng: &mut R, + number: u64, + parent: BlockHash, + ) -> RecoveredBlock { let block = random_block(rng, number, BlockParams { parent: Some(parent), ..Default::default() }); - block.seal_with_senders().unwrap() + block.try_recover().unwrap() } /// Assert that all buffer collections have the same data length. @@ -210,7 +214,10 @@ mod tests { } /// Assert that the block was removed from all buffer collections. - fn assert_block_removal(buffer: &BlockBuffer, block: &SealedBlockWithSenders) { + fn assert_block_removal( + buffer: &BlockBuffer, + block: &RecoveredBlock, + ) { assert!(!buffer.blocks.contains_key(&block.hash())); assert!(buffer .parent_to_child diff --git a/crates/engine/tree/src/tree/error.rs b/crates/engine/tree/src/tree/error.rs index 54c274abbf..f681cd2f0f 100644 --- a/crates/engine/tree/src/tree/error.rs +++ b/crates/engine/tree/src/tree/error.rs @@ -4,7 +4,7 @@ use alloy_consensus::BlockHeader; use reth_consensus::ConsensusError; use reth_errors::{BlockExecutionError, BlockValidationError, ProviderError}; use reth_evm::execute::InternalBlockExecutionError; -use reth_primitives::SealedBlockFor; +use reth_primitives::SealedBlock; use reth_primitives_traits::{Block, BlockBody}; use tokio::sync::oneshot::error::TryRecvError; @@ -27,7 +27,7 @@ pub enum AdvancePersistenceError { .block.parent_hash(), .kind)] struct InsertBlockErrorData { - block: SealedBlockFor, + block: SealedBlock, #[source] kind: InsertBlockErrorKind, } @@ -45,11 +45,11 @@ impl std::fmt::Debug for InsertBlockErrorData { } impl InsertBlockErrorData { - const fn new(block: SealedBlockFor, kind: InsertBlockErrorKind) -> Self { + const fn new(block: SealedBlock, kind: InsertBlockErrorKind) -> Self { Self { block, kind } } - fn boxed(block: SealedBlockFor, kind: InsertBlockErrorKind) -> Box { + fn boxed(block: SealedBlock, kind: InsertBlockErrorKind) -> Box { Box::new(Self::new(block, kind)) } } @@ -65,23 +65,23 @@ pub struct InsertBlockError { impl InsertBlockError { /// Create a new `InsertInvalidBlockErrorTwo` - pub fn new(block: SealedBlockFor, kind: InsertBlockErrorKind) -> Self { + pub fn new(block: SealedBlock, kind: InsertBlockErrorKind) -> Self { Self { inner: InsertBlockErrorData::boxed(block, kind) } } /// Create a new `InsertInvalidBlockError` from a consensus error - pub fn consensus_error(error: ConsensusError, block: SealedBlockFor) -> Self { + pub fn consensus_error(error: ConsensusError, block: SealedBlock) -> Self { Self::new(block, InsertBlockErrorKind::Consensus(error)) } /// Create a new `InsertInvalidBlockError` from a consensus error - pub fn sender_recovery_error(block: SealedBlockFor) -> Self { + pub fn sender_recovery_error(block: SealedBlock) -> Self { Self::new(block, InsertBlockErrorKind::SenderRecovery) } /// Consumes the error and returns the block that resulted in the error #[inline] - pub fn into_block(self) -> SealedBlockFor { + pub fn into_block(self) -> SealedBlock { self.inner.block } @@ -93,13 +93,13 @@ impl InsertBlockError { /// Returns the block that resulted in the error #[inline] - pub const fn block(&self) -> &SealedBlockFor { + pub const fn block(&self) -> &SealedBlock { &self.inner.block } /// Consumes the type and returns the block and error kind. #[inline] - pub fn split(self) -> (SealedBlockFor, InsertBlockErrorKind) { + pub fn split(self) -> (SealedBlock, InsertBlockErrorKind) { let inner = *self.inner; (inner.block, inner.kind) } diff --git a/crates/engine/tree/src/tree/invalid_block_hook.rs b/crates/engine/tree/src/tree/invalid_block_hook.rs index 7c7b0631dd..339ef9c7dd 100644 --- a/crates/engine/tree/src/tree/invalid_block_hook.rs +++ b/crates/engine/tree/src/tree/invalid_block_hook.rs @@ -1,6 +1,6 @@ use alloy_primitives::B256; use reth_engine_primitives::InvalidBlockHook; -use reth_primitives::{NodePrimitives, SealedBlockWithSenders, SealedHeader}; +use reth_primitives::{NodePrimitives, RecoveredBlock, SealedHeader}; use reth_provider::BlockExecutionOutput; use reth_trie::updates::TrieUpdates; @@ -13,7 +13,7 @@ impl InvalidBlockHook for NoopInvalidBlockHook { fn on_invalid_block( &self, _parent_header: &SealedHeader, - _block: &SealedBlockWithSenders, + _block: &RecoveredBlock, _output: &BlockExecutionOutput, _trie_updates: Option<(&TrieUpdates, B256)>, ) { @@ -33,7 +33,7 @@ impl InvalidBlockHook for InvalidBlockHooks { fn on_invalid_block( &self, parent_header: &SealedHeader, - block: &SealedBlockWithSenders, + block: &RecoveredBlock, output: &BlockExecutionOutput, trie_updates: Option<(&TrieUpdates, B256)>, ) { diff --git a/crates/engine/tree/src/tree/invalid_headers.rs b/crates/engine/tree/src/tree/invalid_headers.rs index 8472d44a32..de47c17312 100644 --- a/crates/engine/tree/src/tree/invalid_headers.rs +++ b/crates/engine/tree/src/tree/invalid_headers.rs @@ -111,7 +111,7 @@ mod tests { fn test_hit_eviction() { let mut cache = InvalidHeaderCache::new(10); let header = Header::default(); - let header = SealedHeader::seal(header); + let header = SealedHeader::seal_slow(header); cache.insert(header.block_with_parent()); assert_eq!(cache.headers.get(&header.hash()).unwrap().hit_count, 0); diff --git a/crates/engine/tree/src/tree/mod.rs b/crates/engine/tree/src/tree/mod.rs index 3fff0562a8..cff2dfdebb 100644 --- a/crates/engine/tree/src/tree/mod.rs +++ b/crates/engine/tree/src/tree/mod.rs @@ -36,8 +36,7 @@ use reth_payload_builder::PayloadBuilderHandle; use reth_payload_builder_primitives::PayloadBuilder; use reth_payload_primitives::PayloadBuilderAttributes; use reth_primitives::{ - EthPrimitives, GotExpected, NodePrimitives, SealedBlockFor, SealedBlockWithSenders, - SealedHeader, + EthPrimitives, GotExpected, NodePrimitives, RecoveredBlock, SealedBlock, SealedHeader, }; use reth_primitives_traits::Block; use reth_provider::{ @@ -147,7 +146,7 @@ impl TreeState { } /// Returns the block by hash. - fn block_by_hash(&self, hash: B256) -> Option>> { + fn block_by_hash(&self, hash: B256) -> Option>> { self.blocks_by_hash.get(&hash).map(|b| b.block.clone()) } @@ -737,7 +736,7 @@ where /// block request processing isn't blocked for a long time. fn on_downloaded( &mut self, - mut blocks: Vec>, + mut blocks: Vec>, ) -> Result, InsertBlockFatalError> { if blocks.is_empty() { // nothing to execute @@ -1603,11 +1602,11 @@ where .provider .sealed_block_with_senders(hash.into(), TransactionVariant::WithHash)? .ok_or_else(|| ProviderError::HeaderNotFound(hash.into()))? - .split(); + .split_sealed(); let execution_output = self .provider - .get_state(block.number())? - .ok_or_else(|| ProviderError::StateForNumberNotFound(block.number()))?; + .get_state(block.header().number())? + .ok_or_else(|| ProviderError::StateForNumberNotFound(block.header().number()))?; let hashed_state = self.provider.hashed_post_state(execution_output.state()); Ok(Some(ExecutedBlock { @@ -1650,7 +1649,7 @@ where .tree_state .block_by_hash(hash) // TODO: clone for compatibility. should we return an Arc here? - .map(|block| block.as_ref().clone().unseal()); + .map(|block| block.as_ref().clone().into_block()); } Ok(block) } @@ -1798,11 +1797,10 @@ where /// Validate if block is correct and satisfies all the consensus rules that concern the header /// and block body itself. - fn validate_block( - &self, - block: &SealedBlockWithSenders, - ) -> Result<(), ConsensusError> { - if let Err(e) = self.consensus.validate_header_with_total_difficulty(block, U256::MAX) { + fn validate_block(&self, block: &RecoveredBlock) -> Result<(), ConsensusError> { + if let Err(e) = + self.consensus.validate_header_with_total_difficulty(block.header(), U256::MAX) + { error!( target: "engine::tree", ?block, @@ -1817,7 +1815,7 @@ where return Err(e) } - if let Err(e) = self.consensus.validate_block_pre_execution(block) { + if let Err(e) = self.consensus.validate_block_pre_execution(block.sealed_block()) { error!(target: "engine::tree", ?block, "Failed to validate block {}: {e}", block.hash()); return Err(e) } @@ -1870,21 +1868,21 @@ where /// Returns an error if sender recovery failed or inserting into the buffer failed. fn buffer_block_without_senders( &mut self, - block: SealedBlockFor, + block: SealedBlock, ) -> Result<(), InsertBlockError> { - match block.try_seal_with_senders() { + match block.try_recover() { Ok(block) => self.buffer_block(block), - Err(block) => Err(InsertBlockError::sender_recovery_error(block)), + Err(err) => Err(InsertBlockError::sender_recovery_error(err.into_inner())), } } /// Pre-validates the block and inserts it into the buffer. fn buffer_block( &mut self, - block: SealedBlockWithSenders, + block: RecoveredBlock, ) -> Result<(), InsertBlockError> { if let Err(err) = self.validate_block(&block) { - return Err(InsertBlockError::consensus_error(err, block.block)) + return Err(InsertBlockError::consensus_error(err, block.into_sealed_block())) } self.state.buffer.insert_block(block); Ok(()) @@ -2139,7 +2137,7 @@ where #[instrument(level = "trace", skip_all, fields(block_hash = %block.hash(), block_num = %block.number(),), target = "engine::tree")] fn on_downloaded_block( &mut self, - block: SealedBlockWithSenders, + block: RecoveredBlock, ) -> Result, InsertBlockFatalError> { let block_num_hash = block.num_hash(); let lowest_buffered_ancestor = self.lowest_buffered_ancestor_or(block_num_hash.hash); @@ -2194,25 +2192,25 @@ where fn insert_block_without_senders( &mut self, - block: SealedBlockFor, + block: SealedBlock, ) -> Result> { - match block.try_seal_with_senders() { + match block.try_recover() { Ok(block) => self.insert_block(block), - Err(block) => Err(InsertBlockError::sender_recovery_error(block)), + Err(err) => Err(InsertBlockError::sender_recovery_error(err.into_inner())), } } fn insert_block( &mut self, - block: SealedBlockWithSenders, + block: RecoveredBlock, ) -> Result> { self.insert_block_inner(block.clone()) - .map_err(|kind| InsertBlockError::new(block.block, kind)) + .map_err(|kind| InsertBlockError::new(block.into_sealed_block(), kind)) } fn insert_block_inner( &mut self, - block: SealedBlockWithSenders, + block: RecoveredBlock, ) -> Result { debug!(target: "engine::tree", block=?block.num_hash(), parent = ?block.parent_hash(), state_root = ?block.state_root(), "Inserting new block into tree"); @@ -2270,8 +2268,7 @@ where let block_number = block.number(); let block_hash = block.hash(); - let sealed_block = Arc::new(block.block.clone()); - let block = block.unseal(); + let sealed_block = Arc::new(block.clone_sealed_block()); let persistence_not_in_progress = !self.persistence_state.in_progress(); @@ -2341,12 +2338,7 @@ where 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, - ); + self.invalid_block_hook.on_invalid_block(&parent_block, &block, &output, None); return Err(err.into()) } @@ -2458,7 +2450,7 @@ where // call post-block hook self.invalid_block_hook.on_invalid_block( &parent_block, - &block.clone().seal_slow(), + &block, &output, Some((&trie_output, state_root)), ); @@ -2841,7 +2833,8 @@ mod tests { use reth_ethereum_consensus::EthBeaconConsensus; use reth_ethereum_engine_primitives::{EthEngineTypes, EthereumEngineValidator}; use reth_evm::test_utils::MockExecutorProvider; - use reth_primitives::{Block, BlockExt, EthPrimitives}; + use reth_primitives::{Block, EthPrimitives}; + use reth_primitives_traits::Block as _; use reth_provider::test_utils::MockEthProvider; use reth_rpc_types_compat::engine::{block_to_payload_v1, payload::block_to_payload_v3}; use reth_trie::{updates::TrieUpdates, HashedPostState}; @@ -2951,7 +2944,7 @@ mod tests { let (from_tree_tx, from_tree_rx) = unbounded_channel(); let header = chain_spec.genesis_header().clone(); - let header = SealedHeader::seal(header); + let header = SealedHeader::seal_slow(header); let engine_api_tree_state = EngineApiTreeState::new(10, 10, header.num_hash()); let canonical_in_memory_state = CanonicalInMemoryState::with_head(header, None, None); @@ -3023,12 +3016,7 @@ mod tests { self.persist_blocks( blocks .into_iter() - .map(|b| { - SealedBlockWithSenders::new_unchecked( - (*b.block).clone(), - b.senders().clone(), - ) - }) + .map(|b| RecoveredBlock::new_sealed(b.block().clone(), b.senders().clone())) .collect(), ); @@ -3049,7 +3037,7 @@ mod tests { fn insert_block( &mut self, - block: SealedBlockWithSenders, + block: RecoveredBlock, ) -> Result> { let execution_outcome = self.block_builder.get_execution_outcome(block.clone()); self.extend_execution_outcome([execution_outcome]); @@ -3114,8 +3102,8 @@ mod tests { } } - async fn send_new_payload(&mut self, block: SealedBlockWithSenders) { - let payload = block_to_payload_v3(block.block.clone()); + async fn send_new_payload(&mut self, block: RecoveredBlock) { + let payload = block_to_payload_v3(block.clone_sealed_block()); self.tree .on_new_payload( payload.into(), @@ -3129,7 +3117,7 @@ mod tests { async fn insert_chain( &mut self, - chain: impl IntoIterator + Clone, + chain: impl IntoIterator> + Clone, ) { for block in chain.clone() { self.insert_block(block.clone()).unwrap(); @@ -3151,16 +3139,16 @@ mod tests { async fn check_fork_chain_insertion( &mut self, - chain: impl IntoIterator + Clone, + chain: impl IntoIterator> + Clone, ) { for block in chain { - self.check_fork_block_added(block.block.hash()).await; + self.check_fork_block_added(block.hash()).await; } } async fn check_canon_chain_insertion( &mut self, - chain: impl IntoIterator + Clone, + chain: impl IntoIterator> + Clone, ) { for block in chain.clone() { self.check_canon_block_added(block.hash()).await; @@ -3186,33 +3174,35 @@ mod tests { block, _, )) => { - assert!(block.hash() == expected_hash); + assert_eq!(block.hash(), expected_hash); } _ => panic!("Unexpected event: {:#?}", event), } } - fn persist_blocks(&self, blocks: Vec) { + fn persist_blocks(&self, blocks: Vec>) { let mut block_data: Vec<(B256, Block)> = Vec::with_capacity(blocks.len()); let mut headers_data: Vec<(B256, Header)> = Vec::with_capacity(blocks.len()); for block in &blocks { - let unsealed_block = block.clone().unseal(); - block_data.push((block.hash(), unsealed_block.clone().block)); - headers_data.push((block.hash(), unsealed_block.header.clone())); + block_data.push((block.hash(), block.clone_block())); + headers_data.push((block.hash(), block.header().clone())); } self.provider.extend_blocks(block_data); self.provider.extend_headers(headers_data); } - fn setup_range_insertion_for_valid_chain(&mut self, chain: Vec) { + fn setup_range_insertion_for_valid_chain( + &mut self, + chain: Vec>, + ) { self.setup_range_insertion_for_chain(chain, None) } fn setup_range_insertion_for_invalid_chain( &mut self, - chain: Vec, + chain: Vec>, index: usize, ) { self.setup_range_insertion_for_chain(chain, Some(index)) @@ -3220,7 +3210,7 @@ mod tests { fn setup_range_insertion_for_chain( &mut self, - chain: Vec, + chain: Vec>, invalid_index: Option, ) { // setting up execution outcomes for the chain, the blocks will be @@ -3392,7 +3382,7 @@ mod tests { // ensure block is buffered let buffered = test_harness.tree.state.buffer.block(&hash).unwrap(); - assert_eq!(buffered.block, sealed); + assert_eq!(buffered.clone_sealed_block(), sealed); } #[test] @@ -3732,7 +3722,7 @@ mod tests { for block in &chain_a { test_harness.tree.state.tree_state.insert_executed(ExecutedBlock { - block: Arc::new(block.block.clone()), + block: Arc::new(block.clone_sealed_block()), senders: Arc::new(block.senders().to_vec()), execution_output: Arc::new(ExecutionOutcome::default()), hashed_state: Arc::new(HashedPostState::default()), @@ -3743,7 +3733,7 @@ mod tests { for block in &chain_b { test_harness.tree.state.tree_state.insert_executed(ExecutedBlock { - block: Arc::new(block.block.clone()), + block: Arc::new(block.clone_sealed_block()), senders: Arc::new(block.senders().to_vec()), execution_output: Arc::new(ExecutionOutcome::default()), hashed_state: Arc::new(HashedPostState::default()), @@ -3755,19 +3745,19 @@ mod tests { let mut expected_new = Vec::new(); for block in &chain_b { // reorg to chain from block b - let result = test_harness.tree.on_new_head(block.block.hash()).unwrap(); + let result = test_harness.tree.on_new_head(block.hash()).unwrap(); assert_matches!(result, Some(NewCanonicalChain::Reorg { .. })); expected_new.push(block); if let Some(NewCanonicalChain::Reorg { new, old }) = result { assert_eq!(new.len(), expected_new.len()); for (index, block) in expected_new.iter().enumerate() { - assert_eq!(new[index].block.hash(), block.block.hash()); + assert_eq!(new[index].block.hash(), block.hash()); } assert_eq!(old.len(), chain_a.len()); for (index, block) in chain_a.iter().enumerate() { - assert_eq!(old[index].block.hash(), block.block.hash()); + assert_eq!(old[index].block.hash(), block.hash()); } } @@ -3936,9 +3926,7 @@ mod tests { let backfill_tip_block = main_chain[(backfill_finished_block_number - 1) as usize].clone(); // add block to mock provider to enable persistence clean up. - test_harness - .provider - .add_block(backfill_tip_block.hash(), backfill_tip_block.block.unseal()); + test_harness.provider.add_block(backfill_tip_block.hash(), backfill_tip_block.into_block()); test_harness.tree.on_engine_message(FromEngine::Event(backfill_finished)).unwrap(); let event = test_harness.from_tree_rx.recv().await.unwrap(); @@ -4154,7 +4142,7 @@ mod tests { // extend base chain let extension_chain = test_harness.block_builder.create_fork(old_head, 5); - let fork_block = extension_chain.last().unwrap().block.clone(); + let fork_block = extension_chain.last().unwrap().clone_sealed_block(); test_harness.setup_range_insertion_for_valid_chain(extension_chain.clone()); test_harness.insert_chain(extension_chain).await; @@ -4252,7 +4240,7 @@ mod tests { // extend base chain let extension_chain = test_harness.block_builder.create_fork(old_head, 5); - let fork_block = extension_chain.last().unwrap().block.clone(); + let fork_block = extension_chain.last().unwrap().clone_sealed_block(); test_harness.insert_chain(extension_chain).await; // fcu to old_head @@ -4322,7 +4310,7 @@ mod tests { test_harness.send_new_payload(block.clone()).await; if index < side_chain.len() - invalid_index - 1 { - test_harness.send_fcu(block.block.hash(), ForkchoiceStatus::Valid).await; + test_harness.send_fcu(block.hash(), ForkchoiceStatus::Valid).await; } } diff --git a/crates/engine/util/Cargo.toml b/crates/engine/util/Cargo.toml index 54f9321f23..1d1a524e2b 100644 --- a/crates/engine/util/Cargo.toml +++ b/crates/engine/util/Cargo.toml @@ -13,6 +13,7 @@ workspace = true [dependencies] # reth reth-primitives.workspace = true +reth-primitives-traits.workspace = true reth-errors.workspace = true reth-consensus-common.workspace = true reth-fs-util.workspace = true diff --git a/crates/engine/util/src/reorg.rs b/crates/engine/util/src/reorg.rs index fc38f15be2..2136c92a01 100644 --- a/crates/engine/util/src/reorg.rs +++ b/crates/engine/util/src/reorg.rs @@ -19,9 +19,9 @@ use reth_evm::{ }; use reth_payload_validator::ExecutionPayloadValidator; use reth_primitives::{ - proofs, transaction::SignedTransactionIntoRecoveredExt, Block, BlockBody, BlockExt, Receipt, - Receipts, + proofs, transaction::SignedTransactionIntoRecoveredExt, Block, BlockBody, Receipt, Receipts, }; +use reth_primitives_traits::block::Block as _; use reth_provider::{BlockReader, ExecutionOutcome, ProviderError, StateProviderFactory}; use reth_revm::{ database::StateProviderDatabase, diff --git a/crates/ethereum/consensus/src/lib.rs b/crates/ethereum/consensus/src/lib.rs index b81ee1d5c4..4d2daaaaea 100644 --- a/crates/ethereum/consensus/src/lib.rs +++ b/crates/ethereum/consensus/src/lib.rs @@ -8,7 +8,7 @@ #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] -use alloy_consensus::{BlockHeader, EMPTY_OMMER_ROOT_HASH}; +use alloy_consensus::EMPTY_OMMER_ROOT_HASH; use alloy_eips::{eip7840::BlobParams, merge::ALLOWED_FUTURE_BLOCK_TIME_SECONDS}; use alloy_primitives::U256; use reth_chainspec::{EthChainSpec, EthereumHardforks}; @@ -21,10 +21,10 @@ use reth_consensus_common::validation::{ validate_against_parent_timestamp, validate_block_pre_execution, validate_body_against_header, validate_header_base_fee, validate_header_extra_data, validate_header_gas, }; -use reth_primitives::{BlockWithSenders, NodePrimitives, Receipt, SealedBlock, SealedHeader}; +use reth_primitives::{NodePrimitives, Receipt, RecoveredBlock, SealedBlock, SealedHeader}; use reth_primitives_traits::{ constants::{GAS_LIMIT_BOUND_DIVISOR, MINIMUM_GAS_LIMIT}, - BlockBody, + Block, BlockHeader, }; use std::{fmt::Debug, sync::Arc, time::SystemTime}; @@ -103,30 +103,29 @@ where { fn validate_block_post_execution( &self, - block: &BlockWithSenders, + block: &RecoveredBlock, input: PostExecutionInput<'_>, ) -> Result<(), ConsensusError> { validate_block_post_execution(block, &self.chain_spec, input.receipts, input.requests) } } -impl Consensus +impl Consensus for EthBeaconConsensus where - H: BlockHeader, - B: BlockBody, + B: Block, { type Error = ConsensusError; fn validate_body_against_header( &self, - body: &B, - header: &SealedHeader, + body: &B::Body, + header: &SealedHeader, ) -> Result<(), Self::Error> { validate_body_against_header(body, header.header()) } - fn validate_block_pre_execution(&self, block: &SealedBlock) -> Result<(), Self::Error> { + fn validate_block_pre_execution(&self, block: &SealedBlock) -> Result<(), Self::Error> { validate_block_pre_execution(block, &self.chain_spec) } } @@ -361,7 +360,7 @@ mod tests { }; assert_eq!( - EthBeaconConsensus::new(chain_spec).validate_header(&SealedHeader::seal(header,)), + EthBeaconConsensus::new(chain_spec).validate_header(&SealedHeader::seal_slow(header,)), Ok(()) ); } diff --git a/crates/ethereum/consensus/src/validation.rs b/crates/ethereum/consensus/src/validation.rs index b9b38b6d51..8d6d385492 100644 --- a/crates/ethereum/consensus/src/validation.rs +++ b/crates/ethereum/consensus/src/validation.rs @@ -3,7 +3,7 @@ use alloy_eips::eip7685::Requests; use alloy_primitives::{Bloom, B256}; use reth_chainspec::EthereumHardforks; use reth_consensus::ConsensusError; -use reth_primitives::{gas_spent_by_transactions, BlockWithSenders, GotExpected, Receipt}; +use reth_primitives::{gas_spent_by_transactions, GotExpected, Receipt, RecoveredBlock}; use reth_primitives_traits::Block; /// Validate a block with regard to execution results: @@ -11,7 +11,7 @@ use reth_primitives_traits::Block; /// - Compares the receipts root in the block header to the block body /// - Compares the gas used in the block header to the actual gas usage after execution pub fn validate_block_post_execution( - block: &BlockWithSenders, + block: &RecoveredBlock, chain_spec: &ChainSpec, receipts: &[Receipt], requests: &Requests, diff --git a/crates/ethereum/engine-primitives/src/lib.rs b/crates/ethereum/engine-primitives/src/lib.rs index 350780d0bd..f4723bf39f 100644 --- a/crates/ethereum/engine-primitives/src/lib.rs +++ b/crates/ethereum/engine-primitives/src/lib.rs @@ -22,7 +22,7 @@ use reth_payload_primitives::{ PayloadOrAttributes, PayloadTypes, }; use reth_payload_validator::ExecutionPayloadValidator; -use reth_primitives::{Block, NodePrimitives, SealedBlock, SealedBlockFor}; +use reth_primitives::{Block, NodePrimitives, SealedBlock}; use reth_rpc_types_compat::engine::payload::block_to_payload; use std::sync::Arc; @@ -54,7 +54,7 @@ where type ExecutionPayloadEnvelopeV4 = ExecutionPayloadEnvelopeV4; fn block_to_payload( - block: SealedBlockFor< + block: SealedBlock< <::Primitives as NodePrimitives>::Block, >, ) -> (ExecutionPayload, ExecutionPayloadSidecar) { diff --git a/crates/ethereum/evm/src/execute.rs b/crates/ethereum/evm/src/execute.rs index 0d793fc8a8..99975734ea 100644 --- a/crates/ethereum/evm/src/execute.rs +++ b/crates/ethereum/evm/src/execute.rs @@ -5,7 +5,7 @@ use crate::{ EthEvmConfig, }; use alloc::{boxed::Box, sync::Arc, vec::Vec}; -use alloy_consensus::Transaction; +use alloy_consensus::{BlockHeader, Transaction}; use alloy_eips::{eip6110, eip7685::Requests}; use core::fmt::Display; use reth_chainspec::{ChainSpec, EthereumHardfork, EthereumHardforks, MAINNET}; @@ -21,7 +21,8 @@ use reth_evm::{ system_calls::{OnStateHook, SystemCaller}, ConfigureEvm, TxEnvOverrides, }; -use reth_primitives::{BlockWithSenders, EthPrimitives, Receipt}; +use reth_primitives::{EthPrimitives, Receipt, RecoveredBlock}; +use reth_primitives_traits::BlockBody; use reth_revm::db::State; use revm_primitives::{ db::{Database, DatabaseCommit}, @@ -129,31 +130,34 @@ where self.tx_env_overrides = Some(tx_env_overrides); } - fn apply_pre_execution_changes(&mut self, block: &BlockWithSenders) -> Result<(), Self::Error> { + fn apply_pre_execution_changes( + &mut self, + block: &RecoveredBlock, + ) -> Result<(), Self::Error> { // Set state clear flag if the block is after the Spurious Dragon hardfork. let state_clear_flag = - (*self.chain_spec).is_spurious_dragon_active_at_block(block.header.number); + (*self.chain_spec).is_spurious_dragon_active_at_block(block.number()); self.state.set_state_clear_flag(state_clear_flag); - let mut evm = self.evm_config.evm_for_block(&mut self.state, &block.header); + let mut evm = self.evm_config.evm_for_block(&mut self.state, block.header()); - self.system_caller.apply_pre_execution_changes(&block.header, &mut evm)?; + self.system_caller.apply_pre_execution_changes(block.header(), &mut evm)?; Ok(()) } fn execute_transactions( &mut self, - block: &BlockWithSenders, + block: &RecoveredBlock, ) -> Result, Self::Error> { - let mut evm = self.evm_config.evm_for_block(&mut self.state, &block.header); + let mut evm = self.evm_config.evm_for_block(&mut self.state, block.header()); let mut cumulative_gas_used = 0; - let mut receipts = Vec::with_capacity(block.body.transactions.len()); + let mut receipts = Vec::with_capacity(block.body().transaction_count()); for (sender, transaction) in block.transactions_with_sender() { // The sum of the transaction’s gas limit, Tg, and the gas utilized in this block prior, // must be no greater than the block’s gasLimit. - let block_available_gas = block.header.gas_limit - cumulative_gas_used; + let block_available_gas = block.gas_limit() - cumulative_gas_used; if transaction.gas_limit() > block_available_gas { return Err(BlockValidationError::TransactionGasLimitMoreThanAvailableBlockGas { transaction_gas_limit: transaction.gas_limit(), @@ -204,10 +208,10 @@ where fn apply_post_execution_changes( &mut self, - block: &BlockWithSenders, + block: &RecoveredBlock, receipts: &[Receipt], ) -> Result { - let mut evm = self.evm_config.evm_for_block(&mut self.state, &block.header); + let mut evm = self.evm_config.evm_for_block(&mut self.state, block.header()); let requests = if self.chain_spec.is_prague_active_at_timestamp(block.timestamp) { // Collect all EIP-6110 deposits @@ -227,10 +231,10 @@ where }; drop(evm); - let mut balance_increments = post_block_balance_increments(&self.chain_spec, &block.block); + let mut balance_increments = post_block_balance_increments(&self.chain_spec, block); // Irregular state change at Ethereum DAO hardfork - if self.chain_spec.fork(EthereumHardfork::Dao).transitions_at_block(block.number) { + if self.chain_spec.fork(EthereumHardfork::Dao).transitions_at_block(block.number()) { // drain balances from hardcoded addresses. let drained_balance: u128 = self .state @@ -267,7 +271,7 @@ where fn validate_block_post_execution( &self, - block: &BlockWithSenders, + block: &RecoveredBlock, receipts: &[Receipt], requests: &Requests, ) -> Result<(), ConsensusError> { @@ -311,8 +315,8 @@ mod tests { BasicBlockExecutorProvider, BatchExecutor, BlockExecutorProvider, Executor, }; use reth_execution_types::BlockExecutionOutput; - use reth_primitives::{Account, Block, BlockBody, BlockExt, Transaction}; - use reth_primitives_traits::crypto::secp256k1::public_key_to_address; + use reth_primitives::{Account, Block, BlockBody, Transaction}; + use reth_primitives_traits::{crypto::secp256k1::public_key_to_address, Block as _}; use reth_revm::{ database::StateProviderDatabase, test_utils::StateProviderTest, TransitionState, }; @@ -388,7 +392,7 @@ mod tests { // attempt to execute a block without parent beacon block root, expect err let err = executor - .execute_and_verify_one(&BlockWithSenders::new_unchecked( + .execute_and_verify_one(&RecoveredBlock::new_unhashed( Block { header: header.clone(), body: BlockBody { transactions: vec![], ommers: vec![], withdrawals: None }, @@ -409,7 +413,7 @@ mod tests { // Now execute a block with the fixed header, ensure that it does not fail executor - .execute_and_verify_one(&BlockWithSenders::new_unchecked( + .execute_and_verify_one(&RecoveredBlock::new_unhashed( Block { header: header.clone(), body: BlockBody { transactions: vec![], ommers: vec![], withdrawals: None }, @@ -469,7 +473,7 @@ mod tests { // attempt to execute an empty block with parent beacon block root, this should not fail provider .batch_executor(StateProviderDatabase::new(&db)) - .execute_and_verify_one(&BlockWithSenders::new_unchecked( + .execute_and_verify_one(&RecoveredBlock::new_unhashed( Block { header, body: BlockBody { transactions: vec![], ommers: vec![], withdrawals: None }, @@ -513,7 +517,7 @@ mod tests { // attempt to execute an empty block with parent beacon block root, this should not fail executor - .execute_and_verify_one(&BlockWithSenders::new_unchecked( + .execute_and_verify_one(&RecoveredBlock::new_unhashed( Block { header, body: BlockBody { transactions: vec![], ommers: vec![], withdrawals: None }, @@ -549,7 +553,7 @@ mod tests { // attempt to execute the genesis block with non-zero parent beacon block root, expect err header.parent_beacon_block_root = Some(B256::with_last_byte(0x69)); let _err = executor - .execute_and_verify_one(&BlockWithSenders::new_unchecked( + .execute_and_verify_one(&RecoveredBlock::new_unhashed( Block { header: header.clone(), body: Default::default() }, vec![], )) @@ -564,7 +568,7 @@ mod tests { // now try to process the genesis block again, this time ensuring that a system contract // call does not occur executor - .execute_and_verify_one(&BlockWithSenders::new_unchecked( + .execute_and_verify_one(&RecoveredBlock::new_unhashed( Block { header, body: Default::default() }, vec![], )) @@ -612,7 +616,7 @@ mod tests { // Now execute a block with the fixed header, ensure that it does not fail executor - .execute_and_verify_one(&BlockWithSenders::new_unchecked( + .execute_and_verify_one(&RecoveredBlock::new_unhashed( Block { header: header.clone(), body: Default::default() }, vec![], )) @@ -682,7 +686,7 @@ mod tests { // attempt to execute an empty block, this should not fail executor - .execute_and_verify_one(&BlockWithSenders::new_unchecked( + .execute_and_verify_one(&RecoveredBlock::new_unhashed( Block { header, body: Default::default() }, vec![], )) @@ -719,7 +723,7 @@ mod tests { // attempt to execute genesis block, this should not fail executor - .execute_and_verify_one(&BlockWithSenders::new_unchecked( + .execute_and_verify_one(&RecoveredBlock::new_unhashed( Block { header, body: Default::default() }, vec![], )) @@ -763,7 +767,7 @@ mod tests { // attempt to execute the fork activation block, this should not fail executor - .execute_and_verify_one(&BlockWithSenders::new_unchecked( + .execute_and_verify_one(&RecoveredBlock::new_unhashed( Block { header, body: Default::default() }, vec![], )) @@ -814,7 +818,7 @@ mod tests { // attempt to execute the fork activation block, this should not fail executor - .execute_and_verify_one(&BlockWithSenders::new_unchecked( + .execute_and_verify_one(&RecoveredBlock::new_unhashed( Block { header, body: Default::default() }, vec![], )) @@ -847,7 +851,7 @@ mod tests { // attempt to execute the genesis block, this should not fail executor - .execute_and_verify_one(&BlockWithSenders::new_unchecked( + .execute_and_verify_one(&RecoveredBlock::new_unhashed( Block { header, body: Default::default() }, vec![], )) @@ -876,7 +880,7 @@ mod tests { let header_hash = header.hash_slow(); executor - .execute_and_verify_one(&BlockWithSenders::new_unchecked( + .execute_and_verify_one(&RecoveredBlock::new_unhashed( Block { header, body: Default::default() }, vec![], )) @@ -908,7 +912,7 @@ mod tests { }; executor - .execute_and_verify_one(&BlockWithSenders::new_unchecked( + .execute_and_verify_one(&RecoveredBlock::new_unhashed( Block { header, body: Default::default() }, vec![], )) @@ -1111,7 +1115,7 @@ mod tests { let header = Header { timestamp: 1, number: 1, ..Header::default() }; - let block = &BlockWithSenders::new_unchecked( + let block = &RecoveredBlock::new_unhashed( Block { header, body: BlockBody { diff --git a/crates/ethereum/node/tests/e2e/dev.rs b/crates/ethereum/node/tests/e2e/dev.rs index cb8eb1556a..d81037f171 100644 --- a/crates/ethereum/node/tests/e2e/dev.rs +++ b/crates/ethereum/node/tests/e2e/dev.rs @@ -3,7 +3,7 @@ use alloy_genesis::Genesis; use alloy_primitives::{b256, hex}; use futures::StreamExt; use reth_chainspec::ChainSpec; -use reth_node_api::{FullNodeComponents, FullNodePrimitives, NodeTypes}; +use reth_node_api::{BlockBody, FullNodeComponents, FullNodePrimitives, NodeTypes}; use reth_node_builder::{ rpc::RethRpcAddOns, EngineNodeLauncher, FullNode, NodeBuilder, NodeConfig, NodeHandle, }; @@ -65,7 +65,7 @@ where let head = notifications.next().await.unwrap(); - let tx = &head.tip().transactions()[0]; + let tx = &head.tip().body().transactions()[0]; assert_eq!(tx.trie_hash(), hash); println!("mined transaction: {hash}"); } diff --git a/crates/ethereum/payload/src/lib.rs b/crates/ethereum/payload/src/lib.rs index a4a02c3ef7..4f5fe53016 100644 --- a/crates/ethereum/payload/src/lib.rs +++ b/crates/ethereum/payload/src/lib.rs @@ -30,10 +30,11 @@ use reth_payload_builder_primitives::PayloadBuilderError; use reth_payload_primitives::PayloadBuilderAttributes; use reth_primitives::{ proofs::{self}, - Block, BlockBody, BlockExt, EthereumHardforks, InvalidTransactionError, Receipt, - TransactionSigned, + Block, BlockBody, EthereumHardforks, InvalidTransactionError, Receipt, TransactionSigned, }; +use reth_primitives_traits::Block as _; use reth_revm::database::StateProviderDatabase; +use reth_storage_api::StateProviderFactory; use reth_transaction_pool::{ error::InvalidPoolTransactionError, noop::NoopTransactionPool, BestTransactions, BestTransactionsAttributes, PoolTransaction, TransactionPool, ValidPoolTransaction, @@ -51,7 +52,6 @@ use tracing::{debug, trace, warn}; mod config; pub use config::*; -use reth_storage_api::StateProviderFactory; type BestTransactionsIter = Box< dyn BestTransactions::Transaction>>>, diff --git a/crates/evm/execution-types/src/chain.rs b/crates/evm/execution-types/src/chain.rs index e5f7270bfe..67ed25133e 100644 --- a/crates/evm/execution-types/src/chain.rs +++ b/crates/evm/execution-types/src/chain.rs @@ -8,8 +8,7 @@ use alloy_primitives::{Address, BlockHash, BlockNumber, TxHash}; use core::{fmt, ops::RangeInclusive}; use reth_execution_errors::{BlockExecutionError, InternalBlockExecutionError}; use reth_primitives::{ - transaction::SignedTransactionIntoRecoveredExt, RecoveredTx, SealedBlockFor, - SealedBlockWithSenders, SealedHeader, + transaction::SignedTransactionIntoRecoveredExt, RecoveredBlock, RecoveredTx, SealedHeader, }; use reth_primitives_traits::{Block, BlockBody, NodePrimitives, SignedTransaction}; use reth_trie::updates::TrieUpdates; @@ -29,7 +28,7 @@ use revm::db::BundleState; #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Chain { /// All blocks in this chain. - blocks: BTreeMap>, + blocks: BTreeMap>, /// The outcome of block execution for this chain. /// /// This field contains the state of all accounts after the execution of all blocks in this @@ -60,11 +59,12 @@ impl Chain { /// /// A chain of blocks should not be empty. pub fn new( - blocks: impl IntoIterator>, + blocks: impl IntoIterator>, execution_outcome: ExecutionOutcome, trie_updates: Option, ) -> Self { - let blocks = blocks.into_iter().map(|b| (b.number(), b)).collect::>(); + let blocks = + blocks.into_iter().map(|b| (b.header().number(), b)).collect::>(); debug_assert!(!blocks.is_empty(), "Chain should have at least one block"); Self { blocks, execution_outcome, trie_updates } @@ -72,7 +72,7 @@ impl Chain { /// Create new Chain from a single block and its state. pub fn from_block( - block: SealedBlockWithSenders, + block: RecoveredBlock, execution_outcome: ExecutionOutcome, trie_updates: Option, ) -> Self { @@ -80,12 +80,12 @@ impl Chain { } /// Get the blocks in this chain. - pub const fn blocks(&self) -> &BTreeMap> { + pub const fn blocks(&self) -> &BTreeMap> { &self.blocks } /// Consumes the type and only returns the blocks in this chain. - pub fn into_blocks(self) -> BTreeMap> { + pub fn into_blocks(self) -> BTreeMap> { self.blocks } @@ -131,15 +131,7 @@ impl Chain { } /// Returns the block with matching hash. - pub fn block(&self, block_hash: BlockHash) -> Option<&SealedBlockFor> { - self.block_with_senders(block_hash).map(|block| &block.block) - } - - /// Returns the block with matching hash. - pub fn block_with_senders( - &self, - block_hash: BlockHash, - ) -> Option<&SealedBlockWithSenders> { + pub fn block_with_senders(&self, block_hash: BlockHash) -> Option<&RecoveredBlock> { self.blocks.iter().find_map(|(_num, block)| (block.hash() == block_hash).then_some(block)) } @@ -183,15 +175,14 @@ impl Chain { } /// Returns an iterator over all blocks in the chain with increasing block number. - pub fn blocks_iter(&self) -> impl Iterator> + '_ { + pub fn blocks_iter(&self) -> impl Iterator> + '_ { self.blocks().iter().map(|block| block.1) } /// Returns an iterator over all blocks and their receipts in the chain. pub fn blocks_and_receipts( &self, - ) -> impl Iterator, &Vec>)> + '_ - { + ) -> impl Iterator, &Vec>)> + '_ { self.blocks_iter().zip(self.block_receipts_iter()) } @@ -199,7 +190,10 @@ impl Chain { #[track_caller] pub fn fork_block(&self) -> ForkBlock { let first = self.first(); - ForkBlock { number: first.number().saturating_sub(1), hash: first.parent_hash() } + ForkBlock { + number: first.header().number().saturating_sub(1), + hash: first.header().parent_hash(), + } } /// Get the first block in this chain. @@ -208,7 +202,7 @@ impl Chain { /// /// If chain doesn't have any blocks. #[track_caller] - pub fn first(&self) -> &SealedBlockWithSenders { + pub fn first(&self) -> &RecoveredBlock { self.blocks.first_key_value().expect("Chain should have at least one block").1 } @@ -218,7 +212,7 @@ impl Chain { /// /// If chain doesn't have any blocks. #[track_caller] - pub fn tip(&self) -> &SealedBlockWithSenders { + pub fn tip(&self) -> &RecoveredBlock { self.blocks.last_key_value().expect("Chain should have at least one block").1 } @@ -233,7 +227,7 @@ impl Chain { /// /// If chain doesn't have any blocks. pub fn range(&self) -> RangeInclusive { - self.first().number()..=self.tip().number() + self.first().header().number()..=self.tip().header().number() } /// Get all receipts for the given block. @@ -270,10 +264,10 @@ impl Chain { /// This method assumes that blocks attachment to the chain has already been validated. pub fn append_block( &mut self, - block: SealedBlockWithSenders, + block: RecoveredBlock, execution_outcome: ExecutionOutcome, ) { - self.blocks.insert(block.number(), block); + self.blocks.insert(block.header().number(), block); self.execution_outcome.extend(execution_outcome); self.trie_updates.take(); // reset } @@ -375,7 +369,7 @@ impl Chain { /// Wrapper type for `blocks` display in `Chain` #[derive(Debug)] pub struct DisplayBlocksChain<'a, B: reth_primitives_traits::Block>( - pub &'a BTreeMap>, + pub &'a BTreeMap>, ); impl fmt::Display for DisplayBlocksChain<'_, B> { @@ -396,7 +390,7 @@ impl fmt::Display for DisplayBlocksChain<'_, B /// All blocks in the chain #[derive(Clone, Debug, Default, PartialEq, Eq)] pub struct ChainBlocks<'a, B: Block> { - blocks: Cow<'a, BTreeMap>>, + blocks: Cow<'a, BTreeMap>>, } impl>> ChainBlocks<'_, B> { @@ -404,13 +398,13 @@ impl>> ChainBlocks<'_, /// /// Note: this always yields at least one block. #[inline] - pub fn into_blocks(self) -> impl Iterator> { + pub fn into_blocks(self) -> impl Iterator> { self.blocks.into_owned().into_values() } /// Creates an iterator over all blocks in the chain with increasing block number. #[inline] - pub fn iter(&self) -> impl Iterator)> { + pub fn iter(&self) -> impl Iterator)> { self.blocks.iter() } @@ -420,7 +414,7 @@ impl>> ChainBlocks<'_, /// /// Chains always have at least one block. #[inline] - pub fn tip(&self) -> &SealedBlockWithSenders { + pub fn tip(&self) -> &RecoveredBlock { self.blocks.last_key_value().expect("Chain should have at least one block").1 } @@ -430,7 +424,7 @@ impl>> ChainBlocks<'_, /// /// Chains always have at least one block. #[inline] - pub fn first(&self) -> &SealedBlockWithSenders { + pub fn first(&self) -> &RecoveredBlock { self.blocks.first_key_value().expect("Chain should have at least one block").1 } @@ -461,13 +455,15 @@ impl>> ChainBlocks<'_, /// Returns an iterator over all transaction hashes in the block #[inline] pub fn transaction_hashes(&self) -> impl Iterator + '_ { - self.blocks.values().flat_map(|block| block.transactions().iter().map(|tx| tx.trie_hash())) + self.blocks + .values() + .flat_map(|block| block.body().transactions().iter().map(|tx| tx.trie_hash())) } } impl IntoIterator for ChainBlocks<'_, B> { - type Item = (BlockNumber, SealedBlockWithSenders); - type IntoIter = std::collections::btree_map::IntoIter>; + type Item = (BlockNumber, RecoveredBlock); + type IntoIter = std::collections::btree_map::IntoIter>; fn into_iter(self) -> Self::IntoIter { #[allow(clippy::unnecessary_to_owned)] @@ -536,9 +532,7 @@ pub(super) mod serde_bincode_compat { use crate::ExecutionOutcome; use alloc::borrow::Cow; use alloy_primitives::BlockNumber; - use reth_primitives::{ - serde_bincode_compat::SealedBlockWithSenders, EthPrimitives, NodePrimitives, - }; + use reth_primitives::{serde_bincode_compat::RecoveredBlock, EthPrimitives, NodePrimitives}; use reth_primitives_traits::{serde_bincode_compat::SerdeBincodeCompat, Block}; use reth_trie_common::serde_bincode_compat::updates::TrieUpdates; use serde::{ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer}; @@ -563,21 +557,25 @@ pub(super) mod serde_bincode_compat { #[derive(Debug, Serialize, Deserialize)] pub struct Chain<'a, N = EthPrimitives> where - N: NodePrimitives, + N: NodePrimitives< + Block: Block + 'static, + >, { - blocks: SealedBlocksWithSenders<'a, N::Block>, + blocks: RecoveredBlocks<'a, N::Block>, execution_outcome: Cow<'a, ExecutionOutcome>, trie_updates: Option>, } #[derive(Debug)] - struct SealedBlocksWithSenders<'a, B: reth_primitives_traits::Block>( - Cow<'a, BTreeMap>>, - ); + struct RecoveredBlocks< + 'a, + B: reth_primitives_traits::Block + + 'static, + >(Cow<'a, BTreeMap>>); - impl Serialize for SealedBlocksWithSenders<'_, B> + impl Serialize for RecoveredBlocks<'_, B> where - B: Block, + B: Block + 'static, { fn serialize(&self, serializer: S) -> Result where @@ -586,23 +584,23 @@ pub(super) mod serde_bincode_compat { let mut state = serializer.serialize_map(Some(self.0.len()))?; for (block_number, block) in self.0.iter() { - state.serialize_entry(block_number, &SealedBlockWithSenders::<'_>::from(block))?; + state.serialize_entry(block_number, &RecoveredBlock::<'_, B>::from(block))?; } state.end() } } - impl<'de, B> Deserialize<'de> for SealedBlocksWithSenders<'_, B> + impl<'de, B> Deserialize<'de> for RecoveredBlocks<'_, B> where - B: Block, + B: Block + 'static, { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { Ok(Self(Cow::Owned( - BTreeMap::>::deserialize(deserializer) + BTreeMap::>::deserialize(deserializer) .map(|blocks| blocks.into_iter().map(|(n, b)| (n, b.into())).collect())?, ))) } @@ -610,11 +608,13 @@ pub(super) mod serde_bincode_compat { impl<'a, N> From<&'a super::Chain> for Chain<'a, N> where - N: NodePrimitives, + N: NodePrimitives< + Block: Block + 'static, + >, { fn from(value: &'a super::Chain) -> Self { Self { - blocks: SealedBlocksWithSenders(Cow::Borrowed(&value.blocks)), + blocks: RecoveredBlocks(Cow::Borrowed(&value.blocks)), execution_outcome: Cow::Borrowed(&value.execution_outcome), trie_updates: value.trie_updates.as_ref().map(Into::into), } @@ -623,7 +623,9 @@ pub(super) mod serde_bincode_compat { impl<'a, N> From> for super::Chain where - N: NodePrimitives, + N: NodePrimitives< + Block: Block + 'static, + >, { fn from(value: Chain<'a, N>) -> Self { Self { @@ -634,8 +636,13 @@ pub(super) mod serde_bincode_compat { } } - impl SerializeAs for Chain<'_> { - fn serialize_as(source: &super::Chain, serializer: S) -> Result + impl SerializeAs> for Chain<'_, N> + where + N: NodePrimitives< + Block: Block + 'static, + >, + { + fn serialize_as(source: &super::Chain, serializer: S) -> Result where S: Serializer, { @@ -643,8 +650,13 @@ pub(super) mod serde_bincode_compat { } } - impl<'de> DeserializeAs<'de, super::Chain> for Chain<'de> { - fn deserialize_as(deserializer: D) -> Result + impl<'de, N> DeserializeAs<'de, super::Chain> for Chain<'de, N> + where + N: NodePrimitives< + Block: Block + 'static, + >, + { + fn deserialize_as(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { @@ -654,14 +666,13 @@ pub(super) mod serde_bincode_compat { #[cfg(test)] mod tests { + use super::super::{serde_bincode_compat, Chain}; use arbitrary::Arbitrary; use rand::Rng; - use reth_primitives::SealedBlockWithSenders; + use reth_primitives::RecoveredBlock; use serde::{Deserialize, Serialize}; use serde_with::serde_as; - use super::super::{serde_bincode_compat, Chain}; - #[test] fn test_chain_bincode_roundtrip() { #[serde_as] @@ -675,10 +686,8 @@ pub(super) mod serde_bincode_compat { rand::thread_rng().fill(bytes.as_mut_slice()); let data = Data { chain: Chain::new( - vec![SealedBlockWithSenders::arbitrary(&mut arbitrary::Unstructured::new( - &bytes, - )) - .unwrap()], + vec![RecoveredBlock::arbitrary(&mut arbitrary::Unstructured::new(&bytes)) + .unwrap()], Default::default(), None, ), @@ -716,7 +725,7 @@ mod tests { #[test] fn chain_append() { - let block: SealedBlockWithSenders = Default::default(); + let block: RecoveredBlock = Default::default(); let block1_hash = B256::new([0x01; 32]); let block2_hash = B256::new([0x02; 32]); let block3_hash = B256::new([0x03; 32]); @@ -727,10 +736,10 @@ mod tests { let mut block3 = block.clone(); let mut block4 = block; - block1.block.set_hash(block1_hash); - block2.block.set_hash(block2_hash); - block3.block.set_hash(block3_hash); - block4.block.set_hash(block4_hash); + block1.set_hash(block1_hash); + block2.set_hash(block2_hash); + block3.set_hash(block3_hash); + block4.set_hash(block4_hash); block3.set_parent_hash(block2_hash); @@ -780,13 +789,13 @@ mod tests { vec![], ); - let mut block1: SealedBlockWithSenders = Default::default(); + let mut block1: RecoveredBlock = Default::default(); let block1_hash = B256::new([15; 32]); block1.set_block_number(1); block1.set_hash(block1_hash); block1.push_sender(Address::new([4; 20])); - let mut block2: SealedBlockWithSenders = Default::default(); + let mut block2: RecoveredBlock = Default::default(); let block2_hash = B256::new([16; 32]); block2.set_block_number(2); block2.set_hash(block2_hash); @@ -846,8 +855,8 @@ mod tests { #[test] fn receipts_by_block_hash() { - // Create a default SealedBlockWithSenders object - let block: SealedBlockWithSenders = Default::default(); + // Create a default RecoveredBlock object + let block: RecoveredBlock = Default::default(); // Define block hashes for block1 and block2 let block1_hash = B256::new([0x01; 32]); @@ -858,8 +867,8 @@ mod tests { let mut block2 = block; // Set the hashes of block1 and block2 - block1.block.set_hash(block1_hash); - block2.block.set_hash(block2_hash); + block1.set_hash(block1_hash); + block2.set_hash(block2_hash); // Create a random receipt object, receipt1 let receipt1 = Receipt { diff --git a/crates/evm/src/execute.rs b/crates/evm/src/execute.rs index 8bf40d38ca..2b221f1456 100644 --- a/crates/evm/src/execute.rs +++ b/crates/evm/src/execute.rs @@ -17,8 +17,7 @@ use alloy_primitives::{ }; use core::fmt::Display; use reth_consensus::ConsensusError; -use reth_primitives::{BlockWithSenders, NodePrimitives, Receipt}; -use reth_primitives_traits::Block; +use reth_primitives::{NodePrimitives, Receipt, RecoveredBlock}; use reth_prune_types::PruneModes; use reth_revm::batch::BlockBatchRecord; use revm::{ @@ -151,7 +150,7 @@ pub trait BlockExecutorProvider: Send + Sync + Clone + Unpin + 'static { /// the returned state. type Executor + Display>>: for<'a> Executor< DB, - Input<'a> = &'a BlockWithSenders<::Block>, + Input<'a> = &'a RecoveredBlock<::Block>, Output = BlockExecutionOutput<::Receipt>, Error = BlockExecutionError, >; @@ -159,7 +158,7 @@ pub trait BlockExecutorProvider: Send + Sync + Clone + Unpin + 'static { /// An executor that can execute a batch of blocks given a database. type BatchExecutor + Display>>: for<'a> BatchExecutor< DB, - Input<'a> = &'a BlockWithSenders<::Block>, + Input<'a> = &'a RecoveredBlock<::Block>, Output = ExecutionOutcome<::Receipt>, Error = BlockExecutionError, >; @@ -206,19 +205,19 @@ pub trait BlockExecutionStrategy { /// Applies any necessary changes before executing the block's transactions. fn apply_pre_execution_changes( &mut self, - block: &BlockWithSenders<::Block>, + block: &RecoveredBlock<::Block>, ) -> Result<(), Self::Error>; /// Executes all transactions in the block. fn execute_transactions( &mut self, - block: &BlockWithSenders<::Block>, + block: &RecoveredBlock<::Block>, ) -> Result::Receipt>, Self::Error>; /// Applies any necessary changes after executing the block's transactions. fn apply_post_execution_changes( &mut self, - block: &BlockWithSenders<::Block>, + block: &RecoveredBlock<::Block>, receipts: &[::Receipt], ) -> Result; @@ -240,7 +239,7 @@ pub trait BlockExecutionStrategy { /// Validate a block with regard to execution results. fn validate_block_post_execution( &self, - _block: &BlockWithSenders<::Block>, + _block: &RecoveredBlock<::Block>, _receipts: &[::Receipt], _requests: &Requests, ) -> Result<(), ConsensusError> { @@ -338,7 +337,7 @@ where S: BlockExecutionStrategy, DB: Database + Display>, { - type Input<'a> = &'a BlockWithSenders<::Block>; + type Input<'a> = &'a RecoveredBlock<::Block>; type Output = BlockExecutionOutput<::Receipt>; type Error = S::Error; @@ -425,7 +424,7 @@ where S: BlockExecutionStrategy, DB: Database + Display>, { - type Input<'a> = &'a BlockWithSenders<::Block>; + type Input<'a> = &'a RecoveredBlock<::Block>; type Output = ExecutionOutcome<::Receipt>; type Error = BlockExecutionError; @@ -548,7 +547,7 @@ mod tests { struct TestExecutor(PhantomData); impl Executor for TestExecutor { - type Input<'a> = &'a BlockWithSenders; + type Input<'a> = &'a RecoveredBlock; type Output = BlockExecutionOutput; type Error = BlockExecutionError; @@ -580,7 +579,7 @@ mod tests { } impl BatchExecutor for TestExecutor { - type Input<'a> = &'a BlockWithSenders; + type Input<'a> = &'a RecoveredBlock; type Output = ExecutionOutcome; type Error = BlockExecutionError; @@ -661,21 +660,21 @@ mod tests { fn apply_pre_execution_changes( &mut self, - _block: &BlockWithSenders, + _block: &RecoveredBlock, ) -> Result<(), Self::Error> { Ok(()) } fn execute_transactions( &mut self, - _block: &BlockWithSenders, + _block: &RecoveredBlock, ) -> Result, Self::Error> { Ok(self.execute_transactions_result.clone()) } fn apply_post_execution_changes( &mut self, - _block: &BlockWithSenders, + _block: &RecoveredBlock, _receipts: &[Receipt], ) -> Result { Ok(self.apply_post_execution_changes_result.clone()) @@ -697,7 +696,7 @@ mod tests { fn validate_block_post_execution( &self, - _block: &BlockWithSenders, + _block: &RecoveredBlock, _receipts: &[Receipt], _requests: &Requests, ) -> Result<(), ConsensusError> { diff --git a/crates/evm/src/metrics.rs b/crates/evm/src/metrics.rs index 242ddfe5b7..4787bf9ce5 100644 --- a/crates/evm/src/metrics.rs +++ b/crates/evm/src/metrics.rs @@ -7,7 +7,7 @@ use alloy_consensus::BlockHeader; use metrics::{Counter, Gauge, Histogram}; use reth_execution_types::BlockExecutionOutput; use reth_metrics::Metrics; -use reth_primitives::BlockWithSenders; +use reth_primitives::RecoveredBlock; use revm_primitives::EvmState; use std::time::Instant; @@ -68,7 +68,7 @@ pub struct ExecutorMetrics { } impl ExecutorMetrics { - fn metered(&self, block: &BlockWithSenders, f: F) -> R + fn metered(&self, block: &RecoveredBlock, f: F) -> R where F: FnOnce() -> R, B: reth_primitives_traits::Block, @@ -97,13 +97,13 @@ impl ExecutorMetrics { pub fn execute_metered<'a, E, DB, O, Error, B>( &self, executor: E, - input: &'a BlockWithSenders, + input: &'a RecoveredBlock, state_hook: Box, ) -> Result, Error> where E: Executor< DB, - Input<'a> = &'a BlockWithSenders, + Input<'a> = &'a RecoveredBlock, Output = BlockExecutionOutput, Error = Error, >, @@ -131,9 +131,9 @@ impl ExecutorMetrics { } /// Execute the given block and update metrics for the execution. - pub fn metered_one(&self, input: &BlockWithSenders, f: F) -> R + pub fn metered_one(&self, input: &RecoveredBlock, f: F) -> R where - F: FnOnce(&BlockWithSenders) -> R, + F: FnOnce(&RecoveredBlock) -> R, B: reth_primitives_traits::Block, { self.metered(input, || f(input)) @@ -158,7 +158,7 @@ mod tests { impl Executor<()> for MockExecutor { type Input<'a> - = &'a BlockWithSenders + = &'a RecoveredBlock where Self: 'a; type Output = BlockExecutionOutput<()>; @@ -229,7 +229,7 @@ mod tests { fn test_executor_metrics_hook_metrics_recorded() { let snapshotter = setup_test_recorder(); let metrics = ExecutorMetrics::default(); - let input = BlockWithSenders::default(); + let input = RecoveredBlock::default(); let (tx, _rx) = mpsc::channel(); let expected_output = 42; @@ -278,7 +278,7 @@ mod tests { #[test] fn test_executor_metrics_hook_called() { let metrics = ExecutorMetrics::default(); - let input = BlockWithSenders::default(); + let input = RecoveredBlock::default(); let (tx, rx) = mpsc::channel(); let expected_output = 42; diff --git a/crates/evm/src/noop.rs b/crates/evm/src/noop.rs index 66041840ae..27e2e96239 100644 --- a/crates/evm/src/noop.rs +++ b/crates/evm/src/noop.rs @@ -4,7 +4,7 @@ use alloy_primitives::BlockNumber; use core::fmt::Display; use reth_execution_errors::BlockExecutionError; use reth_execution_types::{BlockExecutionOutput, ExecutionOutcome}; -use reth_primitives::{BlockWithSenders, NodePrimitives}; +use reth_primitives::{NodePrimitives, RecoveredBlock}; use reth_prune_types::PruneModes; use reth_storage_errors::provider::ProviderError; use revm::State; @@ -45,7 +45,7 @@ impl BlockExecutorProvider for NoopBlockExecutorProvider

{ } impl Executor for NoopBlockExecutorProvider

{ - type Input<'a> = &'a BlockWithSenders; + type Input<'a> = &'a RecoveredBlock; type Output = BlockExecutionOutput; type Error = BlockExecutionError; @@ -77,7 +77,7 @@ impl Executor for NoopBlockExecutorProvider

{ } impl BatchExecutor for NoopBlockExecutorProvider

{ - type Input<'a> = &'a BlockWithSenders; + type Input<'a> = &'a RecoveredBlock; type Output = ExecutionOutcome; type Error = BlockExecutionError; diff --git a/crates/evm/src/state_change.rs b/crates/evm/src/state_change.rs index af14705d16..a6f38f6268 100644 --- a/crates/evm/src/state_change.rs +++ b/crates/evm/src/state_change.rs @@ -5,6 +5,7 @@ use alloy_eips::eip4895::Withdrawal; use alloy_primitives::{map::HashMap, Address}; use reth_chainspec::EthereumHardforks; use reth_consensus_common::calc; +use reth_primitives::SealedBlock; use reth_primitives_traits::BlockBody; /// Collect all balance changes at the end of the block. @@ -14,7 +15,7 @@ use reth_primitives_traits::BlockBody; #[inline] pub fn post_block_balance_increments( chain_spec: &ChainSpec, - block: &Block, + block: &SealedBlock, ) -> HashMap where ChainSpec: EthereumHardforks, diff --git a/crates/evm/src/test_utils.rs b/crates/evm/src/test_utils.rs index 762098a487..2eaf7fdc5a 100644 --- a/crates/evm/src/test_utils.rs +++ b/crates/evm/src/test_utils.rs @@ -12,7 +12,7 @@ use alloy_primitives::BlockNumber; use parking_lot::Mutex; use reth_execution_errors::BlockExecutionError; use reth_execution_types::ExecutionOutcome; -use reth_primitives::{BlockWithSenders, EthPrimitives, NodePrimitives, Receipt, Receipts}; +use reth_primitives::{EthPrimitives, NodePrimitives, Receipt, Receipts, RecoveredBlock}; use reth_prune_types::PruneModes; use reth_storage_errors::provider::ProviderError; use revm::State; @@ -55,7 +55,7 @@ impl BlockExecutorProvider for MockExecutorProvider { } impl Executor for MockExecutorProvider { - type Input<'a> = &'a BlockWithSenders; + type Input<'a> = &'a RecoveredBlock; type Output = BlockExecutionOutput; type Error = BlockExecutionError; @@ -97,7 +97,7 @@ impl Executor for MockExecutorProvider { } impl BatchExecutor for MockExecutorProvider { - type Input<'a> = &'a BlockWithSenders; + type Input<'a> = &'a RecoveredBlock; type Output = ExecutionOutcome; type Error = BlockExecutionError; diff --git a/crates/exex/exex/src/backfill/job.rs b/crates/exex/exex/src/backfill/job.rs index 126a2562f7..4f1ac8e97a 100644 --- a/crates/exex/exex/src/backfill/job.rs +++ b/crates/exex/exex/src/backfill/job.rs @@ -10,7 +10,7 @@ use reth_evm::execute::{ BatchExecutor, BlockExecutionError, BlockExecutionOutput, BlockExecutorProvider, Executor, }; use reth_node_api::{Block as _, BlockBody as _, NodePrimitives}; -use reth_primitives::{BlockExt, BlockWithSenders, Receipt}; +use reth_primitives::{Receipt, RecoveredBlock}; use reth_primitives_traits::{format_gas_throughput, SignedTransaction}; use reth_provider::{ BlockReader, Chain, HeaderProvider, ProviderError, StateProviderFactory, TransactionVariant, @@ -107,10 +107,9 @@ where let execute_start = Instant::now(); // Unseal the block for execution - let (block, senders) = block.split(); - let (header, body) = block.split(); - let (unsealed_header, hash) = header.split(); - let block = P::Block::new(unsealed_header, body).with_senders_unchecked(senders); + let (block, senders) = block.split_sealed(); + let (header, body) = block.split_sealed_header_body(); + let block = P::Block::new_sealed(header, body).with_senders(senders); executor.execute_and_verify_one(&block)?; execution_duration += execute_start.elapsed(); @@ -118,7 +117,7 @@ where // TODO(alexey): report gas metrics using `block.header.gas_used` // Seal the block back and save it - blocks.push(block.seal_unchecked(hash)); + blocks.push(block); // Check if we should commit now let bundle_size_hint = executor.size_hint().unwrap_or_default() as u64; @@ -151,7 +150,7 @@ where /// Single block Backfill job started for a specific range. /// /// It implements [`Iterator`] which executes a block each time the -/// iterator is advanced and yields ([`BlockWithSenders`], [`BlockExecutionOutput`]) +/// iterator is advanced and yields ([`RecoveredBlock`], [`BlockExecutionOutput`]) #[derive(Debug, Clone)] pub struct SingleBlockBackfillJob { pub(crate) executor: E, @@ -166,7 +165,7 @@ where P: HeaderProvider + BlockReader + StateProviderFactory, { type Item = BackfillJobResult<( - BlockWithSenders, + RecoveredBlock, BlockExecutionOutput<::Receipt>, )>; @@ -183,7 +182,11 @@ where /// Converts the single block backfill job into a stream. pub fn into_stream( self, - ) -> StreamBackfillJob)> { + ) -> StreamBackfillJob< + E, + P, + (RecoveredBlock, BlockExecutionOutput), + > { self.into() } @@ -192,7 +195,7 @@ where &self, block_number: u64, ) -> BackfillJobResult<( - BlockWithSenders, + RecoveredBlock, BlockExecutionOutput<::Receipt>, )> { // Fetch the block with senders for execution. @@ -206,7 +209,7 @@ where self.provider.history_by_block_number(block_number.saturating_sub(1))?, )); - trace!(target: "exex::backfill", number = block_number, txs = block_with_senders.block.body().transactions().len(), "Executing block"); + trace!(target: "exex::backfill", number = block_number, txs = block_with_senders.body().transaction_count(), "Executing block"); let block_execution_output = executor.execute(&block_with_senders)?; @@ -310,8 +313,7 @@ mod tests { let (block, mut execution_output) = res?; execution_output.state.reverts.sort(); - let sealed_block_with_senders = blocks_and_execution_outcomes[i].0.clone(); - let expected_block = sealed_block_with_senders.unseal(); + let expected_block = blocks_and_execution_outcomes[i].0.clone(); let expected_output = &blocks_and_execution_outcomes[i].1; assert_eq!(block, expected_block); diff --git a/crates/exex/exex/src/backfill/stream.rs b/crates/exex/exex/src/backfill/stream.rs index 2fef2dd57d..30b28b5c66 100644 --- a/crates/exex/exex/src/backfill/stream.rs +++ b/crates/exex/exex/src/backfill/stream.rs @@ -7,7 +7,7 @@ use futures::{ }; use reth_evm::execute::{BlockExecutionError, BlockExecutionOutput, BlockExecutorProvider}; use reth_node_api::NodePrimitives; -use reth_primitives::{BlockWithSenders, EthPrimitives}; +use reth_primitives::{EthPrimitives, RecoveredBlock}; use reth_provider::{BlockReader, Chain, StateProviderFactory}; use reth_prune_types::PruneModes; use reth_stages_api::ExecutionStageThresholds; @@ -38,7 +38,7 @@ struct BackfillTaskOutput { type BackfillTasks = FuturesOrdered>>; type SingleBlockStreamItem = ( - BlockWithSenders<::Block>, + RecoveredBlock<::Block>, BlockExecutionOutput<::Receipt>, ); type BatchBlockStreamItem = Chain; @@ -278,8 +278,7 @@ mod tests { // execute first block let (block, mut execution_output) = backfill_stream.next().await.unwrap().unwrap(); execution_output.state.reverts.sort(); - let sealed_block_with_senders = blocks_and_execution_outcomes[0].0.clone(); - let expected_block = sealed_block_with_senders.unseal(); + let expected_block = blocks_and_execution_outcomes[0].0.clone(); let expected_output = &blocks_and_execution_outcomes[0].1; assert_eq!(block, expected_block); assert_eq!(&execution_output, expected_output); diff --git a/crates/exex/exex/src/backfill/test_utils.rs b/crates/exex/exex/src/backfill/test_utils.rs index 721071f081..f64a09ab75 100644 --- a/crates/exex/exex/src/backfill/test_utils.rs +++ b/crates/exex/exex/src/backfill/test_utils.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use alloy_consensus::{constants::ETH_TO_WEI, Header, TxEip2930}; +use alloy_consensus::{constants::ETH_TO_WEI, BlockHeader, Header, TxEip2930}; use alloy_genesis::{Genesis, GenesisAccount}; use alloy_primitives::{b256, Address, TxKind, U256}; use eyre::OptionExt; @@ -8,9 +8,8 @@ use reth_chainspec::{ChainSpec, ChainSpecBuilder, EthereumHardfork, MAINNET, MIN use reth_evm::execute::{BatchExecutor, BlockExecutionOutput, BlockExecutorProvider, Executor}; use reth_evm_ethereum::execute::EthExecutorProvider; use reth_node_api::FullNodePrimitives; -use reth_primitives::{ - Block, BlockBody, BlockExt, BlockWithSenders, Receipt, SealedBlockWithSenders, Transaction, -}; +use reth_primitives::{Block, BlockBody, Receipt, RecoveredBlock, Transaction}; +use reth_primitives_traits::Block as _; use reth_provider::{ providers::ProviderNodeTypes, BlockWriter as _, ExecutionOutcome, LatestStateProviderRef, ProviderFactory, @@ -53,7 +52,7 @@ pub(crate) fn chain_spec(address: Address) -> Arc { pub(crate) fn execute_block_and_commit_to_database( provider_factory: &ProviderFactory, chain_spec: Arc, - block: &BlockWithSenders, + block: &RecoveredBlock, ) -> eyre::Result> where N: ProviderNodeTypes< @@ -73,13 +72,12 @@ where block_execution_output.state.reverts.sort(); // Convert the block execution output to an execution outcome for committing to the database - let execution_outcome = to_execution_outcome(block.number, &block_execution_output); + let execution_outcome = to_execution_outcome(block.number(), &block_execution_output); // Commit the block's execution outcome to the database let provider_rw = provider_factory.provider_rw()?; - let block = block.clone().seal_slow(); provider_rw.append_blocks_with_state( - vec![block], + vec![block.clone()], &execution_outcome, Default::default(), Default::default(), @@ -92,7 +90,8 @@ where fn blocks( chain_spec: Arc, key_pair: Keypair, -) -> eyre::Result<(BlockWithSenders, BlockWithSenders)> { +) -> eyre::Result<(RecoveredBlock, RecoveredBlock)> +{ // First block has a transaction that transfers some ETH to zero address let block1 = Block { header: Header { @@ -128,7 +127,7 @@ fn blocks( // Second block resends the same transaction with increased nonce let block2 = Block { header: Header { - parent_hash: block1.header.hash_slow(), + parent_hash: block1.hash(), receipts_root: b256!( "d3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e" ), @@ -164,7 +163,7 @@ pub(crate) fn blocks_and_execution_outputs( provider_factory: ProviderFactory, chain_spec: Arc, key_pair: Keypair, -) -> eyre::Result)>> +) -> eyre::Result, BlockExecutionOutput)>> where N: ProviderNodeTypes< Primitives: FullNodePrimitives< @@ -181,9 +180,6 @@ where let block_output2 = execute_block_and_commit_to_database(&provider_factory, chain_spec, &block2)?; - let block1 = block1.seal_slow(); - let block2 = block2.seal_slow(); - Ok(vec![(block1, block_output1), (block2, block_output2)]) } @@ -191,7 +187,7 @@ pub(crate) fn blocks_and_execution_outcome( provider_factory: ProviderFactory, chain_spec: Arc, key_pair: Keypair, -) -> eyre::Result<(Vec, ExecutionOutcome)> +) -> eyre::Result<(Vec>, ExecutionOutcome)> where N: ProviderNodeTypes, N::Primitives: @@ -207,9 +203,6 @@ where let mut execution_outcome = executor.execute_and_verify_batch(vec![&block1, &block2])?; execution_outcome.state_mut().reverts.sort(); - let block1 = block1.seal_slow(); - let block2 = block2.seal_slow(); - // Commit the block's execution outcome to the database let provider_rw = provider_factory.provider_rw()?; provider_rw.append_blocks_with_state( diff --git a/crates/exex/exex/src/manager.rs b/crates/exex/exex/src/manager.rs index b281758276..0d232e3ef2 100644 --- a/crates/exex/exex/src/manager.rs +++ b/crates/exex/exex/src/manager.rs @@ -664,7 +664,7 @@ mod tests { use reth_db_common::init::init_genesis; use reth_evm::test_utils::MockExecutorProvider; use reth_evm_ethereum::execute::EthExecutorProvider; - use reth_primitives::SealedBlockWithSenders; + use reth_primitives::RecoveredBlock; use reth_provider::{ providers::BlockchainProvider, test_utils::create_test_provider_factory, BlockReader, BlockWriter, Chain, DatabaseProviderFactory, StorageLocation, TransactionVariant, @@ -766,9 +766,9 @@ mod tests { ExExManager::new((), vec![exex_handle], 10, wal, empty_finalized_header_stream()); // Define the notification for testing - let mut block1: SealedBlockWithSenders = Default::default(); - block1.block.set_hash(B256::new([0x01; 32])); - block1.block.set_block_number(10); + let mut block1: RecoveredBlock = Default::default(); + block1.set_hash(B256::new([0x01; 32])); + block1.set_block_number(10); let notification1 = ExExNotification::ChainCommitted { new: Arc::new(Chain::new(vec![block1.clone()], Default::default(), Default::default())), @@ -784,9 +784,9 @@ mod tests { assert_eq!(exex_manager.next_id, 1); // Push another notification - let mut block2: SealedBlockWithSenders = Default::default(); - block2.block.set_hash(B256::new([0x02; 32])); - block2.block.set_block_number(20); + let mut block2: RecoveredBlock = Default::default(); + block2.set_hash(B256::new([0x02; 32])); + block2.set_block_number(20); let notification2 = ExExNotification::ChainCommitted { new: Arc::new(Chain::new(vec![block2.clone()], Default::default(), Default::default())), @@ -827,7 +827,7 @@ mod tests { ); // Push some notifications to fill part of the buffer - let mut block1: SealedBlockWithSenders = Default::default(); + let mut block1: RecoveredBlock = Default::default(); block1.set_hash(B256::new([0x01; 32])); block1.set_block_number(10); @@ -1116,13 +1116,13 @@ mod tests { assert_eq!(exex_handle.next_notification_id, 0); // Setup two blocks for the chain commit notification - let mut block1: SealedBlockWithSenders = Default::default(); - block1.block.set_hash(B256::new([0x01; 32])); - block1.block.set_block_number(10); + let mut block1: RecoveredBlock = Default::default(); + block1.set_hash(B256::new([0x01; 32])); + block1.set_block_number(10); - let mut block2: SealedBlockWithSenders = Default::default(); - block2.block.set_hash(B256::new([0x02; 32])); - block2.block.set_block_number(11); + let mut block2: RecoveredBlock = Default::default(); + block2.set_hash(B256::new([0x02; 32])); + block2.set_block_number(11); // Setup a notification let notification = ExExNotification::ChainCommitted { @@ -1169,9 +1169,9 @@ mod tests { // Set finished_height to a value higher than the block tip exex_handle.finished_height = Some(BlockNumHash::new(15, B256::random())); - let mut block1: SealedBlockWithSenders = Default::default(); - block1.block.set_hash(B256::new([0x01; 32])); - block1.block.set_block_number(10); + let mut block1: RecoveredBlock = Default::default(); + block1.set_hash(B256::new([0x01; 32])); + block1.set_block_number(10); let notification = ExExNotification::ChainCommitted { new: Arc::new(Chain::new(vec![block1.clone()], Default::default(), Default::default())), @@ -1300,7 +1300,7 @@ mod tests { genesis_block.number + 1, BlockParams { parent: Some(genesis_hash), ..Default::default() }, ) - .seal_with_senders::() + .try_recover() .unwrap(); let provider_rw = provider_factory.database_provider_rw().unwrap(); provider_rw.insert_block(block.clone(), StorageLocation::Database).unwrap(); diff --git a/crates/exex/exex/src/notifications.rs b/crates/exex/exex/src/notifications.rs index 0d361de300..f9f5dfc914 100644 --- a/crates/exex/exex/src/notifications.rs +++ b/crates/exex/exex/src/notifications.rs @@ -435,16 +435,16 @@ where #[cfg(test)] mod tests { - use crate::Wal; - use super::*; + use crate::Wal; use alloy_consensus::Header; use alloy_eips::BlockNumHash; use eyre::OptionExt; use futures::StreamExt; use reth_db_common::init::init_genesis; use reth_evm_ethereum::execute::EthExecutorProvider; - use reth_primitives::{Block, BlockExt}; + use reth_primitives::Block; + use reth_primitives_traits::Block as _; use reth_provider::{ providers::BlockchainProvider, test_utils::create_test_provider_factory, BlockWriter, Chain, DatabaseProviderFactory, StorageLocation, @@ -473,10 +473,8 @@ mod tests { BlockParams { parent: Some(genesis_hash), tx_count: Some(0), ..Default::default() }, ); let provider_rw = provider_factory.provider_rw()?; - provider_rw.insert_block( - node_head_block.clone().seal_with_senders().ok_or_eyre("failed to recover senders")?, - StorageLocation::Database, - )?; + provider_rw + .insert_block(node_head_block.clone().try_recover()?, StorageLocation::Database)?; provider_rw.commit()?; let node_head = Head { @@ -494,8 +492,7 @@ mod tests { node_head.number + 1, BlockParams { parent: Some(node_head.hash), ..Default::default() }, ) - .seal_with_senders() - .ok_or_eyre("failed to recover senders")?], + .try_recover()?], Default::default(), None, )), @@ -565,8 +562,7 @@ mod tests { ..Default::default() } .seal_slow() - .seal_with_senders() - .ok_or_eyre("failed to recover senders")?], + .try_recover()?], Default::default(), None, )), @@ -611,8 +607,7 @@ mod tests { genesis_block.number + 1, BlockParams { parent: Some(genesis_hash), tx_count: Some(0), ..Default::default() }, ) - .seal_with_senders::() - .ok_or_eyre("failed to recover senders")?; + .try_recover()?; let node_head = Head { number: node_head_block.number, hash: node_head_block.hash(), @@ -638,10 +633,7 @@ mod tests { let exex_head = ExExHead { block: exex_head_block.num_hash() }; let exex_head_notification = ExExNotification::ChainCommitted { new: Arc::new(Chain::new( - vec![exex_head_block - .clone() - .seal_with_senders() - .ok_or_eyre("failed to recover senders")?], + vec![exex_head_block.clone().try_recover()?], Default::default(), None, )), @@ -655,8 +647,7 @@ mod tests { node_head.number + 1, BlockParams { parent: Some(node_head.hash), ..Default::default() }, ) - .seal_with_senders() - .ok_or_eyre("failed to recover senders")?], + .try_recover()?], Default::default(), None, )), @@ -713,10 +704,7 @@ mod tests { ); let exex_head_notification = ExExNotification::ChainCommitted { new: Arc::new(Chain::new( - vec![exex_head_block - .clone() - .seal_with_senders() - .ok_or_eyre("failed to recover senders")?], + vec![exex_head_block.clone().try_recover()?], Default::default(), None, )), @@ -736,8 +724,7 @@ mod tests { genesis_block.number + 1, BlockParams { parent: Some(genesis_hash), ..Default::default() }, ) - .seal_with_senders() - .ok_or_eyre("failed to recover senders")?], + .try_recover()?], Default::default(), None, )), diff --git a/crates/exex/exex/src/wal/mod.rs b/crates/exex/exex/src/wal/mod.rs index fb6be6e8c8..58fb12441f 100644 --- a/crates/exex/exex/src/wal/mod.rs +++ b/crates/exex/exex/src/wal/mod.rs @@ -233,18 +233,15 @@ where #[cfg(test)] mod tests { - use std::sync::Arc; - + use crate::wal::{cache::CachedBlock, Wal}; use alloy_primitives::B256; - use eyre::OptionExt; use itertools::Itertools; use reth_exex_types::ExExNotification; use reth_provider::Chain; use reth_testing_utils::generators::{ self, random_block, random_block_range, BlockParams, BlockRangeParams, }; - - use crate::wal::{cache::CachedBlock, Wal}; + use std::sync::Arc; fn read_notifications(wal: &Wal) -> eyre::Result> { wal.inner.storage.files_range()?.map_or(Ok(Vec::new()), |range| { @@ -279,26 +276,20 @@ mod tests { // Create 4 canonical blocks and one reorged block with number 2 let blocks = random_block_range(&mut rng, 0..=3, BlockRangeParams::default()) .into_iter() - .map(|block| { - block - .seal_with_senders::() - .ok_or_eyre("failed to recover senders") - }) - .collect::>>()?; + .map(|block| block.try_recover()) + .collect::, _>>()?; let block_1_reorged = random_block( &mut rng, 1, BlockParams { parent: Some(blocks[0].hash()), ..Default::default() }, ) - .seal_with_senders::() - .ok_or_eyre("failed to recover senders")?; + .try_recover()?; let block_2_reorged = random_block( &mut rng, 2, BlockParams { parent: Some(blocks[1].hash()), ..Default::default() }, ) - .seal_with_senders::() - .ok_or_eyre("failed to recover senders")?; + .try_recover()?; // Create notifications for the above blocks. // 1. Committed notification for blocks with number 0 and 1 diff --git a/crates/exex/exex/src/wal/storage.rs b/crates/exex/exex/src/wal/storage.rs index 5e268ac5ec..e437fcd7fa 100644 --- a/crates/exex/exex/src/wal/storage.rs +++ b/crates/exex/exex/src/wal/storage.rs @@ -178,14 +178,11 @@ where #[cfg(test)] mod tests { - use std::{fs::File, sync::Arc}; - - use eyre::OptionExt; + use super::Storage; use reth_exex_types::ExExNotification; use reth_provider::Chain; use reth_testing_utils::generators::{self, random_block}; - - use super::Storage; + use std::{fs::File, sync::Arc}; #[test] fn test_roundtrip() -> eyre::Result<()> { @@ -194,12 +191,8 @@ mod tests { let temp_dir = tempfile::tempdir()?; let storage: Storage = Storage::new(&temp_dir)?; - let old_block = random_block(&mut rng, 0, Default::default()) - .seal_with_senders() - .ok_or_eyre("failed to recover senders")?; - let new_block = random_block(&mut rng, 0, Default::default()) - .seal_with_senders() - .ok_or_eyre("failed to recover senders")?; + let old_block = random_block(&mut rng, 0, Default::default()).try_recover()?; + let new_block = random_block(&mut rng, 0, Default::default()).try_recover()?; let notification = ExExNotification::ChainReorged { new: Arc::new(Chain::new(vec![new_block], Default::default(), None)), diff --git a/crates/exex/test-utils/Cargo.toml b/crates/exex/test-utils/Cargo.toml index be3d40c7f2..1bb82e97f7 100644 --- a/crates/exex/test-utils/Cargo.toml +++ b/crates/exex/test-utils/Cargo.toml @@ -27,6 +27,7 @@ reth-node-builder = { workspace = true, features = ["test-utils"] } reth-node-ethereum.workspace = true reth-payload-builder.workspace = true reth-primitives.workspace = true +reth-primitives-traits.workspace = true reth-provider = { workspace = true, features = ["test-utils"] } reth-tasks.workspace = true reth-transaction-pool = { workspace = true, features = ["test-utils"] } diff --git a/crates/exex/test-utils/src/lib.rs b/crates/exex/test-utils/src/lib.rs index bbb8c6710e..60970999bf 100644 --- a/crates/exex/test-utils/src/lib.rs +++ b/crates/exex/test-utils/src/lib.rs @@ -45,12 +45,14 @@ use reth_node_ethereum::{ EthEngineTypes, EthEvmConfig, }; use reth_payload_builder::noop::NoopPayloadBuilderService; -use reth_primitives::{BlockExt, EthPrimitives, Head, SealedBlockWithSenders, TransactionSigned}; -use reth_provider::{providers::StaticFileProvider, BlockReader, EthStorage, ProviderFactory}; +use reth_primitives::{EthPrimitives, Head, RecoveredBlock, TransactionSigned}; +use reth_primitives_traits::Block as _; +use reth_provider::{ + providers::{BlockchainProvider, StaticFileProvider}, + BlockReader, EthStorage, ProviderFactory, +}; use reth_tasks::TaskManager; use reth_transaction_pool::test_utils::{testing_pool, TestPool}; - -use reth_provider::providers::BlockchainProvider; use tempfile::TempDir; use thiserror::Error; use tokio::sync::mpsc::{Sender, UnboundedReceiver}; @@ -185,7 +187,7 @@ pub type TestExExContext = ExExContext; #[derive(Debug)] pub struct TestExExHandle { /// Genesis block that was inserted into the storage - pub genesis: SealedBlockWithSenders, + pub genesis: RecoveredBlock, /// Provider Factory for accessing the emphemeral storage of the host node pub provider_factory: ProviderFactory>, /// Channel for receiving events from the Execution Extension @@ -304,8 +306,7 @@ pub async fn test_exex_context_with_chain_spec( .block_by_hash(genesis_hash)? .ok_or_else(|| eyre::eyre!("genesis block not found"))? .seal_slow() - .seal_with_senders::() - .ok_or_else(|| eyre::eyre!("failed to recover senders"))?; + .try_recover()?; let head = Head { number: genesis.number, diff --git a/crates/exex/types/src/notification.rs b/crates/exex/types/src/notification.rs index 19e47c0a1d..fb3d6c5069 100644 --- a/crates/exex/types/src/notification.rs +++ b/crates/exex/types/src/notification.rs @@ -174,7 +174,7 @@ pub(super) mod serde_bincode_compat { use arbitrary::Arbitrary; use rand::Rng; use reth_execution_types::Chain; - use reth_primitives::SealedBlockWithSenders; + use reth_primitives::RecoveredBlock; use serde::{Deserialize, Serialize}; use serde_with::serde_as; use std::sync::Arc; @@ -193,18 +193,14 @@ pub(super) mod serde_bincode_compat { let data = Data { notification: ExExNotification::ChainReorged { old: Arc::new(Chain::new( - vec![SealedBlockWithSenders::arbitrary(&mut arbitrary::Unstructured::new( - &bytes, - )) - .unwrap()], + vec![RecoveredBlock::arbitrary(&mut arbitrary::Unstructured::new(&bytes)) + .unwrap()], Default::default(), None, )), new: Arc::new(Chain::new( - vec![SealedBlockWithSenders::arbitrary(&mut arbitrary::Unstructured::new( - &bytes, - )) - .unwrap()], + vec![RecoveredBlock::arbitrary(&mut arbitrary::Unstructured::new(&bytes)) + .unwrap()], Default::default(), None, )), diff --git a/crates/net/downloaders/src/bodies/bodies.rs b/crates/net/downloaders/src/bodies/bodies.rs index 9aed7d3b69..93efd6dd93 100644 --- a/crates/net/downloaders/src/bodies/bodies.rs +++ b/crates/net/downloaders/src/bodies/bodies.rs @@ -15,7 +15,7 @@ use reth_network_p2p::{ error::{DownloadError, DownloadResult}, }; use reth_primitives::SealedHeader; -use reth_primitives_traits::size::InMemorySize; +use reth_primitives_traits::{size::InMemorySize, Block}; use reth_storage_api::HeaderProvider; use reth_tasks::{TaskSpawner, TokioTaskExecutor}; use std::{ @@ -35,11 +35,15 @@ use tracing::info; /// All blocks in a batch are fetched at the same time. #[must_use = "Stream does nothing unless polled"] #[derive(Debug)] -pub struct BodiesDownloader { +pub struct BodiesDownloader< + B: Block, + C: BodiesClient, + Provider: HeaderProvider

, +> { /// The bodies client - client: Arc, + client: Arc, /// The consensus client - consensus: Arc>, + consensus: Arc>, /// The database handle provider: Provider, /// The maximum number of non-empty blocks per one request @@ -57,19 +61,20 @@ pub struct BodiesDownloader { /// The latest block number returned. latest_queued_block_number: Option, /// Requests in progress - in_progress_queue: BodiesRequestQueue, + in_progress_queue: BodiesRequestQueue, /// Buffered responses - buffered_responses: BinaryHeap>, + buffered_responses: BinaryHeap>, /// Queued body responses that can be returned for insertion into the database. - queued_bodies: Vec>, + queued_bodies: Vec>, /// The bodies downloader metrics. metrics: BodyDownloaderMetrics, } -impl BodiesDownloader +impl BodiesDownloader where - B: BodiesClient + 'static, - Provider: HeaderProvider + Unpin + 'static, + B: Block, + C: BodiesClient + 'static, + Provider: HeaderProvider
+ Unpin + 'static, { /// Returns the next contiguous request. fn next_headers_request(&self) -> DownloadResult>>> { @@ -97,7 +102,7 @@ where &self, range: RangeInclusive, max_non_empty: u64, - ) -> DownloadResult>>> { + ) -> DownloadResult>>> { if range.is_empty() || max_non_empty == 0 { return Ok(None) } @@ -193,16 +198,14 @@ where } /// Queues bodies and sets the latest queued block number - fn queue_bodies(&mut self, bodies: Vec>) { + fn queue_bodies(&mut self, bodies: Vec>) { self.latest_queued_block_number = Some(bodies.last().expect("is not empty").block_number()); self.queued_bodies.extend(bodies); self.metrics.queued_blocks.set(self.queued_bodies.len() as f64); } /// Removes the next response from the buffer. - fn pop_buffered_response( - &mut self, - ) -> Option> { + fn pop_buffered_response(&mut self) -> Option> { let resp = self.buffered_responses.pop()?; self.metrics.buffered_responses.decrement(1.); self.buffered_blocks_size_bytes -= resp.size(); @@ -212,10 +215,10 @@ where } /// Adds a new response to the internal buffer - fn buffer_bodies_response(&mut self, response: Vec>) { + fn buffer_bodies_response(&mut self, response: Vec>) { // take into account capacity let size = response.iter().map(BlockResponse::size).sum::() + - response.capacity() * mem::size_of::>(); + response.capacity() * mem::size_of::>(); let response = OrderedBodiesResponse { resp: response, size }; let response_len = response.len(); @@ -229,7 +232,7 @@ where } /// Returns a response if it's first block number matches the next expected. - fn try_next_buffered(&mut self) -> Option>> { + fn try_next_buffered(&mut self) -> Option>> { if let Some(next) = self.buffered_responses.peek() { let expected = self.next_expected_block_number(); let next_block_range = next.block_range(); @@ -255,7 +258,7 @@ where /// Returns the next batch of block bodies that can be returned if we have enough buffered /// bodies - fn try_split_next_batch(&mut self) -> Option>> { + fn try_split_next_batch(&mut self) -> Option>> { if self.queued_bodies.len() >= self.stream_batch_size { let next_batch = self.queued_bodies.drain(..self.stream_batch_size).collect::>(); self.queued_bodies.shrink_to_fit(); @@ -280,24 +283,19 @@ where } } -impl BodiesDownloader +impl BodiesDownloader where - B: BodiesClient + 'static, - Provider: HeaderProvider + Unpin + 'static, - Self: BodyDownloader + 'static, + B: Block + 'static, + C: BodiesClient + 'static, + Provider: HeaderProvider
+ Unpin + 'static, { /// Spawns the downloader task via [`tokio::task::spawn`] - pub fn into_task( - self, - ) -> TaskDownloader<::Header, ::Body> { + pub fn into_task(self) -> TaskDownloader { self.into_task_with(&TokioTaskExecutor::default()) } /// Convert the downloader into a [`TaskDownloader`] by spawning it via the given spawner. - pub fn into_task_with( - self, - spawner: &S, - ) -> TaskDownloader<::Header, ::Body> + pub fn into_task_with(self, spawner: &S) -> TaskDownloader where S: TaskSpawner, { @@ -305,13 +303,13 @@ where } } -impl BodyDownloader for BodiesDownloader +impl BodyDownloader for BodiesDownloader where - B: BodiesClient + 'static, - Provider: HeaderProvider + Unpin + 'static, + B: Block + 'static, + C: BodiesClient + 'static, + Provider: HeaderProvider
+ Unpin + 'static, { - type Header = Provider::Header; - type Body = B::Body; + type Block = B; /// Set a new download range (exclusive). /// @@ -356,12 +354,13 @@ where } } -impl Stream for BodiesDownloader +impl Stream for BodiesDownloader where - B: BodiesClient + 'static, - Provider: HeaderProvider + Unpin + 'static, + B: Block + 'static, + C: BodiesClient + 'static, + Provider: HeaderProvider
+ Unpin + 'static, { - type Item = BodyDownloaderResult; + type Item = BodyDownloaderResult; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.get_mut(); @@ -443,13 +442,13 @@ where } #[derive(Debug)] -struct OrderedBodiesResponse { - resp: Vec>, +struct OrderedBodiesResponse { + resp: Vec>, /// The total size of the response in bytes size: usize, } -impl OrderedBodiesResponse { +impl OrderedBodiesResponse { #[inline] fn len(&self) -> usize { self.resp.len() @@ -464,10 +463,7 @@ impl OrderedBodiesResponse { } } -impl OrderedBodiesResponse -where - H: BlockHeader, -{ +impl OrderedBodiesResponse { /// Returns the block number of the first element /// /// # Panics @@ -485,21 +481,21 @@ where } } -impl PartialEq for OrderedBodiesResponse { +impl PartialEq for OrderedBodiesResponse { fn eq(&self, other: &Self) -> bool { self.first_block_number() == other.first_block_number() } } -impl Eq for OrderedBodiesResponse {} +impl Eq for OrderedBodiesResponse {} -impl PartialOrd for OrderedBodiesResponse { +impl PartialOrd for OrderedBodiesResponse { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } -impl Ord for OrderedBodiesResponse { +impl Ord for OrderedBodiesResponse { fn cmp(&self, other: &Self) -> Ordering { self.first_block_number().cmp(&other.first_block_number()).reverse() } @@ -576,15 +572,16 @@ impl BodiesDownloaderBuilder { } /// Consume self and return the concurrent downloader. - pub fn build( + pub fn build( self, - client: B, - consensus: Arc>, + client: C, + consensus: Arc>, provider: Provider, - ) -> BodiesDownloader + ) -> BodiesDownloader where - B: BodiesClient + 'static, - Provider: HeaderProvider, + B: Block, + C: BodiesClient + 'static, + Provider: HeaderProvider
, { let Self { request_limit, @@ -646,15 +643,16 @@ mod tests { ); let (_static_dir, static_dir_path) = create_test_static_files_dir(); - let mut downloader = BodiesDownloaderBuilder::default().build( - client.clone(), - Arc::new(TestConsensus::default()), - ProviderFactory::::new( - db, - MAINNET.clone(), - StaticFileProvider::read_write(static_dir_path).unwrap(), - ), - ); + let mut downloader = BodiesDownloaderBuilder::default() + .build::( + client.clone(), + Arc::new(TestConsensus::default()), + ProviderFactory::::new( + db, + MAINNET.clone(), + StaticFileProvider::read_write(static_dir_path).unwrap(), + ), + ); downloader.set_download_range(0..=19).expect("failed to set download range"); assert_matches!( @@ -689,16 +687,17 @@ mod tests { let client = Arc::new(TestBodiesClient::default().with_bodies(bodies.clone())); let (_static_dir, static_dir_path) = create_test_static_files_dir(); - let mut downloader = - BodiesDownloaderBuilder::default().with_request_limit(request_limit).build( - client.clone(), - Arc::new(TestConsensus::default()), - ProviderFactory::::new( - db, - MAINNET.clone(), - StaticFileProvider::read_write(static_dir_path).unwrap(), - ), - ); + let mut downloader = BodiesDownloaderBuilder::default() + .with_request_limit(request_limit) + .build::( + client.clone(), + Arc::new(TestConsensus::default()), + ProviderFactory::::new( + db, + MAINNET.clone(), + StaticFileProvider::read_write(static_dir_path).unwrap(), + ), + ); downloader.set_download_range(0..=199).expect("failed to set download range"); let _ = downloader.collect::>().await; @@ -724,7 +723,7 @@ mod tests { let mut downloader = BodiesDownloaderBuilder::default() .with_stream_batch_size(stream_batch_size) .with_request_limit(request_limit) - .build( + .build::( client.clone(), Arc::new(TestConsensus::default()), ProviderFactory::::new( @@ -760,7 +759,9 @@ mod tests { let client = Arc::new(TestBodiesClient::default().with_bodies(bodies.clone())); let (_static_dir, static_dir_path) = create_test_static_files_dir(); - let mut downloader = BodiesDownloaderBuilder::default().with_stream_batch_size(100).build( + let mut downloader = BodiesDownloaderBuilder::default() + .with_stream_batch_size(100) + .build::( client.clone(), Arc::new(TestConsensus::default()), ProviderFactory::::new( @@ -806,7 +807,7 @@ mod tests { .with_stream_batch_size(10) .with_request_limit(1) .with_max_buffered_blocks_size_bytes(1) - .build( + .build::( client.clone(), Arc::new(TestConsensus::default()), ProviderFactory::::new( @@ -843,7 +844,7 @@ mod tests { let mut downloader = BodiesDownloaderBuilder::default() .with_request_limit(3) .with_stream_batch_size(100) - .build( + .build::( client.clone(), Arc::new(TestConsensus::default()), ProviderFactory::::new( diff --git a/crates/net/downloaders/src/bodies/noop.rs b/crates/net/downloaders/src/bodies/noop.rs index b7a9431a4d..bd4e9d9b9e 100644 --- a/crates/net/downloaders/src/bodies/noop.rs +++ b/crates/net/downloaders/src/bodies/noop.rs @@ -4,29 +4,26 @@ use reth_network_p2p::{ bodies::{downloader::BodyDownloader, response::BlockResponse}, error::{DownloadError, DownloadResult}, }; +use reth_primitives_traits::Block; use std::{fmt::Debug, ops::RangeInclusive}; /// A [`BodyDownloader`] implementation that does nothing. #[derive(Debug, Default)] #[non_exhaustive] -pub struct NoopBodiesDownloader { - _header: std::marker::PhantomData, - _body: std::marker::PhantomData, +pub struct NoopBodiesDownloader { + _block: std::marker::PhantomData, } -impl - BodyDownloader for NoopBodiesDownloader -{ - type Body = B; - type Header = H; +impl BodyDownloader for NoopBodiesDownloader { + type Block = B; fn set_download_range(&mut self, _: RangeInclusive) -> DownloadResult<()> { Ok(()) } } -impl Stream for NoopBodiesDownloader { - type Item = Result>, DownloadError>; +impl Stream for NoopBodiesDownloader { + type Item = Result>, DownloadError>; fn poll_next( self: std::pin::Pin<&mut Self>, diff --git a/crates/net/downloaders/src/bodies/queue.rs b/crates/net/downloaders/src/bodies/queue.rs index b9f63b143a..73e4c68e88 100644 --- a/crates/net/downloaders/src/bodies/queue.rs +++ b/crates/net/downloaders/src/bodies/queue.rs @@ -10,7 +10,7 @@ use reth_network_p2p::{ error::DownloadResult, }; use reth_primitives::SealedHeader; -use reth_primitives_traits::InMemorySize; +use reth_primitives_traits::Block; use std::{ pin::Pin, sync::Arc, @@ -20,19 +20,19 @@ use std::{ /// The wrapper around [`FuturesUnordered`] that keeps information /// about the blocks currently being requested. #[derive(Debug)] -pub(crate) struct BodiesRequestQueue { +pub(crate) struct BodiesRequestQueue> { /// Inner body request queue. - inner: FuturesUnordered>, + inner: FuturesUnordered>, /// The downloader metrics. metrics: BodyDownloaderMetrics, /// Last requested block number. pub(crate) last_requested_block_number: Option, } -impl BodiesRequestQueue +impl BodiesRequestQueue where - B: BodiesClient + 'static, - H: BlockHeader, + B: Block, + C: BodiesClient + 'static, { /// Create new instance of request queue. pub(crate) fn new(metrics: BodyDownloaderMetrics) -> Self { @@ -58,9 +58,9 @@ where /// Expects a sorted list of headers. pub(crate) fn push_new_request( &mut self, - client: Arc, - consensus: Arc>, - request: Vec>, + client: Arc, + consensus: Arc>, + request: Vec>, ) { // Set last max requested block number self.last_requested_block_number = request @@ -78,12 +78,12 @@ where } } -impl Stream for BodiesRequestQueue +impl Stream for BodiesRequestQueue where - H: BlockHeader + Send + Sync + Unpin + 'static, - B: BodiesClient + 'static, + B: Block + 'static, + C: BodiesClient + 'static, { - type Item = DownloadResult>>; + type Item = DownloadResult>>; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { self.get_mut().inner.poll_next_unpin(cx) diff --git a/crates/net/downloaders/src/bodies/request.rs b/crates/net/downloaders/src/bodies/request.rs index f8c93a2a78..aa455f5790 100644 --- a/crates/net/downloaders/src/bodies/request.rs +++ b/crates/net/downloaders/src/bodies/request.rs @@ -10,7 +10,7 @@ use reth_network_p2p::{ }; use reth_network_peers::{PeerId, WithPeerId}; use reth_primitives::{BlockBody, GotExpected, SealedBlock, SealedHeader}; -use reth_primitives_traits::InMemorySize; +use reth_primitives_traits::{Block, InMemorySize}; use std::{ collections::VecDeque, mem, @@ -38,31 +38,31 @@ use std::{ /// All errors regarding the response cause the peer to get penalized, meaning that adversaries /// that try to give us bodies that do not match the requested order are going to be penalized /// and eventually disconnected. -pub(crate) struct BodiesRequestFuture { - client: Arc, - consensus: Arc>, +pub(crate) struct BodiesRequestFuture> { + client: Arc, + consensus: Arc>, metrics: BodyDownloaderMetrics, /// Metrics for individual responses. This can be used to observe how the size (in bytes) of /// responses change while bodies are being downloaded. response_metrics: ResponseMetrics, // Headers to download. The collection is shrunk as responses are buffered. - pending_headers: VecDeque>, + pending_headers: VecDeque>, /// Internal buffer for all blocks - buffer: Vec>, - fut: Option, + buffer: Vec>, + fut: Option, /// Tracks how many bodies we requested in the last request. last_request_len: Option, } -impl BodiesRequestFuture +impl BodiesRequestFuture where - H: BlockHeader, - B: BodiesClient + 'static, + B: Block, + C: BodiesClient + 'static, { /// Returns an empty future. Use [`BodiesRequestFuture::with_headers`] to set the request. pub(crate) fn new( - client: Arc, - consensus: Arc>, + client: Arc, + consensus: Arc>, metrics: BodyDownloaderMetrics, ) -> Self { Self { @@ -77,7 +77,7 @@ where } } - pub(crate) fn with_headers(mut self, headers: Vec>) -> Self { + pub(crate) fn with_headers(mut self, headers: Vec>) -> Self { self.buffer.reserve_exact(headers.len()); self.pending_headers = VecDeque::from(headers); // Submit the request only if there are any headers to download. @@ -163,9 +163,9 @@ where /// /// This method removes headers from the internal collection. /// If the response fails validation, then the header will be put back. - fn try_buffer_blocks(&mut self, bodies: Vec) -> DownloadResult<()> + fn try_buffer_blocks(&mut self, bodies: Vec) -> DownloadResult<()> where - B::Body: InMemorySize, + C::Body: InMemorySize, { let bodies_capacity = bodies.capacity(); let bodies_len = bodies.len(); @@ -180,7 +180,7 @@ where if next_header.is_empty() { // increment empty block body metric - total_size += mem::size_of::(); + total_size += mem::size_of::(); self.buffer.push(BlockResponse::Empty(next_header)); } else { let next_body = bodies.next().unwrap(); @@ -188,7 +188,7 @@ where // increment full block body metric total_size += next_body.size(); - let block = SealedBlock::new(next_header, next_body); + let block = SealedBlock::from_sealed_parts(next_header, next_body); if let Err(error) = self.consensus.validate_block_pre_execution(&block) { // Body is invalid, put the header back and return an error @@ -214,12 +214,12 @@ where } } -impl Future for BodiesRequestFuture +impl Future for BodiesRequestFuture where - H: BlockHeader + Unpin + Send + Sync + 'static, - B: BodiesClient + 'static, + B: Block + 'static, + C: BodiesClient + 'static, { - type Output = DownloadResult>>; + type Output = DownloadResult>>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = self.get_mut(); @@ -275,7 +275,7 @@ mod tests { let headers = random_header_range(&mut rng, 0..20, B256::ZERO); let client = Arc::new(TestBodiesClient::default()); - let fut = BodiesRequestFuture::new( + let fut = BodiesRequestFuture::::new( client.clone(), Arc::new(TestConsensus::default()), BodyDownloaderMetrics::default(), @@ -299,7 +299,7 @@ mod tests { let client = Arc::new( TestBodiesClient::default().with_bodies(bodies.clone()).with_max_batch_size(batch_size), ); - let fut = BodiesRequestFuture::new( + let fut = BodiesRequestFuture::::new( client.clone(), Arc::new(TestConsensus::default()), BodyDownloaderMetrics::default(), diff --git a/crates/net/downloaders/src/bodies/task.rs b/crates/net/downloaders/src/bodies/task.rs index 863c889532..d3093aec49 100644 --- a/crates/net/downloaders/src/bodies/task.rs +++ b/crates/net/downloaders/src/bodies/task.rs @@ -6,6 +6,7 @@ use reth_network_p2p::{ bodies::downloader::{BodyDownloader, BodyDownloaderResult}, error::DownloadResult, }; +use reth_primitives_traits::Block; use reth_tasks::{TaskSpawner, TokioTaskExecutor}; use std::{ fmt::Debug, @@ -24,15 +25,13 @@ pub const BODIES_TASK_BUFFER_SIZE: usize = 4; /// A [BodyDownloader] that drives a spawned [BodyDownloader] on a spawned task. #[derive(Debug)] #[pin_project] -pub struct TaskDownloader { +pub struct TaskDownloader { #[pin] - from_downloader: ReceiverStream>, + from_downloader: ReceiverStream>, to_downloader: UnboundedSender>, } -// === impl TaskDownloader === - -impl TaskDownloader { +impl TaskDownloader { /// Spawns the given `downloader` via [`tokio::task::spawn`] returns a [`TaskDownloader`] that's /// connected to that task. /// @@ -46,25 +45,27 @@ impl TaskDow /// use reth_consensus::{Consensus, ConsensusError}; /// use reth_downloaders::bodies::{bodies::BodiesDownloaderBuilder, task::TaskDownloader}; /// use reth_network_p2p::bodies::client::BodiesClient; - /// use reth_primitives_traits::InMemorySize; + /// use reth_primitives_traits::{Block, InMemorySize}; /// use reth_storage_api::HeaderProvider; /// use std::{fmt::Debug, sync::Arc}; /// /// fn t< - /// B: BodiesClient + 'static, - /// Provider: HeaderProvider
+ Unpin + 'static, + /// B: Block + 'static, + /// C: BodiesClient + 'static, + /// Provider: HeaderProvider
+ Unpin + 'static, /// >( - /// client: Arc, - /// consensus: Arc>, + /// client: Arc, + /// consensus: Arc>, /// provider: Provider, /// ) { - /// let downloader = BodiesDownloaderBuilder::default().build(client, consensus, provider); + /// let downloader = + /// BodiesDownloaderBuilder::default().build::(client, consensus, provider); /// let downloader = TaskDownloader::spawn(downloader); /// } /// ``` pub fn spawn(downloader: T) -> Self where - T: BodyDownloader
+ 'static, + T: BodyDownloader + 'static, { Self::spawn_with(downloader, &TokioTaskExecutor::default()) } @@ -73,7 +74,7 @@ impl TaskDow /// that's connected to that task. pub fn spawn_with(downloader: T, spawner: &S) -> Self where - T: BodyDownloader
+ 'static, + T: BodyDownloader + 'static, S: TaskSpawner, { let (bodies_tx, bodies_rx) = mpsc::channel(BODIES_TASK_BUFFER_SIZE); @@ -91,11 +92,8 @@ impl TaskDow } } -impl - BodyDownloader for TaskDownloader -{ - type Header = H; - type Body = B; +impl BodyDownloader for TaskDownloader { + type Block = B; fn set_download_range(&mut self, range: RangeInclusive) -> DownloadResult<()> { let _ = self.to_downloader.send(range); @@ -103,8 +101,8 @@ impl Stream for TaskDownloader { - type Item = BodyDownloaderResult; +impl Stream for TaskDownloader { + type Item = BodyDownloaderResult; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { self.project().from_downloader.poll_next(cx) @@ -114,7 +112,7 @@ impl Stream for TaskDownloader { /// A [`BodyDownloader`] that runs on its own task struct SpawnedDownloader { updates: UnboundedReceiverStream>, - bodies_tx: PollSender>, + bodies_tx: PollSender>, downloader: T, } @@ -197,7 +195,7 @@ mod tests { let client = Arc::new( TestBodiesClient::default().with_bodies(bodies.clone()).with_should_delay(true), ); - let downloader = BodiesDownloaderBuilder::default().build( + let downloader = BodiesDownloaderBuilder::default().build::( client.clone(), Arc::new(TestConsensus::default()), factory, @@ -219,7 +217,7 @@ mod tests { reth_tracing::init_test_tracing(); let factory = create_test_provider_factory(); - let downloader = BodiesDownloaderBuilder::default().build( + let downloader = BodiesDownloaderBuilder::default().build::( Arc::new(TestBodiesClient::default()), Arc::new(TestConsensus::default()), factory, diff --git a/crates/net/downloaders/src/bodies/test_utils.rs b/crates/net/downloaders/src/bodies/test_utils.rs index 6ca012f9c6..eb87f1c2b4 100644 --- a/crates/net/downloaders/src/bodies/test_utils.rs +++ b/crates/net/downloaders/src/bodies/test_utils.rs @@ -7,13 +7,14 @@ use alloy_primitives::B256; use reth_db::{tables, DatabaseEnv}; use reth_db_api::{database::Database, transaction::DbTxMut}; use reth_network_p2p::bodies::response::BlockResponse; -use reth_primitives::{Block, BlockBody, SealedBlock, SealedHeader}; +use reth_primitives::{BlockBody, SealedBlock, SealedHeader}; +use reth_primitives_traits::Block; use std::collections::HashMap; -pub(crate) fn zip_blocks<'a, H: Clone + BlockHeader + 'a, B>( - headers: impl Iterator>, - bodies: &mut HashMap, -) -> Vec> { +pub(crate) fn zip_blocks<'a, B: Block>( + headers: impl Iterator>, + bodies: &mut HashMap, +) -> Vec> { headers .into_iter() .map(|header| { @@ -21,7 +22,7 @@ pub(crate) fn zip_blocks<'a, H: Clone + BlockHeader + 'a, B>( if header.is_empty() { BlockResponse::Empty(header.clone()) } else { - BlockResponse::Full(SealedBlock::new(header.clone(), body)) + BlockResponse::Full(SealedBlock::from_sealed_parts(header.clone(), body)) } }) .collect() @@ -30,7 +31,7 @@ pub(crate) fn zip_blocks<'a, H: Clone + BlockHeader + 'a, B>( pub(crate) fn create_raw_bodies( headers: impl IntoIterator, bodies: &mut HashMap, -) -> Vec { +) -> Vec { headers .into_iter() .map(|header| { @@ -45,7 +46,7 @@ pub(crate) fn insert_headers(db: &DatabaseEnv, headers: &[SealedHeader]) { db.update(|tx| { for header in headers { tx.put::(header.number, header.hash()).unwrap(); - tx.put::(header.number, header.clone().unseal()).unwrap(); + tx.put::(header.number, header.clone_header()).unwrap(); } }) .expect("failed to commit") diff --git a/crates/net/downloaders/src/file_client.rs b/crates/net/downloaders/src/file_client.rs index 9230af5415..4cc9f0eaa1 100644 --- a/crates/net/downloaders/src/file_client.rs +++ b/crates/net/downloaders/src/file_client.rs @@ -11,6 +11,7 @@ use reth_network_p2p::{ error::RequestError, headers::client::{HeadersClient, HeadersDirection, HeadersFut, HeadersRequest}, priority::Priority, + BlockClient, }; use reth_network_peers::PeerId; use reth_primitives::SealedHeader; @@ -40,7 +41,7 @@ pub const DEFAULT_BYTE_LEN_CHUNK_CHAIN_FILE: u64 = 1_000_000_000; /// transactions in memory for use in the bodies stage. /// /// This reads the entire file into memory, so it is not suitable for large files. -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct FileClient { /// The buffered headers retrieved when fetching new bodies. headers: HashMap, @@ -116,7 +117,7 @@ impl FileClient { /// Clones and returns the highest header of this client has or `None` if empty. Seals header /// before returning. pub fn tip_header(&self) -> Option> { - self.headers.get(&self.max_block()?).map(|h| SealedHeader::seal(h.clone())) + self.headers.get(&self.max_block()?).map(|h| SealedHeader::seal_slow(h.clone())) } /// Returns true if all blocks are canonical (no gaps) @@ -350,6 +351,10 @@ impl DownloadClient for FileClient { } } +impl BlockClient for FileClient { + type Block = B; +} + /// Chunks file into several [`FileClient`]s. #[derive(Debug)] pub struct ChunkedFileReader { @@ -546,11 +551,12 @@ mod tests { let client: Arc = Arc::new(FileClient::from_file(file.into()).await.unwrap().with_bodies(bodies.clone())); - let mut downloader = BodiesDownloaderBuilder::default().build( - client.clone(), - Arc::new(TestConsensus::default()), - factory, - ); + let mut downloader = BodiesDownloaderBuilder::default() + .build::( + client.clone(), + Arc::new(TestConsensus::default()), + factory, + ); downloader.set_download_range(0..=19).expect("failed to set download range"); assert_matches!( @@ -571,10 +577,10 @@ mod tests { let file = tempfile::tempfile().unwrap(); let client: Arc = Arc::new( FileClient::from_file(file.into()).await.unwrap().with_headers(HashMap::from([ - (0u64, p0.clone().unseal()), - (1, p1.clone().unseal()), - (2, p2.clone().unseal()), - (3, p3.clone().unseal()), + (0u64, p0.clone_header()), + (1, p1.clone_header()), + (2, p2.clone_header()), + (3, p3.clone_header()), ])), ); @@ -628,11 +634,12 @@ mod tests { // insert headers in db for the bodies downloader insert_headers(factory.db_ref().db(), &headers); - let mut downloader = BodiesDownloaderBuilder::default().build( - client.clone(), - Arc::new(TestConsensus::default()), - factory, - ); + let mut downloader = BodiesDownloaderBuilder::default() + .build::( + client.clone(), + Arc::new(TestConsensus::default()), + factory, + ); downloader.set_download_range(0..=19).expect("failed to set download range"); assert_matches!( diff --git a/crates/net/downloaders/src/headers/noop.rs b/crates/net/downloaders/src/headers/noop.rs index e9dee56dd2..45a0656c4a 100644 --- a/crates/net/downloaders/src/headers/noop.rs +++ b/crates/net/downloaders/src/headers/noop.rs @@ -1,3 +1,4 @@ +use alloy_primitives::Sealable; use futures::Stream; use reth_network_p2p::headers::{ downloader::{HeaderDownloader, SyncTarget}, @@ -11,7 +12,9 @@ use std::fmt::Debug; #[non_exhaustive] pub struct NoopHeaderDownloader(std::marker::PhantomData); -impl HeaderDownloader for NoopHeaderDownloader { +impl HeaderDownloader + for NoopHeaderDownloader +{ type Header = H; fn update_local_head(&mut self, _: SealedHeader) {} @@ -21,7 +24,7 @@ impl HeaderDownloader for NoopHeaderDo fn set_batch_size(&mut self, _: usize) {} } -impl Stream for NoopHeaderDownloader { +impl Stream for NoopHeaderDownloader { type Item = Result>, HeadersDownloaderError>; fn poll_next( diff --git a/crates/net/downloaders/src/headers/reverse_headers.rs b/crates/net/downloaders/src/headers/reverse_headers.rs index be359134e7..95cbe1fad4 100644 --- a/crates/net/downloaders/src/headers/reverse_headers.rs +++ b/crates/net/downloaders/src/headers/reverse_headers.rs @@ -4,7 +4,7 @@ use super::task::TaskDownloader; use crate::metrics::HeaderDownloaderMetrics; use alloy_consensus::BlockHeader; use alloy_eips::BlockHashOrNumber; -use alloy_primitives::{BlockNumber, B256}; +use alloy_primitives::{BlockNumber, Sealable, B256}; use futures::{stream::Stream, FutureExt}; use futures_util::{stream::FuturesUnordered, StreamExt}; use rayon::prelude::*; @@ -40,14 +40,14 @@ const REQUESTS_PER_PEER_MULTIPLIER: usize = 5; /// Wrapper for internal downloader errors. #[derive(Error, Debug)] -enum ReverseHeadersDownloaderError { +enum ReverseHeadersDownloaderError { #[error(transparent)] Downloader(#[from] HeadersDownloaderError), #[error(transparent)] Response(#[from] Box), } -impl From for ReverseHeadersDownloaderError { +impl From for ReverseHeadersDownloaderError { fn from(value: HeadersResponseError) -> Self { Self::Response(Box::new(value)) } @@ -251,7 +251,8 @@ where ) -> Result<(), ReverseHeadersDownloaderError> { let mut validated = Vec::with_capacity(headers.len()); - let sealed_headers = headers.into_par_iter().map(SealedHeader::seal).collect::>(); + let sealed_headers = + headers.into_par_iter().map(SealedHeader::seal_slow).collect::>(); for parent in sealed_headers { // Validate that the header is the parent header of the last validated header. if let Some(validated_header) = @@ -378,7 +379,7 @@ where } let header = headers.swap_remove(0); - let target = SealedHeader::seal(header); + let target = SealedHeader::seal_slow(header); match sync_target { SyncTargetBlock::Hash(hash) | SyncTargetBlock::HashAndNumber { hash, .. } => { diff --git a/crates/net/downloaders/src/headers/task.rs b/crates/net/downloaders/src/headers/task.rs index 3dbfd5e361..f2084de872 100644 --- a/crates/net/downloaders/src/headers/task.rs +++ b/crates/net/downloaders/src/headers/task.rs @@ -1,3 +1,4 @@ +use alloy_primitives::Sealable; use futures::{FutureExt, Stream}; use futures_util::StreamExt; use pin_project::pin_project; @@ -23,7 +24,7 @@ pub const HEADERS_TASK_BUFFER_SIZE: usize = 8; /// A [HeaderDownloader] that drives a spawned [HeaderDownloader] on a spawned task. #[derive(Debug)] #[pin_project] -pub struct TaskDownloader { +pub struct TaskDownloader { #[pin] from_downloader: ReceiverStream>, H>>, to_downloader: UnboundedSender>, @@ -31,7 +32,7 @@ pub struct TaskDownloader { // === impl TaskDownloader === -impl TaskDownloader { +impl TaskDownloader { /// Spawns the given `downloader` via [`tokio::task::spawn`] and returns a [`TaskDownloader`] /// that's connected to that task. /// @@ -83,7 +84,7 @@ impl TaskDownloader { } } -impl HeaderDownloader for TaskDownloader { +impl HeaderDownloader for TaskDownloader { type Header = H; fn update_sync_gap(&mut self, head: SealedHeader, target: SyncTarget) { @@ -103,7 +104,7 @@ impl HeaderDownloader for TaskDownload } } -impl Stream for TaskDownloader { +impl Stream for TaskDownloader { type Item = HeadersDownloaderResult>, H>; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { diff --git a/crates/net/downloaders/src/headers/test_utils.rs b/crates/net/downloaders/src/headers/test_utils.rs index baea409f20..34bcfd43ac 100644 --- a/crates/net/downloaders/src/headers/test_utils.rs +++ b/crates/net/downloaders/src/headers/test_utils.rs @@ -9,5 +9,5 @@ pub(crate) fn child_header(parent: &SealedHeader) -> SealedHeader { let mut child = parent.as_ref().clone(); child.number += 1; child.parent_hash = parent.hash_slow(); - SealedHeader::seal(child) + SealedHeader::seal_slow(child) } diff --git a/crates/net/network/src/fetch/client.rs b/crates/net/network/src/fetch/client.rs index e24ea167f5..c043692d26 100644 --- a/crates/net/network/src/fetch/client.rs +++ b/crates/net/network/src/fetch/client.rs @@ -11,6 +11,7 @@ use reth_network_p2p::{ error::{PeerRequestResult, RequestError}, headers::client::{HeadersClient, HeadersRequest}, priority::Priority, + BlockClient, }; use reth_network_peers::PeerId; use reth_network_types::ReputationChangeKind; @@ -96,3 +97,7 @@ impl BodiesClient for FetchClient { } } } + +impl BlockClient for FetchClient { + type Block = N::Block; +} diff --git a/crates/net/p2p/src/bodies/downloader.rs b/crates/net/p2p/src/bodies/downloader.rs index ce7827c8e8..f11473daa9 100644 --- a/crates/net/p2p/src/bodies/downloader.rs +++ b/crates/net/p2p/src/bodies/downloader.rs @@ -2,10 +2,11 @@ use super::response::BlockResponse; use crate::error::DownloadResult; use alloy_primitives::BlockNumber; use futures::Stream; -use std::{fmt::Debug, ops::RangeInclusive}; +use reth_primitives_traits::Block; +use std::ops::RangeInclusive; /// Body downloader return type. -pub type BodyDownloaderResult = DownloadResult>>; +pub type BodyDownloaderResult = DownloadResult>>; /// A downloader capable of fetching and yielding block bodies from block headers. /// @@ -13,13 +14,10 @@ pub type BodyDownloaderResult = DownloadResult>>; /// while a [`BodiesClient`][crate::bodies::client::BodiesClient] represents a client capable of /// fulfilling these requests. pub trait BodyDownloader: - Send + Sync + Stream> + Unpin + Send + Sync + Stream> + Unpin { - /// The type of header that is being used - type Header: Debug + Send + Sync + Unpin + 'static; - - /// The type of the body that is being downloaded. - type Body: Debug + Send + Sync + Unpin + 'static; + /// The Block type this downloader supports + type Block: Block + 'static; /// Method for setting the download range. fn set_download_range(&mut self, range: RangeInclusive) -> DownloadResult<()>; diff --git a/crates/net/p2p/src/bodies/response.rs b/crates/net/p2p/src/bodies/response.rs index 517c5b8798..d53ca32eb3 100644 --- a/crates/net/p2p/src/bodies/response.rs +++ b/crates/net/p2p/src/bodies/response.rs @@ -1,31 +1,26 @@ use alloy_consensus::BlockHeader; use alloy_primitives::{BlockNumber, U256}; -use reth_primitives::{BlockBody, SealedBlock, SealedHeader}; -use reth_primitives_traits::InMemorySize; +use reth_primitives::{SealedBlock, SealedHeader}; +use reth_primitives_traits::{Block, InMemorySize}; /// The block response #[derive(PartialEq, Eq, Debug, Clone)] -pub enum BlockResponse { +pub enum BlockResponse { /// Full block response (with transactions or ommers) - Full(SealedBlock), + Full(SealedBlock), /// The empty block response - Empty(SealedHeader), + Empty(SealedHeader), } -impl BlockResponse +impl BlockResponse where - H: BlockHeader, + B: Block, { - /// Return the reference to the response header - pub const fn header(&self) -> &SealedHeader { - match self { - Self::Full(block) => block.sealed_header(), - Self::Empty(header) => header, - } - } - /// Return the block number pub fn block_number(&self) -> BlockNumber { - self.header().number() + match self { + Self::Full(block) => block.number(), + Self::Empty(header) => header.number(), + } } /// Return the reference to the response header @@ -37,7 +32,7 @@ where } /// Return the reference to the response body - pub fn into_body(self) -> Option { + pub fn into_body(self) -> Option { match self { Self::Full(block) => Some(block.into_body()), Self::Empty(_) => None, @@ -45,7 +40,7 @@ where } } -impl InMemorySize for BlockResponse { +impl InMemorySize for BlockResponse { #[inline] fn size(&self) -> usize { match self { diff --git a/crates/net/p2p/src/full_block.rs b/crates/net/p2p/src/full_block.rs index 309252bb8f..c8b5154cd4 100644 --- a/crates/net/p2p/src/full_block.rs +++ b/crates/net/p2p/src/full_block.rs @@ -30,7 +30,7 @@ where Client: BlockClient, { client: Client, - consensus: Arc>, + consensus: Arc>, } impl FullBlockClient @@ -40,7 +40,7 @@ where /// Creates a new instance of `FullBlockClient`. pub fn new( client: Client, - consensus: Arc>, + consensus: Arc>, ) -> Self { Self { client, consensus } } @@ -118,7 +118,7 @@ where Client: BlockClient, { client: Client, - consensus: Arc>, + consensus: Arc>, hash: B256, request: FullBlockRequest, header: Option>, @@ -140,7 +140,7 @@ where } /// Returns the [`SealedBlock`] if the request is complete and valid. - fn take_block(&mut self) -> Option> { + fn take_block(&mut self) -> Option> { if self.header.is_none() || self.body.is_none() { return None } @@ -148,7 +148,7 @@ where let header = self.header.take().unwrap(); let resp = self.body.take().unwrap(); match resp { - BodyResponse::Validated(body) => Some(SealedBlock::new(header, body)), + BodyResponse::Validated(body) => Some(SealedBlock::from_sealed_parts(header, body)), BodyResponse::PendingValidation(resp) => { // ensure the block is valid, else retry if let Err(err) = self.consensus.validate_body_against_header(resp.data(), &header) @@ -159,7 +159,7 @@ where self.request.body = Some(self.client.get_block_body(self.hash)); return None } - Some(SealedBlock::new(header, resp.into_data())) + Some(SealedBlock::from_sealed_parts(header, resp.into_data())) } } } @@ -182,7 +182,7 @@ impl Future for FetchFullBlockFuture where Client: BlockClient + 'static, { - type Output = SealedBlock; + type Output = SealedBlock; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = self.get_mut(); @@ -196,7 +196,7 @@ where match res { Ok(maybe_header) => { let (peer, maybe_header) = - maybe_header.map(|h| h.map(SealedHeader::seal)).split(); + maybe_header.map(|h| h.map(SealedHeader::seal_slow)).split(); if let Some(header) = maybe_header { if header.hash() == this.hash { this.header = Some(header); @@ -330,7 +330,7 @@ where /// The client used to fetch headers and bodies. client: Client, /// The consensus instance used to validate the blocks. - consensus: Arc>, + consensus: Arc>, /// The block hash to start fetching from (inclusive). start_hash: B256, /// How many blocks to fetch: `len([start_hash, ..]) == count` @@ -388,7 +388,7 @@ where /// /// These are returned in falling order starting with the requested `hash`, i.e. with /// descending block numbers. - fn take_blocks(&mut self) -> Option>> { + fn take_blocks(&mut self) -> Option>> { if !self.is_bodies_complete() { // not done with bodies yet return None @@ -421,7 +421,8 @@ where } }; - valid_responses.push(SealedBlock::new(header.clone(), body)); + valid_responses + .push(SealedBlock::::from_sealed_parts(header.clone(), body)); } } @@ -429,7 +430,7 @@ where // put response hashes back into bodies map since we aren't returning them as a // response for block in valid_responses { - let (header, body) = block.split(); + let (header, body) = block.split_sealed_header_body(); self.bodies.insert(header, BodyResponse::Validated(body)); } @@ -447,7 +448,7 @@ where fn on_headers_response(&mut self, headers: WithPeerId>) { let (peer, mut headers_falling) = - headers.map(|h| h.into_iter().map(SealedHeader::seal).collect::>()).split(); + headers.map(|h| h.into_iter().map(SealedHeader::seal_slow).collect::>()).split(); // fill in the response if it's the correct length if headers_falling.len() == self.count as usize { @@ -505,7 +506,7 @@ impl Future for FetchFullBlockRangeFuture where Client: BlockClient + 'static, { - type Output = Vec>; + type Output = Vec>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = self.get_mut(); @@ -658,7 +659,7 @@ mod tests { let client = FullBlockClient::test_client(client); let received = client.get_full_block(header.hash()).await; - assert_eq!(received, SealedBlock::new(header, body)); + assert_eq!(received, SealedBlock::from_sealed_parts(header, body)); } #[tokio::test] @@ -671,7 +672,7 @@ mod tests { let received = client.get_full_block_range(header.hash(), 1).await; let received = received.first().expect("response should include a block"); - assert_eq!(*received, SealedBlock::new(header, body)); + assert_eq!(*received, SealedBlock::from_sealed_parts(header, body)); } /// Inserts headers and returns the last header and block body. @@ -687,7 +688,7 @@ mod tests { header.parent_hash = hash; header.number += 1; - sealed_header = SealedHeader::seal(header); + sealed_header = SealedHeader::seal_slow(header); client.insert(sealed_header.clone(), body.clone()); } @@ -703,7 +704,7 @@ mod tests { let received = client.get_full_block_range(header.hash(), 1).await; let received = received.first().expect("response should include a block"); - assert_eq!(*received, SealedBlock::new(header.clone(), body)); + assert_eq!(*received, SealedBlock::from_sealed_parts(header.clone(), body)); let received = client.get_full_block_range(header.hash(), 10).await; assert_eq!(received.len(), 10); @@ -722,7 +723,7 @@ mod tests { let received = client.get_full_block_range(header.hash(), 1).await; let received = received.first().expect("response should include a block"); - assert_eq!(*received, SealedBlock::new(header.clone(), body)); + assert_eq!(*received, SealedBlock::from_sealed_parts(header.clone(), body)); let received = client.get_full_block_range(header.hash(), 50).await; assert_eq!(received.len(), 50); diff --git a/crates/net/p2p/src/headers/downloader.rs b/crates/net/p2p/src/headers/downloader.rs index 1bc76924a6..1dc2f691af 100644 --- a/crates/net/p2p/src/headers/downloader.rs +++ b/crates/net/p2p/src/headers/downloader.rs @@ -1,11 +1,10 @@ use super::error::HeadersDownloaderResult; use crate::error::{DownloadError, DownloadResult}; -use alloy_consensus::BlockHeader; use alloy_eips::{eip1898::BlockWithParent, BlockHashOrNumber}; -use alloy_primitives::B256; +use alloy_primitives::{Sealable, B256}; use futures::Stream; use reth_consensus::HeaderValidator; -use reth_primitives::SealedHeader; +use reth_primitives_traits::{BlockHeader, SealedHeader}; use std::fmt::Debug; /// A downloader capable of fetching and yielding block headers. @@ -22,7 +21,7 @@ pub trait HeaderDownloader: + Unpin { /// The header type being downloaded. - type Header: Debug + Send + Sync + Unpin + 'static; + type Header: Sealable + Debug + Send + Sync + Unpin + 'static; /// Updates the gap to sync which ranges from local head to the sync target /// diff --git a/crates/net/p2p/src/headers/error.rs b/crates/net/p2p/src/headers/error.rs index 8757bb215f..5adf016c7d 100644 --- a/crates/net/p2p/src/headers/error.rs +++ b/crates/net/p2p/src/headers/error.rs @@ -1,3 +1,4 @@ +use alloy_primitives::Sealable; use derive_more::{Display, Error}; use reth_consensus::ConsensusError; use reth_primitives::SealedHeader; @@ -7,7 +8,7 @@ pub type HeadersDownloaderResult = Result>; /// Error variants that can happen when sending requests to a session. #[derive(Debug, Clone, Eq, PartialEq, Display, Error)] -pub enum HeadersDownloaderError { +pub enum HeadersDownloaderError { /// The downloaded header cannot be attached to the local head, /// but is valid otherwise. #[display("valid downloaded header cannot be attached to the local head: {error}")] diff --git a/crates/net/p2p/src/lib.rs b/crates/net/p2p/src/lib.rs index 7dcb77671d..bef537bdcf 100644 --- a/crates/net/p2p/src/lib.rs +++ b/crates/net/p2p/src/lib.rs @@ -47,19 +47,20 @@ pub mod test_utils; pub use bodies::client::BodiesClient; pub use headers::client::HeadersClient; +use reth_primitives_traits::Block; -/// Helper trait that unifies network behaviour needed for fetching blocks. -pub trait BlockClient: HeadersClient + BodiesClient + Unpin + Clone {} - -impl BlockClient for T where T: HeadersClient + BodiesClient + Unpin + Clone {} +/// Helper trait that unifies network behaviour needed for fetching entire blocks. +pub trait BlockClient: + HeadersClient
::Header> + + BodiesClient::Body> + + Unpin + + Clone +{ + /// The Block type that this client fetches. + type Block: Block; +} /// The [`BlockClient`] providing Ethereum block parts. -pub trait EthBlockClient: - BlockClient
-{ -} +pub trait EthBlockClient: BlockClient {} -impl EthBlockClient for T where - T: BlockClient
-{ -} +impl EthBlockClient for T where T: BlockClient {} diff --git a/crates/net/p2p/src/test_utils/full_block.rs b/crates/net/p2p/src/test_utils/full_block.rs index ee65bcb3f0..2165ddbf56 100644 --- a/crates/net/p2p/src/test_utils/full_block.rs +++ b/crates/net/p2p/src/test_utils/full_block.rs @@ -4,6 +4,7 @@ use crate::{ error::PeerRequestResult, headers::client::{HeadersClient, HeadersRequest}, priority::Priority, + BlockClient, }; use alloy_consensus::Header; use alloy_eips::{BlockHashOrNumber, BlockNumHash}; @@ -134,7 +135,7 @@ impl TestFullBlockClient { self.headers.lock().iter().max_by_key(|(_, header)| header.number).and_then( |(hash, header)| { self.bodies.lock().get(hash).map(|body| { - SealedBlock::new(SealedHeader::new(header.clone(), *hash), body.clone()) + SealedBlock::from_parts_unchecked(header.clone(), body.clone(), *hash) }) }, ) @@ -243,3 +244,7 @@ impl BodiesClient for TestFullBlockClient { ))) } } + +impl BlockClient for TestFullBlockClient { + type Block = reth_primitives::Block; +} diff --git a/crates/net/p2p/src/test_utils/headers.rs b/crates/net/p2p/src/test_utils/headers.rs index ee0d95d500..15adc3bede 100644 --- a/crates/net/p2p/src/test_utils/headers.rs +++ b/crates/net/p2p/src/test_utils/headers.rs @@ -12,7 +12,7 @@ use crate::{ }; use alloy_consensus::Header; use futures::{Future, FutureExt, Stream, StreamExt}; -use reth_consensus::{test_utils::TestConsensus, Consensus, ConsensusError}; +use reth_consensus::{test_utils::TestConsensus, HeaderValidator}; use reth_eth_wire_types::HeadersDirection; use reth_network_peers::{PeerId, WithPeerId}; use reth_primitives::SealedHeader; @@ -146,13 +146,7 @@ impl Stream for TestDownload { } let empty: SealedHeader = SealedHeader::default(); - if let Err(error) = - >::validate_header_against_parent( - &this.consensus, - &empty, - &empty, - ) - { + if let Err(error) = this.consensus.validate_header_against_parent(&empty, &empty) { this.done = true; return Poll::Ready(Some(Err(DownloadError::HeaderValidation { hash: empty.hash(), @@ -165,7 +159,7 @@ impl Stream for TestDownload { Ok(resp) => { // Skip head and seal headers let mut headers = - resp.1.into_iter().skip(1).map(SealedHeader::seal).collect::>(); + resp.1.into_iter().skip(1).map(SealedHeader::seal_slow).collect::>(); headers.sort_unstable_by_key(|h| h.number); headers.into_iter().for_each(|h| this.buffer.push(h)); this.done = true; diff --git a/crates/node/builder/src/components/builder.rs b/crates/node/builder/src/components/builder.rs index 977381b658..4e67616cd4 100644 --- a/crates/node/builder/src/components/builder.rs +++ b/crates/node/builder/src/components/builder.rs @@ -10,7 +10,7 @@ use crate::{ use reth_consensus::{ConsensusError, FullConsensus}; use reth_evm::execute::BlockExecutorProvider; use reth_network::NetworkPrimitives; -use reth_node_api::{BodyTy, HeaderTy, NodeTypes, NodeTypesWithEngine, TxTy}; +use reth_node_api::{BlockTy, BodyTy, HeaderTy, NodeTypes, NodeTypesWithEngine, TxTy}; use reth_payload_builder::PayloadBuilderHandle; use reth_transaction_pool::{PoolTransaction, TransactionPool}; use std::{future::Future, marker::PhantomData}; @@ -310,6 +310,7 @@ where Primitives: NetworkPrimitives< BlockHeader = HeaderTy, BlockBody = BodyTy, + Block = BlockTy, >, >, PayloadB: PayloadServiceBuilder, @@ -393,7 +394,11 @@ pub trait NodeComponentsBuilder: Send { impl NodeComponentsBuilder for F where - N: NetworkPrimitives, BlockBody = BodyTy>, + N: NetworkPrimitives< + BlockHeader = HeaderTy, + BlockBody = BodyTy, + Block = BlockTy, + >, Node: FullNodeTypes, F: FnOnce(&BuilderContext) -> Fut + Send, Fut: Future>> + Send, diff --git a/crates/node/builder/src/components/mod.rs b/crates/node/builder/src/components/mod.rs index c5ac67e5cb..93fe031bf5 100644 --- a/crates/node/builder/src/components/mod.rs +++ b/crates/node/builder/src/components/mod.rs @@ -27,7 +27,9 @@ use reth_consensus::{ConsensusError, FullConsensus}; use reth_evm::execute::BlockExecutorProvider; use reth_network::{NetworkHandle, NetworkPrimitives}; use reth_network_api::FullNetwork; -use reth_node_api::{BodyTy, HeaderTy, NodeTypes, NodeTypesWithEngine, PayloadBuilder, TxTy}; +use reth_node_api::{ + BlockTy, BodyTy, HeaderTy, NodeTypes, NodeTypesWithEngine, PayloadBuilder, TxTy, +}; use reth_payload_builder::PayloadBuilderHandle; use reth_transaction_pool::{PoolTransaction, TransactionPool}; @@ -53,9 +55,7 @@ pub trait NodeComponents: Clone + Unpin + Send + Sync + 'stati + 'static; /// Network API. - type Network: FullNetwork< - Client: BlockClient
, Body = BodyTy>, - >; + type Network: FullNetwork>>; /// Builds new blocks. type PayloadBuilder: PayloadBuilder::Engine> @@ -102,7 +102,11 @@ pub struct Components NodeComponents for Components where - N: NetworkPrimitives, BlockBody = BodyTy>, + N: NetworkPrimitives< + BlockHeader = HeaderTy, + BlockBody = BodyTy, + Block = BlockTy, + >, Node: FullNodeTypes, Pool: TransactionPool>> + Unpin diff --git a/crates/node/builder/src/setup.rs b/crates/node/builder/src/setup.rs index 610ca7bbc7..00cc9d58f9 100644 --- a/crates/node/builder/src/setup.rs +++ b/crates/node/builder/src/setup.rs @@ -2,6 +2,7 @@ use std::sync::Arc; +use crate::BlockTy; use alloy_primitives::{BlockNumber, B256}; use reth_config::{config::StageConfig, PruneConfig}; use reth_consensus::{Consensus, ConsensusError}; @@ -14,7 +15,7 @@ use reth_exex::ExExManagerHandle; use reth_network_p2p::{ bodies::downloader::BodyDownloader, headers::downloader::HeaderDownloader, BlockClient, }; -use reth_node_api::{BodyTy, HeaderTy}; +use reth_node_api::HeaderTy; use reth_provider::{providers::ProviderNodeTypes, ProviderFactory}; use reth_stages::{prelude::DefaultStages, stages::ExecutionStage, Pipeline, StageSet}; use reth_static_file::StaticFileProducer; @@ -27,7 +28,7 @@ use tokio::sync::watch; pub fn build_networked_pipeline( config: &StageConfig, client: Client, - consensus: Arc>, + consensus: Arc, Error = ConsensusError>>, provider_factory: ProviderFactory, task_executor: &TaskExecutor, metrics_tx: reth_stages::MetricEventsSender, @@ -39,7 +40,7 @@ pub fn build_networked_pipeline( ) -> eyre::Result> where N: ProviderNodeTypes, - Client: BlockClient
, Body = BodyTy> + 'static, + Client: BlockClient> + 'static, Executor: BlockExecutorProvider, { // building network downloaders using the fetch client @@ -75,7 +76,7 @@ pub fn build_pipeline( stage_config: &StageConfig, header_downloader: H, body_downloader: B, - consensus: Arc>, + consensus: Arc, Error = ConsensusError>>, max_block: Option, metrics_tx: reth_stages::MetricEventsSender, prune_config: Option, @@ -86,7 +87,7 @@ pub fn build_pipeline( where N: ProviderNodeTypes, H: HeaderDownloader
> + 'static, - B: BodyDownloader
, Body = BodyTy> + 'static, + B: BodyDownloader> + 'static, Executor: BlockExecutorProvider, { let mut builder = Pipeline::::builder(); diff --git a/crates/node/core/src/utils.rs b/crates/node/core/src/utils.rs index 31d847da7f..184cacfb36 100644 --- a/crates/node/core/src/utils.rs +++ b/crates/node/core/src/utils.rs @@ -10,7 +10,7 @@ use reth_network_p2p::{ bodies::client::BodiesClient, headers::client::HeadersClient, priority::Priority, }; use reth_primitives::SealedBlock; -use reth_primitives_traits::SealedHeader; +use reth_primitives_traits::{Block, SealedHeader}; use std::{ env::VarError, path::{Path, PathBuf}, @@ -49,7 +49,7 @@ where eyre::bail!("Invalid number of headers received. Expected: 1. Received: 0") }; - let header = SealedHeader::seal(header); + let header = SealedHeader::seal_slow(header); let valid = match id { BlockHashOrNumber::Hash(hash) => header.hash() == hash, @@ -69,13 +69,14 @@ where } /// Get a body from network based on header -pub async fn get_single_body( +pub async fn get_single_body( client: Client, - header: SealedHeader, - consensus: impl Consensus, -) -> Result> + header: SealedHeader, + consensus: impl Consensus, +) -> Result> where - Client: BodiesClient, + B: Block, + Client: BodiesClient, { let (peer_id, response) = client.get_block_body(header.hash()).await?.split(); @@ -84,7 +85,7 @@ where eyre::bail!("Invalid number of bodies received. Expected: 1. Received: 0") }; - let block = SealedBlock::new(header, body); + let block = SealedBlock::from_sealed_parts(header, body); consensus.validate_block_pre_execution(&block)?; Ok(block) diff --git a/crates/optimism/chainspec/src/lib.rs b/crates/optimism/chainspec/src/lib.rs index 2735b77dd0..98a019e858 100644 --- a/crates/optimism/chainspec/src/lib.rs +++ b/crates/optimism/chainspec/src/lib.rs @@ -19,7 +19,7 @@ mod op_sepolia; use alloc::{boxed::Box, vec, vec::Vec}; use alloy_chains::Chain; -use alloy_consensus::Header; +use alloy_consensus::{BlockHeader, Header}; use alloy_genesis::Genesis; use alloy_primitives::{B256, U256}; pub use base::BASE_MAINNET; @@ -200,12 +200,12 @@ impl OpChainSpec { /// Caution: Caller must ensure that holocene is active in the parent header. /// /// See also [Base fee computation](https://github.com/ethereum-optimism/specs/blob/main/specs/protocol/holocene/exec-engine.md#base-fee-computation) - pub fn decode_holocene_base_fee( + pub fn decode_holocene_base_fee( &self, - parent: &Header, + parent: &H, timestamp: u64, ) -> Result { - let (elasticity, denominator) = decode_holocene_extra_data(&parent.extra_data)?; + let (elasticity, denominator) = decode_holocene_extra_data(parent.extra_data())?; let base_fee = if elasticity == 0 && denominator == 0 { parent .next_block_base_fee(self.base_fee_params_at_timestamp(timestamp)) @@ -220,15 +220,15 @@ impl OpChainSpec { /// Read from parent to determine the base fee for the next block /// /// See also [Base fee computation](https://github.com/ethereum-optimism/specs/blob/main/specs/protocol/holocene/exec-engine.md#base-fee-computation) - pub fn next_block_base_fee( + pub fn next_block_base_fee( &self, - parent: &Header, + parent: &H, timestamp: u64, ) -> Result { // > if Holocene is active in parent_header.timestamp, then the parameters from // > parent_header.extraData are used. let is_holocene_activated = - self.inner.is_fork_active_at_timestamp(OpHardfork::Holocene, parent.timestamp); + self.inner.is_fork_active_at_timestamp(OpHardfork::Holocene, parent.timestamp()); // If we are in the Holocene, we need to use the base fee params // from the parent block's extra data. diff --git a/crates/optimism/consensus/Cargo.toml b/crates/optimism/consensus/Cargo.toml index e49ffdce22..31925620c3 100644 --- a/crates/optimism/consensus/Cargo.toml +++ b/crates/optimism/consensus/Cargo.toml @@ -41,18 +41,18 @@ reth-optimism-chainspec.workspace = true [features] default = ["std"] std = [ - "reth-chainspec/std", - "reth-consensus/std", - "reth-consensus-common/std", - "reth-primitives/std", - "reth-optimism-forks/std", - "reth-optimism-chainspec/std", - "reth-optimism-primitives/std", - "alloy-eips/std", - "alloy-primitives/std", - "alloy-consensus/std", - "alloy-trie/std", - "op-alloy-consensus/std", - "reth-primitives-traits/std" + "reth-chainspec/std", + "reth-consensus/std", + "reth-consensus-common/std", + "reth-primitives/std", + "reth-primitives-traits/std", + "reth-optimism-forks/std", + "reth-optimism-chainspec/std", + "reth-optimism-primitives/std", + "alloy-eips/std", + "alloy-primitives/std", + "alloy-consensus/std", + "alloy-trie/std", + "op-alloy-consensus/std", ] optimism = ["reth-primitives/optimism", "reth-optimism-primitives/optimism"] diff --git a/crates/optimism/consensus/src/lib.rs b/crates/optimism/consensus/src/lib.rs index 5f1423211b..5d2e002d23 100644 --- a/crates/optimism/consensus/src/lib.rs +++ b/crates/optimism/consensus/src/lib.rs @@ -13,7 +13,7 @@ extern crate alloc; use alloc::sync::Arc; -use alloy_consensus::{BlockHeader, Header, EMPTY_OMMER_ROOT_HASH}; +use alloy_consensus::{BlockHeader as _, EMPTY_OMMER_ROOT_HASH}; use alloy_eips::eip7840::BlobParams; use alloy_primitives::{B64, U256}; use reth_chainspec::EthereumHardforks; @@ -28,11 +28,12 @@ use reth_consensus_common::validation::{ }; use reth_optimism_chainspec::OpChainSpec; use reth_optimism_forks::OpHardforks; -use reth_optimism_primitives::{OpBlock, OpBlockBody, OpPrimitives, OpReceipt}; -use reth_primitives::{BlockWithSenders, GotExpected, SealedBlockFor, SealedHeader}; +use reth_optimism_primitives::{OpBlock, OpPrimitives, OpReceipt}; +use reth_primitives::{GotExpected, RecoveredBlock, SealedHeader}; mod proof; pub use proof::calculate_receipt_root_no_memo_optimism; +use reth_primitives_traits::{Block, BlockBody, BlockHeader, SealedBlock}; mod validation; pub use validation::validate_block_post_execution; @@ -56,33 +57,34 @@ impl OpBeaconConsensus { impl FullConsensus for OpBeaconConsensus { fn validate_block_post_execution( &self, - block: &BlockWithSenders, + block: &RecoveredBlock, input: PostExecutionInput<'_, OpReceipt>, ) -> Result<(), ConsensusError> { - validate_block_post_execution(&block.header, &self.chain_spec, input.receipts) + validate_block_post_execution(block.header(), &self.chain_spec, input.receipts) } } -impl Consensus for OpBeaconConsensus { +impl Consensus for OpBeaconConsensus { type Error = ConsensusError; fn validate_body_against_header( &self, - body: &OpBlockBody, - header: &SealedHeader, + body: &B::Body, + header: &SealedHeader, ) -> Result<(), ConsensusError> { validate_body_against_header(body, header.header()) } - fn validate_block_pre_execution( - &self, - block: &SealedBlockFor, - ) -> Result<(), ConsensusError> { + fn validate_block_pre_execution(&self, block: &SealedBlock) -> Result<(), ConsensusError> { // Check ommers hash let ommers_hash = block.body().calculate_ommers_root(); - if block.ommers_hash != ommers_hash { + if Some(block.ommers_hash()) != ommers_hash { return Err(ConsensusError::BodyOmmersHashDiff( - GotExpected { got: ommers_hash, expected: block.ommers_hash }.into(), + GotExpected { + got: ommers_hash.unwrap_or(EMPTY_OMMER_ROOT_HASH), + expected: block.ommers_hash(), + } + .into(), )) } @@ -92,11 +94,11 @@ impl Consensus for OpBeaconConsensus { } // EIP-4895: Beacon chain push withdrawals as operations - if self.chain_spec.is_shanghai_active_at_timestamp(block.timestamp) { + if self.chain_spec.is_shanghai_active_at_timestamp(block.timestamp()) { validate_shanghai_withdrawals(block)?; } - if self.chain_spec.is_cancun_active_at_timestamp(block.timestamp) { + if self.chain_spec.is_cancun_active_at_timestamp(block.timestamp()) { validate_cancun_gas(block)?; } @@ -104,20 +106,20 @@ impl Consensus for OpBeaconConsensus { } } -impl HeaderValidator for OpBeaconConsensus { - fn validate_header(&self, header: &SealedHeader) -> Result<(), ConsensusError> { +impl HeaderValidator for OpBeaconConsensus { + fn validate_header(&self, header: &SealedHeader) -> Result<(), ConsensusError> { validate_header_gas(header.header())?; validate_header_base_fee(header.header(), &self.chain_spec) } fn validate_header_against_parent( &self, - header: &SealedHeader, - parent: &SealedHeader, + header: &SealedHeader, + parent: &SealedHeader, ) -> Result<(), ConsensusError> { validate_against_parent_hash_number(header.header(), parent)?; - if self.chain_spec.is_bedrock_active_at_block(header.number) { + if self.chain_spec.is_bedrock_active_at_block(header.number()) { validate_against_parent_timestamp(header.header(), parent.header())?; } @@ -125,12 +127,12 @@ impl HeaderValidator for OpBeaconConsensus { // // > if Holocene is active in parent_header.timestamp, then the parameters from // > parent_header.extraData are used. - if self.chain_spec.is_holocene_active_at_timestamp(parent.timestamp) { + if self.chain_spec.is_holocene_active_at_timestamp(parent.timestamp()) { let header_base_fee = header.base_fee_per_gas().ok_or(ConsensusError::BaseFeeMissing)?; let expected_base_fee = self .chain_spec - .decode_holocene_base_fee(parent, header.timestamp) + .decode_holocene_base_fee(parent.header(), header.timestamp()) .map_err(|_| ConsensusError::BaseFeeMissing)?; if expected_base_fee != header_base_fee { return Err(ConsensusError::BaseFeeDiff(GotExpected { @@ -147,7 +149,7 @@ impl HeaderValidator for OpBeaconConsensus { } // ensure that the blob gas fields for this block - if self.chain_spec.is_cancun_active_at_timestamp(header.timestamp) { + if self.chain_spec.is_cancun_active_at_timestamp(header.timestamp()) { validate_against_parent_4844(header.header(), parent.header(), BlobParams::cancun())?; } @@ -156,20 +158,20 @@ impl HeaderValidator for OpBeaconConsensus { fn validate_header_with_total_difficulty( &self, - header: &Header, + header: &H, _total_difficulty: U256, ) -> Result<(), ConsensusError> { // with OP-stack Bedrock activation number determines when TTD (eth Merge) has been reached. debug_assert!( - self.chain_spec.is_bedrock_active_at_block(header.number), + self.chain_spec.is_bedrock_active_at_block(header.number()), "manually import OVM blocks" ); - if header.nonce != B64::ZERO { + if header.nonce() != Some(B64::ZERO) { return Err(ConsensusError::TheMergeNonceIsNotZero) } - if header.ommers_hash != EMPTY_OMMER_ROOT_HASH { + if header.ommers_hash() != EMPTY_OMMER_ROOT_HASH { return Err(ConsensusError::TheMergeOmmerRootIsNotEmpty) } diff --git a/crates/optimism/evm/src/execute.rs b/crates/optimism/evm/src/execute.rs index 59fd6e0eca..bfac67fbb5 100644 --- a/crates/optimism/evm/src/execute.rs +++ b/crates/optimism/evm/src/execute.rs @@ -5,7 +5,7 @@ use crate::{ OpReceiptBuilder, ReceiptBuilderCtx, }; use alloc::{boxed::Box, sync::Arc, vec::Vec}; -use alloy_consensus::{Eip658Value, Receipt, Transaction as _}; +use alloy_consensus::{BlockHeader, Eip658Value, Receipt, Transaction as _}; use alloy_eips::eip7685::Requests; use core::fmt::Display; use op_alloy_consensus::{DepositTransaction, OpDepositReceipt}; @@ -25,8 +25,8 @@ use reth_optimism_chainspec::OpChainSpec; use reth_optimism_consensus::validate_block_post_execution; use reth_optimism_forks::OpHardfork; use reth_optimism_primitives::{DepositReceipt, OpPrimitives, OpReceipt}; -use reth_primitives::{BlockWithSenders, NodePrimitives}; -use reth_primitives_traits::{Block, BlockBody, SignedTransaction}; +use reth_primitives::{NodePrimitives, RecoveredBlock}; +use reth_primitives_traits::{BlockBody, SignedTransaction}; use reth_revm::{Database, State}; use revm_primitives::{db::DatabaseCommit, ResultAndState}; use tracing::trace; @@ -161,11 +161,11 @@ where fn apply_pre_execution_changes( &mut self, - block: &BlockWithSenders, + block: &RecoveredBlock, ) -> Result<(), Self::Error> { // Set state clear flag if the block is after the Spurious Dragon hardfork. let state_clear_flag = - (*self.chain_spec).is_spurious_dragon_active_at_block(block.header().number); + (*self.chain_spec).is_spurious_dragon_active_at_block(block.number()); self.state.set_state_clear_flag(state_clear_flag); let mut evm = self.evm_config.evm_for_block(&mut self.state, block.header()); @@ -189,21 +189,19 @@ where fn execute_transactions( &mut self, - block: &BlockWithSenders, + block: &RecoveredBlock, ) -> Result, Self::Error> { let mut evm = self.evm_config.evm_for_block(&mut self.state, block.header()); - let is_regolith = self - .chain_spec - .fork(OpHardfork::Regolith) - .active_at_timestamp(block.header().timestamp); + let is_regolith = + self.chain_spec.fork(OpHardfork::Regolith).active_at_timestamp(block.timestamp()); let mut cumulative_gas_used = 0; - let mut receipts = Vec::with_capacity(block.body().transactions().len()); + let mut receipts = Vec::with_capacity(block.body().transaction_count()); for (sender, transaction) in block.transactions_with_sender() { // The sum of the transaction’s gas limit, Tg, and the gas utilized in this block prior, // must be no greater than the block’s gasLimit. - let block_available_gas = block.header().gas_limit - cumulative_gas_used; + let block_available_gas = block.gas_limit() - cumulative_gas_used; if transaction.gas_limit() > block_available_gas && (is_regolith || !transaction.is_deposit()) { @@ -298,11 +296,10 @@ where fn apply_post_execution_changes( &mut self, - block: &BlockWithSenders, + block: &RecoveredBlock, _receipts: &[N::Receipt], ) -> Result { - let balance_increments = - post_block_balance_increments(&self.chain_spec.clone(), &block.block); + let balance_increments = post_block_balance_increments(&self.chain_spec.clone(), block); // increment balances self.state .increment_balances(balance_increments.clone()) @@ -328,7 +325,7 @@ where fn validate_block_post_execution( &self, - block: &BlockWithSenders, + block: &RecoveredBlock, receipts: &[N::Receipt], _requests: &Requests, ) -> Result<(), ConsensusError> { @@ -455,7 +452,7 @@ mod tests { // Attempt to execute a block with one deposit and one non-deposit transaction executor - .execute_and_verify_one(&BlockWithSenders::new_unchecked( + .execute_and_verify_one(&RecoveredBlock::new_unhashed( Block { header, body: BlockBody { transactions: vec![tx, tx_deposit], ..Default::default() }, @@ -531,7 +528,7 @@ mod tests { // attempt to execute an empty block with parent beacon block root, this should not fail executor - .execute_and_verify_one(&BlockWithSenders::new_unchecked( + .execute_and_verify_one(&RecoveredBlock::new_unhashed( Block { header, body: BlockBody { transactions: vec![tx, tx_deposit], ..Default::default() }, diff --git a/crates/optimism/evm/src/lib.rs b/crates/optimism/evm/src/lib.rs index 9f7ead2515..a9a88f6729 100644 --- a/crates/optimism/evm/src/lib.rs +++ b/crates/optimism/evm/src/lib.rs @@ -204,7 +204,7 @@ mod tests { }; use reth_optimism_chainspec::BASE_MAINNET; use reth_optimism_primitives::{OpBlock, OpPrimitives, OpReceipt}; - use reth_primitives::{Account, Log, Receipts, SealedBlockWithSenders}; + use reth_primitives::{Account, Log, Receipts, RecoveredBlock}; use reth_revm::{ db::{BundleState, CacheDB, EmptyDBTyped}, inspectors::NoOpInspector, @@ -530,8 +530,8 @@ mod tests { #[test] fn receipts_by_block_hash() { - // Create a default SealedBlockWithSenders object - let block: SealedBlockWithSenders = Default::default(); + // Create a default recovered block + let block: RecoveredBlock = Default::default(); // Define block hashes for block1 and block2 let block1_hash = B256::new([0x01; 32]); @@ -542,11 +542,11 @@ mod tests { let mut block2 = block; // Set the hashes of block1 and block2 - block1.block.set_block_number(10); - block1.block.set_hash(block1_hash); + block1.set_block_number(10); + block1.set_hash(block1_hash); - block2.block.set_block_number(11); - block2.block.set_hash(block2_hash); + block2.set_block_number(11); + block2.set_hash(block2_hash); // Create a random receipt object, receipt1 let receipt1 = OpReceipt::Legacy(Receipt { diff --git a/crates/optimism/node/src/engine.rs b/crates/optimism/node/src/engine.rs index cb4c88e9d5..29a13f9d8b 100644 --- a/crates/optimism/node/src/engine.rs +++ b/crates/optimism/node/src/engine.rs @@ -20,7 +20,7 @@ use reth_optimism_forks::{OpHardfork, OpHardforks}; use reth_optimism_payload_builder::{OpBuiltPayload, OpPayloadBuilderAttributes}; use reth_optimism_primitives::OpBlock; use reth_payload_validator::ExecutionPayloadValidator; -use reth_primitives::SealedBlockFor; +use reth_primitives::SealedBlock; use reth_rpc_types_compat::engine::payload::block_to_payload; use std::sync::Arc; @@ -51,7 +51,7 @@ where type ExecutionPayloadEnvelopeV4 = OpExecutionPayloadEnvelopeV4; fn block_to_payload( - block: SealedBlockFor< + block: SealedBlock< <::Primitives as NodePrimitives>::Block, >, ) -> (ExecutionPayload, ExecutionPayloadSidecar) { @@ -96,7 +96,7 @@ impl PayloadValidator for OpEngineValidator { &self, payload: ExecutionPayload, sidecar: ExecutionPayloadSidecar, - ) -> Result, PayloadError> { + ) -> Result, PayloadError> { self.inner.ensure_well_formed_payload(payload, sidecar) } } diff --git a/crates/optimism/node/src/txpool.rs b/crates/optimism/node/src/txpool.rs index 752a78405c..0cce61fb7a 100644 --- a/crates/optimism/node/src/txpool.rs +++ b/crates/optimism/node/src/txpool.rs @@ -400,10 +400,9 @@ where self.validate_all(transactions) } - fn on_new_head_block(&self, new_tip_block: &SealedBlock) + fn on_new_head_block(&self, new_tip_block: &SealedBlock) where - H: reth_primitives_traits::BlockHeader, - B: BlockBody, + B: Block, { self.inner.on_new_head_block(new_tip_block); self.update_l1_block_info( diff --git a/crates/optimism/payload/Cargo.toml b/crates/optimism/payload/Cargo.toml index 49ae3d93e8..69104acd7c 100644 --- a/crates/optimism/payload/Cargo.toml +++ b/crates/optimism/payload/Cargo.toml @@ -15,6 +15,7 @@ workspace = true # reth reth-chainspec.workspace = true reth-primitives.workspace = true +reth-primitives-traits.workspace = true reth-revm = { workspace = true, features = ["witness"] } reth-transaction-pool.workspace = true reth-provider.workspace = true diff --git a/crates/optimism/payload/src/builder.rs b/crates/optimism/payload/src/builder.rs index 7bf3f8015b..505843370a 100644 --- a/crates/optimism/payload/src/builder.rs +++ b/crates/optimism/payload/src/builder.rs @@ -25,9 +25,9 @@ use reth_payload_builder_primitives::PayloadBuilderError; use reth_payload_primitives::PayloadBuilderAttributes; use reth_payload_util::{NoopPayloadTransactions, PayloadTransactions}; use reth_primitives::{ - proofs, transaction::SignedTransactionIntoRecoveredExt, Block, BlockBody, BlockExt, - SealedHeader, TxType, + proofs, transaction::SignedTransactionIntoRecoveredExt, Block, BlockBody, SealedHeader, TxType, }; +use reth_primitives_traits::block::Block as _; use reth_provider::{ HashedPostStateProvider, ProviderError, StateProofProvider, StateProviderFactory, StateRootProvider, diff --git a/crates/optimism/payload/src/payload.rs b/crates/optimism/payload/src/payload.rs index 2b7c683df8..10c4f2780c 100644 --- a/crates/optimism/payload/src/payload.rs +++ b/crates/optimism/payload/src/payload.rs @@ -17,7 +17,7 @@ use reth_optimism_chainspec::OpChainSpec; use reth_optimism_primitives::{OpBlock, OpPrimitives, OpTransactionSigned}; use reth_payload_builder::EthPayloadBuilderAttributes; use reth_payload_primitives::{BuiltPayload, PayloadBuilderAttributes}; -use reth_primitives::{transaction::WithEncoded, SealedBlockFor}; +use reth_primitives::{transaction::WithEncoded, SealedBlock}; use reth_rpc_types_compat::engine::payload::{ block_to_payload_v1, block_to_payload_v3, convert_block_to_payload_field_v2, }; @@ -135,7 +135,7 @@ pub struct OpBuiltPayload { /// Identifier of the payload pub(crate) id: PayloadId, /// The built block - pub(crate) block: Arc>, + pub(crate) block: Arc>, /// Block execution data for the payload, if any. pub(crate) executed_block: Option>, /// The fees of the block @@ -155,7 +155,7 @@ impl OpBuiltPayload { /// Initializes the payload with the given initial block. pub const fn new( id: PayloadId, - block: Arc>, + block: Arc>, fees: U256, chain_spec: Arc, attributes: OpPayloadBuilderAttributes, @@ -170,7 +170,7 @@ impl OpBuiltPayload { } /// Returns the built block(sealed) - pub fn block(&self) -> &SealedBlockFor { + pub fn block(&self) -> &SealedBlock { &self.block } @@ -188,7 +188,7 @@ impl OpBuiltPayload { impl BuiltPayload for OpBuiltPayload { type Primitives = OpPrimitives; - fn block(&self) -> &SealedBlockFor { + fn block(&self) -> &SealedBlock { &self.block } @@ -208,7 +208,7 @@ impl BuiltPayload for OpBuiltPayload { impl BuiltPayload for &OpBuiltPayload { type Primitives = OpPrimitives; - fn block(&self) -> &SealedBlockFor { + fn block(&self) -> &SealedBlock { (**self).block() } diff --git a/crates/optimism/rpc/src/eth/pending_block.rs b/crates/optimism/rpc/src/eth/pending_block.rs index 5361d00be0..b33a3dda86 100644 --- a/crates/optimism/rpc/src/eth/pending_block.rs +++ b/crates/optimism/rpc/src/eth/pending_block.rs @@ -14,7 +14,7 @@ use reth_evm::ConfigureEvm; use reth_optimism_consensus::calculate_receipt_root_no_memo_optimism; use reth_optimism_forks::OpHardforks; use reth_optimism_primitives::{OpBlock, OpReceipt, OpTransactionSigned}; -use reth_primitives::{logs_bloom, BlockBody, SealedBlockWithSenders}; +use reth_primitives::{logs_bloom, BlockBody, RecoveredBlock}; use reth_provider::{ BlockReader, BlockReaderIdExt, ChainSpecProvider, ProviderBlock, ProviderHeader, ProviderReceipt, ProviderTx, ReceiptProvider, StateProviderFactory, @@ -64,7 +64,7 @@ where &self, ) -> Result< Option<( - SealedBlockWithSenders>, + RecoveredBlock>, Vec>, )>, Self::Error, @@ -80,8 +80,7 @@ where .provider() .block_with_senders(block_id, Default::default()) .map_err(Self::Error::from_eth_err)? - .ok_or(EthApiError::HeaderNotFound(block_id.into()))? - .seal_unchecked(latest.hash()); + .ok_or(EthApiError::HeaderNotFound(block_id.into()))?; let receipts = self .provider() diff --git a/crates/payload/basic/src/stack.rs b/crates/payload/basic/src/stack.rs index d7cf9d1311..1dd57d1556 100644 --- a/crates/payload/basic/src/stack.rs +++ b/crates/payload/basic/src/stack.rs @@ -7,7 +7,7 @@ use alloy_eips::eip4895::Withdrawals; use alloy_primitives::{Address, B256, U256}; use reth_payload_builder::PayloadId; use reth_payload_primitives::BuiltPayload; -use reth_primitives::{NodePrimitives, SealedBlockFor}; +use reth_primitives::{NodePrimitives, SealedBlock}; use alloy_eips::eip7685::Requests; use std::{error::Error, fmt}; @@ -155,7 +155,7 @@ where { type Primitives = L::Primitives; - fn block(&self) -> &SealedBlockFor<::Block> { + fn block(&self) -> &SealedBlock<::Block> { match self { Self::Left(l) => l.block(), Self::Right(r) => r.block(), diff --git a/crates/payload/builder/src/lib.rs b/crates/payload/builder/src/lib.rs index b6191ea7fd..2dbf8e86ee 100644 --- a/crates/payload/builder/src/lib.rs +++ b/crates/payload/builder/src/lib.rs @@ -31,7 +31,7 @@ //! use alloy_consensus::Header; //! use alloy_primitives::U256; //! use reth_payload_builder::{EthBuiltPayload, PayloadBuilderError, KeepPayloadJobAlive, EthPayloadBuilderAttributes, PayloadJob, PayloadJobGenerator, PayloadKind}; -//! use reth_primitives::{Block, BlockExt}; +//! use reth_primitives::{Block, SealedBlock}; //! //! /// The generator type that creates new jobs that builds empty blocks. //! pub struct EmptyBlockPayloadJobGenerator; @@ -67,7 +67,7 @@ //! }, //! ..Default::default() //! }; -//! let payload = EthBuiltPayload::new(self.attributes.id, Arc::new(block.seal_slow()), U256::ZERO, None, None); +//! let payload = EthBuiltPayload::new(self.attributes.id, Arc::new(SealedBlock::seal_slow(block)), U256::ZERO, None, None); //! Ok(payload) //! } //! diff --git a/crates/payload/builder/src/test_utils.rs b/crates/payload/builder/src/test_utils.rs index 4690ca14f0..9cd680ce65 100644 --- a/crates/payload/builder/src/test_utils.rs +++ b/crates/payload/builder/src/test_utils.rs @@ -9,7 +9,8 @@ use alloy_primitives::U256; use reth_chain_state::{CanonStateNotification, ExecutedBlock}; use reth_payload_builder_primitives::PayloadBuilderError; use reth_payload_primitives::{PayloadKind, PayloadTypes}; -use reth_primitives::{Block, BlockExt}; +use reth_primitives::Block; +use reth_primitives_traits::Block as _; use std::{ future::Future, pin::Pin, diff --git a/crates/payload/primitives/src/traits.rs b/crates/payload/primitives/src/traits.rs index a02e00d99f..05c58e35b9 100644 --- a/crates/payload/primitives/src/traits.rs +++ b/crates/payload/primitives/src/traits.rs @@ -5,7 +5,7 @@ use alloy_eips::{ use alloy_primitives::{Address, B256, U256}; use alloy_rpc_types_engine::{PayloadAttributes as EthPayloadAttributes, PayloadId}; use reth_chain_state::ExecutedBlock; -use reth_primitives::{NodePrimitives, SealedBlockFor}; +use reth_primitives::{NodePrimitives, SealedBlock}; /// Represents a built payload type that contains a built `SealedBlock` and can be converted into /// engine API execution payloads. @@ -14,7 +14,7 @@ pub trait BuiltPayload: Send + Sync + std::fmt::Debug { type Primitives: NodePrimitives; /// Returns the built block (sealed) - fn block(&self) -> &SealedBlockFor<::Block>; + fn block(&self) -> &SealedBlock<::Block>; /// Returns the fees collected for the built block fn fees(&self) -> U256; diff --git a/crates/payload/validator/src/lib.rs b/crates/payload/validator/src/lib.rs index e696e557af..ba78f1cbc8 100644 --- a/crates/payload/validator/src/lib.rs +++ b/crates/payload/validator/src/lib.rs @@ -12,8 +12,8 @@ use alloy_rpc_types::engine::{ ExecutionPayload, ExecutionPayloadSidecar, MaybeCancunPayloadFields, PayloadError, }; use reth_chainspec::EthereumHardforks; -use reth_primitives::{BlockBody, BlockExt, Header, SealedBlock}; -use reth_primitives_traits::SignedTransaction; +use reth_primitives::SealedBlock; +use reth_primitives_traits::{Block, SignedTransaction}; use std::sync::Arc; /// Execution payload validator. @@ -59,9 +59,9 @@ impl ExecutionPayloadValidator { /// /// Ensures that the number of blob versioned hashes matches the number hashes included in the /// _separate_ `block_versioned_hashes` of the cancun payload fields. - fn ensure_matching_blob_versioned_hashes( + fn ensure_matching_blob_versioned_hashes( &self, - sealed_block: &SealedBlock>, + sealed_block: &SealedBlock, cancun_fields: &MaybeCancunPayloadFields, ) -> Result<(), PayloadError> { let num_blob_versioned_hashes = sealed_block.blob_versioned_hashes_iter().count(); @@ -116,7 +116,7 @@ impl ExecutionPayloadValidator { &self, payload: ExecutionPayload, sidecar: ExecutionPayloadSidecar, - ) -> Result>, PayloadError> { + ) -> Result>, PayloadError> { let expected_hash = payload.block_hash(); // First parse the block diff --git a/crates/primitives-traits/src/block/body.rs b/crates/primitives-traits/src/block/body.rs index 279e7d45cc..7120d95b35 100644 --- a/crates/primitives-traits/src/block/body.rs +++ b/crates/primitives-traits/src/block/body.rs @@ -1,10 +1,11 @@ //! Block body abstraction. use crate::{ - BlockHeader, FullSignedTx, InMemorySize, MaybeSerde, MaybeSerdeBincodeCompat, SignedTransaction, + transaction::signed::RecoveryError, BlockHeader, FullSignedTx, InMemorySize, MaybeSerde, + MaybeSerdeBincodeCompat, SignedTransaction, }; use alloc::{fmt, vec::Vec}; -use alloy_consensus::{Header, Transaction}; +use alloy_consensus::{Header, Transaction, Typed2718}; use alloy_eips::{eip2718::Encodable2718, eip4895::Withdrawals}; use alloy_primitives::{Address, Bytes, B256}; @@ -14,6 +15,9 @@ pub trait FullBlockBody: BlockBody + MaybeSerdeBincod impl FullBlockBody for T where T: BlockBody + MaybeSerdeBincodeCompat {} /// Abstraction for block's body. +/// +/// This type is a container for everything that is included in a block except the header. +/// For ethereum this includes transactions, ommers, and withdrawals. pub trait BlockBody: Send + Sync @@ -47,9 +51,15 @@ pub trait BlockBody: fn transaction_count(&self) -> usize { self.transactions().len() } + /// Consume the block body and return a [`Vec`] of transactions. fn into_transactions(self) -> Vec; + /// Returns `true` if the block body contains a transaction of the given type. + fn contains_transaction_type(&self, tx_type: u8) -> bool { + self.transactions().iter().any(|tx| tx.is_type(tx_type)) + } + /// Calculate the transaction root for the block body. fn calculate_tx_root(&self) -> B256 { alloy_consensus::proofs::calculate_transaction_root(self.transactions()) @@ -115,6 +125,16 @@ pub trait BlockBody: crate::transaction::recover::recover_signers(self.transactions()) } + /// Recover signer addresses for all transactions in the block body. + /// + /// Returns an error if some transaction's signature is invalid. + fn try_recover_signers(&self) -> Result, RecoveryError> + where + Self::Transaction: SignedTransaction, + { + self.recover_signers().ok_or(RecoveryError) + } + /// Recover signer addresses for all transactions in the block body _without ensuring that the /// signature has a low `s` value_. /// @@ -125,6 +145,17 @@ pub trait BlockBody: { crate::transaction::recover::recover_signers_unchecked(self.transactions()) } + + /// Recover signer addresses for all transactions in the block body _without ensuring that the + /// signature has a low `s` value_. + /// + /// Returns an error if some transaction's signature is invalid. + fn try_recover_signers_unchecked(&self) -> Result, RecoveryError> + where + Self::Transaction: SignedTransaction, + { + self.recover_signers_unchecked().ok_or(RecoveryError) + } } impl BlockBody for alloy_consensus::BlockBody diff --git a/crates/primitives-traits/src/block/error.rs b/crates/primitives-traits/src/block/error.rs new file mode 100644 index 0000000000..471eeb800b --- /dev/null +++ b/crates/primitives-traits/src/block/error.rs @@ -0,0 +1,33 @@ +//! Error types for the `block` module. + +use crate::transaction::signed::RecoveryError; + +/// Type alias for [`BlockRecoveryError`] with a [`SealedBlock`](crate::SealedBlock) value. +pub type SealedBlockRecoveryError = BlockRecoveryError>; + +/// Error when recovering a block from [`SealedBlock`](crate::SealedBlock) to +/// [`RecoveredBlock`](crate::RecoveredBlock). +/// +/// This error is returned when the block recovery fails and contains the erroneous block, because +/// recovering a block takes ownership of the block. +#[derive(Debug, Clone, thiserror::Error)] +#[error("Failed to recover the block")] +pub struct BlockRecoveryError(pub T); + +impl BlockRecoveryError { + /// Create a new error. + pub const fn new(inner: T) -> Self { + Self(inner) + } + + /// Unwrap the error and return the original value. + pub fn into_inner(self) -> T { + self.0 + } +} + +impl From> for RecoveryError { + fn from(_: BlockRecoveryError) -> Self { + Self + } +} diff --git a/crates/primitives-traits/src/block/mod.rs b/crates/primitives-traits/src/block/mod.rs index 85e29995f4..f0a9c36702 100644 --- a/crates/primitives-traits/src/block/mod.rs +++ b/crates/primitives-traits/src/block/mod.rs @@ -1,17 +1,33 @@ //! Block abstraction. +pub(crate) mod sealed; +pub use sealed::SealedBlock; + +pub(crate) mod recovered; +pub use recovered::RecoveredBlock; + pub mod body; +pub mod error; pub mod header; -use alloc::fmt; +use alloc::{fmt, vec::Vec}; use alloy_consensus::Header; +use alloy_primitives::{Address, B256}; use alloy_rlp::{Decodable, Encodable}; use crate::{ - BlockBody, BlockHeader, FullBlockBody, FullBlockHeader, InMemorySize, MaybeSerde, + BlockBody, BlockHeader, FullBlockBody, FullBlockHeader, InMemorySize, MaybeSerde, SealedHeader, SignedTransaction, }; +/// Bincode-compatible header type serde implementations. +#[cfg(feature = "serde-bincode-compat")] +pub mod serde_bincode_compat { + pub use super::{ + recovered::serde_bincode_compat::RecoveredBlock, sealed::serde_bincode_compat::SealedBlock, + }; +} + /// Helper trait that unifies all behaviour required by block to support full node operations. pub trait FullBlock: Block + alloy_rlp::Encodable + alloy_rlp::Decodable @@ -29,9 +45,10 @@ impl FullBlock for T where pub type BlockTx = <::Body as BlockBody>::Transaction; /// Abstraction of block data type. -// todo: make sealable super-trait, depends on -// todo: make with senders extension trait, so block can be impl by block type already containing -// senders +/// +/// This type defines the structure of a block in the blockchain. +/// A [`Block`] is composed of a header and a body. +/// It is expected that a block can always be completely reconstructed from its header and body. pub trait Block: Send + Sync @@ -49,12 +66,30 @@ pub trait Block: /// Header part of the block. type Header: BlockHeader; - /// The block's body contains the transactions in the block. + /// The block's body contains the transactions in the block and additional data, e.g. + /// withdrawals in ethereum. type Body: BlockBody; /// Create new block instance. fn new(header: Self::Header, body: Self::Body) -> Self; + /// Create new a sealed block instance from a sealed header and the block body. + fn new_sealed(header: SealedHeader, body: Self::Body) -> SealedBlock { + SealedBlock::from_sealed_parts(header, body) + } + + /// Seal the block with a known hash. + /// + /// WARNING: This method does not perform validation whether the hash is correct. + fn seal(self, hash: B256) -> SealedBlock { + SealedBlock::new_unchecked(self, hash) + } + + /// Calculate the header hash and seal the block so that it can't be changed. + fn seal_slow(self) -> SealedBlock { + SealedBlock::seal_slow(self) + } + /// Returns reference to block header. fn header(&self) -> &Self::Header; @@ -63,6 +98,84 @@ pub trait Block: /// Splits the block into its header and body. fn split(self) -> (Self::Header, Self::Body); + + /// Returns a tuple of references to the block's header and body. + fn split_ref(&self) -> (&Self::Header, &Self::Body) { + (self.header(), self.body()) + } + + /// Consumes the block and returns the header. + fn into_header(self) -> Self::Header { + self.split().0 + } + + /// Consumes the block and returns the body. + fn into_body(self) -> Self::Body { + self.split().1 + } + + /// Returns the rlp length of the block with the given header and body. + fn rlp_length(header: &Self::Header, body: &Self::Body) -> usize { + // TODO(mattsse): replace default impl with + header.length() + body.length() + } + + /// Expensive operation that recovers transaction signer. + fn senders(&self) -> Option> + where + ::Transaction: SignedTransaction, + { + self.body().recover_signers() + } + + /// Transform into a [`RecoveredBlock`]. + /// + /// # Panics + /// + /// If the number of senders does not match the number of transactions in the block + /// and the signer recovery for one of the transactions fails. + /// + /// Note: this is expected to be called with blocks read from disk. + #[track_caller] + fn with_senders_unchecked(self, senders: Vec
) -> RecoveredBlock + where + ::Transaction: SignedTransaction, + { + self.try_with_senders_unchecked(senders).expect("stored block is valid") + } + + /// Transform into a [`RecoveredBlock`] using the given senders. + /// + /// 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_. + /// + /// Returns an error if a signature is invalid. + #[track_caller] + fn try_with_senders_unchecked(self, senders: Vec
) -> Result, Self> + where + ::Transaction: SignedTransaction, + { + let senders = if self.body().transactions().len() == senders.len() { + senders + } else { + let Some(senders) = self.body().recover_signers_unchecked() else { return Err(self) }; + senders + }; + + Ok(RecoveredBlock::new_unhashed(self, senders)) + } + + /// **Expensive**. Transform into a [`RecoveredBlock`] by recovering senders in the contained + /// transactions. + /// + /// Returns `None` if a transaction is invalid. + fn with_recovered_senders(self) -> Option> + where + ::Transaction: SignedTransaction, + { + let senders = self.senders()?; + Some(RecoveredBlock::new_unhashed(self, senders)) + } } impl Block for alloy_consensus::Block diff --git a/crates/primitives-traits/src/block/recovered.rs b/crates/primitives-traits/src/block/recovered.rs new file mode 100644 index 0000000000..0828646cf1 --- /dev/null +++ b/crates/primitives-traits/src/block/recovered.rs @@ -0,0 +1,598 @@ +//! Recovered Block variant. + +use crate::{ + block::{error::SealedBlockRecoveryError, SealedBlock}, + transaction::signed::{RecoveryError, SignedTransactionIntoRecoveredExt}, + Block, BlockBody, InMemorySize, SealedHeader, +}; +use alloc::vec::Vec; +use alloy_consensus::{transaction::Recovered, BlockHeader}; +use alloy_eips::{eip1898::BlockWithParent, BlockNumHash}; +use alloy_primitives::{Address, BlockHash, BlockNumber, Bloom, Bytes, Sealed, B256, B64, U256}; +use derive_more::Deref; + +/// A block with senders recovered from the block's transactions. +/// +/// This type is a [`SealedBlock`] with a list of senders that match the transactions in the block. +/// +/// ## Sealing +/// +/// This type uses lazy sealing to avoid hashing the header until it is needed: +/// +/// [`RecoveredBlock::new_unhashed`] creates a recovered block without hashing the header. +/// [`RecoveredBlock::new`] creates a recovered block with the corresponding block hash. +/// +/// ## Recovery +/// +/// Sender recovery is fallible and can fail if any of the transactions fail to recover the sender. +/// A [`SealedBlock`] can be upgraded to a [`RecoveredBlock`] using the +/// [`RecoveredBlock::try_recover`] or [`SealedBlock::try_recover`] method. +#[derive(Debug, Clone, Deref)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct RecoveredBlock { + /// Block + #[deref] + #[cfg_attr( + feature = "serde", + serde(bound = "SealedBlock: serde::Serialize + serde::de::DeserializeOwned") + )] + block: SealedBlock, + /// List of senders that match the transactions in the block + senders: Vec
, +} + +impl RecoveredBlock { + /// Creates a new recovered block instance with the given senders as provided and the block + /// hash. + /// + /// Note: This expects that the given senders match the transactions in the block. + pub fn new(block: B, senders: Vec
, hash: BlockHash) -> Self { + Self { block: SealedBlock::new_unchecked(block, hash), senders } + } + + /// Creates a new recovered block instance with the given senders as provided. + /// + /// Note: This expects that the given senders match the transactions in the block. + pub fn new_unhashed(block: B, senders: Vec
) -> Self { + Self { block: SealedBlock::new_unhashed(block), senders } + } + + /// Returns the recovered senders. + pub fn senders(&self) -> &[Address] { + &self.senders + } + + /// Returns an iterator over the recovered senders. + pub fn senders_iter(&self) -> impl Iterator { + self.senders.iter() + } + + /// Consumes the type and returns the inner block. + pub fn into_block(self) -> B { + self.block.into_block() + } + + /// Returns a reference to the sealed block. + pub const fn sealed_block(&self) -> &SealedBlock { + &self.block + } + + /// Creates a new recovered block instance with the given [`SealedBlock`] and senders as + /// provided + pub const fn new_sealed(block: SealedBlock, senders: Vec
) -> Self { + Self { block, senders } + } + + /// A safer variant of [`Self::new_unhashed`] that checks if the number of senders is equal to + /// the number of transactions in the block and recovers the senders from the transactions, if + /// not using [`SignedTransaction::recover_signer`](crate::transaction::signed::SignedTransaction) + /// to recover the senders. + pub fn try_new( + block: B, + senders: Vec
, + hash: BlockHash, + ) -> Result> { + let senders = if block.body().transaction_count() == senders.len() { + senders + } else { + let Ok(senders) = block.body().try_recover_signers() else { + return Err(SealedBlockRecoveryError::new(SealedBlock::new_unchecked(block, hash))); + }; + senders + }; + Ok(Self::new(block, senders, hash)) + } + + /// A safer variant of [`Self::new`] that checks if the number of senders is equal to + /// the number of transactions in the block and recovers the senders from the transactions, if + /// not using [`SignedTransaction::recover_signer_unchecked`](crate::transaction::signed::SignedTransaction) + /// to recover the senders. + pub fn try_new_unchecked( + block: B, + senders: Vec
, + hash: BlockHash, + ) -> Result> { + let senders = if block.body().transaction_count() == senders.len() { + senders + } else { + let Ok(senders) = block.body().try_recover_signers_unchecked() else { + return Err(SealedBlockRecoveryError::new(SealedBlock::new_unchecked(block, hash))); + }; + senders + }; + Ok(Self::new(block, senders, hash)) + } + + /// A safer variant of [`Self::new_unhashed`] that checks if the number of senders is equal to + /// the number of transactions in the block and recovers the senders from the transactions, if + /// not using [`SignedTransaction::recover_signer`](crate::transaction::signed::SignedTransaction) + /// to recover the senders. + pub fn try_new_unhashed(block: B, senders: Vec
) -> Result { + let senders = if block.body().transaction_count() == senders.len() { + senders + } else { + block.body().try_recover_signers()? + }; + Ok(Self::new_unhashed(block, senders)) + } + + /// A safer variant of [`Self::new_unhashed`] that checks if the number of senders is equal to + /// the number of transactions in the block and recovers the senders from the transactions, if + /// not using [`SignedTransaction::recover_signer_unchecked`](crate::transaction::signed::SignedTransaction) + /// to recover the senders. + pub fn try_new_unhashed_unchecked( + block: B, + senders: Vec
, + ) -> Result { + let senders = if block.body().transaction_count() == senders.len() { + senders + } else { + block.body().try_recover_signers_unchecked()? + }; + Ok(Self::new_unhashed(block, senders)) + } + + /// Recovers the senders from the transactions in the block using + /// [`SignedTransaction::recover_signer`](crate::transaction::signed::SignedTransaction). + /// + /// Returns an error if any of the transactions fail to recover the sender. + pub fn try_recover(block: B) -> Result { + let senders = block.body().try_recover_signers()?; + Ok(Self::new_unhashed(block, senders)) + } + + /// Recovers the senders from the transactions in the block using + /// [`SignedTransaction::recover_signer_unchecked`](crate::transaction::signed::SignedTransaction). + /// + /// Returns an error if any of the transactions fail to recover the sender. + pub fn try_recover_unchecked(block: B) -> Result { + let senders = block.body().try_recover_signers_unchecked()?; + Ok(Self::new_unhashed(block, senders)) + } + + /// Recovers the senders from the transactions in the block using + /// [`SignedTransaction::recover_signer`](crate::transaction::signed::SignedTransaction). + /// + /// Returns an error if any of the transactions fail to recover the sender. + pub fn try_recover_sealed(block: SealedBlock) -> Result> { + let Ok(senders) = block.body().try_recover_signers() else { + return Err(SealedBlockRecoveryError::new(block)); + }; + let (block, hash) = block.split(); + Ok(Self::new(block, senders, hash)) + } + + /// Recovers the senders from the transactions in the sealed block using + /// [`SignedTransaction::recover_signer_unchecked`](crate::transaction::signed::SignedTransaction). + /// + /// Returns an error if any of the transactions fail to recover the sender. + pub fn try_recover_sealed_unchecked( + block: SealedBlock, + ) -> Result> { + let Ok(senders) = block.body().try_recover_signers_unchecked() else { + return Err(SealedBlockRecoveryError::new(block)); + }; + let (block, hash) = block.split(); + Ok(Self::new(block, senders, hash)) + } + + /// A safer variant of [`Self::new_unhashed`] that checks if the number of senders is equal to + /// the number of transactions in the block and recovers the senders from the transactions, if + /// not using [`SignedTransaction::recover_signer_unchecked`](crate::transaction::signed::SignedTransaction) + /// to recover the senders. + /// + /// Returns an error if any of the transactions fail to recover the sender. + pub fn try_recover_sealed_with_senders( + block: SealedBlock, + senders: Vec
, + ) -> Result> { + let (block, hash) = block.split(); + Self::try_new(block, senders, hash) + } + + /// A safer variant of [`Self::new`] that checks if the number of senders is equal to + /// the number of transactions in the block and recovers the senders from the transactions, if + /// not using [`SignedTransaction::recover_signer_unchecked`](crate::transaction::signed::SignedTransaction) + /// to recover the senders. + pub fn try_recover_sealed_with_senders_unchecked( + block: SealedBlock, + senders: Vec
, + ) -> Result> { + let (block, hash) = block.split(); + Self::try_new_unchecked(block, senders, hash) + } + + /// Returns the block hash. + pub fn hash_ref(&self) -> &BlockHash { + self.block.hash_ref() + } + + /// Returns a copy of the block hash. + pub fn hash(&self) -> BlockHash { + *self.hash_ref() + } + + /// Return the number hash tuple. + pub fn num_hash(&self) -> BlockNumHash { + BlockNumHash::new(self.header().number(), self.hash()) + } + + /// Return a [`BlockWithParent`] for this header. + pub fn block_with_parent(&self) -> BlockWithParent { + BlockWithParent { parent: self.header().parent_hash(), block: self.num_hash() } + } + + /// Clone the header. + pub fn clone_header(&self) -> B::Header { + self.header().clone() + } + + /// Clones the internal header and returns a [`SealedHeader`] sealed with the hash. + pub fn clone_sealed_header(&self) -> SealedHeader { + SealedHeader::new(self.clone_header(), self.hash()) + } + + /// Clones the wrapped block and returns the [`SealedBlock`] sealed with the hash. + pub fn clone_sealed_block(&self) -> SealedBlock { + self.block.clone() + } + + /// Consumes the block and returns the block's header. + pub fn into_header(self) -> B::Header { + self.block.into_header() + } + + /// Consumes the block and returns the block's body. + pub fn into_body(self) -> B::Body { + self.block.into_body() + } + + /// Consumes the block and returns the [`SealedBlock`] and drops the recovered senders. + pub fn into_sealed_block(self) -> SealedBlock { + self.block + } + + /// Consumes the type and returns its components. + pub fn split_sealed(self) -> (SealedBlock, Vec
) { + (self.block, self.senders) + } + + /// Consumes the type and returns its components. + #[doc(alias = "into_components")] + pub fn split(self) -> (B, Vec
) { + (self.block.into_block(), self.senders) + } + + /// Returns an iterator over all transactions and their sender. + #[inline] + pub fn transactions_with_sender( + &self, + ) -> impl Iterator::Transaction)> + '_ { + self.senders.iter().zip(self.block.body().transactions()) + } + + /// Returns an iterator over all transactions in the block. + #[inline] + pub fn into_transactions_ecrecovered( + self, + ) -> impl Iterator::Transaction>> { + self.block + .split() + .0 + .into_body() + .into_transactions() + .into_iter() + .zip(self.senders) + .map(|(tx, sender)| tx.with_signer(sender)) + } + + /// Consumes the block and returns the transactions of the block. + #[inline] + pub fn into_transactions(self) -> Vec<::Transaction> { + self.block.split().0.into_body().into_transactions() + } +} + +impl BlockHeader for RecoveredBlock { + fn parent_hash(&self) -> B256 { + self.header().parent_hash() + } + + fn ommers_hash(&self) -> B256 { + self.header().ommers_hash() + } + + fn beneficiary(&self) -> Address { + self.header().beneficiary() + } + + fn state_root(&self) -> B256 { + self.header().state_root() + } + + fn transactions_root(&self) -> B256 { + self.header().transactions_root() + } + + fn receipts_root(&self) -> B256 { + self.header().receipts_root() + } + + fn withdrawals_root(&self) -> Option { + self.header().withdrawals_root() + } + + fn logs_bloom(&self) -> Bloom { + self.header().logs_bloom() + } + + fn difficulty(&self) -> U256 { + self.header().difficulty() + } + + fn number(&self) -> BlockNumber { + self.header().number() + } + + fn gas_limit(&self) -> u64 { + self.header().gas_limit() + } + + fn gas_used(&self) -> u64 { + self.header().gas_used() + } + + fn timestamp(&self) -> u64 { + self.header().timestamp() + } + + fn mix_hash(&self) -> Option { + self.header().mix_hash() + } + + fn nonce(&self) -> Option { + self.header().nonce() + } + + fn base_fee_per_gas(&self) -> Option { + self.header().base_fee_per_gas() + } + + fn blob_gas_used(&self) -> Option { + self.header().blob_gas_used() + } + + fn excess_blob_gas(&self) -> Option { + self.header().excess_blob_gas() + } + + fn parent_beacon_block_root(&self) -> Option { + self.header().parent_beacon_block_root() + } + + fn requests_hash(&self) -> Option { + self.header().requests_hash() + } + + fn extra_data(&self) -> &Bytes { + self.header().extra_data() + } +} + +impl Eq for RecoveredBlock {} + +impl PartialEq for RecoveredBlock { + fn eq(&self, other: &Self) -> bool { + self.hash_ref().eq(other.hash_ref()) && + self.block.eq(&other.block) && + self.senders.eq(&other.senders) + } +} + +impl Default for RecoveredBlock { + #[inline] + fn default() -> Self { + Self::new_unhashed(B::default(), Default::default()) + } +} + +impl InMemorySize for RecoveredBlock { + #[inline] + fn size(&self) -> usize { + self.block.size() + self.senders.len() * core::mem::size_of::
() + } +} + +impl From> for Sealed { + fn from(value: RecoveredBlock) -> Self { + value.block.into() + } +} + +#[cfg(any(test, feature = "arbitrary"))] +impl<'a, B> arbitrary::Arbitrary<'a> for RecoveredBlock +where + B: Block + arbitrary::Arbitrary<'a>, +{ + fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { + let block = B::arbitrary(u)?; + Ok(Self::try_recover(block).unwrap()) + } +} + +#[cfg(any(test, feature = "test-utils"))] +impl RecoveredBlock { + /// Returns a mutable reference to the recovered senders. + pub fn senders_mut(&mut self) -> &mut Vec
{ + &mut self.senders + } + + /// Appends the sender to the list of senders. + pub fn push_sender(&mut self, sender: Address) { + self.senders.push(sender); + } +} + +#[cfg(any(test, feature = "test-utils"))] +impl core::ops::DerefMut for RecoveredBlock +where + B: Block, +{ + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.block + } +} + +#[cfg(any(test, feature = "test-utils"))] +impl RecoveredBlock { + /// Updates the block header. + pub fn set_header(&mut self, header: B::Header) { + *self.header_mut() = header + } + + /// Updates the block hash. + pub fn set_hash(&mut self, hash: BlockHash) { + self.block.set_hash(hash) + } + + /// Returns a mutable reference to the header. + pub fn header_mut(&mut self) -> &mut B::Header { + self.block.header_mut() + } + + /// Returns a mutable reference to the header. + pub fn block_mut(&mut self) -> &mut B::Body { + self.block.body_mut() + } + + /// Updates the parent block hash. + pub fn set_parent_hash(&mut self, hash: BlockHash) { + self.block.set_parent_hash(hash); + } + + /// Updates the block number. + pub fn set_block_number(&mut self, number: alloy_primitives::BlockNumber) { + self.block.set_block_number(number); + } + + /// Updates the block state root. + pub fn set_state_root(&mut self, state_root: alloy_primitives::B256) { + self.block.set_state_root(state_root); + } + + /// Updates the block difficulty. + pub fn set_difficulty(&mut self, difficulty: alloy_primitives::U256) { + self.block.set_difficulty(difficulty); + } +} + +/// Bincode-compatible [`RecoveredBlock`] serde implementation. +#[cfg(feature = "serde-bincode-compat")] +pub(super) mod serde_bincode_compat { + use crate::{ + serde_bincode_compat::{self, SerdeBincodeCompat}, + Block, + }; + use alloc::{borrow::Cow, vec::Vec}; + use alloy_primitives::Address; + use serde::{Deserialize, Deserializer, Serialize, Serializer}; + use serde_with::{DeserializeAs, SerializeAs}; + + /// Bincode-compatible [`super::RecoveredBlock`] serde implementation. + /// + /// Intended to use with the [`serde_with::serde_as`] macro in the following way: + /// ```rust + /// use reth_primitives_traits::{ + /// block::RecoveredBlock, + /// serde_bincode_compat::{self, SerdeBincodeCompat}, + /// Block, + /// }; + /// use serde::{Deserialize, Serialize}; + /// use serde_with::serde_as; + /// + /// #[serde_as] + /// #[derive(Serialize, Deserialize)] + /// struct Data + 'static> { + /// #[serde_as(as = "serde_bincode_compat::RecoveredBlock<'_, T>")] + /// block: RecoveredBlock, + /// } + /// ``` + #[derive(derive_more::Debug, Serialize, Deserialize)] + pub struct RecoveredBlock< + 'a, + T: Block + 'static, + > { + #[serde( + bound = "serde_bincode_compat::SealedBlock<'a, T>: Serialize + serde::de::DeserializeOwned" + )] + block: serde_bincode_compat::SealedBlock<'a, T>, + senders: Cow<'a, Vec
>, + } + + impl<'a, T: Block + 'static> + From<&'a super::RecoveredBlock> for RecoveredBlock<'a, T> + { + fn from(value: &'a super::RecoveredBlock) -> Self { + Self { block: (&value.block).into(), senders: Cow::Borrowed(&value.senders) } + } + } + + impl<'a, T: Block + 'static> + From> for super::RecoveredBlock + { + fn from(value: RecoveredBlock<'a, T>) -> Self { + Self::new_sealed(value.block.into(), value.senders.into_owned()) + } + } + + impl + 'static> + SerializeAs> for RecoveredBlock<'_, T> + { + fn serialize_as( + source: &super::RecoveredBlock, + serializer: S, + ) -> Result + where + S: Serializer, + { + RecoveredBlock::from(source).serialize(serializer) + } + } + + impl<'de, T: Block + 'static> + DeserializeAs<'de, super::RecoveredBlock> for RecoveredBlock<'de, T> + { + fn deserialize_as(deserializer: D) -> Result, D::Error> + where + D: Deserializer<'de>, + { + RecoveredBlock::deserialize(deserializer).map(Into::into) + } + } + + impl + 'static> + SerdeBincodeCompat for super::RecoveredBlock + { + type BincodeRepr<'a> = RecoveredBlock<'a, T>; + } +} diff --git a/crates/primitives-traits/src/block/sealed.rs b/crates/primitives-traits/src/block/sealed.rs new file mode 100644 index 0000000000..5ff43bff67 --- /dev/null +++ b/crates/primitives-traits/src/block/sealed.rs @@ -0,0 +1,462 @@ +//! Sealed block types + +use crate::{ + block::{error::BlockRecoveryError, RecoveredBlock}, + Block, BlockBody, GotExpected, InMemorySize, SealedHeader, +}; +use alloc::vec::Vec; +use alloy_consensus::BlockHeader; +use alloy_eips::{eip1898::BlockWithParent, BlockNumHash}; +use alloy_primitives::{Address, BlockHash, Sealable, Sealed, B256}; +use alloy_rlp::{Decodable, Encodable}; +use bytes::BufMut; +use core::ops::Deref; + +/// Sealed full block composed of the block's header and body. +/// +/// This type uses lazy sealing to avoid hashing the header until it is needed, see also +/// [`SealedHeader`]. +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct SealedBlock { + /// Sealed Header. + header: SealedHeader, + /// the block's body. + body: B::Body, +} + +impl SealedBlock { + /// Hashes the header and creates a sealed block. + /// + /// This calculates the header hash. To create a [`SealedBlock`] without calculating the hash + /// upfront see [`SealedBlock::new_unhashed`] + pub fn seal_slow(block: B) -> Self { + let hash = block.header().hash_slow(); + Self::new_unchecked(block, hash) + } + + /// Create a new sealed block instance using the block. + /// + /// Caution: This assumes the given hash is the block's hash. + #[inline] + pub fn new_unchecked(block: B, hash: BlockHash) -> Self { + let (header, body) = block.split(); + Self { header: SealedHeader::new(header, hash), body } + } + + /// Creates a `SealedBlock` from the block without the available hash + pub fn new_unhashed(block: B) -> Self { + let (header, body) = block.split(); + Self { header: SealedHeader::new_unhashed(header), body } + } + + /// Creates the [`SealedBlock`] from the block's parts by hashing the header. + /// + /// + /// This calculates the header hash. To create a [`SealedBlock`] from its parts without + /// calculating the hash upfront see [`SealedBlock::from_parts_unhashed`] + pub fn seal_parts(header: B::Header, body: B::Body) -> Self { + Self::seal_slow(B::new(header, body)) + } + + /// Creates the [`SealedBlock`] from the block's parts without calculating the hash upfront. + pub fn from_parts_unhashed(header: B::Header, body: B::Body) -> Self { + Self::new_unhashed(B::new(header, body)) + } + + /// Creates the [`SealedBlock`] from the block's parts. + pub fn from_parts_unchecked(header: B::Header, body: B::Body, hash: BlockHash) -> Self { + Self::new_unchecked(B::new(header, body), hash) + } + + /// Creates the [`SealedBlock`] from the [`SealedHeader`] and the body. + pub fn from_sealed_parts(header: SealedHeader, body: B::Body) -> Self { + let (header, hash) = header.split(); + Self::from_parts_unchecked(header, body, hash) + } + + /// Returns a reference to the block hash. + #[inline] + pub fn hash_ref(&self) -> &BlockHash { + self.header.hash_ref() + } + + /// Returns the block hash. + #[inline] + pub fn hash(&self) -> B256 { + self.header.hash() + } + + /// Consumes the type and returns its components. + #[doc(alias = "into_components")] + pub fn split(self) -> (B, BlockHash) { + let (header, hash) = self.header.split(); + (B::new(header, self.body), hash) + } + + /// Consumes the type and returns the block. + pub fn into_block(self) -> B { + self.unseal() + } + + /// Consumes the type and returns the block. + pub fn unseal(self) -> B { + let header = self.header.unseal(); + B::new(header, self.body) + } + + /// Clones the wrapped block. + pub fn clone_block(&self) -> B { + B::new(self.header.clone_header(), self.body.clone()) + } + + /// Converts this block into a [`RecoveredBlock`] with the given senders + /// + /// Note: This method assumes the senders are correct and does not validate them. + pub const fn with_senders(self, senders: Vec
) -> RecoveredBlock { + RecoveredBlock::new_sealed(self, senders) + } + + /// Converts this block into a [`RecoveredBlock`] with the given senders if the number of + /// senders is equal to the number of transactions in the block and recovers the senders from + /// the transactions, if + /// not using [`SignedTransaction::recover_signer`](crate::transaction::signed::SignedTransaction) + /// to recover the senders. + /// + /// Returns an error if any of the transactions fail to recover the sender. + pub fn try_with_senders( + self, + senders: Vec
, + ) -> Result, BlockRecoveryError> { + RecoveredBlock::try_recover_sealed_with_senders(self, senders) + } + + /// Converts this block into a [`RecoveredBlock`] with the given senders if the number of + /// senders is equal to the number of transactions in the block and recovers the senders from + /// the transactions, if + /// not using [`SignedTransaction::recover_signer_unchecked`](crate::transaction::signed::SignedTransaction) + /// to recover the senders. + /// + /// Returns an error if any of the transactions fail to recover the sender. + pub fn try_with_senders_unchecked( + self, + senders: Vec
, + ) -> Result, BlockRecoveryError> { + RecoveredBlock::try_recover_sealed_with_senders_unchecked(self, senders) + } + + /// Recovers the senders from the transactions in the block using + /// [`SignedTransaction::recover_signer`](crate::transaction::signed::SignedTransaction). + /// + /// Returns an error if any of the transactions fail to recover the sender. + pub fn try_recover(self) -> Result, BlockRecoveryError> { + RecoveredBlock::try_recover_sealed(self) + } + + /// Recovers the senders from the transactions in the block using + /// [`SignedTransaction::recover_signer_unchecked`](crate::transaction::signed::SignedTransaction). + /// + /// Returns an error if any of the transactions fail to recover the sender. + pub fn try_recover_unchecked(self) -> Result, BlockRecoveryError> { + RecoveredBlock::try_recover_sealed_unchecked(self) + } + + /// Returns reference to block header. + pub const fn header(&self) -> &B::Header { + self.header.header() + } + + /// Returns reference to block body. + pub const fn body(&self) -> &B::Body { + &self.body + } + + /// Returns the length of the block. + pub fn rlp_length(&self) -> usize { + B::rlp_length(self.header(), self.body()) + } + + /// Recovers all senders from the transactions in the block. + /// + /// Returns `None` if any of the transactions fail to recover the sender. + pub fn senders(&self) -> Option> { + self.body().recover_signers() + } + + /// Return the number hash tuple. + pub fn num_hash(&self) -> BlockNumHash { + BlockNumHash::new(self.number(), self.hash()) + } + + /// Return a [`BlockWithParent`] for this header. + pub fn block_with_parent(&self) -> BlockWithParent { + BlockWithParent { parent: self.parent_hash(), block: self.num_hash() } + } + + /// Returns the Sealed header. + pub const fn sealed_header(&self) -> &SealedHeader { + &self.header + } + + /// Returns the wrapped `SealedHeader` as `SealedHeader<&B::Header>`. + pub fn sealed_header_ref(&self) -> SealedHeader<&B::Header> { + SealedHeader::new(self.header(), self.hash()) + } + + /// Clones the wrapped header and returns a [`SealedHeader`] sealed with the hash. + pub fn clone_sealed_header(&self) -> SealedHeader { + self.header.clone() + } + + /// Consumes the block and returns the sealed header. + pub fn into_sealed_header(self) -> SealedHeader { + self.header + } + + /// Consumes the block and returns the header. + pub fn into_header(self) -> B::Header { + self.header.unseal() + } + + /// Consumes the block and returns the body. + pub fn into_body(self) -> B::Body { + self.body + } + + /// Splits the block into body and header into separate components + pub fn split_header_body(self) -> (B::Header, B::Body) { + let header = self.header.unseal(); + (header, self.body) + } + + /// Splits the block into body and header into separate components. + pub fn split_sealed_header_body(self) -> (SealedHeader, B::Body) { + (self.header, self.body) + } + + /// Returns an iterator over all blob versioned hashes from the block body. + #[inline] + pub fn blob_versioned_hashes_iter(&self) -> impl Iterator + '_ { + self.body().blob_versioned_hashes_iter() + } + + /// Returns the number of transactions in the block. + #[inline] + pub fn transaction_count(&self) -> usize { + self.body().transaction_count() + } + + /// Ensures that the transaction root in the block header is valid. + /// + /// The transaction root is the Keccak 256-bit hash of the root node of the trie structure + /// populated with each transaction in the transactions list portion of the block. + /// + /// # Returns + /// + /// Returns `Ok(())` if the calculated transaction root matches the one stored in the header, + /// indicating that the transactions in the block are correctly represented in the trie. + /// + /// Returns `Err(error)` if the transaction root validation fails, providing a `GotExpected` + /// error containing the calculated and expected roots. + pub fn ensure_transaction_root_valid(&self) -> Result<(), GotExpected> { + let calculated_root = self.body().calculate_tx_root(); + + if self.header().transactions_root() != calculated_root { + return Err(GotExpected { + got: calculated_root, + expected: self.header().transactions_root(), + }) + } + + Ok(()) + } +} + +impl From for SealedBlock +where + B: Block, +{ + fn from(block: B) -> Self { + Self::seal_slow(block) + } +} + +impl Default for SealedBlock +where + B: Block + Default, +{ + fn default() -> Self { + Self::seal_slow(Default::default()) + } +} + +impl InMemorySize for SealedBlock { + #[inline] + fn size(&self) -> usize { + self.body.size() + self.header.size() + } +} + +impl Deref for SealedBlock { + type Target = B::Header; + + fn deref(&self) -> &Self::Target { + self.header() + } +} + +impl Encodable for SealedBlock { + fn encode(&self, out: &mut dyn BufMut) { + self.body.encode(out); + } +} + +impl Decodable for SealedBlock { + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { + let block = B::decode(buf)?; + Ok(Self::seal_slow(block)) + } +} + +impl From> for Sealed { + fn from(value: SealedBlock) -> Self { + let (block, hash) = value.split(); + Self::new_unchecked(block, hash) + } +} + +#[cfg(any(test, feature = "arbitrary"))] +impl<'a, B> arbitrary::Arbitrary<'a> for SealedBlock +where + B: Block + arbitrary::Arbitrary<'a>, +{ + fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { + let block = B::arbitrary(u)?; + Ok(Self::seal_slow(block)) + } +} + +#[cfg(any(test, feature = "test-utils"))] +impl SealedBlock { + /// Returns a mutable reference to the header. + pub fn header_mut(&mut self) -> &mut B::Header { + self.header.header_mut() + } + + /// Updates the block hash. + pub fn set_hash(&mut self, hash: BlockHash) { + self.header.set_hash(hash) + } + + /// Returns a mutable reference to the header. + pub fn body_mut(&mut self) -> &mut B::Body { + &mut self.body + } + + /// Updates the parent block hash. + pub fn set_parent_hash(&mut self, hash: BlockHash) { + self.header.set_parent_hash(hash) + } + + /// Updates the block number. + pub fn set_block_number(&mut self, number: alloy_primitives::BlockNumber) { + self.header.set_block_number(number) + } + + /// Updates the block state root. + pub fn set_state_root(&mut self, state_root: alloy_primitives::B256) { + self.header.set_state_root(state_root) + } + + /// Updates the block difficulty. + pub fn set_difficulty(&mut self, difficulty: alloy_primitives::U256) { + self.header.set_difficulty(difficulty) + } +} + +/// Bincode-compatible [`SealedBlock`] serde implementation. +#[cfg(feature = "serde-bincode-compat")] +pub(super) mod serde_bincode_compat { + use crate::{ + serde_bincode_compat::{self, BincodeReprFor, SerdeBincodeCompat}, + Block, + }; + use serde::{Deserialize, Deserializer, Serialize, Serializer}; + use serde_with::{serde_as, DeserializeAs, SerializeAs}; + + /// Bincode-compatible [`super::SealedBlock`] serde implementation. + /// + /// Intended to use with the [`serde_with::serde_as`] macro in the following way: + /// ```rust + /// use reth_primitives_traits::{ + /// block::SealedBlock, + /// serde_bincode_compat::{self, SerdeBincodeCompat}, + /// Block, + /// }; + /// use serde::{Deserialize, Serialize}; + /// use serde_with::serde_as; + /// + /// #[serde_as] + /// #[derive(Serialize, Deserialize)] + /// struct Data + 'static> { + /// #[serde_as(as = "serde_bincode_compat::SealedBlock<'_, T>")] + /// block: SealedBlock, + /// } + /// ``` + #[serde_as] + #[derive(derive_more::Debug, Serialize, Deserialize)] + pub struct SealedBlock< + 'a, + T: Block + 'static, + > { + #[serde( + bound = "serde_bincode_compat::SealedHeader<'a, T::Header>: Serialize + serde::de::DeserializeOwned" + )] + header: serde_bincode_compat::SealedHeader<'a, T::Header>, + body: BincodeReprFor<'a, T::Body>, + } + + impl<'a, T: Block + 'static> + From<&'a super::SealedBlock> for SealedBlock<'a, T> + { + fn from(value: &'a super::SealedBlock) -> Self { + Self { header: (&value.header).into(), body: (&value.body).into() } + } + } + + impl<'a, T: Block + 'static> + From> for super::SealedBlock + { + fn from(value: SealedBlock<'a, T>) -> Self { + Self::from_sealed_parts(value.header.into(), value.body.into()) + } + } + + impl + 'static> + SerializeAs> for SealedBlock<'_, T> + { + fn serialize_as(source: &super::SealedBlock, serializer: S) -> Result + where + S: Serializer, + { + SealedBlock::from(source).serialize(serializer) + } + } + + impl<'de, T: Block + 'static> + DeserializeAs<'de, super::SealedBlock> for SealedBlock<'de, T> + { + fn deserialize_as(deserializer: D) -> Result, D::Error> + where + D: Deserializer<'de>, + { + SealedBlock::deserialize(deserializer).map(Into::into) + } + } + + impl + 'static> + SerdeBincodeCompat for super::SealedBlock + { + type BincodeRepr<'a> = SealedBlock<'a, T>; + } +} diff --git a/crates/primitives-traits/src/header/sealed.rs b/crates/primitives-traits/src/header/sealed.rs index 4b1a83fb50..c7a61f2532 100644 --- a/crates/primitives-traits/src/header/sealed.rs +++ b/crates/primitives-traits/src/header/sealed.rs @@ -1,4 +1,4 @@ -use crate::InMemorySize; +use crate::{sync::OnceLock, InMemorySize}; pub use alloy_consensus::Header; use alloy_consensus::Sealed; use alloy_eips::{eip1898::BlockWithParent, BlockNumHash}; @@ -8,14 +8,20 @@ use bytes::BufMut; use core::mem; use derive_more::{AsRef, Deref}; -/// A [`Header`] that is sealed at a precalculated hash, use [`SealedHeader::unseal()`] if you want -/// to modify header. -#[derive(Debug, Clone, PartialEq, Eq, Hash, AsRef, Deref)] +/// Seals the header with the block hash. +/// +/// This type uses lazy sealing to avoid hashing the header until it is needed: +/// +/// [`SealedHeader::new_unhashed`] creates a sealed header without hashing the header. +/// [`SealedHeader::new`] creates a sealed header with the corresponding block hash. +/// [`SealedHeader::hash`] computes the hash if it has not been computed yet. +#[derive(Debug, Clone, AsRef, Deref)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(any(test, feature = "reth-codec"), reth_codecs::add_arbitrary_tests(rlp))] pub struct SealedHeader { - /// Locked Header hash. - hash: BlockHash, + /// Block hash + #[cfg_attr(feature = "serde", serde(skip))] + hash: OnceLock, /// Locked Header fields. #[as_ref] #[deref] @@ -23,10 +29,16 @@ pub struct SealedHeader { } impl SealedHeader { + /// Creates the sealed header without hashing the header. + #[inline] + pub fn new_unhashed(header: H) -> Self { + Self { header, hash: Default::default() } + } + /// Creates the sealed header with the corresponding block hash. #[inline] - pub const fn new(header: H, hash: BlockHash) -> Self { - Self { header, hash } + pub fn new(header: H, hash: BlockHash) -> Self { + Self { header, hash: hash.into() } } /// Returns the sealed Header fields. @@ -43,35 +55,62 @@ impl SealedHeader { self.header.clone() } - /// Returns header/block hash. - #[inline] - pub const fn hash(&self) -> BlockHash { - self.hash + /// Consumes the type and returns the wrapped header. + pub fn into_header(self) -> H { + self.header } - /// Extract raw header that can be modified. + /// Consumes the type and returns the wrapped header. pub fn unseal(self) -> H { self.header } - /// This is the inverse of [`Header::seal_slow`] which returns the raw header and hash. - pub fn split(self) -> (H, BlockHash) { - (self.header, self.hash) + /// Converts from &`SealedHeader` to `SealedHeader<&H>`. + pub fn sealed_ref(&self) -> SealedHeader<&H> { + SealedHeader { hash: self.hash.clone(), header: &self.header } } } impl SealedHeader { /// Hashes the header and creates a sealed header. - pub fn seal(header: H) -> Self { + pub fn seal_slow(header: H) -> Self { let hash = header.hash_slow(); Self::new(header, hash) } + + /// Returns the block hash. + /// + /// Note: if the hash has not been computed yet, this will compute the hash: + /// [`Sealable::hash_slow`]. + pub fn hash_ref(&self) -> &BlockHash { + self.hash.get_or_init(|| self.header.hash_slow()) + } + + /// Returns a copy of the block hash. + pub fn hash(&self) -> BlockHash { + *self.hash_ref() + } + + /// This is the inverse of [`Header::seal_slow`] which returns the raw header and hash. + pub fn split(self) -> (H, BlockHash) { + let hash = self.hash(); + (self.header, hash) + } + + /// Clones the header and returns a new sealed header. + pub fn cloned(self) -> Self + where + H: Clone, + { + let (header, hash) = self.split(); + Self::new(header, hash) + } } -impl SealedHeader { +impl SealedHeader { /// Return the number hash tuple. pub fn num_hash(&self) -> BlockNumHash { - BlockNumHash::new(self.number(), self.hash) + BlockNumHash::new(self.number(), self.hash()) } /// Return a [`BlockWithParent`] for this header. @@ -80,6 +119,20 @@ impl SealedHeader { } } +impl Eq for SealedHeader {} + +impl PartialEq for SealedHeader { + fn eq(&self, other: &Self) -> bool { + self.hash() == other.hash() + } +} + +impl core::hash::Hash for SealedHeader { + fn hash(&self, state: &mut Ha) { + self.hash().hash(state) + } +} + impl InMemorySize for SealedHeader { /// Calculates a heuristic for the in-memory size of the [`SealedHeader`]. #[inline] @@ -90,7 +143,7 @@ impl InMemorySize for SealedHeader { impl Default for SealedHeader { fn default() -> Self { - Self::seal(H::default()) + Self::seal_slow(H::default()) } } @@ -115,13 +168,14 @@ impl Decodable for SealedHeader { // update original buffer *buf = *b; - Ok(Self { header, hash }) + Ok(Self::new(header, hash)) } } -impl From> for Sealed { +impl From> for Sealed { fn from(value: SealedHeader) -> Self { - Self::new_unchecked(value.header, value.hash) + let (header, hash) = value.split(); + Self::new_unchecked(header, hash) } } @@ -133,7 +187,7 @@ where fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { let header = H::arbitrary(u)?; - Ok(Self::seal(header)) + Ok(Self::seal_slow(header)) } } @@ -146,7 +200,7 @@ impl SealedHeader { /// Updates the block hash. pub fn set_hash(&mut self, hash: BlockHash) { - self.hash = hash + self.hash = hash.into() } /// Returns a mutable reference to the header. @@ -178,12 +232,11 @@ impl SealedHeader { /// Bincode-compatible [`SealedHeader`] serde implementation. #[cfg(feature = "serde-bincode-compat")] pub(super) mod serde_bincode_compat { - use alloy_primitives::BlockHash; + use crate::serde_bincode_compat::SerdeBincodeCompat; + use alloy_primitives::{BlockHash, Sealable}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde_with::{DeserializeAs, SerializeAs}; - use crate::serde_bincode_compat::SerdeBincodeCompat; - /// Bincode-compatible [`super::SealedHeader`] serde implementation. /// /// Intended to use with the [`serde_with::serde_as`] macro in the following way: @@ -201,20 +254,22 @@ pub(super) mod serde_bincode_compat { /// ``` #[derive(derive_more::Debug, Serialize, Deserialize)] #[debug(bound(H::BincodeRepr<'a>: core::fmt::Debug))] - pub struct SealedHeader<'a, H: SerdeBincodeCompat = super::Header> { + pub struct SealedHeader<'a, H: Sealable + SerdeBincodeCompat = super::Header> { hash: BlockHash, header: H::BincodeRepr<'a>, } - impl<'a, H: SerdeBincodeCompat> From<&'a super::SealedHeader> for SealedHeader<'a, H> { + impl<'a, H: Sealable + SerdeBincodeCompat> From<&'a super::SealedHeader> + for SealedHeader<'a, H> + { fn from(value: &'a super::SealedHeader) -> Self { - Self { hash: value.hash, header: (&value.header).into() } + Self { hash: value.hash(), header: (&value.header).into() } } } - impl<'a, H: SerdeBincodeCompat> From> for super::SealedHeader { + impl<'a, H: Sealable + SerdeBincodeCompat> From> for super::SealedHeader { fn from(value: SealedHeader<'a, H>) -> Self { - Self { hash: value.hash, header: value.header.into() } + Self::new(value.header.into(), value.hash) } } @@ -236,9 +291,10 @@ pub(super) mod serde_bincode_compat { } } - impl SerdeBincodeCompat for super::SealedHeader { + impl SerdeBincodeCompat for super::SealedHeader { type BincodeRepr<'a> = SealedHeader<'a, H>; } + #[cfg(test)] mod tests { use super::super::{serde_bincode_compat, SealedHeader}; diff --git a/crates/primitives-traits/src/lib.rs b/crates/primitives-traits/src/lib.rs index bad587e0f6..f09875ed34 100644 --- a/crates/primitives-traits/src/lib.rs +++ b/crates/primitives-traits/src/lib.rs @@ -17,6 +17,32 @@ //! - `secp256k1`: Adds secp256k1 support for transaction signing/recovery. (By default the no-std //! friendly `k256` is used) //! - `rayon`: Uses `rayon` for parallel transaction sender recovery in [`BlockBody`] by default. +//! +//! ## Overview +//! +//! This crate defines various traits and types that form the foundation of the reth stack. +//! The top-level trait is [`Block`] which represents a block in the blockchain. A [`Block`] is +//! composed of a [`Header`] and a [`BlockBody`]. A [`BlockBody`] contains the transactions in the +//! block any additional data that is part of the block. A [`Header`] contains the metadata of the +//! block. +//! +//! ### Sealing (Hashing) +//! +//! The block hash is derived from the [`Header`] and is used to uniquely identify the block. This +//! operation is referred to as sealing in the context of this crate. Sealing is an expensive +//! operation. This crate provides various wrapper types that cache the hash of the block to avoid +//! recomputing it: [`SealedHeader`] and [`SealedBlock`]. All sealed types can be downgraded to +//! their unsealed counterparts. +//! +//! ### Recovery +//! +//! The raw consensus transactions that make up a block don't include the sender's address. This +//! information is recovered from the transaction signature. This operation is referred to as +//! recovery in the context of this crate and is an expensive operation. The [`RecoveredBlock`] +//! represents a [`SealedBlock`] with the sender addresses recovered. A [`SealedBlock`] can be +//! upgraded to a [`RecoveredBlock`] by recovering the sender addresses: +//! [`SealedBlock::try_recover`]. A [`RecoveredBlock`] can be downgraded to a [`SealedBlock`] by +//! removing the sender addresses: [`RecoveredBlock::into_sealed_block`]. #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", @@ -52,7 +78,7 @@ pub mod block; pub use block::{ body::{BlockBody, FullBlockBody}, header::{BlockHeader, FullBlockHeader}, - Block, FullBlock, + Block, FullBlock, RecoveredBlock, SealedBlock, }; mod encoded; @@ -138,6 +164,6 @@ impl MaybeSerdeBincodeCompat for T {} #[cfg(any(test, feature = "arbitrary", feature = "test-utils"))] pub mod test_utils { pub use crate::header::test_utils::{generate_valid_header, valid_header_strategy}; - #[cfg(feature = "test-utils")] + #[cfg(any(test, feature = "test-utils"))] pub use crate::{block::TestBlock, header::test_utils::TestHeader}; } diff --git a/crates/primitives-traits/src/node.rs b/crates/primitives-traits/src/node.rs index 3f6786c8f9..fecb34d70f 100644 --- a/crates/primitives-traits/src/node.rs +++ b/crates/primitives-traits/src/node.rs @@ -1,4 +1,7 @@ -use crate::{Block, FullBlock, FullBlockBody, FullBlockHeader, FullReceipt, FullSignedTx, Receipt}; +use crate::{ + Block, FullBlock, FullBlockBody, FullBlockHeader, FullReceipt, FullSignedTx, + MaybeSerdeBincodeCompat, Receipt, +}; use core::fmt; /// Configures all the primitive types of the node. @@ -6,7 +9,7 @@ pub trait NodePrimitives: Send + Sync + Unpin + Clone + Default + fmt::Debug + PartialEq + Eq + 'static { /// Block primitive. - type Block: Block
; + type Block: Block
+ MaybeSerdeBincodeCompat; /// Block header primitive. type BlockHeader: FullBlockHeader; /// Block body primitive. diff --git a/crates/primitives-traits/src/serde_bincode_compat.rs b/crates/primitives-traits/src/serde_bincode_compat.rs index 705898e6da..9d3a2fbd50 100644 --- a/crates/primitives-traits/src/serde_bincode_compat.rs +++ b/crates/primitives-traits/src/serde_bincode_compat.rs @@ -1,8 +1,11 @@ use core::fmt::Debug; use serde::{de::DeserializeOwned, Serialize}; -pub use super::header::{serde_bincode_compat as header, serde_bincode_compat::*}; -pub use block_bincode::BlockBody; +pub use super::{ + block::{serde_bincode_compat as block, serde_bincode_compat::*}, + header::{serde_bincode_compat as header, serde_bincode_compat::*}, +}; +pub use block_bincode::{Block, BlockBody}; /// Trait for types that can be serialized and deserialized using bincode. pub trait SerdeBincodeCompat: Sized + 'static { @@ -14,6 +17,9 @@ impl SerdeBincodeCompat for alloy_consensus::Header { type BincodeRepr<'a> = alloy_consensus::serde_bincode_compat::Header<'a>; } +/// Type alias for the [`SerdeBincodeCompat::BincodeRepr`] associated type. +pub type BincodeReprFor<'a, T> = ::BincodeRepr<'a>; + mod block_bincode { use crate::serde_bincode_compat::SerdeBincodeCompat; use alloc::{borrow::Cow, vec::Vec}; @@ -22,6 +28,77 @@ mod block_bincode { use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde_with::{DeserializeAs, SerializeAs}; + /// Bincode-compatible [`alloy_consensus::Block`] serde implementation. + /// + /// Intended to use with the [`serde_with::serde_as`] macro in the following way: + /// ```rust + /// use alloy_consensus::Block; + /// use reth_primitives_traits::serde_bincode_compat::{self, SerdeBincodeCompat}; + /// use serde::{Deserialize, Serialize}; + /// use serde_with::serde_as; + /// + /// #[serde_as] + /// #[derive(Serialize, Deserialize)] + /// struct Data { + /// #[serde_as(as = "serde_bincode_compat::Block<'_, T, H>")] + /// body: Block, + /// } + /// ``` + #[derive(derive_more::Debug, Serialize, Deserialize)] + #[debug(bound())] + pub struct Block<'a, T: SerdeBincodeCompat, H: SerdeBincodeCompat> { + header: H::BincodeRepr<'a>, + #[serde(bound = "BlockBody<'a, T>: Serialize + serde::de::DeserializeOwned")] + body: BlockBody<'a, T>, + } + + impl<'a, T: SerdeBincodeCompat, H: SerdeBincodeCompat> From<&'a alloy_consensus::Block> + for Block<'a, T, H> + { + fn from(value: &'a alloy_consensus::Block) -> Self { + Self { header: (&value.header).into(), body: (&value.body).into() } + } + } + + impl<'a, T: SerdeBincodeCompat, H: SerdeBincodeCompat> From> + for alloy_consensus::Block + { + fn from(value: Block<'a, T, H>) -> Self { + Self { header: value.header.into(), body: value.body.into() } + } + } + + impl SerializeAs> + for Block<'_, T, H> + { + fn serialize_as( + source: &alloy_consensus::Block, + serializer: S, + ) -> Result + where + S: Serializer, + { + Block::from(source).serialize(serializer) + } + } + + impl<'de, T: SerdeBincodeCompat, H: SerdeBincodeCompat> + DeserializeAs<'de, alloy_consensus::Block> for Block<'de, T, H> + { + fn deserialize_as(deserializer: D) -> Result, D::Error> + where + D: Deserializer<'de>, + { + Block::deserialize(deserializer).map(Into::into) + } + } + + impl SerdeBincodeCompat + for alloy_consensus::Block + { + type BincodeRepr<'a> = Block<'a, T, H>; + } + /// Bincode-compatible [`alloy_consensus::BlockBody`] serde implementation. /// /// Intended to use with the [`serde_with::serde_as`] macro in the following way: diff --git a/crates/primitives-traits/src/transaction/signed.rs b/crates/primitives-traits/src/transaction/signed.rs index ddc79829ad..bc64b45212 100644 --- a/crates/primitives-traits/src/transaction/signed.rs +++ b/crates/primitives-traits/src/transaction/signed.rs @@ -64,6 +64,13 @@ pub trait SignedTransaction: /// the signature has a low `s` value. fn recover_signer(&self) -> Option
; + /// Recover signer from signature and hash. + /// + /// Returns an error if the transaction's signature is invalid. + fn try_recover(&self) -> Result { + self.recover_signer().ok_or(RecoveryError) + } + /// Recover signer from signature and hash _without ensuring that the signature has a low `s` /// value_. /// @@ -73,6 +80,14 @@ pub trait SignedTransaction: self.recover_signer_unchecked_with_buf(&mut Vec::new()) } + /// Recover signer from signature and hash _without ensuring that the signature has a low `s` + /// value_. + /// + /// Returns an error if the transaction's signature is invalid. + fn try_recover_unchecked(&self) -> Result { + self.recover_signer_unchecked().ok_or(RecoveryError) + } + /// Same as [`Self::recover_signer_unchecked`] but receives a buffer to operate on. This is used /// during batch recovery to avoid allocating a new buffer for each transaction. fn recover_signer_unchecked_with_buf(&self, buf: &mut Vec) -> Option
; @@ -195,3 +210,8 @@ pub trait SignedTransactionIntoRecoveredExt: SignedTransaction { } impl SignedTransactionIntoRecoveredExt for T where T: SignedTransaction {} + +/// Opaque error type for sender recovery. +#[derive(Debug, Default, thiserror::Error)] +#[error("Failed to recover the signer")] +pub struct RecoveryError; diff --git a/crates/primitives/src/alloy_compat.rs b/crates/primitives/src/alloy_compat.rs index 8888765208..a269ebfb72 100644 --- a/crates/primitives/src/alloy_compat.rs +++ b/crates/primitives/src/alloy_compat.rs @@ -1,34 +1,12 @@ //! Common conversions from alloy types. -use crate::{BlockBody, SealedBlock, Transaction, TransactionSigned}; +use crate::{Transaction, TransactionSigned}; use alloc::string::ToString; -use alloy_consensus::{Header, TxEnvelope}; -use alloy_network::{AnyRpcBlock, AnyRpcTransaction, AnyTxEnvelope}; +use alloy_consensus::TxEnvelope; +use alloy_network::{AnyRpcTransaction, AnyTxEnvelope}; use alloy_serde::WithOtherFields; + use op_alloy_rpc_types as _; -use reth_primitives_traits::SealedHeader; - -impl TryFrom for SealedBlock> -where - T: TryFrom, -{ - type Error = alloy_rpc_types::ConversionError; - - fn try_from(block: AnyRpcBlock) -> Result { - let block = block.inner; - let block_hash = block.header.hash; - let block = block.try_map_transactions(|tx| tx.try_into())?; - - Ok(Self::new( - SealedHeader::new(block.header.inner.into_header_with_defaults(), block_hash), - BlockBody { - transactions: block.transactions.into_transactions().collect(), - ommers: Default::default(), - withdrawals: block.withdrawals.map(|w| w.into_inner().into()), - }, - )) - } -} impl TryFrom for TransactionSigned { type Error = alloy_rpc_types::ConversionError; @@ -114,8 +92,9 @@ mod tests { "gas": "0xc27a8", "gasPrice": "0x0", "hash": "0x0bf1845c5d7a82ec92365d5027f7310793d53004f3c86aa80965c67bf7e7dc80", - "input": "0xd764ad0b000100000000000000000000000000000000000000000000000000000001cf5400000000000000000000000099c9fc46f92e8a1c0dec1b1747d010903e884be100000000000000000000000042000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a12000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e40166a07a0000000000000000000000000994206dfe8de6ec6920ff4d779b0d950605fb53000000000000000000000000d533a949740bb3306d119cc777fa900ba034cd52000000000000000000000000ca74f404e0c7bfa35b13b511097df966d5a65597000000000000000000000000ca74f404e0c7bfa35b13b511097df966d5a65597000000000000000000000000000000000000000000000216614199391dbba2ba00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "mint": "0x0", + "input": +"0xd764ad0b000100000000000000000000000000000000000000000000000000000001cf5400000000000000000000000099c9fc46f92e8a1c0dec1b1747d010903e884be100000000000000000000000042000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a12000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e40166a07a0000000000000000000000000994206dfe8de6ec6920ff4d779b0d950605fb53000000000000000000000000d533a949740bb3306d119cc777fa900ba034cd52000000000000000000000000ca74f404e0c7bfa35b13b511097df966d5a65597000000000000000000000000ca74f404e0c7bfa35b13b511097df966d5a65597000000000000000000000000000000000000000000000216614199391dbba2ba00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" +, "mint": "0x0", "nonce": "0x74060", "r": "0x0", "s": "0x0", @@ -165,8 +144,9 @@ mod tests { "gas": "0x7812e", "gasPrice": "0x0", "hash": "0xf7e83886d3c6864f78e01c453ebcd57020c5795d96089e8f0e0b90a467246ddb", - "input": "0xd764ad0b000100000000000000000000000000000000000000000000000000000001cf5f00000000000000000000000099c9fc46f92e8a1c0dec1b1747d010903e884be100000000000000000000000042000000000000000000000000000000000000100000000000000000000000000000000000000000000000239c2e16a5ca5900000000000000000000000000000000000000000000000000000000000000030d4000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e41635f5fd0000000000000000000000002ce910fbba65b454bbaf6a18c952a70f3bcd82990000000000000000000000002ce910fbba65b454bbaf6a18c952a70f3bcd82990000000000000000000000000000000000000000000000239c2e16a5ca590000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "mint": "0x239c2e16a5ca590000", + "input": +"0xd764ad0b000100000000000000000000000000000000000000000000000000000001cf5f00000000000000000000000099c9fc46f92e8a1c0dec1b1747d010903e884be100000000000000000000000042000000000000000000000000000000000000100000000000000000000000000000000000000000000000239c2e16a5ca5900000000000000000000000000000000000000000000000000000000000000030d4000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e41635f5fd0000000000000000000000002ce910fbba65b454bbaf6a18c952a70f3bcd82990000000000000000000000002ce910fbba65b454bbaf6a18c952a70f3bcd82990000000000000000000000000000000000000000000000239c2e16a5ca590000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" +, "mint": "0x239c2e16a5ca590000", "nonce": "0x7406b", "r": "0x0", "s": "0x0", diff --git a/crates/primitives/src/block.rs b/crates/primitives/src/block.rs index 8c6c8a870d..04d5940002 100644 --- a/crates/primitives/src/block.rs +++ b/crates/primitives/src/block.rs @@ -1,19 +1,6 @@ -use crate::{ - traits::BlockExt, transaction::SignedTransactionIntoRecoveredExt, GotExpected, RecoveredTx, - SealedHeader, TransactionSigned, -}; -use alloc::vec::Vec; -use alloy_consensus::Header; -use alloy_eips::{ - eip1898::BlockWithParent, eip2718::Encodable2718, eip4895::Withdrawals, BlockNumHash, -}; -use alloy_primitives::{Address, B256}; -use alloy_rlp::{Decodable, Encodable, RlpDecodable, RlpEncodable}; -use derive_more::{Deref, DerefMut}; +use crate::TransactionSigned; #[cfg(any(test, feature = "arbitrary"))] pub use reth_primitives_traits::test_utils::{generate_valid_header, valid_header_strategy}; -use reth_primitives_traits::{BlockBody as _, InMemorySize, SignedTransaction}; -use serde::{Deserialize, Serialize}; /// Ethereum full block. /// @@ -25,818 +12,20 @@ pub type Block = alloy_consensus::Block; /// Withdrawals can be optionally included at the end of the RLP encoded message. pub type BlockBody = alloy_consensus::BlockBody; -/// We need to implement RLP traits manually because we currently don't have a way to flatten -/// [`BlockBody`] into [`Block`]. -mod block_rlp { - use super::*; +/// Ethereum sealed block type +pub type SealedBlock = reth_primitives_traits::block::SealedBlock; - #[derive(RlpDecodable)] - #[rlp(trailing)] - struct Helper { - header: H, - transactions: Vec, - ommers: Vec
, - withdrawals: Option, - } +/// Helper type for constructing the block +#[deprecated(note = "Use `RecoveredBlock` instead")] +pub type SealedBlockFor = reth_primitives_traits::block::SealedBlock; - #[derive(RlpEncodable)] - #[rlp(trailing)] - struct HelperRef<'a, H, T = TransactionSigned> { - header: &'a H, - transactions: &'a Vec, - ommers: &'a Vec
, - withdrawals: Option<&'a Withdrawals>, - } +/// Ethereum recovered block +#[deprecated(note = "Use `RecoveredBlock` instead")] +pub type BlockWithSenders = reth_primitives_traits::block::RecoveredBlock; - impl<'a, T> From<&'a Block> for HelperRef<'a, Header, T> { - fn from(block: &'a Block) -> Self { - let Block { header, body: BlockBody { transactions, ommers, withdrawals } } = block; - Self { header, transactions, ommers, withdrawals: withdrawals.as_ref() } - } - } - - impl<'a> From<&'a SealedBlock> for HelperRef<'a, SealedHeader> { - fn from(block: &'a SealedBlock) -> Self { - let SealedBlock { header, body: BlockBody { transactions, ommers, withdrawals } } = - block; - Self { header, transactions, ommers, withdrawals: withdrawals.as_ref() } - } - } - - impl Decodable for SealedBlock { - fn decode(b: &mut &[u8]) -> alloy_rlp::Result { - let Helper { header, transactions, ommers, withdrawals } = Helper::decode(b)?; - Ok(Self { header, body: BlockBody { transactions, ommers, withdrawals } }) - } - } - - impl Encodable for SealedBlock { - fn encode(&self, out: &mut dyn bytes::BufMut) { - let helper: HelperRef<'_, _, _> = self.into(); - helper.encode(out) - } - - fn length(&self) -> usize { - let helper: HelperRef<'_, _, _> = self.into(); - helper.length() - } - } -} - -/// Sealed block with senders recovered from transactions. -#[derive(Debug, Clone, PartialEq, Eq, Default, Deref, DerefMut)] -pub struct BlockWithSenders { - /// Block - #[deref] - #[deref_mut] - pub block: B, - /// List of senders that match the transactions in the block - senders: Vec
, -} - -impl BlockWithSenders { - /// New block with senders - pub const fn new_unchecked(block: B, senders: Vec
) -> Self { - Self { block, senders } - } - - /// New block with senders. Return none if len of tx and senders does not match - pub fn new(block: B, senders: Vec
) -> Option { - (block.body().transactions().len() == senders.len()).then_some(Self { block, senders }) - } - - /// Returns all senders of the transactions in the block. - pub fn senders(&self) -> &[Address] { - &self.senders - } - - /// Returns an iterator over all senders in the block. - pub fn senders_iter(&self) -> impl Iterator { - self.senders.iter() - } - - /// Seal the block with a known hash. - /// - /// WARNING: This method does not perform validation whether the hash is correct. - #[inline] - pub fn seal_unchecked(self, hash: B256) -> SealedBlockWithSenders { - let Self { block, senders } = self; - SealedBlockWithSenders:: { block: block.seal(hash), senders } - } - - /// Calculate the header hash and seal the block with senders so that it can't be changed. - #[inline] - pub fn seal_slow(self) -> SealedBlockWithSenders { - SealedBlockWithSenders { block: self.block.seal_slow(), senders: self.senders } - } - - /// Split Structure to its components - #[inline] - pub fn split(self) -> (B, Vec
) { - (self.block, self.senders) - } - - /// Returns an iterator over all transactions and their sender. - #[inline] - pub fn transactions_with_sender( - &self, - ) -> impl Iterator::Transaction)> - + '_ { - self.senders.iter().zip(self.block.body().transactions()) - } - - /// Returns an iterator over all transactions in the chain. - #[inline] - pub fn into_transactions_ecrecovered( - self, - ) -> impl Iterator::Transaction>> - where - ::Transaction: SignedTransaction, - { - self.block - .split() - .1 - .into_transactions() - .into_iter() - .zip(self.senders) - .map(|(tx, sender)| tx.with_signer(sender)) - } - - /// Consumes the block and returns the transactions of the block. - #[inline] - pub fn into_transactions( - self, - ) -> Vec<::Transaction> { - self.block.split().1.into_transactions() - } -} - -/// Sealed Ethereum full block. -/// -/// Withdrawals can be optionally included at the end of the RLP encoded message. -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub struct SealedBlock { - /// Locked block header. - header: SealedHeader, - /// Block body. - body: B, -} - -impl SealedBlock { - /// Create a new sealed block instance using the sealed header and block body. - #[inline] - pub const fn new(header: SealedHeader, body: B) -> Self { - Self { header, body } - } - - /// Header hash. - #[inline] - pub const fn hash(&self) -> B256 { - self.header.hash() - } - - /// Returns reference to block header. - pub const fn header(&self) -> &H { - self.header.header() - } - - /// Returns reference to block body. - pub const fn body(&self) -> &B { - &self.body - } - - /// Returns the Sealed header. - pub const fn sealed_header(&self) -> &SealedHeader { - &self.header - } - - /// Clones the wrapped header and returns a [`SealedHeader`] sealed with the hash. - pub fn clone_sealed_header(&self) -> SealedHeader - where - H: Clone, - { - self.header.clone() - } - - /// Consumes the block and returns the sealed header. - pub fn into_sealed_header(self) -> SealedHeader { - self.header - } - - /// Consumes the block and returns the header. - pub fn into_header(self) -> H { - self.header.unseal() - } - - /// Consumes the block and returns the body. - pub fn into_body(self) -> B { - self.body - } - - /// Splits the [`BlockBody`] and [`SealedHeader`] into separate components - #[inline] - pub fn split(self) -> (SealedHeader, B) { - (self.header, self.body) - } -} - -impl SealedBlock -where - B: reth_primitives_traits::BlockBody, -{ - /// Returns an iterator over all blob versioned hashes from the block body. - #[inline] - pub fn blob_versioned_hashes_iter(&self) -> impl Iterator + '_ { - self.body.blob_versioned_hashes_iter() - } -} - -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, - B: reth_primitives_traits::BlockBody, -{ - /// Return the number hash tuple. - pub fn num_hash(&self) -> BlockNumHash { - BlockNumHash::new(self.number(), self.hash()) - } - - /// Return a [`BlockWithParent`] for this header. - pub fn block_with_parent(&self) -> BlockWithParent { - BlockWithParent { parent: self.parent_hash(), block: self.num_hash() } - } - - /// Ensures that the transaction root in the block header is valid. - /// - /// The transaction root is the Keccak 256-bit hash of the root node of the trie structure - /// populated with each transaction in the transactions list portion of the block. - /// - /// # Returns - /// - /// Returns `Ok(())` if the calculated transaction root matches the one stored in the header, - /// indicating that the transactions in the block are correctly represented in the trie. - /// - /// Returns `Err(error)` if the transaction root validation fails, providing a `GotExpected` - /// error containing the calculated and expected roots. - pub fn ensure_transaction_root_valid(&self) -> Result<(), GotExpected> - where - B::Transaction: Encodable2718, - { - let calculated_root = self.body.calculate_tx_root(); - - if self.header.transactions_root() != calculated_root { - return Err(GotExpected { - got: calculated_root, - expected: self.header.transactions_root(), - }) - } - - Ok(()) - } -} - -impl SealedBlock -where - H: reth_primitives_traits::BlockHeader, - B: reth_primitives_traits::BlockBody, -{ - /// Expensive operation that recovers transaction signer. See [`SealedBlockWithSenders`]. - pub fn senders(&self) -> Option> - where - B::Transaction: SignedTransaction, - { - self.body.recover_signers() - } - - /// Seal sealed block with recovered transaction senders. - pub fn seal_with_senders(self) -> Option> - where - B::Transaction: SignedTransaction, - T: reth_primitives_traits::Block
, - { - self.try_seal_with_senders().ok() - } - - /// Seal sealed block with recovered transaction senders. - pub fn try_seal_with_senders(self) -> Result, Self> - where - B::Transaction: SignedTransaction, - T: reth_primitives_traits::Block
, - { - match self.senders() { - Some(senders) => Ok(SealedBlockWithSenders { block: self, senders }), - None => Err(self), - } - } - - /// Transform into a [`SealedBlockWithSenders`]. - /// - /// # Panics - /// - /// If the number of senders does not match the number of transactions in the block - /// and the signer recovery for one of the transactions fails. - #[track_caller] - pub fn with_senders_unchecked(self, senders: Vec
) -> SealedBlockWithSenders - where - B::Transaction: SignedTransaction, - T: reth_primitives_traits::Block
, - { - self.try_with_senders_unchecked(senders).expect("stored block is valid") - } - - /// Transform into a [`SealedBlockWithSenders`] using the given senders. - /// - /// 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 [`TransactionSigned::recover_signer_unchecked`] - /// - /// Returns an error if a signature is invalid. - #[track_caller] - pub fn try_with_senders_unchecked( - self, - senders: Vec
, - ) -> Result, Self> - where - B::Transaction: SignedTransaction, - T: reth_primitives_traits::Block
, - { - let senders = if self.body.transactions().len() == senders.len() { - senders - } else { - let Some(senders) = self.body.recover_signers_unchecked() else { return Err(self) }; - senders - }; - - Ok(SealedBlockWithSenders { block: self, senders }) - } - - /// Unseal the block - pub fn unseal(self) -> Block - where - Block: reth_primitives_traits::Block
, - { - Block::new(self.header.unseal(), self.body) - } -} - -impl InMemorySize for SealedBlock { - #[inline] - fn size(&self) -> usize { - self.header.size() + self.body.size() - } -} - -impl From for Block { - fn from(block: SealedBlock) -> Self { - block.unseal() - } -} - -impl Default for SealedBlock -where - SealedHeader: Default, - B: Default, -{ - fn default() -> Self { - Self { header: Default::default(), body: Default::default() } - } -} - -impl Deref for SealedBlock { - type Target = H; - - fn deref(&self) -> &Self::Target { - self.header.header() - } -} - -#[cfg(any(test, feature = "arbitrary"))] -impl<'a, H, B> arbitrary::Arbitrary<'a> for SealedBlock -where - SealedHeader: arbitrary::Arbitrary<'a>, - B: arbitrary::Arbitrary<'a>, -{ - fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { - Ok(Self { header: u.arbitrary()?, body: u.arbitrary()? }) - } -} - -#[cfg(any(test, feature = "test-utils"))] -impl SealedBlock -where - H: reth_primitives_traits::test_utils::TestHeader, -{ - /// Returns a mutable reference to the header. - pub fn header_mut(&mut self) -> &mut H { - self.header.header_mut() - } - - /// Returns a mutable reference to the header. - pub fn body_mut(&mut self) -> &mut B { - &mut self.body - } - - /// Updates the block header. - pub fn set_header(&mut self, header: H) { - self.header.set_header(header) - } - - /// Updates the block hash. - pub fn set_hash(&mut self, hash: alloy_primitives::BlockHash) { - self.header.set_hash(hash); - } - - /// Updates the parent block hash. - pub fn set_parent_hash(&mut self, hash: alloy_primitives::BlockHash) { - self.header.set_parent_hash(hash); - } - - /// Updates the block number. - pub fn set_block_number(&mut self, number: alloy_primitives::BlockNumber) { - self.header.set_block_number(number); - } - - /// Updates the block state root. - pub fn set_state_root(&mut self, state_root: B256) { - self.header.set_state_root(state_root); - } - - /// Updates the block difficulty. - pub fn set_difficulty(&mut self, difficulty: alloy_primitives::U256) { - self.header.set_difficulty(difficulty); - } -} - -/// A helepr trait to construct [`SealedBlock`] from a [`reth_primitives_traits::Block`]. -pub type SealedBlockFor = SealedBlock< - ::Header, - ::Body, ->; - -/// Sealed block with senders recovered from transactions. -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Deref, DerefMut)] -pub struct SealedBlockWithSenders { - /// Sealed block - #[deref] - #[deref_mut] - #[serde(bound = "SealedBlock: Serialize + serde::de::DeserializeOwned")] - pub block: SealedBlock, - /// List of senders that match transactions from block. - senders: Vec
, -} - -impl Default for SealedBlockWithSenders { - fn default() -> Self { - Self { block: SealedBlock::default(), senders: Default::default() } - } -} - -impl SealedBlockWithSenders { - /// New sealed block with sender - pub const fn new_unchecked( - block: SealedBlock, - senders: Vec
, - ) -> Self { - Self { block, senders } - } - - /// New sealed block with sender. Return none if len of tx and senders does not match - pub fn new(block: SealedBlock, senders: Vec
) -> Option { - (block.body.transactions().len() == senders.len()).then_some(Self { block, senders }) - } -} - -impl SealedBlockWithSenders { - /// Returns all senders of the transactions in the block. - pub fn senders(&self) -> &[Address] { - &self.senders - } - - /// Returns an iterator over all senders in the block. - pub fn senders_iter(&self) -> impl Iterator { - self.senders.iter() - } - - /// Split Structure to its components - #[inline] - pub fn split(self) -> (SealedBlock, Vec
) { - (self.block, self.senders) - } - - /// Returns the unsealed [`BlockWithSenders`] - #[inline] - pub fn unseal(self) -> BlockWithSenders { - let (block, senders) = self.split(); - let (header, body) = block.split(); - let header = header.unseal(); - BlockWithSenders::new_unchecked(B::new(header, body), senders) - } - - /// Returns an iterator over all transactions in the block. - #[inline] - pub fn transactions(&self) -> &[::Transaction] { - self.block.body.transactions() - } - - /// Returns an iterator over all transactions and their sender. - #[inline] - pub fn transactions_with_sender( - &self, - ) -> impl Iterator::Transaction)> - + '_ { - self.senders.iter().zip(self.block.body.transactions()) - } - - /// Consumes the block and returns the transactions of the block. - #[inline] - pub fn into_transactions( - self, - ) -> Vec<::Transaction> { - self.block.body.into_transactions() - } - - /// Returns an iterator over all transactions in the chain. - #[inline] - pub fn into_transactions_ecrecovered( - self, - ) -> impl Iterator::Transaction>> - where - ::Transaction: SignedTransaction, - { - self.block - .body - .into_transactions() - .into_iter() - .zip(self.senders) - .map(|(tx, sender)| tx.with_signer(sender)) - } -} - -#[cfg(any(test, feature = "test-utils"))] -impl SealedBlockWithSenders -where - B: reth_primitives_traits::Block, -{ - /// Returns a mutable reference to the recovered senders. - pub fn senders_mut(&mut self) -> &mut Vec
{ - &mut self.senders - } - - /// Appends the sender to the list of senders. - pub fn push_sender(&mut self, sender: Address) { - self.senders.push(sender); - } -} - -#[cfg(any(test, feature = "arbitrary"))] -impl<'a, B> arbitrary::Arbitrary<'a> for SealedBlockWithSenders -where - B: reth_primitives_traits::Block + arbitrary::Arbitrary<'a>, -{ - fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { - let block = B::arbitrary(u)?; - - let senders = block - .body() - .transactions() - .iter() - .map(|tx| tx.recover_signer().unwrap()) - .collect::>(); - - let (header, body) = block.split(); - let block = SealedBlock::new(SealedHeader::seal(header), body); - Ok(Self { block, senders }) - } -} - -/// Bincode-compatible block type serde implementations. -#[cfg(feature = "serde-bincode-compat")] -pub(super) mod serde_bincode_compat { - use alloc::{borrow::Cow, vec::Vec}; - use alloy_primitives::Address; - use reth_primitives_traits::{ - serde_bincode_compat::{SealedHeader, SerdeBincodeCompat}, - Block, - }; - use serde::{Deserialize, Deserializer, Serialize, Serializer}; - use serde_with::{DeserializeAs, SerializeAs}; - - /// Bincode-compatible [`super::BlockBody`] serde implementation. - pub type BlockBody<'a, T = super::TransactionSigned> = - reth_primitives_traits::serde_bincode_compat::BlockBody<'a, T>; - - /// Bincode-compatible [`super::SealedBlock`] serde implementation. - /// - /// Intended to use with the [`serde_with::serde_as`] macro in the following way: - /// ```rust - /// use reth_primitives::{serde_bincode_compat, SealedBlock}; - /// use serde::{Deserialize, Serialize}; - /// use serde_with::serde_as; - /// - /// #[serde_as] - /// #[derive(Serialize, Deserialize)] - /// struct Data { - /// #[serde_as(as = "serde_bincode_compat::SealedBlock")] - /// block: SealedBlock, - /// } - /// ``` - #[derive(Debug, Serialize, Deserialize)] - pub struct SealedBlock<'a, H = super::Header, B = super::BlockBody> - where - H: SerdeBincodeCompat, - B: SerdeBincodeCompat, - { - header: SealedHeader<'a, H>, - body: B::BincodeRepr<'a>, - } - - impl<'a, H, B> From<&'a super::SealedBlock> for SealedBlock<'a, H, B> - where - H: SerdeBincodeCompat, - B: SerdeBincodeCompat, - { - fn from(value: &'a super::SealedBlock) -> Self { - Self { - header: SealedHeader::from(&value.header), - body: B::BincodeRepr::from(&value.body), - } - } - } - - impl<'a, H, B> From> for super::SealedBlock - where - H: SerdeBincodeCompat, - B: SerdeBincodeCompat, - { - fn from(value: SealedBlock<'a, H, B>) -> Self { - Self { header: value.header.into(), body: value.body.into() } - } - } - - impl SerializeAs for SealedBlock<'_> { - fn serialize_as(source: &super::SealedBlock, serializer: S) -> Result - where - S: Serializer, - { - SealedBlock::from(source).serialize(serializer) - } - } - - impl<'de> DeserializeAs<'de, super::SealedBlock> for SealedBlock<'de> { - fn deserialize_as(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - SealedBlock::deserialize(deserializer).map(Into::into) - } - } - - /// Bincode-compatible [`super::SealedBlockWithSenders`] serde implementation. - /// - /// Intended to use with the [`serde_with::serde_as`] macro in the following way: - /// ```rust - /// use reth_primitives::{serde_bincode_compat, SealedBlockWithSenders}; - /// use serde::{Deserialize, Serialize}; - /// use serde_with::serde_as; - /// - /// #[serde_as] - /// #[derive(Serialize, Deserialize)] - /// struct Data { - /// #[serde_as(as = "serde_bincode_compat::SealedBlockWithSenders")] - /// block: SealedBlockWithSenders, - /// } - /// ``` - #[derive(Debug, Serialize, Deserialize)] - pub struct SealedBlockWithSenders<'a, B = super::Block> - where - B: Block, - { - block: SealedBlock<'a, B::Header, B::Body>, - senders: Cow<'a, Vec
>, - } - - impl<'a, B> From<&'a super::SealedBlockWithSenders> for SealedBlockWithSenders<'a, B> - where - B: Block, - { - fn from(value: &'a super::SealedBlockWithSenders) -> Self { - Self { block: SealedBlock::from(&value.block), senders: Cow::Borrowed(&value.senders) } - } - } - - impl<'a, B> From> for super::SealedBlockWithSenders - where - B: Block, - { - fn from(value: SealedBlockWithSenders<'a, B>) -> Self { - Self { block: value.block.into(), senders: value.senders.into_owned() } - } - } - - impl SerializeAs for SealedBlockWithSenders<'_> { - fn serialize_as( - source: &super::SealedBlockWithSenders, - serializer: S, - ) -> Result - where - S: Serializer, - { - SealedBlockWithSenders::from(source).serialize(serializer) - } - } - - impl<'de> DeserializeAs<'de, super::SealedBlockWithSenders> for SealedBlockWithSenders<'de> { - fn deserialize_as(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - SealedBlockWithSenders::deserialize(deserializer).map(Into::into) - } - } - - #[cfg(test)] - mod tests { - use super::super::{serde_bincode_compat, BlockBody, SealedBlock, SealedBlockWithSenders}; - use arbitrary::Arbitrary; - use rand::Rng; - use reth_testing_utils::generators; - use serde::{Deserialize, Serialize}; - use serde_with::serde_as; - - #[test] - fn test_block_body_bincode_roundtrip() { - #[serde_as] - #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] - struct Data { - #[serde_as(as = "serde_bincode_compat::BlockBody")] - block_body: BlockBody, - } - - let mut bytes = [0u8; 1024]; - generators::rng().fill(bytes.as_mut_slice()); - let data = Data { - block_body: BlockBody::arbitrary(&mut arbitrary::Unstructured::new(&bytes)) - .unwrap(), - }; - - let encoded = bincode::serialize(&data).unwrap(); - let decoded: Data = bincode::deserialize(&encoded).unwrap(); - assert_eq!(decoded, data); - } - - #[test] - fn test_sealed_block_bincode_roundtrip() { - #[serde_as] - #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] - struct Data { - #[serde_as(as = "serde_bincode_compat::SealedBlock")] - block: SealedBlock, - } - - let mut bytes = [0u8; 1024]; - generators::rng().fill(bytes.as_mut_slice()); - let data = Data { - block: SealedBlock::arbitrary(&mut arbitrary::Unstructured::new(&bytes)).unwrap(), - }; - - let encoded = bincode::serialize(&data).unwrap(); - let decoded: Data = bincode::deserialize(&encoded).unwrap(); - assert_eq!(decoded, data); - } - - #[test] - fn test_sealed_block_with_senders_bincode_roundtrip() { - #[serde_as] - #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] - struct Data { - #[serde_as(as = "serde_bincode_compat::SealedBlockWithSenders")] - block: SealedBlockWithSenders, - } - - let mut bytes = [0u8; 1024]; - generators::rng().fill(bytes.as_mut_slice()); - let data = Data { - block: SealedBlockWithSenders::arbitrary(&mut arbitrary::Unstructured::new(&bytes)) - .unwrap(), - }; - - let encoded = bincode::serialize(&data).unwrap(); - let decoded: Data = bincode::deserialize(&encoded).unwrap(); - assert_eq!(decoded, data); - } - } -} +/// Ethereum recovered block +#[deprecated(note = "Use `RecoveredBlock` instead")] +pub type SealedBlockWithSenders = reth_primitives_traits::block::RecoveredBlock; #[cfg(test)] mod tests { @@ -845,8 +34,9 @@ mod tests { eip1898::HexStringMissingPrefixError, BlockId, BlockNumberOrTag, BlockNumberOrTag::*, RpcBlockHash, }; - use alloy_primitives::hex_literal::hex; + use alloy_primitives::{hex_literal::hex, B256}; use alloy_rlp::{Decodable, Encodable}; + use reth_primitives_traits::{BlockBody, RecoveredBlock}; use std::str::FromStr; const fn _traits() { @@ -1008,37 +198,18 @@ mod tests { #[test] fn block_with_senders() { - let mut block = Block::default(); - let sender = Address::random(); + let mut block: Block = Block::default(); block.body.transactions.push(TransactionSigned::default()); - assert_eq!(BlockWithSenders::new(block.clone(), vec![]), None); - assert_eq!( - BlockWithSenders::new(block.clone(), vec![sender]), - Some(BlockWithSenders { block: block.clone(), senders: vec![sender] }) - ); - let sealed = block.seal_slow(); - assert_eq!(SealedBlockWithSenders::::new(sealed.clone(), vec![]), None); - assert_eq!( - SealedBlockWithSenders::::new(sealed.clone(), vec![sender]), - Some(SealedBlockWithSenders { block: sealed, senders: vec![sender] }) - ); - } - - #[test] - fn test_default_seal() { - let block: SealedBlock = SealedBlock::default(); - let sealed = block.hash(); - let block: Block = block.unseal(); - let block = block.seal_slow(); - assert_eq!(sealed, block.hash()); + let block = RecoveredBlock::try_new_unhashed(block.clone(), vec![]).unwrap(); + assert_eq!(block.senders().len(), 1); } #[test] fn empty_block_rlp() { - let body: BlockBody = BlockBody::default(); + let body = alloy_consensus::BlockBody::::default(); let mut buf = Vec::new(); body.encode(&mut buf); - let decoded = BlockBody::decode(&mut buf.as_slice()).unwrap(); + let decoded = alloy_consensus::BlockBody::decode(&mut buf.as_slice()).unwrap(); assert_eq!(body, decoded); } diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index 4667689aeb..b613141242 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -21,9 +21,6 @@ extern crate alloc; -mod traits; -pub use traits::*; - #[cfg(feature = "alloy-compat")] mod alloy_compat; mod block; @@ -33,13 +30,14 @@ pub use reth_static_file_types as static_file; pub mod transaction; #[cfg(any(test, feature = "arbitrary"))] pub use block::{generate_valid_header, valid_header_strategy}; -pub use block::{ - Block, BlockBody, BlockWithSenders, SealedBlock, SealedBlockFor, SealedBlockWithSenders, -}; +pub use block::{Block, BlockBody, SealedBlock}; +#[allow(deprecated)] +pub use block::{BlockWithSenders, SealedBlockFor, SealedBlockWithSenders}; + pub use receipt::{gas_spent_by_transactions, Receipt, Receipts}; pub use reth_primitives_traits::{ logs_bloom, Account, Bytecode, GotExpected, GotExpectedBoxed, Header, HeaderError, Log, - LogData, NodePrimitives, SealedHeader, StorageEntry, + LogData, NodePrimitives, RecoveredBlock, SealedHeader, StorageEntry, }; pub use static_file::StaticFileSegment; @@ -71,10 +69,8 @@ pub use c_kzg as kzg; /// Read more: #[cfg(feature = "serde-bincode-compat")] pub mod serde_bincode_compat { - pub use super::{ - block::serde_bincode_compat::*, - transaction::{serde_bincode_compat as transaction, serde_bincode_compat::*}, - }; + pub use super::transaction::{serde_bincode_compat as transaction, serde_bincode_compat::*}; + pub use reth_primitives_traits::serde_bincode_compat::*; } /// Temp helper struct for integrating [`NodePrimitives`]. diff --git a/crates/primitives/src/traits.rs b/crates/primitives/src/traits.rs deleted file mode 100644 index 08a8ab3e66..0000000000 --- a/crates/primitives/src/traits.rs +++ /dev/null @@ -1,85 +0,0 @@ -use crate::{BlockWithSenders, SealedBlock}; -use alloc::vec::Vec; -use reth_primitives_traits::{Block, BlockBody, SealedHeader, SignedTransaction}; -use revm_primitives::{Address, B256}; - -/// Extension trait for [`reth_primitives_traits::Block`] implementations -/// allowing for conversions into common block parts containers such as [`SealedBlock`], -/// [`BlockWithSenders`], etc. -pub trait BlockExt: Block { - /// Calculate the header hash and seal the block so that it can't be changed. - fn seal_slow(self) -> SealedBlock { - let (header, body) = self.split(); - SealedBlock::new(SealedHeader::seal(header), body) - } - - /// Seal the block with a known hash. - /// - /// WARNING: This method does not perform validation whether the hash is correct. - fn seal(self, hash: B256) -> SealedBlock { - let (header, body) = self.split(); - SealedBlock::new(SealedHeader::new(header, hash), body) - } - - /// Expensive operation that recovers transaction signer. - fn senders(&self) -> Option> - where - ::Transaction: SignedTransaction, - { - self.body().recover_signers() - } - - /// Transform into a [`BlockWithSenders`]. - /// - /// # Panics - /// - /// If the number of senders does not match the number of transactions in the block - /// and the signer recovery for one of the transactions fails. - /// - /// Note: this is expected to be called with blocks read from disk. - #[track_caller] - fn with_senders_unchecked(self, senders: Vec
) -> BlockWithSenders - where - ::Transaction: SignedTransaction, - { - self.try_with_senders_unchecked(senders).expect("stored block is valid") - } - - /// Transform into a [`BlockWithSenders`] using the given senders. - /// - /// 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_. - /// - /// Returns an error if a signature is invalid. - #[track_caller] - fn try_with_senders_unchecked( - self, - senders: Vec
, - ) -> Result, Self> - where - ::Transaction: SignedTransaction, - { - let senders = if self.body().transactions().len() == senders.len() { - senders - } else { - let Some(senders) = self.body().recover_signers_unchecked() else { return Err(self) }; - senders - }; - - Ok(BlockWithSenders::new_unchecked(self, senders)) - } - - /// **Expensive**. Transform into a [`BlockWithSenders`] by recovering senders in the contained - /// transactions. - /// - /// Returns `None` if a transaction is invalid. - fn with_recovered_senders(self) -> Option> - where - ::Transaction: SignedTransaction, - { - let senders = self.senders()?; - Some(BlockWithSenders::new_unchecked(self, senders)) - } -} - -impl BlockExt for T {} diff --git a/crates/prune/prune/src/segments/mod.rs b/crates/prune/prune/src/segments/mod.rs index c1e23063fe..a947ab8eb8 100644 --- a/crates/prune/prune/src/segments/mod.rs +++ b/crates/prune/prune/src/segments/mod.rs @@ -191,7 +191,7 @@ mod tests { for block in &blocks { provider_rw .insert_historical_block( - block.clone().seal_with_senders().expect("failed to seal block with senders"), + block.clone().try_recover().expect("failed to seal block with senders"), ) .expect("failed to insert block"); } @@ -229,7 +229,7 @@ mod tests { for block in &blocks { provider_rw .insert_historical_block( - block.clone().seal_with_senders().expect("failed to seal block with senders"), + block.clone().try_recover().expect("failed to seal block with senders"), ) .expect("failed to insert block"); } @@ -275,7 +275,7 @@ mod tests { for block in &blocks { provider_rw .insert_historical_block( - block.clone().seal_with_senders().expect("failed to seal block with senders"), + block.clone().try_recover().expect("failed to seal block with senders"), ) .expect("failed to insert block"); } @@ -311,7 +311,7 @@ mod tests { for block in &blocks { provider_rw .insert_historical_block( - block.clone().seal_with_senders().expect("failed to seal block with senders"), + block.clone().try_recover().expect("failed to seal block with senders"), ) .expect("failed to insert block"); } diff --git a/crates/rpc/rpc-builder/Cargo.toml b/crates/rpc/rpc-builder/Cargo.toml index 957e2e33cf..79ff504dfc 100644 --- a/crates/rpc/rpc-builder/Cargo.toml +++ b/crates/rpc/rpc-builder/Cargo.toml @@ -50,6 +50,7 @@ tokio-util = { workspace = true } tokio = { workspace = true, features = ["rt", "rt-multi-thread"] } [dev-dependencies] +reth-primitives-traits.workspace = true reth-chainspec.workspace = true reth-network-api.workspace = true reth-network-peers.workspace = true diff --git a/crates/rpc/rpc-builder/tests/it/auth.rs b/crates/rpc/rpc-builder/tests/it/auth.rs index ca5db0494e..381b48dad2 100644 --- a/crates/rpc/rpc-builder/tests/it/auth.rs +++ b/crates/rpc/rpc-builder/tests/it/auth.rs @@ -8,10 +8,12 @@ use alloy_rpc_types_engine::{ }; use jsonrpsee::core::client::{ClientT, SubscriptionClientT}; use reth_ethereum_engine_primitives::EthEngineTypes; -use reth_primitives::{Block, BlockExt, TransactionSigned}; +use reth_primitives::{Block, TransactionSigned}; +use reth_primitives_traits::block::Block as _; use reth_rpc_api::clients::EngineApiClient; use reth_rpc_layer::JwtSecret; use reth_rpc_types_compat::engine::payload::block_to_payload_v1; + #[allow(unused_must_use)] async fn test_basic_engine_calls(client: &C) where @@ -23,7 +25,7 @@ where client, ExecutionPayloadInputV2 { execution_payload: ExecutionPayloadV1::from_block_slow::( - &block.unseal(), + &block.into_block(), ), withdrawals: None, }, diff --git a/crates/rpc/rpc-engine-api/src/engine_api.rs b/crates/rpc/rpc-engine-api/src/engine_api.rs index c3ed8dc5ad..50177199cb 100644 --- a/crates/rpc/rpc-engine-api/src/engine_api.rs +++ b/crates/rpc/rpc-engine-api/src/engine_api.rs @@ -1150,12 +1150,14 @@ mod tests { start..=start + count - 1, BlockRangeParams { tx_count: 0..2, ..Default::default() }, ); - handle.provider.extend_blocks(blocks.iter().cloned().map(|b| (b.hash(), b.unseal()))); + handle + .provider + .extend_blocks(blocks.iter().cloned().map(|b| (b.hash(), b.into_block()))); let expected = blocks .iter() .cloned() - .map(|b| Some(ExecutionPayloadBodyV1::from_block(b.unseal::()))) + .map(|b| Some(ExecutionPayloadBodyV1::from_block(b.into_block()))) .collect::>(); let res = api.get_payload_bodies_by_range_v1(start, count).await.unwrap(); @@ -1184,7 +1186,7 @@ mod tests { !first_missing_range.contains(&b.number) && !second_missing_range.contains(&b.number) }) - .map(|b| (b.hash(), b.clone().unseal())), + .map(|b| (b.hash(), b.clone().into_block())), ); let expected = blocks @@ -1197,7 +1199,7 @@ mod tests { if first_missing_range.contains(&b.number) { None } else { - Some(ExecutionPayloadBodyV1::from_block(b.unseal::())) + Some(ExecutionPayloadBodyV1::from_block(b.into_block())) } }) .collect::>(); @@ -1216,7 +1218,7 @@ mod tests { { None } else { - Some(ExecutionPayloadBodyV1::from_block(b.unseal::())) + Some(ExecutionPayloadBodyV1::from_block(b.into_block())) } }) .collect::>(); @@ -1290,7 +1292,7 @@ mod tests { // Add block and to provider local store and test for mismatch handle.provider.add_block( execution_terminal_block.hash(), - execution_terminal_block.clone().unseal(), + execution_terminal_block.clone().into_block(), ); let res = api.exchange_transition_configuration(transition_config); @@ -1320,7 +1322,7 @@ mod tests { terminal_block_number, }; - handle.provider.add_block(terminal_block.hash(), terminal_block.unseal()); + handle.provider.add_block(terminal_block.hash(), terminal_block.into_block()); let config = api.exchange_transition_configuration(transition_config).unwrap(); assert_eq!(config, transition_config); diff --git a/crates/rpc/rpc-engine-api/tests/it/payload.rs b/crates/rpc/rpc-engine-api/tests/it/payload.rs index 385607e47f..e0debe679d 100644 --- a/crates/rpc/rpc-engine-api/tests/it/payload.rs +++ b/crates/rpc/rpc-engine-api/tests/it/payload.rs @@ -15,13 +15,17 @@ use reth_testing_utils::generators::{ }; fn transform_block Block>(src: SealedBlock, f: F) -> ExecutionPayload { - let unsealed = src.unseal(); + let unsealed = src.into_block(); let mut transformed: Block = f(unsealed); // Recalculate roots transformed.header.transactions_root = proofs::calculate_transaction_root(&transformed.body.transactions); transformed.header.ommers_hash = proofs::calculate_ommers_root(&transformed.body.ommers); - block_to_payload(SealedBlock::new(SealedHeader::seal(transformed.header), transformed.body)).0 + block_to_payload(SealedBlock::from_sealed_parts( + SealedHeader::seal_slow(transformed.header), + transformed.body, + )) + .0 } #[test] @@ -33,7 +37,7 @@ fn payload_body_roundtrip() { BlockRangeParams { tx_count: 0..2, ..Default::default() }, ) { let payload_body: ExecutionPayloadBodyV1 = - ExecutionPayloadBodyV1::from_block(block.clone().unseal::()); + ExecutionPayloadBodyV1::from_block(block.clone().into_block()); assert_eq!( Ok(block.body().transactions.clone()), diff --git a/crates/rpc/rpc-eth-api/src/helpers/block.rs b/crates/rpc/rpc-eth-api/src/helpers/block.rs index 4cb01d16da..b1930995d5 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/block.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/block.rs @@ -1,33 +1,30 @@ //! Database access for `eth_` block RPC methods. Loads block and receipt data w.r.t. network. -use std::sync::Arc; - +use super::{LoadPendingBlock, LoadReceipt, SpawnBlocking}; +use crate::{ + node::RpcNodeCoreExt, EthApiTypes, FromEthApiError, FullEthApiTypes, RpcBlock, RpcNodeCore, + RpcReceipt, +}; use alloy_eips::BlockId; use alloy_primitives::Sealable; use alloy_rlp::Encodable; use alloy_rpc_types_eth::{Block, BlockTransactions, Header, Index}; use futures::Future; use reth_node_api::BlockBody; -use reth_primitives::{SealedBlockFor, SealedBlockWithSenders}; +use reth_primitives::{RecoveredBlock, SealedBlock}; use reth_provider::{ BlockIdReader, BlockReader, BlockReaderIdExt, ProviderHeader, ProviderReceipt, }; use reth_rpc_types_compat::block::from_block; use revm_primitives::U256; - -use crate::{ - node::RpcNodeCoreExt, EthApiTypes, FromEthApiError, FullEthApiTypes, RpcBlock, RpcNodeCore, - RpcReceipt, -}; - -use super::{LoadPendingBlock, LoadReceipt, SpawnBlocking}; +use std::sync::Arc; /// Result type of the fetched block receipts. pub type BlockReceiptsResult = Result>>, E>; /// Result type of the fetched block and its receipts. pub type BlockAndReceiptsResult = Result< Option<( - SealedBlockFor<<::Provider as BlockReader>::Block>, + SealedBlock<<::Provider as BlockReader>::Block>, Arc::Provider>>>, )>, ::Error, @@ -62,14 +59,8 @@ pub trait EthBlocks: LoadBlock { { async move { let Some(block) = self.block_with_senders(block_id).await? else { return Ok(None) }; - let block_hash = block.hash(); - let block = from_block( - (*block).clone().unseal(), - full.into(), - Some(block_hash), - self.tx_resp_builder(), - )?; + let block = from_block((*block).clone(), full.into(), self.tx_resp_builder())?; Ok(Some(block)) } } @@ -105,7 +96,7 @@ pub trait EthBlocks: LoadBlock { .get_sealed_block_with_senders(block_hash) .await .map_err(Self::Error::from_eth_err)? - .map(|b| b.body().transactions().len())) + .map(|b| b.body().transaction_count())) } } @@ -143,7 +134,7 @@ pub trait EthBlocks: LoadBlock { // If no pending block from provider, build the pending block locally. if let Some((block, receipts)) = self.local_pending_block().await? { - return Ok(Some((block.block, Arc::new(receipts)))); + return Ok(Some((block.into_sealed_block(), Arc::new(receipts)))); } } @@ -155,7 +146,7 @@ pub trait EthBlocks: LoadBlock { .get_block_and_receipts(block_hash) .await .map_err(Self::Error::from_eth_err) - .map(|b| b.map(|(b, r)| (b.block.clone(), r))) + .map(|b| b.map(|(b, r)| (b.clone_sealed_block(), r))) } Ok(None) @@ -219,7 +210,7 @@ pub trait LoadBlock: LoadPendingBlock + SpawnBlocking + RpcNodeCoreExt { block_id: BlockId, ) -> impl Future< Output = Result< - Option::Block>>>, + Option::Block>>>, Self::Error, >, > + Send { diff --git a/crates/rpc/rpc-eth-api/src/helpers/fee.rs b/crates/rpc/rpc-eth-api/src/helpers/fee.rs index f2ab11acc3..30b414859e 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/fee.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/fee.rs @@ -1,5 +1,7 @@ //! Loads fee history from database. Helper trait for `eth_` fee and transaction RPC methods. +use super::LoadBlock; +use crate::FromEthApiError; use alloy_consensus::BlockHeader; use alloy_eips::eip7840::BlobParams; use alloy_primitives::U256; @@ -14,10 +16,6 @@ use reth_rpc_eth_types::{ }; use tracing::debug; -use crate::FromEthApiError; - -use super::LoadBlock; - /// Fee related functions for the [`EthApiServer`](crate::EthApiServer) trait in the /// `eth_` namespace. pub trait EthFees: LoadFee { 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 9b52b94a4d..e947a0d0a6 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs @@ -15,7 +15,7 @@ use reth_evm::{ env::EvmEnv, state_change::post_block_withdrawals_balance_increments, system_calls::SystemCaller, ConfigureEvm, ConfigureEvmEnv, NextBlockEnvAttributes, }; -use reth_primitives::{BlockExt, InvalidTransactionError, SealedBlockWithSenders}; +use reth_primitives::{InvalidTransactionError, RecoveredBlock}; use reth_primitives_traits::Receipt; use reth_provider::{ BlockReader, BlockReaderIdExt, ChainSpecProvider, ProviderBlock, ProviderError, ProviderHeader, @@ -133,7 +133,7 @@ pub trait LoadPendingBlock: ) -> impl Future< Output = Result< Option<( - SealedBlockWithSenders<::Block>, + RecoveredBlock<::Block>, Vec>, )>, Self::Error, @@ -247,10 +247,7 @@ pub trait LoadPendingBlock: block_env: BlockEnv, parent_hash: B256, ) -> Result< - ( - SealedBlockWithSenders>, - Vec>, - ), + (RecoveredBlock>, Vec>), Self::Error, > where @@ -426,6 +423,6 @@ pub trait LoadPendingBlock: results, ); - Ok((SealedBlockWithSenders::new_unchecked(block.seal_slow(), senders), receipts)) + Ok((RecoveredBlock::new_unhashed(block, senders), receipts)) } } diff --git a/crates/rpc/rpc-eth-api/src/helpers/trace.rs b/crates/rpc/rpc-eth-api/src/helpers/trace.rs index bb4c9c5ebf..ccb0cd84fe 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/trace.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/trace.rs @@ -1,7 +1,6 @@ //! Loads a pending block from database. Helper trait for `eth_` call and trace RPC methods. -use std::{fmt::Display, sync::Arc}; - +use super::{Call, LoadBlock, LoadPendingBlock, LoadState, LoadTransaction}; use crate::{FromEvmError, RpcNodeCore}; use alloy_consensus::BlockHeader; use alloy_primitives::B256; @@ -9,7 +8,7 @@ use alloy_rpc_types_eth::{BlockId, TransactionInfo}; use futures::Future; use reth_chainspec::ChainSpecProvider; use reth_evm::{env::EvmEnv, system_calls::SystemCaller, ConfigureEvm, ConfigureEvmEnv}; -use reth_primitives::SealedBlockWithSenders; +use reth_primitives::RecoveredBlock; use reth_primitives_traits::{BlockBody, SignedTransaction}; use reth_provider::{BlockReader, ProviderBlock, ProviderHeader, ProviderTx}; use reth_revm::database::StateProviderDatabase; @@ -22,8 +21,7 @@ use revm_inspectors::tracing::{TracingInspector, TracingInspectorConfig}; use revm_primitives::{ BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, EvmState, ExecutionResult, ResultAndState, }; - -use super::{Call, LoadBlock, LoadPendingBlock, LoadState, LoadTransaction}; +use std::{fmt::Display, sync::Arc}; /// Executes CPU heavy tasks. pub trait Trace: @@ -246,7 +244,7 @@ pub trait Trace: fn trace_block_until( &self, block_id: BlockId, - block: Option>>>, + block: Option>>>, highest_index: Option, config: TracingInspectorConfig, f: F, @@ -286,7 +284,7 @@ pub trait Trace: fn trace_block_until_with_inspector( &self, block_id: BlockId, - block: Option>>>, + block: Option>>>, highest_index: Option, mut inspector_setup: Setup, f: F, @@ -350,7 +348,7 @@ pub trait Trace: // prepare transactions, we do everything upfront to reduce time spent with open // state let max_transactions = - highest_index.map_or(block.body().transactions().len(), |highest| { + highest_index.map_or(block.body().transaction_count(), |highest| { // we need + 1 because the index is 0-based highest as usize + 1 }); @@ -413,7 +411,7 @@ pub trait Trace: fn trace_block_with( &self, block_id: BlockId, - block: Option>>>, + block: Option>>>, config: TracingInspectorConfig, f: F, ) -> impl Future>, Self::Error>> + Send @@ -452,7 +450,7 @@ pub trait Trace: fn trace_block_inspector( &self, block_id: BlockId, - block: Option>>>, + block: Option>>>, insp_setup: Setup, f: F, ) -> impl Future>, Self::Error>> + Send @@ -483,7 +481,7 @@ pub trait Trace: /// already applied. fn apply_pre_execution_changes + DatabaseCommit>( &self, - block: &SealedBlockWithSenders>, + block: &RecoveredBlock>, db: &mut DB, cfg: &CfgEnvWithHandlerCfg, block_env: &BlockEnv, diff --git a/crates/rpc/rpc-eth-api/src/helpers/transaction.rs b/crates/rpc/rpc-eth-api/src/helpers/transaction.rs index 285b12f856..6ab585dede 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/transaction.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/transaction.rs @@ -14,7 +14,7 @@ use alloy_primitives::{Address, Bytes, TxHash, B256}; use alloy_rpc_types_eth::{transaction::TransactionRequest, BlockNumberOrTag, TransactionInfo}; use futures::Future; use reth_node_api::BlockBody; -use reth_primitives::{transaction::SignedTransactionIntoRecoveredExt, SealedBlockWithSenders}; +use reth_primitives::{transaction::SignedTransactionIntoRecoveredExt, RecoveredBlock}; use reth_primitives_traits::SignedTransaction; use reth_provider::{ BlockNumReader, BlockReaderIdExt, ProviderBlock, ProviderReceipt, ProviderTx, ReceiptProvider, @@ -320,7 +320,7 @@ pub trait EthTransactions: LoadTransaction { { async move { if let Some(block) = self.block_with_senders(block_id).await? { - if let Some(tx) = block.transactions().get(index) { + if let Some(tx) = block.body().transactions().get(index) { return Ok(Some(tx.encoded_2718().into())) } } @@ -546,7 +546,7 @@ pub trait LoadTransaction: SpawnBlocking + FullEthApiTypes + RpcNodeCoreExt { Output = Result< Option<( TransactionSource>, - Arc>>, + Arc>>, )>, Self::Error, >, diff --git a/crates/rpc/rpc-eth-types/src/cache/mod.rs b/crates/rpc/rpc-eth-types/src/cache/mod.rs index 271f9d2141..ff2646cfc5 100644 --- a/crates/rpc/rpc-eth-types/src/cache/mod.rs +++ b/crates/rpc/rpc-eth-types/src/cache/mod.rs @@ -7,7 +7,7 @@ use futures::{future::Either, Stream, StreamExt}; use reth_chain_state::CanonStateNotification; use reth_errors::{ProviderError, ProviderResult}; use reth_execution_types::Chain; -use reth_primitives::{NodePrimitives, SealedBlockWithSenders}; +use reth_primitives::{NodePrimitives, RecoveredBlock}; use reth_primitives_traits::{Block, BlockBody}; use reth_storage_api::{BlockReader, StateProviderFactory, TransactionVariant}; use reth_tasks::{TaskSpawner, TokioTaskExecutor}; @@ -29,12 +29,12 @@ pub mod db; pub mod metrics; pub mod multi_consumer; -/// The type that can send the response to a requested [`SealedBlockWithSenders`] +/// The type that can send the response to a requested [`RecoveredBlock`] type BlockTransactionsResponseSender = oneshot::Sender>>>; -/// The type that can send the response to a requested [`SealedBlockWithSenders`] +/// The type that can send the response to a requested [`RecoveredBlock`] type BlockWithSendersResponseSender = - oneshot::Sender>>>>; + oneshot::Sender>>>>; /// The type that can send the response to the requested receipts of a block. type ReceiptsResponseSender = oneshot::Sender>>>>; @@ -44,7 +44,7 @@ type HeaderResponseSender = oneshot::Sender>; type BlockLruCache = MultiConsumerLruCache< B256, - Arc>, + Arc>, L, Either< BlockWithSendersResponseSender, @@ -76,10 +76,7 @@ impl ActionSender { const fn new(blockhash: B256, tx: Option>>) -> Self { Self { blockhash, tx } } - fn send_block( - &mut self, - block_sender: Result>>, ProviderError>, - ) { + fn send_block(&mut self, block_sender: Result>>, ProviderError>) { if let Some(tx) = self.tx.take() { let _ = tx.send(CacheAction::BlockWithSendersResult { block_hash: self.blockhash, @@ -191,13 +188,13 @@ impl EthStateCache { this } - /// Requests the [`SealedBlockWithSenders`] for the block hash + /// Requests the [`RecoveredBlock`] for the block hash /// /// Returns `None` if the block does not exist. pub async fn get_sealed_block_with_senders( &self, block_hash: B256, - ) -> ProviderResult>>> { + ) -> ProviderResult>>> { let (response_tx, rx) = oneshot::channel(); let _ = self.to_service.send(CacheAction::GetBlockWithSenders { block_hash, response_tx }); rx.await.map_err(|_| ProviderError::CacheServiceUnavailable)? @@ -216,7 +213,7 @@ impl EthStateCache { pub async fn get_block_and_receipts( &self, block_hash: B256, - ) -> ProviderResult>, Arc>)>> { + ) -> ProviderResult>, Arc>)>> { let block = self.get_sealed_block_with_senders(block_hash); let receipts = self.get_receipts(block_hash); @@ -260,7 +257,7 @@ pub(crate) struct EthStateCacheService< LimitHeaders = ByLength, > where Provider: BlockReader, - LimitBlocks: Limiter>>, + LimitBlocks: Limiter>>, LimitReceipts: Limiter>>, LimitHeaders: Limiter, { @@ -293,7 +290,7 @@ where fn on_new_block( &mut self, block_hash: B256, - res: ProviderResult>>>, + res: ProviderResult>>>, ) { if let Some(queued) = self.full_block_cache.remove(&block_hash) { // send the response to queued senders @@ -304,7 +301,7 @@ where } Either::Right(transaction_tx) => { let _ = transaction_tx.send(res.clone().map(|maybe_block| { - maybe_block.map(|block| block.block.body().transactions().to_vec()) + maybe_block.map(|block| block.body().transactions().to_vec()) })); } } @@ -338,7 +335,7 @@ where fn on_reorg_block( &mut self, block_hash: B256, - res: ProviderResult>>, + res: ProviderResult>>, ) { let res = res.map(|b| b.map(Arc::new)); if let Some(queued) = self.full_block_cache.remove(&block_hash) { @@ -350,7 +347,7 @@ where } Either::Right(transaction_tx) => { let _ = transaction_tx.send(res.clone().map(|maybe_block| { - maybe_block.map(|block| block.block.body().transactions().to_vec()) + maybe_block.map(|block| block.body().transactions().to_vec()) })); } } @@ -541,36 +538,14 @@ where /// All message variants sent through the channel enum CacheAction { - GetBlockWithSenders { - block_hash: B256, - response_tx: BlockWithSendersResponseSender, - }, - GetHeader { - block_hash: B256, - response_tx: HeaderResponseSender, - }, - GetReceipts { - block_hash: B256, - response_tx: ReceiptsResponseSender, - }, - BlockWithSendersResult { - block_hash: B256, - res: ProviderResult>>>, - }, - ReceiptsResult { - block_hash: B256, - res: ProviderResult>>>, - }, - HeaderResult { - block_hash: B256, - res: Box>, - }, - CacheNewCanonicalChain { - chain_change: ChainChange, - }, - RemoveReorgedChain { - chain_change: ChainChange, - }, + GetBlockWithSenders { block_hash: B256, response_tx: BlockWithSendersResponseSender }, + GetHeader { block_hash: B256, response_tx: HeaderResponseSender }, + GetReceipts { block_hash: B256, response_tx: ReceiptsResponseSender }, + BlockWithSendersResult { block_hash: B256, res: ProviderResult>>> }, + ReceiptsResult { block_hash: B256, res: ProviderResult>>> }, + HeaderResult { block_hash: B256, res: Box> }, + CacheNewCanonicalChain { chain_change: ChainChange }, + RemoveReorgedChain { chain_change: ChainChange }, } struct BlockReceipts { @@ -580,7 +555,7 @@ struct BlockReceipts { /// A change of the canonical chain struct ChainChange { - blocks: Vec>, + blocks: Vec>, receipts: Vec>, } @@ -593,7 +568,7 @@ impl ChainChange { .blocks_and_receipts() .map(|(block, receipts)| { let block_receipts = - BlockReceipts { block_hash: block.block.hash(), receipts: receipts.clone() }; + BlockReceipts { block_hash: block.hash(), receipts: receipts.clone() }; (block.clone(), block_receipts) }) .unzip(); diff --git a/crates/rpc/rpc-eth-types/src/fee_history.rs b/crates/rpc/rpc-eth-types/src/fee_history.rs index ae509dd2fd..d5c6b72f7a 100644 --- a/crates/rpc/rpc-eth-types/src/fee_history.rs +++ b/crates/rpc/rpc-eth-types/src/fee_history.rs @@ -18,7 +18,7 @@ use metrics::atomics::AtomicU64; use reth_chain_state::CanonStateNotification; use reth_chainspec::{ChainSpecProvider, EthChainSpec}; use reth_primitives::{NodePrimitives, SealedBlock}; -use reth_primitives_traits::BlockBody; +use reth_primitives_traits::{Block, BlockBody}; use reth_rpc_server_types::constants::gas_oracle::MAX_HEADER_HISTORY; use reth_storage_api::BlockReaderIdExt; use serde::{Deserialize, Serialize}; @@ -72,12 +72,11 @@ impl FeeHistoryCache { } /// Insert block data into the cache. - async fn insert_blocks<'a, I, H, B, R>(&self, blocks: I) + async fn insert_blocks<'a, I, B, R>(&self, blocks: I) where - H: BlockHeader + 'a, - B: BlockBody, + B: Block + 'a, R: TxReceipt, - I: IntoIterator, Arc>)>, + I: IntoIterator, Arc>)>, { let mut entries = self.inner.entries.write().await; @@ -236,9 +235,9 @@ pub async fn fee_history_cache_new_blocks_task( tokio::select! { res = &mut fetch_missing_block => { if let Ok(res) = res { - fee_history_cache.insert_blocks(res.as_ref() - .map(|(b, r)| (&b.block, r.clone())) - .into_iter()).await; + let res = res.as_ref() + .map(|(b, r)| (b.sealed_block(), r.clone())); + fee_history_cache.insert_blocks(res).await; } } event = events.next() => { @@ -251,10 +250,10 @@ pub async fn fee_history_cache_new_blocks_task( let (blocks, receipts): (Vec<_>, Vec<_>) = committed .blocks_and_receipts() .map(|(block, receipts)| { - (&block.block, Arc::new(receipts.iter().flatten().cloned().collect::>())) + (block.clone_sealed_block(), Arc::new(receipts.iter().flatten().cloned().collect::>())) }) .unzip(); - fee_history_cache.insert_blocks(blocks.into_iter().zip(receipts)).await; + fee_history_cache.insert_blocks(blocks.iter().zip(receipts)).await; // keep track of missing blocks missing_blocks = fee_history_cache.missing_consecutive_blocks().await; @@ -363,22 +362,23 @@ impl FeeHistoryEntry { /// Creates a new entry from a sealed block. /// /// Note: This does not calculate the rewards for the block. - pub fn new(block: &SealedBlock) -> Self { + pub fn new(block: &SealedBlock) -> Self { Self { - base_fee_per_gas: block.base_fee_per_gas().unwrap_or_default(), - gas_used_ratio: block.gas_used() as f64 / block.gas_limit() as f64, + base_fee_per_gas: block.header().base_fee_per_gas().unwrap_or_default(), + gas_used_ratio: block.header().gas_used() as f64 / block.header().gas_limit() as f64, base_fee_per_blob_gas: block + .header() .excess_blob_gas() .map(alloy_eips::eip4844::calc_blob_gasprice), blob_gas_used_ratio: block.body().blob_gas_used() as f64 / alloy_eips::eip4844::MAX_DATA_GAS_PER_BLOCK as f64, - excess_blob_gas: block.excess_blob_gas(), - blob_gas_used: block.blob_gas_used(), - gas_used: block.gas_used(), + excess_blob_gas: block.header().excess_blob_gas(), + blob_gas_used: block.header().blob_gas_used(), + gas_used: block.header().gas_used(), header_hash: block.hash(), - gas_limit: block.gas_limit(), + gas_limit: block.header().gas_limit(), rewards: Vec::new(), - timestamp: block.timestamp(), + timestamp: block.header().timestamp(), } } diff --git a/crates/rpc/rpc-eth-types/src/logs_utils.rs b/crates/rpc/rpc-eth-types/src/logs_utils.rs index dd523a19a0..147159b40d 100644 --- a/crates/rpc/rpc-eth-types/src/logs_utils.rs +++ b/crates/rpc/rpc-eth-types/src/logs_utils.rs @@ -8,7 +8,7 @@ use alloy_primitives::TxHash; use alloy_rpc_types_eth::{FilteredParams, Log}; use reth_chainspec::ChainInfo; use reth_errors::ProviderError; -use reth_primitives::SealedBlockWithSenders; +use reth_primitives::RecoveredBlock; use reth_primitives_traits::{BlockBody, SignedTransaction}; use reth_storage_api::{BlockReader, ProviderBlock}; use std::sync::Arc; @@ -55,8 +55,8 @@ where pub enum ProviderOrBlock<'a, P: BlockReader> { /// Provider Provider(&'a P), - /// [`SealedBlockWithSenders`] - Block(Arc>>), + /// [`RecoveredBlock`] + Block(Arc>>), } /// Appends all matching logs of a block's receipts. diff --git a/crates/rpc/rpc-eth-types/src/pending_block.rs b/crates/rpc/rpc-eth-types/src/pending_block.rs index ef2a61dd72..62d5954cd9 100644 --- a/crates/rpc/rpc-eth-types/src/pending_block.rs +++ b/crates/rpc/rpc-eth-types/src/pending_block.rs @@ -8,7 +8,7 @@ use alloy_consensus::BlockHeader; use alloy_eips::{BlockId, BlockNumberOrTag}; use alloy_primitives::B256; use derive_more::Constructor; -use reth_primitives::{Receipt, SealedBlockWithSenders}; +use reth_primitives::{Receipt, RecoveredBlock}; use reth_primitives_traits::Block; use revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg}; @@ -27,7 +27,7 @@ pub struct PendingBlockEnv { #[derive(Clone, Debug)] pub enum PendingBlockEnvOrigin { /// The pending block as received from the CL. - ActualPending(SealedBlockWithSenders, Vec), + ActualPending(RecoveredBlock, Vec), /// The _modified_ header of the latest block. /// /// This derives the pending state based on the latest header by modifying: @@ -44,7 +44,7 @@ impl PendingBlockEnvOrigin { } /// Consumes the type and returns the actual pending block. - pub fn into_actual_pending(self) -> Option> { + pub fn into_actual_pending(self) -> Option> { match self { Self::ActualPending(block, _) => Some(block), _ => None, @@ -81,7 +81,7 @@ pub struct PendingBlock { /// Timestamp when the pending block is considered outdated. pub expires_at: Instant, /// The locally built pending block. - pub block: SealedBlockWithSenders, + pub block: RecoveredBlock, /// The receipts for the pending block pub receipts: Vec, } diff --git a/crates/rpc/rpc-eth-types/src/simulate.rs b/crates/rpc/rpc-eth-types/src/simulate.rs index a5d4773981..0782d62ac2 100644 --- a/crates/rpc/rpc-eth-types/src/simulate.rs +++ b/crates/rpc/rpc-eth-types/src/simulate.rs @@ -7,7 +7,7 @@ use alloy_rpc_types_eth::{ Block, BlockTransactionsKind, Header, }; use jsonrpsee_types::ErrorObject; -use reth_primitives::BlockWithSenders; +use reth_primitives::RecoveredBlock; use reth_primitives_traits::{block::BlockTx, BlockBody as _, SignedTransaction}; use reth_rpc_server_types::result::rpc_err; use reth_rpc_types_compat::{block::from_block, TransactionCompat}; @@ -178,11 +178,11 @@ where calls.push(call); } - let block = BlockWithSenders::new_unchecked(block, senders); + let block = RecoveredBlock::new_unhashed(block, senders); let txs_kind = if full_transactions { BlockTransactionsKind::Full } else { BlockTransactionsKind::Hashes }; - let block = from_block(block, txs_kind, None, tx_resp_builder)?; + let block = from_block(block, txs_kind, tx_resp_builder)?; Ok(SimulatedBlock { inner: block, calls }) } diff --git a/crates/rpc/rpc-types-compat/src/block.rs b/crates/rpc/rpc-types-compat/src/block.rs index ed97c7f5b4..752bf15414 100644 --- a/crates/rpc/rpc-types-compat/src/block.rs +++ b/crates/rpc/rpc-types-compat/src/block.rs @@ -1,15 +1,14 @@ //! Compatibility functions for rpc `Block` type. -use alloy_consensus::{BlockHeader, Sealable, Sealed}; +use crate::transaction::TransactionCompat; +use alloy_consensus::{BlockHeader, Sealable}; use alloy_eips::eip4895::Withdrawals; -use alloy_primitives::{B256, U256}; +use alloy_primitives::U256; use alloy_rpc_types_eth::{ Block, BlockTransactions, BlockTransactionsKind, Header, TransactionInfo, }; -use reth_primitives::{transaction::SignedTransactionIntoRecoveredExt, BlockWithSenders}; -use reth_primitives_traits::{Block as BlockTrait, BlockBody, SignedTransaction}; - -use crate::transaction::TransactionCompat; +use reth_primitives::{transaction::SignedTransactionIntoRecoveredExt, RecoveredBlock}; +use reth_primitives_traits::{Block as BlockTrait, BlockBody, SealedHeader, SignedTransaction}; /// Converts the given primitive block into a [`Block`] response with the given /// [`BlockTransactionsKind`] @@ -17,9 +16,8 @@ use crate::transaction::TransactionCompat; /// If a `block_hash` is provided, then this is used, otherwise the block hash is computed. #[expect(clippy::type_complexity)] pub fn from_block( - block: BlockWithSenders, + block: RecoveredBlock, kind: BlockTransactionsKind, - block_hash: Option, tx_resp_builder: &T, ) -> Result>, T::Error> where @@ -27,10 +25,8 @@ where B: BlockTrait, { match kind { - BlockTransactionsKind::Hashes => { - Ok(from_block_with_tx_hashes::(block, block_hash)) - } - BlockTransactionsKind::Full => from_block_full::(block, block_hash, tx_resp_builder), + BlockTransactionsKind::Hashes => Ok(from_block_with_tx_hashes::(block)), + BlockTransactionsKind::Full => from_block_full::(block, tx_resp_builder), } } @@ -39,20 +35,17 @@ where /// /// This will populate the `transactions` field with only the hashes of the transactions in the /// block: [`BlockTransactions::Hashes`] -pub fn from_block_with_tx_hashes( - block: BlockWithSenders, - block_hash: Option, -) -> Block> +pub fn from_block_with_tx_hashes(block: RecoveredBlock) -> Block> where B: BlockTrait, { - let block_hash = block_hash.unwrap_or_else(|| block.header().hash_slow()); let transactions = block.body().transaction_hashes_iter().copied().collect(); - - from_block_with_transactions( - block.length(), - block_hash, - block.block, + let rlp_length = block.rlp_length(); + let (header, body) = block.into_sealed_block().split_sealed_header_body(); + from_block_with_transactions::( + rlp_length, + header, + body, BlockTransactions::Hashes(transactions), ) } @@ -64,23 +57,22 @@ where /// [`TransactionCompat::Transaction`] objects: [`BlockTransactions::Full`] #[expect(clippy::type_complexity)] pub fn from_block_full( - block: BlockWithSenders, - block_hash: Option, + block: RecoveredBlock, tx_resp_builder: &T, ) -> Result>, T::Error> where T: TransactionCompat<<::Body as BlockBody>::Transaction>, B: BlockTrait, { - let block_hash = block_hash.unwrap_or_else(|| block.block.header().hash_slow()); - let block_number = block.block.header().number(); - let base_fee_per_gas = block.block.header().base_fee_per_gas(); + let block_number = block.header().number(); + let base_fee_per_gas = block.header().base_fee_per_gas(); // NOTE: we can safely remove the body here because not needed to finalize the `Block` in // `from_block_with_transactions`, however we need to compute the length before - let block_length = block.block.length(); - let transactions = block.block.body().transactions().to_vec(); + let block_length = block.rlp_length(); + let transactions = block.body().transactions().to_vec(); let transactions_with_senders = transactions.into_iter().zip(block.senders_iter().copied()); + let block_hash = Some(block.hash()); let transactions = transactions_with_senders .enumerate() .map(|(idx, (tx, sender))| { @@ -88,7 +80,7 @@ where let signed_tx_ec_recovered = tx.with_signer(sender); let tx_info = TransactionInfo { hash: Some(tx_hash), - block_hash: Some(block_hash), + block_hash, block_number: Some(block_number), base_fee: base_fee_per_gas.map(u128::from), index: Some(idx as u64), @@ -98,10 +90,11 @@ where }) .collect::, T::Error>>()?; - Ok(from_block_with_transactions( + let (header, body) = block.into_sealed_block().split_sealed_header_body(); + Ok(from_block_with_transactions::<_, B>( block_length, - block_hash, - block.block, + header, + body, BlockTransactions::Full(transactions), )) } @@ -109,28 +102,19 @@ where #[inline] fn from_block_with_transactions( block_length: usize, - block_hash: B256, - block: B, + header: SealedHeader, + body: B::Body, transactions: BlockTransactions, ) -> Block> { - let withdrawals = block - .header() + let withdrawals = header .withdrawals_root() .is_some() - .then(|| block.body().withdrawals().cloned().map(Withdrawals::into_inner).map(Into::into)) + .then(|| body.withdrawals().cloned().map(Withdrawals::into_inner).map(Into::into)) .flatten(); - let uncles = block - .body() - .ommers() - .map(|o| o.iter().map(|h| h.hash_slow()).collect()) - .unwrap_or_default(); - let (header, _) = block.split(); - let header = Header::from_consensus( - Sealed::new_unchecked(header, block_hash), - None, - Some(U256::from(block_length)), - ); + let uncles = + body.ommers().map(|o| o.iter().map(|h| h.hash_slow()).collect()).unwrap_or_default(); + let header = Header::from_consensus(header.into(), None, Some(U256::from(block_length))); Block { header, uncles, transactions, withdrawals } } diff --git a/crates/rpc/rpc-types-compat/src/engine/payload.rs b/crates/rpc/rpc-types-compat/src/engine/payload.rs index 6645188f31..0584c30872 100644 --- a/crates/rpc/rpc-types-compat/src/engine/payload.rs +++ b/crates/rpc/rpc-types-compat/src/engine/payload.rs @@ -1,7 +1,6 @@ //! Standalone Conversion Functions for Handling Different Versions of Execution Payloads in //! Ethereum's Engine -use alloy_consensus::Header; use alloy_eips::{eip2718::Encodable2718, eip4895::Withdrawals, eip7685::RequestsOrHash}; use alloy_primitives::U256; use alloy_rpc_types_engine::{ @@ -9,12 +8,14 @@ use alloy_rpc_types_engine::{ CancunPayloadFields, ExecutionPayload, ExecutionPayloadSidecar, ExecutionPayloadV1, ExecutionPayloadV2, ExecutionPayloadV3, PraguePayloadFields, }; -use reth_primitives::{BlockBody, SealedBlock}; +use reth_primitives::{Block, SealedBlock}; use reth_primitives_traits::{BlockBody as _, SignedTransaction}; -/// Converts [`SealedBlock`] to [`ExecutionPayload`] +/// Converts [`SealedBlock`] to [`ExecutionPayload`]. +/// +/// TODO(mattsse): remove after next alloy bump pub fn block_to_payload( - value: SealedBlock>, + value: SealedBlock>, ) -> (ExecutionPayload, ExecutionPayloadSidecar) { let cancun = value.parent_beacon_block_root.map(|parent_beacon_block_root| CancunPayloadFields { @@ -47,8 +48,8 @@ pub fn block_to_payload( } /// Converts [`SealedBlock`] to [`ExecutionPayloadV1`] -pub fn block_to_payload_v1( - value: SealedBlock>, +pub fn block_to_payload_v1( + value: SealedBlock>, ) -> ExecutionPayloadV1 { let transactions = value.body().transactions.iter().map(|tx| tx.encoded_2718().into()).collect::>(); @@ -71,8 +72,8 @@ pub fn block_to_payload_v1( } /// Converts [`SealedBlock`] to [`ExecutionPayloadV2`] -pub fn block_to_payload_v2( - value: SealedBlock>, +pub fn block_to_payload_v2( + value: SealedBlock>, ) -> ExecutionPayloadV2 { ExecutionPayloadV2 { withdrawals: value.body().withdrawals.clone().unwrap_or_default().into_inner(), @@ -81,8 +82,8 @@ pub fn block_to_payload_v2( } /// Converts [`SealedBlock`] to [`ExecutionPayloadV3`], and returns the parent beacon block root. -pub fn block_to_payload_v3( - value: SealedBlock>, +pub fn block_to_payload_v3( + value: SealedBlock>, ) -> ExecutionPayloadV3 { ExecutionPayloadV3 { blob_gas_used: value.blob_gas_used.unwrap_or_default(), @@ -92,8 +93,8 @@ pub fn block_to_payload_v3( } /// Converts [`SealedBlock`] to [`ExecutionPayloadFieldV2`] -pub fn convert_block_to_payload_field_v2( - value: SealedBlock>, +pub fn convert_block_to_payload_field_v2( + value: SealedBlock>, ) -> ExecutionPayloadFieldV2 { // if there are withdrawals, return V2 if value.body().withdrawals.is_some() { @@ -122,7 +123,8 @@ mod tests { CancunPayloadFields, ExecutionPayload, ExecutionPayloadSidecar, ExecutionPayloadV1, ExecutionPayloadV2, ExecutionPayloadV3, }; - use reth_primitives::{Block, BlockExt, TransactionSigned}; + use reth_primitives::{Block, TransactionSigned}; + use reth_primitives_traits::Block as _; #[test] fn roundtrip_payload_to_block() { diff --git a/crates/rpc/rpc/src/debug.rs b/crates/rpc/rpc/src/debug.rs index b88bac816f..ea79f0580d 100644 --- a/crates/rpc/rpc/src/debug.rs +++ b/crates/rpc/rpc/src/debug.rs @@ -20,7 +20,7 @@ use reth_evm::{ execute::{BlockExecutorProvider, Executor}, ConfigureEvmEnv, }; -use reth_primitives::{BlockExt, NodePrimitives, ReceiptWithBloom, SealedBlockWithSenders}; +use reth_primitives::{NodePrimitives, ReceiptWithBloom, RecoveredBlock}; use reth_primitives_traits::{Block as _, BlockBody, SignedTransaction}; use reth_provider::{ BlockIdReader, BlockReaderIdExt, ChainSpecProvider, HeaderProvider, ProviderBlock, @@ -94,7 +94,7 @@ where /// Trace the entire block asynchronously async fn trace_block( &self, - block: Arc>>, + block: Arc>>, cfg: CfgEnvWithHandlerCfg, block_env: BlockEnv, opts: GethDebugTracingOptions, @@ -192,7 +192,7 @@ where }; self.trace_block( - Arc::new(block.with_senders_unchecked(senders).seal_slow()), + Arc::new(block.with_senders_unchecked(senders)), cfg_env_with_handler_cfg, block_env, opts, @@ -639,7 +639,7 @@ where let mut witness_record = ExecutionWitnessRecord::default(); let _ = block_executor - .execute_with_state_closure(&(*block).clone().unseal(), |statedb: &State<_>| { + .execute_with_state_closure(&(*block).clone(), |statedb: &State<_>| { witness_record.record_executed_state(statedb); }) .map_err(|err| EthApiError::Internal(err.into()))?; diff --git a/crates/rpc/rpc/src/eth/filter.rs b/crates/rpc/rpc/src/eth/filter.rs index 337fbb91e0..e7337f6e7b 100644 --- a/crates/rpc/rpc/src/eth/filter.rs +++ b/crates/rpc/rpc/src/eth/filter.rs @@ -9,7 +9,7 @@ use alloy_rpc_types_eth::{ use async_trait::async_trait; use jsonrpsee::{core::RpcResult, server::IdProvider}; use reth_chainspec::ChainInfo; -use reth_primitives::SealedBlockWithSenders; +use reth_primitives::RecoveredBlock; use reth_provider::{ BlockHashReader, BlockIdReader, BlockNumReader, BlockReader, HeaderProvider, ProviderBlock, ProviderError, ProviderReceipt, @@ -546,7 +546,7 @@ where ) -> Result< Option<( Arc>>, - Option>>>, + Option>>>, )>, EthFilterError, > { diff --git a/crates/rpc/rpc/src/validation.rs b/crates/rpc/rpc/src/validation.rs index d2faf0dd52..c621c8b979 100644 --- a/crates/rpc/rpc/src/validation.rs +++ b/crates/rpc/rpc/src/validation.rs @@ -17,8 +17,8 @@ use reth_consensus::{Consensus, FullConsensus, PostExecutionInput}; use reth_engine_primitives::PayloadValidator; use reth_errors::{BlockExecutionError, ConsensusError, ProviderError}; use reth_evm::execute::{BlockExecutorProvider, Executor}; -use reth_primitives::{GotExpected, NodePrimitives, SealedBlockWithSenders, SealedHeader}; -use reth_primitives_traits::{constants::GAS_LIMIT_BOUND_DIVISOR, Block as _, BlockBody}; +use reth_primitives::{GotExpected, NodePrimitives, RecoveredBlock, SealedHeader}; +use reth_primitives_traits::{constants::GAS_LIMIT_BOUND_DIVISOR, BlockBody, SealedBlock}; use reth_provider::{BlockExecutionOutput, BlockReaderIdExt, StateProviderFactory}; use reth_revm::{cached::CachedReads, database::StateProviderDatabase}; use reth_rpc_api::BlockSubmissionValidationApiServer; @@ -98,7 +98,7 @@ where /// Validates the given block and a [`BidTrace`] against it. pub async fn validate_message_against_block( &self, - block: SealedBlockWithSenders<::Block>, + block: RecoveredBlock<::Block>, message: BidTrace, registered_gas_limit: u64, ) -> Result<(), ValidationApiError> { @@ -106,7 +106,7 @@ where self.consensus.validate_header_with_total_difficulty(block.sealed_header(), U256::MAX)?; self.consensus.validate_header(block.sealed_header())?; - self.consensus.validate_block_pre_execution(&block)?; + self.consensus.validate_block_pre_execution(block.sealed_block())?; if !self.disallow.is_empty() { if self.disallow.contains(&block.beneficiary()) { @@ -115,7 +115,7 @@ where if self.disallow.contains(&message.proposer_fee_recipient) { return Err(ValidationApiError::Blacklist(message.proposer_fee_recipient)) } - for (sender, tx) in block.senders_iter().zip(block.transactions()) { + for (sender, tx) in block.senders_iter().zip(block.body().transactions()) { if self.disallow.contains(sender) { return Err(ValidationApiError::Blacklist(*sender)) } @@ -147,7 +147,6 @@ where let cached_db = request_cache.as_db_mut(StateProviderDatabase::new(&state_provider)); let executor = self.executor_provider.executor(cached_db); - let block = block.unseal(); let mut accessed_blacklisted = None; let output = executor.execute_with_state_closure(&block, |state| { if !self.disallow.is_empty() { @@ -251,7 +250,7 @@ where /// to checking the latest block transaction. fn ensure_payment( &self, - block: &::Block, + block: &SealedBlock<::Block>, output: &BlockExecutionOutput<::Receipt>, message: &BidTrace, ) -> Result<(), ValidationApiError> { @@ -349,7 +348,7 @@ where versioned_hashes: self.validate_blobs_bundle(request.request.blobs_bundle)?, }), )? - .try_seal_with_senders() + .try_recover() .map_err(|_| ValidationApiError::InvalidTransactionSignature)?; self.validate_message_against_block( @@ -382,7 +381,7 @@ where }, ), )? - .try_seal_with_senders() + .try_recover() .map_err(|_| ValidationApiError::InvalidTransactionSignature)?; self.validate_message_against_block( diff --git a/crates/stages/stages/benches/setup/mod.rs b/crates/stages/stages/benches/setup/mod.rs index d6bf441445..c98dc05cca 100644 --- a/crates/stages/stages/benches/setup/mod.rs +++ b/crates/stages/stages/benches/setup/mod.rs @@ -153,8 +153,10 @@ pub(crate) fn txs_testdata(num_blocks: u64) -> TestStageDB { let cloned_second = second_block.clone(); let mut updated_header = cloned_second.header().clone(); updated_header.state_root = root; - *second_block = - SealedBlock::new(SealedHeader::seal(updated_header), cloned_second.into_body()); + *second_block = SealedBlock::from_sealed_parts( + SealedHeader::seal_slow(updated_header), + cloned_second.into_body(), + ); let offset = transitions.len() as u64; @@ -187,7 +189,10 @@ pub(crate) fn txs_testdata(num_blocks: u64) -> TestStageDB { let cloned_last = last_block.clone(); let mut updated_header = cloned_last.header().clone(); updated_header.state_root = root; - *last_block = SealedBlock::new(SealedHeader::seal(updated_header), cloned_last.into_body()); + *last_block = SealedBlock::from_sealed_parts( + SealedHeader::seal_slow(updated_header), + cloned_last.into_body(), + ); db.insert_blocks(blocks.iter(), StorageKind::Static).unwrap(); diff --git a/crates/stages/stages/src/lib.rs b/crates/stages/stages/src/lib.rs index 20c780e24c..76b88e3918 100644 --- a/crates/stages/stages/src/lib.rs +++ b/crates/stages/stages/src/lib.rs @@ -34,7 +34,7 @@ //! # use reth_consensus::test_utils::TestConsensus; //! # //! # let chain_spec = MAINNET.clone(); -//! # let consensus: Arc> = Arc::new(TestConsensus::default()); +//! # let consensus: Arc> = Arc::new(TestConsensus::default()); //! # let headers_downloader = ReverseHeadersDownloaderBuilder::default().build( //! # Arc::new(TestHeadersClient::default()), //! # consensus.clone().as_header_validator() diff --git a/crates/stages/stages/src/sets.rs b/crates/stages/stages/src/sets.rs index 7b8205e25e..37c84be83a 100644 --- a/crates/stages/stages/src/sets.rs +++ b/crates/stages/stages/src/sets.rs @@ -47,6 +47,7 @@ use reth_config::config::StageConfig; use reth_consensus::{Consensus, ConsensusError}; use reth_evm::execute::BlockExecutorProvider; use reth_network_p2p::{bodies::downloader::BodyDownloader, headers::downloader::HeaderDownloader}; +use reth_primitives_traits::Block; use reth_provider::HeaderSyncGapProvider; use reth_prune_types::PruneModes; use reth_stages_api::Stage; @@ -102,7 +103,7 @@ where pub fn new( provider: Provider, tip: watch::Receiver, - consensus: Arc>, + consensus: Arc>, header_downloader: H, body_downloader: B, executor_factory: E, @@ -185,7 +186,7 @@ where /// The tip for the headers stage. tip: watch::Receiver, /// The consensus engine used to validate incoming data. - consensus: Arc>, + consensus: Arc>, /// The block header downloader header_downloader: H, /// The block body downloader @@ -203,7 +204,7 @@ where pub fn new( provider: Provider, tip: watch::Receiver, - consensus: Arc>, + consensus: Arc>, header_downloader: H, body_downloader: B, stages_config: StageConfig, @@ -215,7 +216,7 @@ where impl OnlineStages where P: HeaderSyncGapProvider + 'static, - H: HeaderDownloader + 'static, + H: HeaderDownloader
::Header> + 'static, B: BodyDownloader + 'static, { /// Create a new builder using the given headers stage. @@ -236,7 +237,7 @@ where provider: P, tip: watch::Receiver, header_downloader: H, - consensus: Arc>, + consensus: Arc>, stages_config: StageConfig, ) -> StageSetBuilder where @@ -258,7 +259,7 @@ where impl StageSet for OnlineStages where P: HeaderSyncGapProvider + 'static, - H: HeaderDownloader + 'static, + H: HeaderDownloader
::Header> + 'static, B: BodyDownloader + 'static, HeaderStage: Stage, BodyStage: Stage, diff --git a/crates/stages/stages/src/stages/bodies.rs b/crates/stages/stages/src/stages/bodies.rs index 5194118395..7c796ec6ad 100644 --- a/crates/stages/stages/src/stages/bodies.rs +++ b/crates/stages/stages/src/stages/bodies.rs @@ -1,11 +1,9 @@ use super::missing_static_data_error; use futures_util::TryStreamExt; -use reth_codecs::Compact; use reth_db::{tables, transaction::DbTx}; use reth_db_api::{cursor::DbCursorRO, transaction::DbTxMut}; use reth_network_p2p::bodies::{downloader::BodyDownloader, response::BlockResponse}; use reth_primitives::StaticFileSegment; -use reth_primitives_traits::{Block, BlockBody, BlockHeader}; use reth_provider::{ providers::StaticFileWriter, BlockReader, BlockWriter, DBProvider, ProviderError, StaticFileProviderFactory, StatsReader, StorageLocation, @@ -56,7 +54,7 @@ pub struct BodyStage { /// The body downloader. downloader: D, /// Block response buffer. - buffer: Option>>, + buffer: Option>>, } impl BodyStage { @@ -150,8 +148,8 @@ where + StaticFileProviderFactory + StatsReader + BlockReader - + BlockWriter>, - D: BodyDownloader>, + + BlockWriter, + D: BodyDownloader, { /// Return the id of the stage fn id(&self) -> StageId { @@ -762,8 +760,7 @@ mod tests { } impl BodyDownloader for TestBodyDownloader { - type Header = Header; - type Body = BlockBody; + type Block = reth_primitives::Block; fn set_download_range( &mut self, @@ -785,7 +782,7 @@ mod tests { } impl Stream for TestBodyDownloader { - type Item = BodyDownloaderResult; + type Item = BodyDownloaderResult; fn poll_next(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll> { let this = self.get_mut(); @@ -801,7 +798,9 @@ mod tests { } else { let body = this.responses.remove(&header.hash()).expect("requested unknown body"); - response.push(BlockResponse::Full(SealedBlock::new(header, body))); + response.push(BlockResponse::Full(SealedBlock::from_sealed_parts( + header, body, + ))); } if response.len() as u64 >= this.batch_size { diff --git a/crates/stages/stages/src/stages/execution.rs b/crates/stages/stages/src/stages/execution.rs index 77b8a78df1..5557beda51 100644 --- a/crates/stages/stages/src/stages/execution.rs +++ b/crates/stages/stages/src/stages/execution.rs @@ -422,11 +422,6 @@ where // Note: Since we only write to `blocks` if there are any ExExes, we don't need to perform // the `has_exexs` check here as well if !blocks.is_empty() { - let blocks = blocks.into_iter().map(|block| { - let hash = block.header().hash_slow(); - block.seal_unchecked(hash) - }); - let previous_input = self.post_execute_commit_input.replace(Chain::new(blocks, state.clone(), None)); @@ -713,18 +708,18 @@ mod tests { let provider = factory.provider_rw().unwrap(); let mut genesis_rlp = hex!("f901faf901f5a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa045571b40ae66ca7480791bbb2887286e4e4c4b1b298b191c889d6959023a32eda056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000808502540be400808000a00000000000000000000000000000000000000000000000000000000000000000880000000000000000c0c0").as_slice(); - let genesis = SealedBlock::decode(&mut genesis_rlp).unwrap(); + let genesis = SealedBlock::::decode(&mut genesis_rlp).unwrap(); let mut block_rlp = hex!("f90262f901f9a075c371ba45999d87f4542326910a11af515897aebce5265d3f6acd1f1161f82fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa098f2dcd87c8ae4083e7017a05456c14eea4b1db2032126e27b3b1563d57d7cc0a08151d548273f6683169524b66ca9fe338b9ce42bc3540046c828fd939ae23bcba03f4e5c2ec5b2170b711d97ee755c160457bb58d8daa338e835ec02ae6860bbabb901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000018502540be40082a8798203e800a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f863f861800a8405f5e10094100000000000000000000000000000000000000080801ba07e09e26678ed4fac08a249ebe8ed680bf9051a5e14ad223e4b2b9d26e0208f37a05f6e3f188e3e6eab7d7d3b6568f5eac7d687b08d307d3154ccd8c87b4630509bc0").as_slice(); - let block = SealedBlock::decode(&mut block_rlp).unwrap(); + let block = SealedBlock::::decode(&mut block_rlp).unwrap(); provider .insert_historical_block( genesis - .try_seal_with_senders() + .try_recover() .map_err(|_| BlockValidationError::SenderRecoveryError) .unwrap(), ) .unwrap(); - provider.insert_historical_block(block.clone().try_seal_with_senders().unwrap()).unwrap(); + provider.insert_historical_block(block.clone().try_recover().unwrap()).unwrap(); provider .static_file_provider() .latest_writer(StaticFileSegment::Headers) @@ -761,11 +756,11 @@ mod tests { let provider = factory.provider_rw().unwrap(); let mut genesis_rlp = hex!("f901faf901f5a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa045571b40ae66ca7480791bbb2887286e4e4c4b1b298b191c889d6959023a32eda056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000808502540be400808000a00000000000000000000000000000000000000000000000000000000000000000880000000000000000c0c0").as_slice(); - let genesis = SealedBlock::decode(&mut genesis_rlp).unwrap(); + let genesis = SealedBlock::::decode(&mut genesis_rlp).unwrap(); let mut block_rlp = hex!("f90262f901f9a075c371ba45999d87f4542326910a11af515897aebce5265d3f6acd1f1161f82fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa098f2dcd87c8ae4083e7017a05456c14eea4b1db2032126e27b3b1563d57d7cc0a08151d548273f6683169524b66ca9fe338b9ce42bc3540046c828fd939ae23bcba03f4e5c2ec5b2170b711d97ee755c160457bb58d8daa338e835ec02ae6860bbabb901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000018502540be40082a8798203e800a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f863f861800a8405f5e10094100000000000000000000000000000000000000080801ba07e09e26678ed4fac08a249ebe8ed680bf9051a5e14ad223e4b2b9d26e0208f37a05f6e3f188e3e6eab7d7d3b6568f5eac7d687b08d307d3154ccd8c87b4630509bc0").as_slice(); - let block = SealedBlock::decode(&mut block_rlp).unwrap(); - provider.insert_historical_block(genesis.try_seal_with_senders().unwrap()).unwrap(); - provider.insert_historical_block(block.clone().try_seal_with_senders().unwrap()).unwrap(); + let block = SealedBlock::::decode(&mut block_rlp).unwrap(); + provider.insert_historical_block(genesis.try_recover().unwrap()).unwrap(); + provider.insert_historical_block(block.clone().try_recover().unwrap()).unwrap(); provider .static_file_provider() .latest_writer(StaticFileSegment::Headers) @@ -793,7 +788,7 @@ mod tests { total } }) if processed == previous_stage_checkpoint.progress.processed && - total == previous_stage_checkpoint.progress.total + block.gas_used); + total == previous_stage_checkpoint.progress.total + block.gas_used()); } #[test] @@ -802,11 +797,11 @@ mod tests { let provider = factory.provider_rw().unwrap(); let mut genesis_rlp = hex!("f901faf901f5a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa045571b40ae66ca7480791bbb2887286e4e4c4b1b298b191c889d6959023a32eda056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000808502540be400808000a00000000000000000000000000000000000000000000000000000000000000000880000000000000000c0c0").as_slice(); - let genesis = SealedBlock::decode(&mut genesis_rlp).unwrap(); + let genesis = SealedBlock::::decode(&mut genesis_rlp).unwrap(); let mut block_rlp = hex!("f90262f901f9a075c371ba45999d87f4542326910a11af515897aebce5265d3f6acd1f1161f82fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa098f2dcd87c8ae4083e7017a05456c14eea4b1db2032126e27b3b1563d57d7cc0a08151d548273f6683169524b66ca9fe338b9ce42bc3540046c828fd939ae23bcba03f4e5c2ec5b2170b711d97ee755c160457bb58d8daa338e835ec02ae6860bbabb901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000018502540be40082a8798203e800a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f863f861800a8405f5e10094100000000000000000000000000000000000000080801ba07e09e26678ed4fac08a249ebe8ed680bf9051a5e14ad223e4b2b9d26e0208f37a05f6e3f188e3e6eab7d7d3b6568f5eac7d687b08d307d3154ccd8c87b4630509bc0").as_slice(); - let block = SealedBlock::decode(&mut block_rlp).unwrap(); - provider.insert_historical_block(genesis.try_seal_with_senders().unwrap()).unwrap(); - provider.insert_historical_block(block.clone().try_seal_with_senders().unwrap()).unwrap(); + let block = SealedBlock::::decode(&mut block_rlp).unwrap(); + provider.insert_historical_block(genesis.try_recover().unwrap()).unwrap(); + provider.insert_historical_block(block.clone().try_recover().unwrap()).unwrap(); provider .static_file_provider() .latest_writer(StaticFileSegment::Headers) @@ -835,11 +830,11 @@ mod tests { let provider = factory.provider_rw().unwrap(); let input = ExecInput { target: Some(1), checkpoint: None }; let mut genesis_rlp = hex!("f901faf901f5a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa045571b40ae66ca7480791bbb2887286e4e4c4b1b298b191c889d6959023a32eda056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000808502540be400808000a00000000000000000000000000000000000000000000000000000000000000000880000000000000000c0c0").as_slice(); - let genesis = SealedBlock::decode(&mut genesis_rlp).unwrap(); + let genesis = SealedBlock::::decode(&mut genesis_rlp).unwrap(); let mut block_rlp = hex!("f90262f901f9a075c371ba45999d87f4542326910a11af515897aebce5265d3f6acd1f1161f82fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa098f2dcd87c8ae4083e7017a05456c14eea4b1db2032126e27b3b1563d57d7cc0a08151d548273f6683169524b66ca9fe338b9ce42bc3540046c828fd939ae23bcba03f4e5c2ec5b2170b711d97ee755c160457bb58d8daa338e835ec02ae6860bbabb901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000018502540be40082a8798203e800a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f863f861800a8405f5e10094100000000000000000000000000000000000000080801ba07e09e26678ed4fac08a249ebe8ed680bf9051a5e14ad223e4b2b9d26e0208f37a05f6e3f188e3e6eab7d7d3b6568f5eac7d687b08d307d3154ccd8c87b4630509bc0").as_slice(); - let block = SealedBlock::decode(&mut block_rlp).unwrap(); - provider.insert_historical_block(genesis.try_seal_with_senders().unwrap()).unwrap(); - provider.insert_historical_block(block.clone().try_seal_with_senders().unwrap()).unwrap(); + let block = SealedBlock::::decode(&mut block_rlp).unwrap(); + provider.insert_historical_block(genesis.try_recover().unwrap()).unwrap(); + provider.insert_historical_block(block.clone().try_recover().unwrap()).unwrap(); provider .static_file_provider() .latest_writer(StaticFileSegment::Headers) @@ -977,11 +972,11 @@ mod tests { let provider = factory.provider_rw().unwrap(); let input = ExecInput { target: Some(1), checkpoint: None }; let mut genesis_rlp = hex!("f901faf901f5a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa045571b40ae66ca7480791bbb2887286e4e4c4b1b298b191c889d6959023a32eda056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000808502540be400808000a00000000000000000000000000000000000000000000000000000000000000000880000000000000000c0c0").as_slice(); - let genesis = SealedBlock::decode(&mut genesis_rlp).unwrap(); + let genesis = SealedBlock::::decode(&mut genesis_rlp).unwrap(); let mut block_rlp = hex!("f90262f901f9a075c371ba45999d87f4542326910a11af515897aebce5265d3f6acd1f1161f82fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa098f2dcd87c8ae4083e7017a05456c14eea4b1db2032126e27b3b1563d57d7cc0a08151d548273f6683169524b66ca9fe338b9ce42bc3540046c828fd939ae23bcba03f4e5c2ec5b2170b711d97ee755c160457bb58d8daa338e835ec02ae6860bbabb901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000018502540be40082a8798203e800a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f863f861800a8405f5e10094100000000000000000000000000000000000000080801ba07e09e26678ed4fac08a249ebe8ed680bf9051a5e14ad223e4b2b9d26e0208f37a05f6e3f188e3e6eab7d7d3b6568f5eac7d687b08d307d3154ccd8c87b4630509bc0").as_slice(); - let block = SealedBlock::decode(&mut block_rlp).unwrap(); - provider.insert_historical_block(genesis.try_seal_with_senders().unwrap()).unwrap(); - provider.insert_historical_block(block.clone().try_seal_with_senders().unwrap()).unwrap(); + let block = SealedBlock::::decode(&mut block_rlp).unwrap(); + provider.insert_historical_block(genesis.try_recover().unwrap()).unwrap(); + provider.insert_historical_block(block.clone().try_recover().unwrap()).unwrap(); provider .static_file_provider() .latest_writer(StaticFileSegment::Headers) @@ -1085,11 +1080,11 @@ mod tests { let provider = test_db.factory.database_provider_rw().unwrap(); let input = ExecInput { target: Some(1), checkpoint: None }; let mut genesis_rlp = hex!("f901f8f901f3a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa0c9ceb8372c88cb461724d8d3d87e8b933f6fc5f679d4841800e662f4428ffd0da056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080830f4240808000a00000000000000000000000000000000000000000000000000000000000000000880000000000000000c0c0").as_slice(); - let genesis = SealedBlock::decode(&mut genesis_rlp).unwrap(); + let genesis = SealedBlock::::decode(&mut genesis_rlp).unwrap(); let mut block_rlp = hex!("f9025ff901f7a0c86e8cc0310ae7c531c758678ddbfd16fc51c8cef8cec650b032de9869e8b94fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa050554882fbbda2c2fd93fdc466db9946ea262a67f7a76cc169e714f105ab583da00967f09ef1dfed20c0eacfaa94d5cd4002eda3242ac47eae68972d07b106d192a0e3c8b47fbfc94667ef4cceb17e5cc21e3b1eebd442cebb27f07562b33836290db90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001830f42408238108203e800a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f862f860800a83061a8094095e7baea6a6c7c4c2dfeb977efac326af552d8780801ba072ed817487b84ba367d15d2f039b5fc5f087d0a8882fbdf73e8cb49357e1ce30a0403d800545b8fc544f92ce8124e2255f8c3c6af93f28243a120585d4c4c6a2a3c0").as_slice(); - let block = SealedBlock::decode(&mut block_rlp).unwrap(); - provider.insert_historical_block(genesis.try_seal_with_senders().unwrap()).unwrap(); - provider.insert_historical_block(block.clone().try_seal_with_senders().unwrap()).unwrap(); + let block = SealedBlock::::decode(&mut block_rlp).unwrap(); + provider.insert_historical_block(genesis.try_recover().unwrap()).unwrap(); + provider.insert_historical_block(block.clone().try_recover().unwrap()).unwrap(); provider .static_file_provider() .latest_writer(StaticFileSegment::Headers) diff --git a/crates/stages/stages/src/stages/hashing_account.rs b/crates/stages/stages/src/stages/hashing_account.rs index 976c775d1a..d256883e16 100644 --- a/crates/stages/stages/src/stages/hashing_account.rs +++ b/crates/stages/stages/src/stages/hashing_account.rs @@ -64,7 +64,7 @@ impl AccountHashingStage { ) -> Result, StageError> where N::Primitives: reth_primitives_traits::FullNodePrimitives< - BlockBody = reth_primitives::BlockBody, + Block = reth_primitives::Block, BlockHeader = reth_primitives::Header, >, { @@ -85,7 +85,7 @@ impl AccountHashingStage { ); for block in blocks { - provider.insert_historical_block(block.try_seal_with_senders().unwrap()).unwrap(); + provider.insert_historical_block(block.try_recover().unwrap()).unwrap(); } provider .static_file_provider() diff --git a/crates/stages/stages/src/stages/headers.rs b/crates/stages/stages/src/stages/headers.rs index f411060bcc..cbec9c9ae4 100644 --- a/crates/stages/stages/src/stages/headers.rs +++ b/crates/stages/stages/src/stages/headers.rs @@ -407,7 +407,7 @@ mod tests { use alloy_primitives::B256; use assert_matches::assert_matches; use reth_execution_types::ExecutionOutcome; - use reth_primitives::{BlockBody, SealedBlock, SealedBlockWithSenders}; + use reth_primitives::{BlockBody, RecoveredBlock, SealedBlock}; use reth_provider::{BlockWriter, ProviderFactory, StaticFileProviderFactory}; use reth_stages_api::StageUnitCheckpoint; use reth_testing_utils::generators::{self, random_header, random_header_range}; @@ -521,7 +521,7 @@ mod tests { // validate the header let header = provider.header_by_number(block_num)?; assert!(header.is_some()); - let header = SealedHeader::seal(header.unwrap()); + let header = SealedHeader::seal_slow(header.unwrap()); assert_eq!(header.hash(), hash); // validate the header total difficulty @@ -535,7 +535,7 @@ mod tests { } async fn after_execution(&self, headers: Self::Seed) -> Result<(), TestRunnerError> { - self.client.extend(headers.iter().map(|h| h.clone().unseal())).await; + self.client.extend(headers.iter().map(|h| h.clone_header())).await; let tip = if headers.is_empty() { let tip = random_header(&mut generators::rng(), 0, None); self.db.insert_headers(std::iter::once(&tip))?; @@ -610,7 +610,7 @@ mod tests { let headers = runner.seed_execution(input).expect("failed to seed execution"); let rx = runner.execute(input); - runner.client.extend(headers.iter().rev().map(|h| h.clone().unseal())).await; + runner.client.extend(headers.iter().rev().map(|h| h.clone_header())).await; // skip `after_execution` hook for linear downloader let tip = headers.last().unwrap(); @@ -647,11 +647,10 @@ mod tests { let sealed_blocks = sealed_headers .iter() .map(|header| { - SealedBlockWithSenders::new( - SealedBlock::new(header.clone(), BlockBody::default()), + RecoveredBlock::new_sealed( + SealedBlock::from_sealed_parts(header.clone(), BlockBody::default()), vec![], ) - .unwrap() }) .collect(); @@ -693,7 +692,7 @@ mod tests { let headers = runner.seed_execution(input).expect("failed to seed execution"); let rx = runner.execute(input); - runner.client.extend(headers.iter().rev().map(|h| h.clone().unseal())).await; + runner.client.extend(headers.iter().rev().map(|h| h.clone_header())).await; // skip `after_execution` hook for linear downloader let tip = headers.last().unwrap(); diff --git a/crates/stages/stages/src/stages/merkle.rs b/crates/stages/stages/src/stages/merkle.rs index a2b4655835..3d36964a71 100644 --- a/crates/stages/stages/src/stages/merkle.rs +++ b/crates/stages/stages/src/stages/merkle.rs @@ -1,5 +1,5 @@ use alloy_consensus::BlockHeader; -use alloy_primitives::{BlockNumber, B256}; +use alloy_primitives::{BlockNumber, Sealable, B256}; use reth_codecs::Compact; use reth_consensus::ConsensusError; use reth_db::tables; @@ -277,7 +277,7 @@ where // Reset the checkpoint self.save_execution_checkpoint(provider, None)?; - validate_state_root(trie_root, SealedHeader::seal(target_block), to_block)?; + validate_state_root(trie_root, SealedHeader::seal_slow(target_block), to_block)?; Ok(ExecOutput { checkpoint: StageCheckpoint::new(to_block) @@ -330,7 +330,7 @@ where .header_by_number(input.unwind_to)? .ok_or_else(|| ProviderError::HeaderNotFound(input.unwind_to.into()))?; - validate_state_root(block_root, SealedHeader::seal(target), input.unwind_to)?; + validate_state_root(block_root, SealedHeader::seal_slow(target), input.unwind_to)?; // Validation passed, apply unwind changes to the database. provider.write_trie_updates(&updates)?; @@ -344,7 +344,7 @@ where /// Check that the computed state root matches the root in the expected header. #[inline] -fn validate_state_root( +fn validate_state_root( got: B256, expected: SealedHeader, target_block: BlockNumber, @@ -525,7 +525,7 @@ mod tests { stage_progress, BlockParams { parent: preblocks.last().map(|b| b.hash()), ..Default::default() }, ) - .split(); + .split_sealed_header_body(); let mut header = header.unseal(); header.state_root = state_root( @@ -534,7 +534,10 @@ mod tests { .into_iter() .map(|(address, account)| (address, (account, std::iter::empty()))), ); - let sealed_head = SealedBlock::new(SealedHeader::seal(header), body); + let sealed_head = SealedBlock::::from_sealed_parts( + SealedHeader::seal_slow(header), + body, + ); let head_hash = sealed_head.hash(); let mut blocks = vec![sealed_head]; @@ -584,8 +587,8 @@ mod tests { let static_file_provider = self.db.factory.static_file_provider(); let mut writer = static_file_provider.latest_writer(StaticFileSegment::Headers).unwrap(); - let mut last_header = last_block.header().clone(); - last_header.state_root = root; + let mut last_header = last_block.clone_sealed_header(); + last_header.set_state_root(root); let hash = last_header.hash_slow(); writer.prune_headers(1).unwrap(); diff --git a/crates/stages/stages/src/stages/mod.rs b/crates/stages/stages/src/stages/mod.rs index 33a4d76a11..cdc84e7727 100644 --- a/crates/stages/stages/src/stages/mod.rs +++ b/crates/stages/stages/src/stages/mod.rs @@ -82,13 +82,11 @@ mod tests { let tip = 66; let input = ExecInput { target: Some(tip), checkpoint: None }; let mut genesis_rlp = hex!("f901faf901f5a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa045571b40ae66ca7480791bbb2887286e4e4c4b1b298b191c889d6959023a32eda056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000808502540be400808000a00000000000000000000000000000000000000000000000000000000000000000880000000000000000c0c0").as_slice(); - let genesis = SealedBlock::decode(&mut genesis_rlp).unwrap(); + let genesis = SealedBlock::::decode(&mut genesis_rlp).unwrap(); let mut block_rlp = hex!("f90262f901f9a075c371ba45999d87f4542326910a11af515897aebce5265d3f6acd1f1161f82fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa098f2dcd87c8ae4083e7017a05456c14eea4b1db2032126e27b3b1563d57d7cc0a08151d548273f6683169524b66ca9fe338b9ce42bc3540046c828fd939ae23bcba03f4e5c2ec5b2170b711d97ee755c160457bb58d8daa338e835ec02ae6860bbabb901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000018502540be40082a8798203e800a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f863f861800a8405f5e10094100000000000000000000000000000000000000080801ba07e09e26678ed4fac08a249ebe8ed680bf9051a5e14ad223e4b2b9d26e0208f37a05f6e3f188e3e6eab7d7d3b6568f5eac7d687b08d307d3154ccd8c87b4630509bc0").as_slice(); - let block = SealedBlock::decode(&mut block_rlp).unwrap(); - provider_rw.insert_historical_block(genesis.try_seal_with_senders().unwrap()).unwrap(); - provider_rw - .insert_historical_block(block.clone().try_seal_with_senders().unwrap()) - .unwrap(); + let block = SealedBlock::::decode(&mut block_rlp).unwrap(); + provider_rw.insert_historical_block(genesis.try_recover().unwrap()).unwrap(); + provider_rw.insert_historical_block(block.clone().try_recover().unwrap()).unwrap(); // Fill with bogus blocks to respect PruneMode distance. let mut head = block.hash(); @@ -100,7 +98,7 @@ mod tests { generators::BlockParams { parent: Some(head), ..Default::default() }, ); head = nblock.hash(); - provider_rw.insert_historical_block(nblock.try_seal_with_senders().unwrap()).unwrap(); + provider_rw.insert_historical_block(nblock.try_recover().unwrap()).unwrap(); } provider_rw .static_file_provider() diff --git a/crates/stages/stages/src/test_utils/test_db.rs b/crates/stages/stages/src/test_utils/test_db.rs index 59ba08df8a..9f13986d29 100644 --- a/crates/stages/stages/src/test_utils/test_db.rs +++ b/crates/stages/stages/src/test_utils/test_db.rs @@ -153,7 +153,7 @@ impl TestStageDB { let segment_header = writer.user_header(); if segment_header.block_end().is_none() && segment_header.expected_block_start() == 0 { for block_number in 0..header.number { - let mut prev = header.clone().unseal(); + let mut prev = header.clone_header(); prev.number = block_number; writer.append_header(&prev, U256::ZERO, &B256::ZERO)?; } diff --git a/crates/storage/db/Cargo.toml b/crates/storage/db/Cargo.toml index ab1608edde..b3d4610f2f 100644 --- a/crates/storage/db/Cargo.toml +++ b/crates/storage/db/Cargo.toml @@ -90,6 +90,7 @@ mdbx = [ ] test-utils = [ "dep:tempfile", + "mdbx", "arbitrary", "parking_lot", "reth-primitives/test-utils", diff --git a/crates/storage/provider/src/providers/blockchain_provider.rs b/crates/storage/provider/src/providers/blockchain_provider.rs index 4a338d206c..707ce2212a 100644 --- a/crates/storage/provider/src/providers/blockchain_provider.rs +++ b/crates/storage/provider/src/providers/blockchain_provider.rs @@ -27,8 +27,8 @@ use reth_evm::{env::EvmEnv, ConfigureEvmEnv}; use reth_execution_types::ExecutionOutcome; use reth_node_types::{BlockTy, HeaderTy, NodeTypesWithDB, ReceiptTy, TxTy}; use reth_primitives::{ - Account, Block, BlockWithSenders, EthPrimitives, NodePrimitives, Receipt, SealedBlock, - SealedBlockFor, SealedBlockWithSenders, SealedHeader, StorageEntry, TransactionSigned, + Account, Block, EthPrimitives, NodePrimitives, Receipt, RecoveredBlock, SealedBlock, + SealedHeader, StorageEntry, TransactionSigned, }; use reth_primitives_traits::BlockBody; use reth_prune_types::{PruneCheckpoint, PruneSegment}; @@ -296,19 +296,17 @@ impl BlockReader for BlockchainProvider { self.consistent_provider()?.block(id) } - fn pending_block(&self) -> ProviderResult>> { + fn pending_block(&self) -> ProviderResult>> { Ok(self.canonical_in_memory_state.pending_block()) } - fn pending_block_with_senders( - &self, - ) -> ProviderResult>> { - Ok(self.canonical_in_memory_state.pending_block_with_senders()) + fn pending_block_with_senders(&self) -> ProviderResult>> { + Ok(self.canonical_in_memory_state.pending_recovered_block()) } fn pending_block_and_receipts( &self, - ) -> ProviderResult, Vec)>> { + ) -> ProviderResult, Vec)>> { Ok(self.canonical_in_memory_state.pending_block_and_receipts()) } @@ -322,7 +320,7 @@ impl BlockReader for BlockchainProvider { &self, id: BlockHashOrNumber, transaction_kind: TransactionVariant, - ) -> ProviderResult>> { + ) -> ProviderResult>> { self.consistent_provider()?.block_with_senders(id, transaction_kind) } @@ -330,7 +328,7 @@ impl BlockReader for BlockchainProvider { &self, id: BlockHashOrNumber, transaction_kind: TransactionVariant, - ) -> ProviderResult>> { + ) -> ProviderResult>> { self.consistent_provider()?.sealed_block_with_senders(id, transaction_kind) } @@ -341,14 +339,14 @@ impl BlockReader for BlockchainProvider { fn block_with_senders_range( &self, range: RangeInclusive, - ) -> ProviderResult>> { + ) -> ProviderResult>> { self.consistent_provider()?.block_with_senders_range(range) } fn sealed_block_with_senders_range( &self, range: RangeInclusive, - ) -> ProviderResult>> { + ) -> ProviderResult>> { self.consistent_provider()?.sealed_block_with_senders_range(range) } } @@ -794,7 +792,7 @@ mod tests { use reth_db_api::{cursor::DbCursorRO, transaction::DbTx}; use reth_errors::ProviderError; use reth_execution_types::{Chain, ExecutionOutcome}; - use reth_primitives::{BlockExt, EthPrimitives, Receipt, SealedBlock, StaticFileSegment}; + use reth_primitives::{EthPrimitives, Receipt, SealedBlock, StaticFileSegment}; use reth_primitives_traits::{BlockBody, SignedTransaction}; use reth_storage_api::{ BlockBodyIndicesProvider, BlockHashReader, BlockIdReader, BlockNumReader, BlockReader, @@ -907,7 +905,7 @@ mod tests { } provider_rw.insert_historical_block( - block.clone().seal_with_senders().expect("failed to seal block with senders"), + block.clone().try_recover().expect("failed to seal block with senders"), )?; } @@ -1027,7 +1025,7 @@ mod tests { let provider_rw = factory.provider_rw()?; for block in database_blocks { provider_rw.insert_historical_block( - block.clone().seal_with_senders().expect("failed to seal block with senders"), + block.clone().try_recover().expect("failed to seal block with senders"), )?; } provider_rw.commit()?; @@ -1069,21 +1067,21 @@ mod tests { // Now the block should be found in memory assert_eq!( provider.find_block_by_hash(first_in_mem_block.hash(), BlockSource::Any)?, - Some(first_in_mem_block.clone().into()) + Some(first_in_mem_block.clone().into_block()) ); assert_eq!( provider.find_block_by_hash(first_in_mem_block.hash(), BlockSource::Canonical)?, - Some(first_in_mem_block.clone().into()) + Some(first_in_mem_block.clone().into_block()) ); // Find the first block in database by hash assert_eq!( provider.find_block_by_hash(first_db_block.hash(), BlockSource::Any)?, - Some(first_db_block.clone().into()) + Some(first_db_block.clone().into_block()) ); assert_eq!( provider.find_block_by_hash(first_db_block.hash(), BlockSource::Canonical)?, - Some(first_db_block.clone().into()) + Some(first_db_block.clone().into_block()) ); // No pending block in database @@ -1101,7 +1099,7 @@ mod tests { // Now the last block should be found in memory assert_eq!( provider.find_block_by_hash(last_in_mem_block.hash(), BlockSource::Pending)?, - Some(last_in_mem_block.clone().into()) + Some(last_in_mem_block.clone().into_block()) ); Ok(()) @@ -1125,7 +1123,7 @@ mod tests { let provider_rw = factory.provider_rw()?; for block in database_blocks { provider_rw.insert_historical_block( - block.clone().seal_with_senders().expect("failed to seal block with senders"), + block.clone().try_recover().expect("failed to seal block with senders"), )?; } provider_rw.commit()?; @@ -1159,21 +1157,21 @@ mod tests { // First in memory block should be found assert_eq!( provider.block(BlockHashOrNumber::Hash(first_in_mem_block.hash()))?, - Some(first_in_mem_block.clone().into()) + Some(first_in_mem_block.clone().into_block()) ); assert_eq!( provider.block(BlockHashOrNumber::Number(first_in_mem_block.number))?, - Some(first_in_mem_block.clone().into()) + Some(first_in_mem_block.clone().into_block()) ); // First database block should be found assert_eq!( provider.block(BlockHashOrNumber::Hash(first_db_block.hash()))?, - Some(first_db_block.clone().into()) + Some(first_db_block.clone().into_block()) ); assert_eq!( provider.block(BlockHashOrNumber::Number(first_db_block.number))?, - Some(first_db_block.clone().into()) + Some(first_db_block.clone().into_block()) ); Ok(()) @@ -1211,7 +1209,7 @@ mod tests { assert_eq!( provider.pending_block_with_senders()?, - Some(reth_primitives::SealedBlockWithSenders::new_unchecked( + Some(reth_primitives::RecoveredBlock::new_sealed( block.clone(), block.senders().unwrap() )) @@ -1508,19 +1506,22 @@ mod tests { assert_eq!( provider.block_by_id(block_number.into()).unwrap(), - Some(database_block.clone().unseal()) + Some(database_block.clone().into_block()) + ); + assert_eq!( + provider.block_by_id(block_hash.into()).unwrap(), + Some(database_block.into_block()) ); - assert_eq!(provider.block_by_id(block_hash.into()).unwrap(), Some(database_block.unseal())); let block_number = in_memory_block.number; let block_hash = in_memory_block.hash(); assert_eq!( provider.block_by_id(block_number.into()).unwrap(), - Some(in_memory_block.clone().unseal()) + Some(in_memory_block.clone().into_block()) ); assert_eq!( provider.block_by_id(block_hash.into()).unwrap(), - Some(in_memory_block.unseal()) + Some(in_memory_block.into_block()) ); Ok(()) @@ -1806,7 +1807,7 @@ mod tests { provider_rw.append_blocks_with_state( database_blocks .into_iter() - .map(|b| b.seal_with_senders().expect("failed to seal block with senders")) + .map(|b| b.try_recover().expect("failed to seal block with senders")) .collect(), &ExecutionOutcome { bundle: BundleState::new( @@ -2326,14 +2327,12 @@ mod tests { test_by_block_range!([ (headers_range, |block: &SealedBlock| block.header().clone()), (sealed_headers_range, |block: &SealedBlock| block.clone_sealed_header()), - (block_range, |block: &SealedBlock| block.clone().unseal()), - (block_with_senders_range, |block: &SealedBlock| block - .clone() - .unseal::() - .with_senders_unchecked(vec![])), + (block_range, |block: &SealedBlock| block.clone().into_block()), + (block_with_senders_range, |block: &SealedBlock| block.clone().try_recover().unwrap()), (sealed_block_with_senders_range, |block: &SealedBlock| block .clone() - .with_senders_unchecked(vec![])), + .try_recover() + .unwrap()), (transactions_by_block_range, |block: &SealedBlock| block.body().transactions.clone()), ]); @@ -2494,7 +2493,7 @@ mod tests { block, |block: &SealedBlock, _: TxNumber, _: B256, _: &Vec>| ( BlockHashOrNumber::Hash(block.hash()), - Some(block.clone().unseal()) + Some(block.clone().into_block()) ), BlockHashOrNumber::Hash(B256::random()) ), @@ -2503,7 +2502,7 @@ mod tests { block, |block: &SealedBlock, _: TxNumber, _: B256, _: &Vec>| ( BlockHashOrNumber::Number(block.number), - Some(block.clone().unseal()) + Some(block.clone().into_block()) ), BlockHashOrNumber::Number(u64::MAX) ), @@ -2524,7 +2523,7 @@ mod tests { block_with_senders, |block: &SealedBlock, _: TxNumber, _: B256, _: &Vec>| ( (BlockHashOrNumber::Number(block.number), TransactionVariant::WithHash), - block.clone().unseal::().with_recovered_senders() + block.clone().try_recover().ok() ), (BlockHashOrNumber::Number(u64::MAX), TransactionVariant::WithHash) ), @@ -2533,7 +2532,7 @@ mod tests { block_with_senders, |block: &SealedBlock, _: TxNumber, _: B256, _: &Vec>| ( (BlockHashOrNumber::Hash(block.hash()), TransactionVariant::WithHash), - block.clone().unseal::().with_recovered_senders() + block.clone().try_recover().ok() ), (BlockHashOrNumber::Hash(B256::random()), TransactionVariant::WithHash) ), @@ -2542,14 +2541,7 @@ mod tests { sealed_block_with_senders, |block: &SealedBlock, _: TxNumber, _: B256, _: &Vec>| ( (BlockHashOrNumber::Number(block.number), TransactionVariant::WithHash), - Some( - block - .clone() - .unseal::() - .with_recovered_senders() - .unwrap() - .seal_unchecked(block.hash()) - ) + block.clone().try_recover().ok() ), (BlockHashOrNumber::Number(u64::MAX), TransactionVariant::WithHash) ), @@ -2558,14 +2550,7 @@ mod tests { sealed_block_with_senders, |block: &SealedBlock, _: TxNumber, _: B256, _: &Vec>| ( (BlockHashOrNumber::Hash(block.hash()), TransactionVariant::WithHash), - Some( - block - .clone() - .unseal::() - .with_recovered_senders() - .unwrap() - .seal_unchecked(block.hash()) - ) + block.clone().try_recover().ok() ), (BlockHashOrNumber::Hash(B256::random()), TransactionVariant::WithHash) ), diff --git a/crates/storage/provider/src/providers/consistent.rs b/crates/storage/provider/src/providers/consistent.rs index 4d6ce309fd..1417be828f 100644 --- a/crates/storage/provider/src/providers/consistent.rs +++ b/crates/storage/provider/src/providers/consistent.rs @@ -21,9 +21,7 @@ use reth_db::models::BlockNumberAddress; use reth_db_api::models::{AccountBeforeTx, StoredBlockBodyIndices}; use reth_execution_types::{BundleStateInit, ExecutionOutcome, RevertsInit}; use reth_node_types::{BlockTy, HeaderTy, ReceiptTy, TxTy}; -use reth_primitives::{ - Account, BlockWithSenders, SealedBlockFor, SealedBlockWithSenders, SealedHeader, StorageEntry, -}; +use reth_primitives::{Account, RecoveredBlock, SealedBlock, SealedHeader, StorageEntry}; use reth_primitives_traits::BlockBody; use reth_prune_types::{PruneCheckpoint, PruneSegment}; use reth_stages_types::{StageCheckpoint, StageId}; @@ -804,11 +802,11 @@ impl BlockReader for ConsistentProvider { self.get_in_memory_or_storage_by_block( hash.into(), |db_provider| db_provider.find_block_by_hash(hash, source), - |block_state| Ok(Some(block_state.block_ref().block().clone().unseal())), + |block_state| Ok(Some(block_state.block_ref().block().clone_block())), ) } BlockSource::Pending => { - Ok(self.canonical_in_memory_state.pending_block().map(|block| block.unseal())) + Ok(self.canonical_in_memory_state.pending_block().map(|block| block.into_block())) } } } @@ -817,23 +815,21 @@ impl BlockReader for ConsistentProvider { self.get_in_memory_or_storage_by_block( id, |db_provider| db_provider.block(id), - |block_state| Ok(Some(block_state.block_ref().block().clone().unseal())), + |block_state| Ok(Some(block_state.block_ref().block().clone_block())), ) } - fn pending_block(&self) -> ProviderResult>> { + fn pending_block(&self) -> ProviderResult>> { Ok(self.canonical_in_memory_state.pending_block()) } - fn pending_block_with_senders( - &self, - ) -> ProviderResult>> { - Ok(self.canonical_in_memory_state.pending_block_with_senders()) + fn pending_block_with_senders(&self) -> ProviderResult>> { + Ok(self.canonical_in_memory_state.pending_recovered_block()) } fn pending_block_and_receipts( &self, - ) -> ProviderResult, Vec)>> { + ) -> ProviderResult, Vec)>> { Ok(self.canonical_in_memory_state.pending_block_and_receipts()) } @@ -847,11 +843,11 @@ impl BlockReader for ConsistentProvider { &self, id: BlockHashOrNumber, transaction_kind: TransactionVariant, - ) -> ProviderResult>> { + ) -> ProviderResult>> { self.get_in_memory_or_storage_by_block( id, |db_provider| db_provider.block_with_senders(id, transaction_kind), - |block_state| Ok(Some(block_state.block_with_senders())), + |block_state| Ok(Some(block_state.clone_recovered_block())), ) } @@ -859,11 +855,11 @@ impl BlockReader for ConsistentProvider { &self, id: BlockHashOrNumber, transaction_kind: TransactionVariant, - ) -> ProviderResult>> { + ) -> ProviderResult>> { self.get_in_memory_or_storage_by_block( id, |db_provider| db_provider.sealed_block_with_senders(id, transaction_kind), - |block_state| Ok(Some(block_state.sealed_block_with_senders())), + |block_state| Ok(Some(block_state.clone_recovered_block())), ) } @@ -871,7 +867,7 @@ impl BlockReader for ConsistentProvider { self.get_in_memory_or_storage_by_block_range_while( range, |db_provider, range, _| db_provider.block_range(range), - |block_state, _| Some(block_state.block_ref().block().clone().unseal()), + |block_state, _| Some(block_state.block_ref().block().clone_block()), |_| true, ) } @@ -879,11 +875,11 @@ impl BlockReader for ConsistentProvider { fn block_with_senders_range( &self, range: RangeInclusive, - ) -> ProviderResult>> { + ) -> ProviderResult>> { self.get_in_memory_or_storage_by_block_range_while( range, |db_provider, range, _| db_provider.block_with_senders_range(range), - |block_state, _| Some(block_state.block_with_senders()), + |block_state, _| Some(block_state.clone_recovered_block()), |_| true, ) } @@ -891,11 +887,11 @@ impl BlockReader for ConsistentProvider { fn sealed_block_with_senders_range( &self, range: RangeInclusive, - ) -> ProviderResult>> { + ) -> ProviderResult>> { self.get_in_memory_or_storage_by_block_range_while( range, |db_provider, range, _| db_provider.sealed_block_with_senders_range(range), - |block_state, _| Some(block_state.sealed_block_with_senders()), + |block_state, _| Some(block_state.clone_recovered_block()), |_| true, ) } @@ -1271,11 +1267,11 @@ impl BlockReaderIdExt for ConsistentProvider { BlockNumberOrTag::Safe => Ok(self.canonical_in_memory_state.get_safe_header()), BlockNumberOrTag::Earliest => self .header_by_number(0)? - .map_or_else(|| Ok(None), |h| Ok(Some(SealedHeader::seal(h)))), + .map_or_else(|| Ok(None), |h| Ok(Some(SealedHeader::seal_slow(h)))), BlockNumberOrTag::Pending => Ok(self.canonical_in_memory_state.pending_sealed_header()), BlockNumberOrTag::Number(num) => self .header_by_number(num)? - .map_or_else(|| Ok(None), |h| Ok(Some(SealedHeader::seal(h)))), + .map_or_else(|| Ok(None), |h| Ok(Some(SealedHeader::seal_slow(h)))), } } @@ -1285,7 +1281,7 @@ impl BlockReaderIdExt for ConsistentProvider { ) -> ProviderResult>>> { Ok(match id { BlockId::Number(num) => self.sealed_header_by_number_or_tag(num)?, - BlockId::Hash(hash) => self.header(&hash.block_hash)?.map(SealedHeader::seal), + BlockId::Hash(hash) => self.header(&hash.block_hash)?.map(SealedHeader::seal_slow), }) } @@ -1518,7 +1514,7 @@ mod tests { let provider_rw = factory.provider_rw()?; for block in database_blocks { provider_rw.insert_historical_block( - block.clone().seal_with_senders().expect("failed to seal block with senders"), + block.clone().try_recover().expect("failed to seal block with senders"), )?; } provider_rw.commit()?; @@ -1567,23 +1563,23 @@ mod tests { // Now the block should be found in memory assert_eq!( consistent_provider.find_block_by_hash(first_in_mem_block.hash(), BlockSource::Any)?, - Some(first_in_mem_block.clone().into()) + Some(first_in_mem_block.clone().into_block()) ); assert_eq!( consistent_provider .find_block_by_hash(first_in_mem_block.hash(), BlockSource::Canonical)?, - Some(first_in_mem_block.clone().into()) + Some(first_in_mem_block.clone().into_block()) ); // Find the first block in database by hash assert_eq!( consistent_provider.find_block_by_hash(first_db_block.hash(), BlockSource::Any)?, - Some(first_db_block.clone().into()) + Some(first_db_block.clone().into_block()) ); assert_eq!( consistent_provider .find_block_by_hash(first_db_block.hash(), BlockSource::Canonical)?, - Some(first_db_block.clone().into()) + Some(first_db_block.clone().into_block()) ); // No pending block in database @@ -1605,7 +1601,7 @@ mod tests { assert_eq!( consistent_provider .find_block_by_hash(last_in_mem_block.hash(), BlockSource::Pending)?, - Some(last_in_mem_block.clone().into()) + Some(last_in_mem_block.clone_block()) ); Ok(()) @@ -1629,7 +1625,7 @@ mod tests { let provider_rw = factory.provider_rw()?; for block in database_blocks { provider_rw.insert_historical_block( - block.clone().seal_with_senders().expect("failed to seal block with senders"), + block.clone().try_recover().expect("failed to seal block with senders"), )?; } provider_rw.commit()?; @@ -1672,21 +1668,21 @@ mod tests { // First in memory block should be found assert_eq!( consistent_provider.block(BlockHashOrNumber::Hash(first_in_mem_block.hash()))?, - Some(first_in_mem_block.clone().into()) + Some(first_in_mem_block.clone().into_block()) ); assert_eq!( consistent_provider.block(BlockHashOrNumber::Number(first_in_mem_block.number))?, - Some(first_in_mem_block.clone().into()) + Some(first_in_mem_block.clone().into_block()) ); // First database block should be found assert_eq!( consistent_provider.block(BlockHashOrNumber::Hash(first_db_block.hash()))?, - Some(first_db_block.clone().into()) + Some(first_db_block.clone().into_block()) ); assert_eq!( consistent_provider.block(BlockHashOrNumber::Number(first_db_block.number))?, - Some(first_db_block.clone().into()) + Some(first_db_block.clone().into_block()) ); Ok(()) @@ -1728,7 +1724,7 @@ mod tests { provider_rw.append_blocks_with_state( database_blocks .into_iter() - .map(|b| b.seal_with_senders().expect("failed to seal block with senders")) + .map(|b| b.try_recover().expect("failed to seal block with senders")) .collect(), &ExecutionOutcome { bundle: BundleState::new( diff --git a/crates/storage/provider/src/providers/database/mod.rs b/crates/storage/provider/src/providers/database/mod.rs index 57ec9c0597..4c781b304b 100644 --- a/crates/storage/provider/src/providers/database/mod.rs +++ b/crates/storage/provider/src/providers/database/mod.rs @@ -16,9 +16,7 @@ use reth_db::{init_db, mdbx::DatabaseArguments, DatabaseEnv}; use reth_db_api::{database::Database, models::StoredBlockBodyIndices}; use reth_errors::{RethError, RethResult}; use reth_node_types::{BlockTy, HeaderTy, NodeTypesWithDB, ReceiptTy, TxTy}; -use reth_primitives::{ - BlockWithSenders, SealedBlockFor, SealedBlockWithSenders, SealedHeader, StaticFileSegment, -}; +use reth_primitives::{RecoveredBlock, SealedBlock, SealedHeader, StaticFileSegment}; use reth_prune_types::{PruneCheckpoint, PruneModes, PruneSegment}; use reth_stages_types::{StageCheckpoint, StageId}; use reth_storage_api::{ @@ -382,19 +380,17 @@ impl BlockReader for ProviderFactory { self.provider()?.block(id) } - fn pending_block(&self) -> ProviderResult>> { + fn pending_block(&self) -> ProviderResult>> { self.provider()?.pending_block() } - fn pending_block_with_senders( - &self, - ) -> ProviderResult>> { + fn pending_block_with_senders(&self) -> ProviderResult>> { self.provider()?.pending_block_with_senders() } fn pending_block_and_receipts( &self, - ) -> ProviderResult, Vec)>> { + ) -> ProviderResult, Vec)>> { self.provider()?.pending_block_and_receipts() } @@ -402,7 +398,7 @@ impl BlockReader for ProviderFactory { &self, id: BlockHashOrNumber, transaction_kind: TransactionVariant, - ) -> ProviderResult>> { + ) -> ProviderResult>> { self.provider()?.block_with_senders(id, transaction_kind) } @@ -410,7 +406,7 @@ impl BlockReader for ProviderFactory { &self, id: BlockHashOrNumber, transaction_kind: TransactionVariant, - ) -> ProviderResult>> { + ) -> ProviderResult>> { self.provider()?.sealed_block_with_senders(id, transaction_kind) } @@ -421,14 +417,14 @@ impl BlockReader for ProviderFactory { fn block_with_senders_range( &self, range: RangeInclusive, - ) -> ProviderResult>> { + ) -> ProviderResult>> { self.provider()?.block_with_senders_range(range) } fn sealed_block_with_senders_range( &self, range: RangeInclusive, - ) -> ProviderResult>> { + ) -> ProviderResult>> { self.provider()?.sealed_block_with_senders_range(range) } } @@ -703,10 +699,8 @@ mod tests { { let provider = factory.provider_rw().unwrap(); assert_matches!( - provider.insert_block( - block.clone().try_seal_with_senders().unwrap(), - StorageLocation::Database - ), + provider + .insert_block(block.clone().try_recover().unwrap(), StorageLocation::Database), Ok(_) ); assert_matches!( @@ -727,10 +721,8 @@ mod tests { }; let provider = factory.with_prune_modes(prune_modes).provider_rw().unwrap(); assert_matches!( - provider.insert_block( - block.clone().try_seal_with_senders().unwrap(), - StorageLocation::Database - ), + provider + .insert_block(block.clone().try_recover().unwrap(), StorageLocation::Database), Ok(_) ); assert_matches!(provider.transaction_sender(0), Ok(None)); @@ -751,10 +743,8 @@ mod tests { let provider = factory.provider_rw().unwrap(); assert_matches!( - provider.insert_block( - block.clone().try_seal_with_senders().unwrap(), - StorageLocation::Database - ), + provider + .insert_block(block.clone().try_recover().unwrap(), StorageLocation::Database), Ok(_) ); diff --git a/crates/storage/provider/src/providers/database/provider.rs b/crates/storage/provider/src/providers/database/provider.rs index 34713d108b..4a9e5affa2 100644 --- a/crates/storage/provider/src/providers/database/provider.rs +++ b/crates/storage/provider/src/providers/database/provider.rs @@ -47,8 +47,8 @@ use reth_execution_types::{Chain, ExecutionOutcome}; use reth_network_p2p::headers::downloader::SyncTarget; use reth_node_types::{BlockTy, BodyTy, HeaderTy, NodeTypes, ReceiptTy, TxTy}; use reth_primitives::{ - Account, BlockExt, BlockWithSenders, Bytecode, GotExpected, NodePrimitives, SealedBlock, - SealedBlockFor, SealedBlockWithSenders, SealedHeader, StaticFileSegment, StorageEntry, + Account, Bytecode, GotExpected, NodePrimitives, RecoveredBlock, SealedBlock, SealedHeader, + StaticFileSegment, StorageEntry, }; use reth_primitives_traits::{Block as _, BlockBody as _, SignedTransaction}; use reth_prune_types::{PruneCheckpoint, PruneModes, PruneSegment}; @@ -424,14 +424,14 @@ impl< /// Inserts an historical block. **Used for setting up test environments** pub fn insert_historical_block( &self, - block: SealedBlockWithSenders<::Block>, + block: RecoveredBlock<::Block>, ) -> ProviderResult { let ttd = if block.number() == 0 { - block.difficulty() + block.header().difficulty() } else { let parent_block_number = block.number() - 1; let parent_ttd = self.header_td_by_number(parent_block_number)?.unwrap_or_default(); - parent_ttd + block.difficulty() + parent_ttd + block.header().difficulty() }; let mut writer = self.static_file_provider.latest_writer(StaticFileSegment::Headers)?; @@ -440,7 +440,7 @@ impl< let segment_header = writer.user_header(); if segment_header.block_end().is_none() && segment_header.expected_block_start() == 0 { for block_number in 0..block.number() { - let mut prev = block.clone_sealed_header().unseal(); + let mut prev = block.clone_header(); prev.number = block_number; writer.append_header(&prev, U256::ZERO, &B256::ZERO)?; } @@ -1197,19 +1197,17 @@ impl BlockReader for DatabaseProvid Ok(None) } - fn pending_block(&self) -> ProviderResult>> { + fn pending_block(&self) -> ProviderResult>> { Ok(None) } - fn pending_block_with_senders( - &self, - ) -> ProviderResult>> { + fn pending_block_with_senders(&self) -> ProviderResult>> { Ok(None) } fn pending_block_and_receipts( &self, - ) -> ProviderResult, Vec)>> { + ) -> ProviderResult, Vec)>> { Ok(None) } @@ -1225,7 +1223,7 @@ impl BlockReader for DatabaseProvid &self, id: BlockHashOrNumber, transaction_kind: TransactionVariant, - ) -> ProviderResult>> { + ) -> ProviderResult>> { self.block_with_senders( id, transaction_kind, @@ -1246,13 +1244,13 @@ impl BlockReader for DatabaseProvid &self, id: BlockHashOrNumber, transaction_kind: TransactionVariant, - ) -> ProviderResult>> { + ) -> ProviderResult>> { self.block_with_senders( id, transaction_kind, |block_number| self.sealed_header(block_number), |header, body, senders| { - SealedBlock::new(header, body) + Self::Block::new_sealed(header, body) // Note: we're using unchecked here because we know the block contains valid txs // wrt to its height and can ignore the s value check so pre // EIP-2 txs are allowed @@ -1274,7 +1272,7 @@ impl BlockReader for DatabaseProvid fn block_with_senders_range( &self, range: RangeInclusive, - ) -> ProviderResult>> { + ) -> ProviderResult>> { self.block_with_senders_range( range, |range| self.headers_range(range), @@ -1289,13 +1287,14 @@ impl BlockReader for DatabaseProvid fn sealed_block_with_senders_range( &self, range: RangeInclusive, - ) -> ProviderResult>> { + ) -> ProviderResult>> { self.block_with_senders_range( range, |range| self.sealed_headers_range(range), |header, body, senders| { - SealedBlockWithSenders::new(SealedBlock::new(header, body), senders) - .ok_or(ProviderError::SenderRecoveryError) + Self::Block::new_sealed(header, body) + .try_with_senders(senders) + .map_err(|_| ProviderError::SenderRecoveryError) }, ) } @@ -2749,7 +2748,7 @@ impl BlockWrite /// [`TransactionHashNumbers`](tables::TransactionHashNumbers). fn insert_block( &self, - block: SealedBlockWithSenders, + block: RecoveredBlock, write_to: StorageLocation, ) -> ProviderResult { let block_number = block.number(); @@ -2758,12 +2757,12 @@ impl BlockWrite // total difficulty let ttd = if block_number == 0 { - block.difficulty() + block.header().difficulty() } else { let parent_block_number = block_number - 1; let parent_ttd = self.header_td_by_number(parent_block_number)?.unwrap_or_default(); durations_recorder.record_relative(metrics::Action::GetParentTD); - parent_ttd + block.difficulty() + parent_ttd + block.header().difficulty() }; if write_to.database() { @@ -2796,12 +2795,10 @@ impl BlockWrite durations_recorder.record_relative(metrics::Action::GetNextTxNum); let first_tx_num = next_tx_num; - let tx_count = block.block.body().transactions().len() as u64; + let tx_count = block.body().transaction_count() as u64; // Ensures we have all the senders for the block's transactions. - for (transaction, sender) in - block.block.body().transactions().iter().zip(block.senders_iter()) - { + for (transaction, sender) in block.body().transactions().iter().zip(block.senders_iter()) { let hash = transaction.tx_hash(); if self.prune_modes.sender_recovery.as_ref().is_none_or(|m| !m.is_full()) { @@ -2814,7 +2811,7 @@ impl BlockWrite next_tx_num += 1; } - self.append_block_bodies(vec![(block_number, Some(block.block.into_body()))], write_to)?; + self.append_block_bodies(vec![(block_number, Some(block.into_body()))], write_to)?; debug!( target: "providers::db", @@ -2992,7 +2989,7 @@ impl BlockWrite /// TODO(joshie): this fn should be moved to `UnifiedStorageWriter` eventually fn append_blocks_with_state( &self, - blocks: Vec>, + blocks: Vec>, execution_outcome: &ExecutionOutcome, hashed_state: HashedPostStateSorted, trie_updates: TrieUpdates, diff --git a/crates/storage/provider/src/providers/static_file/manager.rs b/crates/storage/provider/src/providers/static_file/manager.rs index f501d64d43..d601098490 100644 --- a/crates/storage/provider/src/providers/static_file/manager.rs +++ b/crates/storage/provider/src/providers/static_file/manager.rs @@ -33,8 +33,7 @@ use reth_primitives::{ find_fixed_range, HighestStaticFiles, SegmentHeader, SegmentRangeInclusive, DEFAULT_BLOCKS_PER_STATIC_FILE, }, - BlockWithSenders, Receipt, SealedBlockFor, SealedBlockWithSenders, SealedHeader, - StaticFileSegment, TransactionSigned, + Receipt, RecoveredBlock, SealedBlock, SealedHeader, StaticFileSegment, TransactionSigned, }; use reth_primitives_traits::SignedTransaction; use reth_stages_types::{PipelineTarget, StageId}; @@ -1621,21 +1620,19 @@ impl> Err(ProviderError::UnsupportedProvider) } - fn pending_block(&self) -> ProviderResult>> { + fn pending_block(&self) -> ProviderResult>> { // Required data not present in static_files Err(ProviderError::UnsupportedProvider) } - fn pending_block_with_senders( - &self, - ) -> ProviderResult>> { + fn pending_block_with_senders(&self) -> ProviderResult>> { // Required data not present in static_files Err(ProviderError::UnsupportedProvider) } fn pending_block_and_receipts( &self, - ) -> ProviderResult, Vec)>> { + ) -> ProviderResult, Vec)>> { // Required data not present in static_files Err(ProviderError::UnsupportedProvider) } @@ -1644,7 +1641,7 @@ impl> &self, _id: BlockHashOrNumber, _transaction_kind: TransactionVariant, - ) -> ProviderResult>> { + ) -> ProviderResult>> { // Required data not present in static_files Err(ProviderError::UnsupportedProvider) } @@ -1653,7 +1650,7 @@ impl> &self, _id: BlockHashOrNumber, _transaction_kind: TransactionVariant, - ) -> ProviderResult>> { + ) -> ProviderResult>> { // Required data not present in static_files Err(ProviderError::UnsupportedProvider) } @@ -1666,14 +1663,14 @@ impl> fn block_with_senders_range( &self, _range: RangeInclusive, - ) -> ProviderResult>> { + ) -> ProviderResult>> { Err(ProviderError::UnsupportedProvider) } fn sealed_block_with_senders_range( &self, _range: RangeInclusive, - ) -> ProviderResult>> { + ) -> ProviderResult>> { Err(ProviderError::UnsupportedProvider) } } diff --git a/crates/storage/provider/src/providers/static_file/mod.rs b/crates/storage/provider/src/providers/static_file/mod.rs index 897da8509d..7d98cf2a34 100644 --- a/crates/storage/provider/src/providers/static_file/mod.rs +++ b/crates/storage/provider/src/providers/static_file/mod.rs @@ -110,7 +110,7 @@ mod tests { let hash = header.hash(); tx.put::(header.number, hash).unwrap(); - tx.put::(header.number, header.clone().unseal()).unwrap(); + tx.put::(header.number, header.clone_header()).unwrap(); tx.put::(header.number, td.into()).unwrap(); tx.put::(hash, header.number).unwrap(); } diff --git a/crates/storage/provider/src/test_utils/blocks.rs b/crates/storage/provider/src/test_utils/blocks.rs index 4477340245..fec124ad12 100644 --- a/crates/storage/provider/src/test_utils/blocks.rs +++ b/crates/storage/provider/src/test_utils/blocks.rs @@ -12,7 +12,7 @@ use reth_db::tables; use reth_db_api::{database::Database, models::StoredBlockBodyIndices}; use reth_node_types::NodeTypes; use reth_primitives::{ - Account, BlockBody, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader, Transaction, + Account, BlockBody, Receipt, RecoveredBlock, SealedBlock, SealedHeader, Transaction, TransactionSigned, TxType, }; use reth_trie::root::{state_root_unhashed, storage_root_unhashed}; @@ -64,7 +64,7 @@ pub fn assert_genesis_block( } pub(crate) static TEST_BLOCK: LazyLock = LazyLock::new(|| { - SealedBlock::new( + SealedBlock::from_sealed_parts( SealedHeader::new( Header { parent_hash: hex!( @@ -127,7 +127,7 @@ pub struct BlockchainTestData { /// Genesis pub genesis: SealedBlock, /// Blocks with its execution result - pub blocks: Vec<(SealedBlockWithSenders, ExecutionOutcome)>, + pub blocks: Vec<(RecoveredBlock, ExecutionOutcome)>, } impl BlockchainTestData { @@ -163,7 +163,7 @@ impl Default for BlockchainTestData { /// Genesis block pub fn genesis() -> SealedBlock { - SealedBlock::new( + SealedBlock::from_sealed_parts( SealedHeader::new( Header { number: 0, difficulty: U256::from(1), ..Default::default() }, B256::ZERO, @@ -192,7 +192,7 @@ fn bundle_state_root(execution_outcome: &ExecutionOutcome) -> B256 { } /// Block one that points to genesis -fn block1(number: BlockNumber) -> (SealedBlockWithSenders, ExecutionOutcome) { +fn block1(number: BlockNumber) -> (RecoveredBlock, ExecutionOutcome) { // block changes let account1: Address = [0x60; 20].into(); let account2: Address = [0x61; 20].into(); @@ -232,18 +232,14 @@ fn block1(number: BlockNumber) -> (SealedBlockWithSenders, ExecutionOutcome) { b256!("5d035ccb3e75a9057452ff060b773b213ec1fc353426174068edfc3971a0b6bd") ); - let (header, mut body) = TEST_BLOCK.clone().split(); + let (mut header, mut body) = TEST_BLOCK.clone().split_header_body(); body.withdrawals = Some(Withdrawals::new(vec![Withdrawal::default()])); - let mut header = header.unseal(); header.number = number; header.state_root = state_root; header.parent_hash = B256::ZERO; - let block = SealedBlock::new(SealedHeader::seal(header), body); + let block = SealedBlock::seal_parts(header, body); - ( - SealedBlockWithSenders::new_unchecked(block, vec![Address::new([0x30; 20])]), - execution_outcome, - ) + (RecoveredBlock::new_sealed(block, vec![Address::new([0x30; 20])]), execution_outcome) } /// Block two that points to block 1 @@ -251,7 +247,7 @@ fn block2( number: BlockNumber, parent_hash: B256, prev_execution_outcome: &ExecutionOutcome, -) -> (SealedBlockWithSenders, ExecutionOutcome) { +) -> (RecoveredBlock, ExecutionOutcome) { // block changes let account: Address = [0x60; 20].into(); let slot = U256::from(5); @@ -297,20 +293,16 @@ fn block2( b256!("90101a13dd059fa5cca99ed93d1dc23657f63626c5b8f993a2ccbdf7446b64f8") ); - let (header, mut body) = TEST_BLOCK.clone().split(); + let (mut header, mut body) = TEST_BLOCK.clone().split_header_body(); body.withdrawals = Some(Withdrawals::new(vec![Withdrawal::default()])); - let mut header = header.unseal(); header.number = number; header.state_root = state_root; // parent_hash points to block1 hash header.parent_hash = parent_hash; - let block = SealedBlock::new(SealedHeader::seal(header), body); + let block = SealedBlock::seal_parts(header, body); - ( - SealedBlockWithSenders::new_unchecked(block, vec![Address::new([0x31; 20])]), - execution_outcome, - ) + (RecoveredBlock::new_sealed(block, vec![Address::new([0x31; 20])]), execution_outcome) } /// Block three that points to block 2 @@ -318,7 +310,7 @@ fn block3( number: BlockNumber, parent_hash: B256, prev_execution_outcome: &ExecutionOutcome, -) -> (SealedBlockWithSenders, ExecutionOutcome) { +) -> (RecoveredBlock, ExecutionOutcome) { let address_range = 1..=20; let slot_range = 1..=100; @@ -365,19 +357,15 @@ fn block3( extended.extend(execution_outcome.clone()); let state_root = bundle_state_root(&extended); - let (header, mut body) = TEST_BLOCK.clone().split(); + let (mut header, mut body) = TEST_BLOCK.clone().split_header_body(); body.withdrawals = Some(Withdrawals::new(vec![Withdrawal::default()])); - let mut header = header.unseal(); header.number = number; header.state_root = state_root; // parent_hash points to block1 hash header.parent_hash = parent_hash; - let block = SealedBlock::new(SealedHeader::seal(header), body); + let block = SealedBlock::seal_parts(header, body); - ( - SealedBlockWithSenders::new_unchecked(block, vec![Address::new([0x31; 20])]), - execution_outcome, - ) + (RecoveredBlock::new_sealed(block, vec![Address::new([0x31; 20])]), execution_outcome) } /// Block four that points to block 3 @@ -385,7 +373,7 @@ fn block4( number: BlockNumber, parent_hash: B256, prev_execution_outcome: &ExecutionOutcome, -) -> (SealedBlockWithSenders, ExecutionOutcome) { +) -> (RecoveredBlock, ExecutionOutcome) { let address_range = 1..=20; let slot_range = 1..=100; @@ -457,19 +445,15 @@ fn block4( extended.extend(execution_outcome.clone()); let state_root = bundle_state_root(&extended); - let (header, mut body) = TEST_BLOCK.clone().split(); + let (mut header, mut body) = TEST_BLOCK.clone().split_header_body(); body.withdrawals = Some(Withdrawals::new(vec![Withdrawal::default()])); - let mut header = header.unseal(); header.number = number; header.state_root = state_root; // parent_hash points to block1 hash header.parent_hash = parent_hash; - let block = SealedBlock::new(SealedHeader::seal(header), body); + let block = SealedBlock::seal_parts(header, body); - ( - SealedBlockWithSenders::new_unchecked(block, vec![Address::new([0x31; 20])]), - execution_outcome, - ) + (RecoveredBlock::new_sealed(block, vec![Address::new([0x31; 20])]), execution_outcome) } /// Block five that points to block 4 @@ -477,7 +461,7 @@ fn block5( number: BlockNumber, parent_hash: B256, prev_execution_outcome: &ExecutionOutcome, -) -> (SealedBlockWithSenders, ExecutionOutcome) { +) -> (RecoveredBlock, ExecutionOutcome) { let address_range = 1..=20; let slot_range = 1..=100; @@ -546,17 +530,13 @@ fn block5( extended.extend(execution_outcome.clone()); let state_root = bundle_state_root(&extended); - let (header, mut body) = TEST_BLOCK.clone().split(); + let (mut header, mut body) = TEST_BLOCK.clone().split_header_body(); body.withdrawals = Some(Withdrawals::new(vec![Withdrawal::default()])); - let mut header = header.unseal(); header.number = number; header.state_root = state_root; // parent_hash points to block1 hash header.parent_hash = parent_hash; - let block = SealedBlock::new(SealedHeader::seal(header), body); + let block = SealedBlock::seal_parts(header, body); - ( - SealedBlockWithSenders::new_unchecked(block, vec![Address::new([0x31; 20])]), - execution_outcome, - ) + (RecoveredBlock::new_sealed(block, vec![Address::new([0x31; 20])]), execution_outcome) } diff --git a/crates/storage/provider/src/test_utils/mock.rs b/crates/storage/provider/src/test_utils/mock.rs index 362bbc32df..8c3b6422e9 100644 --- a/crates/storage/provider/src/test_utils/mock.rs +++ b/crates/storage/provider/src/test_utils/mock.rs @@ -19,8 +19,8 @@ use reth_db_api::models::{AccountBeforeTx, StoredBlockBodyIndices}; use reth_execution_types::ExecutionOutcome; use reth_node_types::NodeTypes; use reth_primitives::{ - Account, Block, BlockWithSenders, Bytecode, EthPrimitives, GotExpected, Receipt, SealedBlock, - SealedBlockWithSenders, SealedHeader, TransactionSigned, + Account, Block, Bytecode, EthPrimitives, GotExpected, Receipt, RecoveredBlock, SealedBlock, + SealedHeader, TransactionSigned, }; use reth_primitives_traits::SignedTransaction; use reth_stages_types::{StageCheckpoint, StageId}; @@ -220,7 +220,7 @@ impl HeaderProvider for MockEthProvider { } fn sealed_header(&self, number: BlockNumber) -> ProviderResult> { - Ok(self.header_by_number(number)?.map(SealedHeader::seal)) + Ok(self.header_by_number(number)?.map(SealedHeader::seal_slow)) } fn sealed_headers_while( @@ -231,7 +231,7 @@ impl HeaderProvider for MockEthProvider { Ok(self .headers_range(range)? .into_iter() - .map(SealedHeader::seal) + .map(SealedHeader::seal_slow) .take_while(|h| predicate(h)) .collect()) } @@ -497,7 +497,9 @@ impl BlockReader for MockEthProvider { Ok(None) } - fn pending_block_with_senders(&self) -> ProviderResult> { + fn pending_block_with_senders( + &self, + ) -> ProviderResult>> { Ok(None) } @@ -509,7 +511,7 @@ impl BlockReader for MockEthProvider { &self, _id: BlockHashOrNumber, _transaction_kind: TransactionVariant, - ) -> ProviderResult> { + ) -> ProviderResult>> { Ok(None) } @@ -517,7 +519,7 @@ impl BlockReader for MockEthProvider { &self, _id: BlockHashOrNumber, _transaction_kind: TransactionVariant, - ) -> ProviderResult> { + ) -> ProviderResult>> { Ok(None) } @@ -534,14 +536,14 @@ impl BlockReader for MockEthProvider { fn block_with_senders_range( &self, _range: RangeInclusive, - ) -> ProviderResult> { + ) -> ProviderResult>> { Ok(vec![]) } fn sealed_block_with_senders_range( &self, _range: RangeInclusive, - ) -> ProviderResult> { + ) -> ProviderResult>> { Ok(vec![]) } } @@ -555,7 +557,7 @@ impl BlockReaderIdExt for MockEthProvider { } fn sealed_header_by_id(&self, id: BlockId) -> ProviderResult> { - self.header_by_id(id)?.map_or_else(|| Ok(None), |h| Ok(Some(SealedHeader::seal(h)))) + self.header_by_id(id)?.map_or_else(|| Ok(None), |h| Ok(Some(SealedHeader::seal_slow(h)))) } fn header_by_id(&self, id: BlockId) -> ProviderResult> { diff --git a/crates/storage/provider/src/traits/block.rs b/crates/storage/provider/src/traits/block.rs index a0b9657e40..6116cfdd04 100644 --- a/crates/storage/provider/src/traits/block.rs +++ b/crates/storage/provider/src/traits/block.rs @@ -2,7 +2,7 @@ use alloy_primitives::BlockNumber; use reth_db_api::models::StoredBlockBodyIndices; use reth_execution_types::{Chain, ExecutionOutcome}; use reth_node_types::NodePrimitives; -use reth_primitives::SealedBlockWithSenders; +use reth_primitives::RecoveredBlock; use reth_storage_api::{NodePrimitivesProvider, StorageLocation}; use reth_storage_errors::provider::ProviderResult; use reth_trie::{updates::TrieUpdates, HashedPostStateSorted}; @@ -85,7 +85,7 @@ pub trait BlockWriter: Send + Sync { /// written. fn insert_block( &self, - block: SealedBlockWithSenders, + block: RecoveredBlock, write_to: StorageLocation, ) -> ProviderResult; @@ -124,7 +124,7 @@ pub trait BlockWriter: Send + Sync { /// /// # Parameters /// - /// - `blocks`: Vector of `SealedBlockWithSenders` instances to append. + /// - `blocks`: Vector of `RecoveredBlock` instances to append. /// - `state`: Post-state information to update after appending. /// /// # Returns @@ -132,7 +132,7 @@ pub trait BlockWriter: Send + Sync { /// Returns `Ok(())` on success, or an error if any operation fails. fn append_blocks_with_state( &self, - blocks: Vec>, + blocks: Vec>, execution_outcome: &ExecutionOutcome, hashed_state: HashedPostStateSorted, trie_updates: TrieUpdates, diff --git a/crates/storage/provider/src/traits/header_sync_gap.rs b/crates/storage/provider/src/traits/header_sync_gap.rs index b572750d4a..f9e628513e 100644 --- a/crates/storage/provider/src/traits/header_sync_gap.rs +++ b/crates/storage/provider/src/traits/header_sync_gap.rs @@ -1,6 +1,6 @@ use alloy_consensus::{BlockHeader, Header}; use alloy_eips::BlockHashOrNumber; -use alloy_primitives::{BlockNumber, B256}; +use alloy_primitives::{BlockNumber, Sealable, B256}; use reth_network_p2p::headers::downloader::SyncTarget; use reth_primitives::SealedHeader; use reth_storage_errors::provider::ProviderResult; @@ -16,7 +16,7 @@ pub struct HeaderSyncGap { pub target: SyncTarget, } -impl HeaderSyncGap { +impl HeaderSyncGap { /// Returns `true` if the gap from the head to the target was closed #[inline] pub fn is_closed(&self) -> bool { diff --git a/crates/storage/storage-api/src/block.rs b/crates/storage/storage-api/src/block.rs index 5e55042a76..23c0f8460a 100644 --- a/crates/storage/storage-api/src/block.rs +++ b/crates/storage/storage-api/src/block.rs @@ -4,7 +4,7 @@ use crate::{ }; use alloy_eips::{BlockHashOrNumber, BlockId, BlockNumberOrTag}; use alloy_primitives::{BlockNumber, B256}; -use reth_primitives::{BlockWithSenders, SealedBlockFor, SealedBlockWithSenders, SealedHeader}; +use reth_primitives::{RecoveredBlock, SealedBlock, SealedHeader}; use reth_storage_errors::provider::ProviderResult; use std::ops::RangeInclusive; @@ -81,23 +81,21 @@ pub trait BlockReader: /// Returns the pending block if available /// - /// Note: This returns a [`SealedBlockFor`] because it's expected that this is sealed by the + /// Note: This returns a [`SealedBlock`] because it's expected that this is sealed by the /// provider and the caller does not know the hash. - fn pending_block(&self) -> ProviderResult>>; + fn pending_block(&self) -> ProviderResult>>; /// Returns the pending block if available /// - /// Note: This returns a [`SealedBlockWithSenders`] because it's expected that this is sealed by + /// Note: This returns a [`RecoveredBlock`] because it's expected that this is sealed by /// the provider and the caller does not know the hash. - fn pending_block_with_senders( - &self, - ) -> ProviderResult>>; + fn pending_block_with_senders(&self) -> ProviderResult>>; /// Returns the pending block and receipts if available. #[allow(clippy::type_complexity)] fn pending_block_and_receipts( &self, - ) -> ProviderResult, Vec)>>; + ) -> ProviderResult, Vec)>>; /// Returns the block with matching hash from the database. /// @@ -122,7 +120,7 @@ pub trait BlockReader: &self, id: BlockHashOrNumber, transaction_kind: TransactionVariant, - ) -> ProviderResult>>; + ) -> ProviderResult>>; /// Returns the sealed block with senders with matching number or hash from database. /// @@ -133,7 +131,7 @@ pub trait BlockReader: &self, id: BlockHashOrNumber, transaction_kind: TransactionVariant, - ) -> ProviderResult>>; + ) -> ProviderResult>>; /// Returns all blocks in the given inclusive range. /// @@ -145,14 +143,14 @@ pub trait BlockReader: fn block_with_senders_range( &self, range: RangeInclusive, - ) -> ProviderResult>>; + ) -> ProviderResult>>; /// Returns a range of sealed blocks from the database, along with the senders of each /// transaction in the blocks. fn sealed_block_with_senders_range( &self, range: RangeInclusive, - ) -> ProviderResult>>; + ) -> ProviderResult>>; } impl BlockReader for std::sync::Arc { @@ -168,17 +166,15 @@ impl BlockReader for std::sync::Arc { fn block(&self, id: BlockHashOrNumber) -> ProviderResult> { T::block(self, id) } - fn pending_block(&self) -> ProviderResult>> { + fn pending_block(&self) -> ProviderResult>> { T::pending_block(self) } - fn pending_block_with_senders( - &self, - ) -> ProviderResult>> { + fn pending_block_with_senders(&self) -> ProviderResult>> { T::pending_block_with_senders(self) } fn pending_block_and_receipts( &self, - ) -> ProviderResult, Vec)>> { + ) -> ProviderResult, Vec)>> { T::pending_block_and_receipts(self) } fn block_by_hash(&self, hash: B256) -> ProviderResult> { @@ -191,14 +187,14 @@ impl BlockReader for std::sync::Arc { &self, id: BlockHashOrNumber, transaction_kind: TransactionVariant, - ) -> ProviderResult>> { + ) -> ProviderResult>> { T::block_with_senders(self, id, transaction_kind) } fn sealed_block_with_senders( &self, id: BlockHashOrNumber, transaction_kind: TransactionVariant, - ) -> ProviderResult>> { + ) -> ProviderResult>> { T::sealed_block_with_senders(self, id, transaction_kind) } fn block_range(&self, range: RangeInclusive) -> ProviderResult> { @@ -207,13 +203,13 @@ impl BlockReader for std::sync::Arc { fn block_with_senders_range( &self, range: RangeInclusive, - ) -> ProviderResult>> { + ) -> ProviderResult>> { T::block_with_senders_range(self, range) } fn sealed_block_with_senders_range( &self, range: RangeInclusive, - ) -> ProviderResult>> { + ) -> ProviderResult>> { T::sealed_block_with_senders_range(self, range) } } @@ -231,17 +227,15 @@ impl BlockReader for &T { fn block(&self, id: BlockHashOrNumber) -> ProviderResult> { T::block(self, id) } - fn pending_block(&self) -> ProviderResult>> { + fn pending_block(&self) -> ProviderResult>> { T::pending_block(self) } - fn pending_block_with_senders( - &self, - ) -> ProviderResult>> { + fn pending_block_with_senders(&self) -> ProviderResult>> { T::pending_block_with_senders(self) } fn pending_block_and_receipts( &self, - ) -> ProviderResult, Vec)>> { + ) -> ProviderResult, Vec)>> { T::pending_block_and_receipts(self) } fn block_by_hash(&self, hash: B256) -> ProviderResult> { @@ -254,14 +248,14 @@ impl BlockReader for &T { &self, id: BlockHashOrNumber, transaction_kind: TransactionVariant, - ) -> ProviderResult>> { + ) -> ProviderResult>> { T::block_with_senders(self, id, transaction_kind) } fn sealed_block_with_senders( &self, id: BlockHashOrNumber, transaction_kind: TransactionVariant, - ) -> ProviderResult>> { + ) -> ProviderResult>> { T::sealed_block_with_senders(self, id, transaction_kind) } fn block_range(&self, range: RangeInclusive) -> ProviderResult> { @@ -270,13 +264,13 @@ impl BlockReader for &T { fn block_with_senders_range( &self, range: RangeInclusive, - ) -> ProviderResult>> { + ) -> ProviderResult>> { T::block_with_senders_range(self, range) } fn sealed_block_with_senders_range( &self, range: RangeInclusive, - ) -> ProviderResult>> { + ) -> ProviderResult>> { T::sealed_block_with_senders_range(self, range) } } @@ -345,7 +339,7 @@ pub trait BlockReaderIdExt: BlockReader + ReceiptProviderIdExt { &self, id: BlockId, transaction_kind: TransactionVariant, - ) -> ProviderResult>> { + ) -> ProviderResult>> { match id { BlockId::Hash(hash) => { self.block_with_senders(hash.block_hash.into(), transaction_kind) @@ -377,7 +371,7 @@ pub trait BlockReaderIdExt: BlockReader + ReceiptProviderIdExt { ) -> ProviderResult>> { self.convert_block_number(id)? .map_or_else(|| Ok(None), |num| self.header_by_hash_or_number(num.into()))? - .map_or_else(|| Ok(None), |h| Ok(Some(SealedHeader::seal(h)))) + .map_or_else(|| Ok(None), |h| Ok(Some(SealedHeader::seal_slow(h)))) } /// Returns the sealed header with the matching `BlockId` from the database. diff --git a/crates/storage/storage-api/src/noop.rs b/crates/storage/storage-api/src/noop.rs index 3e6ed7dbd5..a88fbbdd9e 100644 --- a/crates/storage/storage-api/src/noop.rs +++ b/crates/storage/storage-api/src/noop.rs @@ -16,7 +16,7 @@ use alloy_primitives::{ }; use reth_chainspec::{ChainInfo, ChainSpecProvider, EthChainSpec, MAINNET}; use reth_db_models::{AccountBeforeTx, StoredBlockBodyIndices}; -use reth_primitives::{BlockWithSenders, EthPrimitives, SealedBlockFor, SealedBlockWithSenders}; +use reth_primitives::{EthPrimitives, RecoveredBlock, SealedBlock}; use reth_primitives_traits::{Account, Bytecode, NodePrimitives, SealedHeader}; use reth_prune_types::{PruneCheckpoint, PruneSegment}; use reth_stages_types::{StageCheckpoint, StageId}; @@ -165,19 +165,17 @@ impl BlockReader for NoopProvider { Ok(None) } - fn pending_block(&self) -> ProviderResult>> { + fn pending_block(&self) -> ProviderResult>> { Ok(None) } - fn pending_block_with_senders( - &self, - ) -> ProviderResult>> { + fn pending_block_with_senders(&self) -> ProviderResult>> { Ok(None) } fn pending_block_and_receipts( &self, - ) -> ProviderResult, Vec)>> { + ) -> ProviderResult, Vec)>> { Ok(None) } @@ -185,7 +183,7 @@ impl BlockReader for NoopProvider { &self, _id: BlockHashOrNumber, _transaction_kind: TransactionVariant, - ) -> ProviderResult>> { + ) -> ProviderResult>> { Ok(None) } @@ -193,7 +191,7 @@ impl BlockReader for NoopProvider { &self, _id: BlockHashOrNumber, _transaction_kind: TransactionVariant, - ) -> ProviderResult>> { + ) -> ProviderResult>> { Ok(None) } @@ -204,14 +202,14 @@ impl BlockReader for NoopProvider { fn block_with_senders_range( &self, _range: RangeInclusive, - ) -> ProviderResult>> { + ) -> ProviderResult>> { Ok(vec![]) } fn sealed_block_with_senders_range( &self, _range: RangeInclusive, - ) -> ProviderResult>> { + ) -> ProviderResult>> { Ok(vec![]) } } diff --git a/crates/transaction-pool/src/blobstore/tracker.rs b/crates/transaction-pool/src/blobstore/tracker.rs index de51b87c82..fee9a13eb8 100644 --- a/crates/transaction-pool/src/blobstore/tracker.rs +++ b/crates/transaction-pool/src/blobstore/tracker.rs @@ -92,8 +92,7 @@ mod tests { use alloy_primitives::PrimitiveSignature as Signature; use reth_execution_types::Chain; use reth_primitives::{ - BlockBody, SealedBlock, SealedBlockWithSenders, SealedHeader, Transaction, - TransactionSigned, + BlockBody, RecoveredBlock, SealedBlock, SealedHeader, Transaction, TransactionSigned, }; use super::*; @@ -127,8 +126,8 @@ mod tests { let tx3_hash = B256::random(); // Non-EIP-4844 transaction // Creating a first block with EIP-4844 transactions - let block1 = SealedBlockWithSenders::new_unchecked( - SealedBlock::new( + let block1 = RecoveredBlock::new_sealed( + SealedBlock::from_sealed_parts( SealedHeader::new(Header { number: 10, ..Default::default() }, B256::random()), BlockBody { transactions: vec![ @@ -157,8 +156,8 @@ mod tests { // Creating a second block with EIP-1559 and EIP-2930 transactions // Note: This block does not contain any EIP-4844 transactions - let block2 = SealedBlockWithSenders::new_unchecked( - SealedBlock::new( + let block2 = RecoveredBlock::new_sealed( + SealedBlock::from_sealed_parts( SealedHeader::new(Header { number: 11, ..Default::default() }, B256::random()), BlockBody { transactions: vec![ diff --git a/crates/transaction-pool/src/lib.rs b/crates/transaction-pool/src/lib.rs index 56fe99421d..c85d84a80a 100644 --- a/crates/transaction-pool/src/lib.rs +++ b/crates/transaction-pool/src/lib.rs @@ -177,7 +177,7 @@ use aquamarine as _; use reth_eth_wire_types::HandleMempoolData; use reth_execution_types::ChangedAccount; use reth_primitives::RecoveredTx; -use reth_primitives_traits::{BlockBody, BlockHeader}; +use reth_primitives_traits::Block; use reth_storage_api::StateProviderFactory; use std::{collections::HashSet, sync::Arc}; use tokio::sync::mpsc::Receiver; @@ -614,10 +614,9 @@ where self.pool.set_block_info(info) } - fn on_canonical_state_change(&self, update: CanonicalStateUpdate<'_, H, B>) + fn on_canonical_state_change(&self, update: CanonicalStateUpdate<'_, B>) where - H: BlockHeader, - B: BlockBody, + B: Block, { self.pool.on_canonical_state_change(update); } diff --git a/crates/transaction-pool/src/maintain.rs b/crates/transaction-pool/src/maintain.rs index 583b291685..af8e8da33c 100644 --- a/crates/transaction-pool/src/maintain.rs +++ b/crates/transaction-pool/src/maintain.rs @@ -108,7 +108,7 @@ pub async fn maintain_transaction_pool( let MaintainPoolConfig { max_update_depth, max_reload_accounts, .. } = config; // ensure the pool points to latest state if let Ok(Some(latest)) = client.header_by_number_or_tag(BlockNumberOrTag::Latest) { - let latest = SealedHeader::seal(latest); + let latest = SealedHeader::seal_slow(latest); let chain_spec = client.chain_spec(); let info = BlockInfo { block_gas_limit: latest.gas_limit(), @@ -272,11 +272,13 @@ pub async fn maintain_transaction_pool( // fees for the next block: `new_tip+1` let pending_block_base_fee = new_tip + .header() .next_block_base_fee( chain_spec.base_fee_params_at_timestamp(new_tip.timestamp() + 12), ) .unwrap_or_default(); - let pending_block_blob_fee = new_tip.next_block_blob_fee(BlobParams::cancun()); + let pending_block_blob_fee = + new_tip.header().next_block_blob_fee(BlobParams::cancun()); // we know all changed account in the new chain let new_changed_accounts: HashSet<_> = @@ -346,7 +348,7 @@ pub async fn maintain_transaction_pool( // update the pool first let update = CanonicalStateUpdate { - new_tip: &new_tip.block, + new_tip: new_tip.sealed_block(), pending_block_base_fee, pending_block_blob_fee, changed_accounts, @@ -375,11 +377,12 @@ pub async fn maintain_transaction_pool( // fees for the next block: `tip+1` let pending_block_base_fee = tip + .header() .next_block_base_fee( chain_spec.base_fee_params_at_timestamp(tip.timestamp() + 12), ) .unwrap_or_default(); - let pending_block_blob_fee = tip.next_block_blob_fee(BlobParams::cancun()); + let pending_block_blob_fee = tip.header().next_block_blob_fee(BlobParams::cancun()); let first_block = blocks.first(); trace!( @@ -397,7 +400,7 @@ pub async fn maintain_transaction_pool( maintained_state = MaintainedPoolState::Drifted; debug!(target: "txpool", ?depth, "skipping deep canonical update"); let info = BlockInfo { - block_gas_limit: tip.gas_limit(), + block_gas_limit: tip.header().gas_limit(), last_seen_block_hash: tip.hash(), last_seen_block_number: tip.number(), pending_basefee: pending_block_base_fee, @@ -430,7 +433,7 @@ pub async fn maintain_transaction_pool( // Canonical update let update = CanonicalStateUpdate { - new_tip: &tip.block, + new_tip: tip.sealed_block(), pending_block_base_fee, pending_block_blob_fee, changed_accounts, diff --git a/crates/transaction-pool/src/pool/mod.rs b/crates/transaction-pool/src/pool/mod.rs index a7c16d05aa..983a86306c 100644 --- a/crates/transaction-pool/src/pool/mod.rs +++ b/crates/transaction-pool/src/pool/mod.rs @@ -109,7 +109,7 @@ pub use events::{FullTransactionEvent, TransactionEvent}; pub use listener::{AllTransactionsEvents, TransactionEvents}; pub use parked::{BasefeeOrd, ParkedOrd, ParkedPool, QueuedOrd}; pub use pending::PendingPool; -use reth_primitives_traits::{BlockBody, BlockHeader}; +use reth_primitives_traits::Block; mod best; mod blob; @@ -379,10 +379,9 @@ where } /// Updates the entire pool after a new block was executed. - pub fn on_canonical_state_change(&self, update: CanonicalStateUpdate<'_, H, B>) + pub fn on_canonical_state_change(&self, update: CanonicalStateUpdate<'_, B>) where - H: BlockHeader, - B: BlockBody, + B: Block, { trace!(target: "txpool", ?update, "updating pool on canonical state change"); diff --git a/crates/transaction-pool/src/traits.rs b/crates/transaction-pool/src/traits.rs index 862ecc15a7..f7e2f310e8 100644 --- a/crates/transaction-pool/src/traits.rs +++ b/crates/transaction-pool/src/traits.rs @@ -23,7 +23,7 @@ use reth_primitives::{ transaction::{SignedTransactionIntoRecoveredExt, TryFromRecoveredTransactionError}, PooledTransaction, RecoveredTx, SealedBlock, Transaction, TransactionSigned, }; -use reth_primitives_traits::{BlockBody, SignedTransaction}; +use reth_primitives_traits::{Block, SignedTransaction}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; use std::{ @@ -518,10 +518,9 @@ pub trait TransactionPoolExt: TransactionPool { /// sidecar must not be removed from the blob store. Only after a blob transaction is /// finalized, its sidecar is removed from the blob store. This ensures that in case of a reorg, /// the sidecar is still available. - fn on_canonical_state_change(&self, update: CanonicalStateUpdate<'_, H, B>) + fn on_canonical_state_change(&self, update: CanonicalStateUpdate<'_, B>) where - H: reth_primitives_traits::BlockHeader, - B: BlockBody; + B: Block; /// Updates the accounts in the pool fn update_accounts(&self, accounts: Vec); @@ -721,9 +720,9 @@ pub enum PoolUpdateKind { /// /// This is used to update the pool state accordingly. #[derive(Clone, Debug)] -pub struct CanonicalStateUpdate<'a, H, B> { +pub struct CanonicalStateUpdate<'a, B: Block> { /// Hash of the tip block. - pub new_tip: &'a SealedBlock, + pub new_tip: &'a SealedBlock, /// EIP-1559 Base fee of the _next_ (pending) block /// /// The base fee of a block depends on the utilization of the last block and its base fee. @@ -740,9 +739,9 @@ pub struct CanonicalStateUpdate<'a, H, B> { pub update_kind: PoolUpdateKind, } -impl CanonicalStateUpdate<'_, H, B> +impl CanonicalStateUpdate<'_, B> where - H: BlockHeader, + B: Block, { /// Returns the number of the tip block. pub fn number(&self) -> u64 { @@ -750,7 +749,7 @@ where } /// Returns the hash of the tip block. - pub const fn hash(&self) -> B256 { + pub fn hash(&self) -> B256 { self.new_tip.hash() } @@ -771,9 +770,9 @@ where } } -impl fmt::Display for CanonicalStateUpdate<'_, H, B> +impl fmt::Display for CanonicalStateUpdate<'_, B> where - H: BlockHeader, + B: Block, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("CanonicalStateUpdate") diff --git a/crates/transaction-pool/src/validate/eth.rs b/crates/transaction-pool/src/validate/eth.rs index f6733a5c1a..ba5b38c484 100644 --- a/crates/transaction-pool/src/validate/eth.rs +++ b/crates/transaction-pool/src/validate/eth.rs @@ -24,7 +24,7 @@ use alloy_eips::{ }; use reth_chainspec::{ChainSpec, EthereumHardforks}; use reth_primitives::{InvalidTransactionError, SealedBlock}; -use reth_primitives_traits::{BlockBody, GotExpected}; +use reth_primitives_traits::{Block, GotExpected}; use reth_storage_api::{StateProvider, StateProviderFactory}; use reth_tasks::TaskSpawner; use std::{ @@ -106,10 +106,9 @@ where self.validate_all(transactions) } - fn on_new_head_block(&self, new_tip_block: &SealedBlock) + fn on_new_head_block(&self, new_tip_block: &SealedBlock) where - H: reth_primitives_traits::BlockHeader, - B: BlockBody, + B: Block, { self.inner.on_new_head_block(new_tip_block.header()) } diff --git a/crates/transaction-pool/src/validate/mod.rs b/crates/transaction-pool/src/validate/mod.rs index cb8f98660c..a567bdbe58 100644 --- a/crates/transaction-pool/src/validate/mod.rs +++ b/crates/transaction-pool/src/validate/mod.rs @@ -26,7 +26,7 @@ pub use task::{TransactionValidationTaskExecutor, ValidationTask}; pub use constants::{ DEFAULT_MAX_TX_INPUT_BYTES, MAX_CODE_BYTE_SIZE, MAX_INIT_CODE_BYTE_SIZE, TX_SLOT_BYTE_SIZE, }; -use reth_primitives_traits::{BlockBody, BlockHeader}; +use reth_primitives_traits::Block; /// A Result type returned after checking a transaction's validity. #[derive(Debug)] @@ -207,10 +207,9 @@ pub trait TransactionValidator: Send + Sync { /// Invoked when the head block changes. /// /// This can be used to update fork specific values (timestamp). - fn on_new_head_block(&self, _new_tip_block: &SealedBlock) + fn on_new_head_block(&self, _new_tip_block: &SealedBlock) where - H: BlockHeader, - B: BlockBody, + B: Block, { } } @@ -243,10 +242,9 @@ where } } - fn on_new_head_block(&self, new_tip_block: &SealedBlock) + fn on_new_head_block(&self, new_tip_block: &SealedBlock) where - H: BlockHeader, - Body: BlockBody, + Bl: Block, { match self { Self::Left(v) => v.on_new_head_block(new_tip_block), diff --git a/crates/transaction-pool/src/validate/task.rs b/crates/transaction-pool/src/validate/task.rs index 766752ef4b..22cc84bd9d 100644 --- a/crates/transaction-pool/src/validate/task.rs +++ b/crates/transaction-pool/src/validate/task.rs @@ -9,7 +9,7 @@ use crate::{ use futures_util::{lock::Mutex, StreamExt}; use reth_chainspec::ChainSpec; use reth_primitives::SealedBlock; -use reth_primitives_traits::{BlockBody, BlockHeader}; +use reth_primitives_traits::Block; use reth_tasks::TaskSpawner; use std::{future::Future, pin::Pin, sync::Arc}; use tokio::{ @@ -206,10 +206,9 @@ where } } - fn on_new_head_block(&self, new_tip_block: &SealedBlock) + fn on_new_head_block(&self, new_tip_block: &SealedBlock) where - H: BlockHeader, - B: BlockBody, + B: Block, { self.validator.on_new_head_block(new_tip_block) } diff --git a/examples/beacon-api-sidecar-fetcher/src/mined_sidecar.rs b/examples/beacon-api-sidecar-fetcher/src/mined_sidecar.rs index c7f0083fe3..32a4e910ae 100644 --- a/examples/beacon-api-sidecar-fetcher/src/mined_sidecar.rs +++ b/examples/beacon-api-sidecar-fetcher/src/mined_sidecar.rs @@ -1,6 +1,6 @@ use crate::BeaconSidecarConfig; use alloy_consensus::{ - transaction::PooledTransaction, Signed, Transaction as _, TxEip4844WithSidecar, + transaction::PooledTransaction, BlockHeader, Signed, Transaction as _, TxEip4844WithSidecar, }; use alloy_primitives::B256; use alloy_rpc_types_beacon::sidecar::{BeaconBlobBundle, SidecarIterator}; @@ -8,7 +8,7 @@ use eyre::Result; use futures_util::{stream::FuturesUnordered, Future, Stream, StreamExt}; use reqwest::{Error, StatusCode}; use reth::{ - primitives::SealedBlockWithSenders, + primitives::RecoveredBlock, providers::CanonStateNotification, transaction_pool::{BlobStoreError, TransactionPoolExt}, }; @@ -97,10 +97,10 @@ where St: Stream + Send + Unpin + 'static, P: TransactionPoolExt + Unpin + 'static, { - fn process_block(&mut self, block: &SealedBlockWithSenders) { + fn process_block(&mut self, block: &RecoveredBlock) { let txs: Vec<_> = block + .body() .transactions() - .iter() .filter(|tx| tx.is_eip4844()) .map(|tx| (tx.clone(), tx.blob_versioned_hashes().unwrap().len())) .collect(); @@ -195,17 +195,15 @@ where // handle reorged blocks for (_, block) in old.blocks().iter() { let txs: Vec = block + .body() .transactions() - .iter() - .filter(|tx: &&reth::primitives::TransactionSigned| { - tx.is_eip4844() - }) + .filter(|tx| tx.is_eip4844()) .map(|tx| { let transaction_hash = tx.hash(); let block_metadata = BlockMetadata { - block_hash: new.tip().block.hash(), - block_number: new.tip().block.number, - gas_used: new.tip().block.gas_used, + block_hash: new.tip().hash(), + block_number: new.tip().number(), + gas_used: new.tip().gas_used(), }; BlobTransactionEvent::Reorged(ReorgedBlob { transaction_hash, @@ -231,7 +229,7 @@ where async fn fetch_blobs_for_block( client: reqwest::Client, url: String, - block: SealedBlockWithSenders, + block: RecoveredBlock, txs: Vec<(reth::primitives::TransactionSigned, usize)>, ) -> Result, SideCarError> { let response = match client.get(url).header("Accept", "application/json").send().await { diff --git a/examples/custom-beacon-withdrawals/src/main.rs b/examples/custom-beacon-withdrawals/src/main.rs index 7d20b298f7..7bb8a77d25 100644 --- a/examples/custom-beacon-withdrawals/src/main.rs +++ b/examples/custom-beacon-withdrawals/src/main.rs @@ -3,6 +3,7 @@ #![cfg_attr(not(test), warn(unused_crate_dependencies))] +use alloy_consensus::BlockHeader; use alloy_eips::{eip4895::Withdrawal, eip7685::Requests}; use alloy_sol_macro::sol; use alloy_sol_types::SolCall; @@ -26,7 +27,7 @@ use reth_evm::execute::{ }; use reth_evm_ethereum::EthEvmConfig; use reth_node_ethereum::{node::EthereumAddOns, BasicBlockExecutorProvider, EthereumNode}; -use reth_primitives::{BlockWithSenders, EthPrimitives, Receipt}; +use reth_primitives::{EthPrimitives, Receipt, RecoveredBlock}; use std::{fmt::Display, sync::Arc}; pub const SYSTEM_ADDRESS: Address = address!("fffffffffffffffffffffffffffffffffffffffe"); @@ -125,10 +126,13 @@ where type Primitives = EthPrimitives; type Error = BlockExecutionError; - fn apply_pre_execution_changes(&mut self, block: &BlockWithSenders) -> Result<(), Self::Error> { + fn apply_pre_execution_changes( + &mut self, + block: &RecoveredBlock, + ) -> Result<(), Self::Error> { // Set state clear flag if the block is after the Spurious Dragon hardfork. let state_clear_flag = - (*self.chain_spec).is_spurious_dragon_active_at_block(block.header.number); + (*self.chain_spec).is_spurious_dragon_active_at_block(block.number()); self.state.set_state_clear_flag(state_clear_flag); Ok(()) @@ -136,19 +140,19 @@ where fn execute_transactions( &mut self, - _block: &BlockWithSenders, + _block: &RecoveredBlock, ) -> Result, Self::Error> { Ok(ExecuteOutput { receipts: vec![], gas_used: 0 }) } fn apply_post_execution_changes( &mut self, - block: &BlockWithSenders, + block: &RecoveredBlock, _receipts: &[Receipt], ) -> Result { - let mut evm = self.evm_config.evm_for_block(&mut self.state, &block.header); + let mut evm = self.evm_config.evm_for_block(&mut self.state, block.header()); - if let Some(withdrawals) = block.body.withdrawals.as_ref() { + if let Some(withdrawals) = block.body().withdrawals.as_ref() { apply_withdrawals_contract_call(withdrawals, &mut evm)?; } diff --git a/examples/custom-dev-node/src/main.rs b/examples/custom-dev-node/src/main.rs index 42bb83782a..7688c1ce2b 100644 --- a/examples/custom-dev-node/src/main.rs +++ b/examples/custom-dev-node/src/main.rs @@ -50,7 +50,7 @@ async fn main() -> eyre::Result<()> { let head = notifications.next().await.unwrap(); - let tx = &head.tip().transactions()[0]; + let tx = &head.tip().body().transactions().next().unwrap(); assert_eq!(tx.hash(), hash); println!("mined transaction: {hash}"); Ok(()) diff --git a/examples/custom-engine-types/src/main.rs b/examples/custom-engine-types/src/main.rs index ce25eedaac..2de7d3bf55 100644 --- a/examples/custom-engine-types/src/main.rs +++ b/examples/custom-engine-types/src/main.rs @@ -38,7 +38,7 @@ use reth::{ }, network::NetworkHandle, payload::ExecutionPayloadValidator, - primitives::{Block, EthPrimitives, SealedBlockFor, TransactionSigned}, + primitives::{Block, EthPrimitives, SealedBlock, TransactionSigned}, providers::{CanonStateSubscriptions, EthStorage, StateProviderFactory}, rpc::{ compat::engine::payload::block_to_payload, @@ -177,7 +177,7 @@ impl EngineTypes for CustomEngineTypes { type ExecutionPayloadEnvelopeV4 = ExecutionPayloadEnvelopeV4; fn block_to_payload( - block: SealedBlockFor< + block: SealedBlock< <::Primitives as reth_node_api::NodePrimitives>::Block, >, ) -> (ExecutionPayload, ExecutionPayloadSidecar) { @@ -211,7 +211,7 @@ impl PayloadValidator for CustomEngineValidator { &self, payload: ExecutionPayload, sidecar: ExecutionPayloadSidecar, - ) -> Result, PayloadError> { + ) -> Result, PayloadError> { self.inner.ensure_well_formed_payload(payload, sidecar) } } diff --git a/examples/custom-payload-builder/src/generator.rs b/examples/custom-payload-builder/src/generator.rs index 6620170fe8..76222e0ccd 100644 --- a/examples/custom-payload-builder/src/generator.rs +++ b/examples/custom-payload-builder/src/generator.rs @@ -1,6 +1,7 @@ use crate::job::EmptyBlockPayloadJob; use alloy_eips::BlockNumberOrTag; use reth::{ + api::Block, providers::{BlockReaderIdExt, BlockSource, StateProviderFactory}, tasks::TaskSpawner, transaction_pool::TransactionPool, @@ -8,7 +9,7 @@ use reth::{ use reth_basic_payload_builder::{BasicPayloadJobGeneratorConfig, PayloadBuilder, PayloadConfig}; use reth_node_api::PayloadBuilderAttributes; use reth_payload_builder::{PayloadBuilderError, PayloadJobGenerator}; -use reth_primitives::{BlockExt, SealedHeader}; +use reth_primitives::SealedHeader; use std::sync::Arc; /// The generator type that creates new jobs that builds empty blocks. diff --git a/examples/db-access/src/main.rs b/examples/db-access/src/main.rs index 4c4aaa2570..bda1ea26cd 100644 --- a/examples/db-access/src/main.rs +++ b/examples/db-access/src/main.rs @@ -5,7 +5,7 @@ use reth_chainspec::ChainSpecBuilder; use reth_db::{open_db_read_only, DatabaseEnv}; use reth_node_ethereum::EthereumNode; use reth_node_types::NodeTypesWithDBAdapter; -use reth_primitives::{BlockExt, SealedHeader, TransactionSigned}; +use reth_primitives::{SealedBlock, SealedHeader, TransactionSigned}; use reth_provider::{ providers::StaticFileProvider, AccountReader, BlockReader, BlockSource, HeaderProvider, ProviderFactory, ReceiptProvider, StateProvider, TransactionsProvider, @@ -64,7 +64,7 @@ fn header_provider_example(provider: T, number: u64) -> eyre: // We can convert a header to a sealed header which contains the hash w/o needing to re-compute // it every time. - let sealed_header = SealedHeader::seal(header); + let sealed_header = SealedHeader::seal_slow(header); // Can also query the header by hash! let header_by_hash = @@ -134,7 +134,7 @@ fn block_provider_example>( let block = provider.block(number.into())?.ok_or(eyre::eyre!("block num not found"))?; // Can seal the block to cache the hash, like the Header above. - let sealed_block = block.clone().seal_slow(); + let sealed_block = SealedBlock::seal_slow(block.clone()); // Can also query the block by hash directly let block_by_hash = provider diff --git a/testing/ef-tests/src/cases/blockchain_test.rs b/testing/ef-tests/src/cases/blockchain_test.rs index 7d80ec6c47..a3c168cb54 100644 --- a/testing/ef-tests/src/cases/blockchain_test.rs +++ b/testing/ef-tests/src/cases/blockchain_test.rs @@ -91,11 +91,11 @@ impl Case for BlockchainTestCase { // Insert initial test state into the provider. provider.insert_historical_block( - SealedBlock::new( + SealedBlock::::from_sealed_parts( case.genesis_block_header.clone().into(), BlockBody::default(), ) - .try_seal_with_senders() + .try_recover() .unwrap(), )?; case.pre.write_to_db(provider.tx_ref())?; @@ -111,10 +111,9 @@ impl Case for BlockchainTestCase { // Decode and insert blocks, creating a chain of blocks for the test case. let last_block = case.blocks.iter().try_fold(None, |_, block| { - let decoded = SealedBlock::decode(&mut block.rlp.as_ref())?; - provider.insert_historical_block( - decoded.clone().try_seal_with_senders().unwrap(), - )?; + let decoded = + SealedBlock::::decode(&mut block.rlp.as_ref())?; + provider.insert_historical_block(decoded.clone().try_recover().unwrap())?; Ok::, Error>(Some(decoded)) })?; provider diff --git a/testing/testing-utils/src/generators.rs b/testing/testing-utils/src/generators.rs index 9cf6515eb6..307ef1cda3 100644 --- a/testing/testing-utils/src/generators.rs +++ b/testing/testing-utils/src/generators.rs @@ -1,6 +1,6 @@ //! Generators for different data structures like block headers, block bodies and ranges of those. -use alloy_consensus::{Header, Transaction as _, TxLegacy}; +use alloy_consensus::{Block, Header, Transaction as _, TxLegacy}; use alloy_eips::{ eip1898::BlockWithParent, eip4895::{Withdrawal, Withdrawals}, @@ -16,7 +16,7 @@ use reth_primitives::{ TransactionSigned, }; -use reth_primitives_traits::crypto::secp256k1::sign_message; +use reth_primitives_traits::{crypto::secp256k1::sign_message, Block as _}; use secp256k1::{Keypair, Secp256k1}; use std::{ cmp::{max, min}, @@ -125,7 +125,7 @@ pub fn random_header(rng: &mut R, number: u64, parent: Option) -> parent_hash: parent.unwrap_or_default(), ..Default::default() }; - SealedHeader::seal(header) + SealedHeader::seal_slow(header) } /// Generates a random legacy [Transaction]. @@ -234,10 +234,11 @@ pub fn random_block(rng: &mut R, number: u64, block_params: BlockParams) ..Default::default() }; - SealedBlock::new( - SealedHeader::seal(header), - BlockBody { transactions, ommers, withdrawals: withdrawals.map(Withdrawals::new) }, - ) + Block { + header, + body: BlockBody { transactions, ommers, withdrawals: withdrawals.map(Withdrawals::new) }, + } + .seal_slow() } /// Generate a range of random blocks.