From 49c02c3b8e91fac28a4d5befa73e6146eb56c1e8 Mon Sep 17 00:00:00 2001 From: Oliver Nordbjerg Date: Fri, 19 Apr 2024 16:39:52 +0200 Subject: [PATCH] feat: send `CanonStateNotification`s from execution stage (#7578) --- Cargo.lock | 151 +++++++-------- bin/reth/Cargo.toml | 12 +- bin/reth/src/commands/debug_cmd/execution.rs | 2 + bin/reth/src/commands/debug_cmd/merkle.rs | 2 + bin/reth/src/commands/import.rs | 4 +- bin/reth/src/commands/stage/dump/merkle.rs | 2 + bin/reth/src/commands/stage/run.rs | 2 + bin/reth/src/commands/stage/unwind.rs | 2 + crates/consensus/beacon/Cargo.toml | 4 +- crates/consensus/beacon/src/engine/error.rs | 2 +- crates/consensus/beacon/src/engine/mod.rs | 2 +- crates/consensus/beacon/src/engine/sync.rs | 2 +- crates/exex/src/manager.rs | 20 ++ crates/node-builder/src/builder.rs | 6 +- crates/node-builder/src/setup.rs | 5 + crates/stages/Cargo.toml | 19 +- crates/stages/src/stages/execution.rs | 178 ++++++++---------- crates/stages/src/stages/mod.rs | 2 + .../bundle_state_with_receipts.rs | 8 +- .../src/providers/database/provider.rs | 7 +- .../storage/provider/src/traits/executor.rs | 8 +- 21 files changed, 246 insertions(+), 194 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d8bde9658..b7cee919e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -332,7 +332,7 @@ checksum = "1a047897373be4bbb0224c1afdabca92648dc57a9c9ef6e7b0be3aff7a859c83" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -471,7 +471,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", "syn-solidity", "tiny-keccak", ] @@ -489,7 +489,7 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.58", + "syn 2.0.60", "syn-solidity", ] @@ -652,7 +652,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -872,7 +872,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -883,7 +883,7 @@ checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -899,9 +899,9 @@ dependencies = [ [[package]] name = "aurora-engine-modexp" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfacad86e9e138fca0670949eb8ed4ffdf73a55bded8887efe0863cd1a3a6f70" +checksum = "0aef7712851e524f35fbbb74fa6599c5cd8692056a1c36f9ca0d2001b670e7e5" dependencies = [ "hex", "num", @@ -915,7 +915,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -1043,7 +1043,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.58", + "syn 2.0.60", "which", ] @@ -1240,7 +1240,7 @@ checksum = "6be9c93793b60dac381af475b98634d4b451e28336e72218cad9a20176218dbc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", "synstructure", ] @@ -1349,7 +1349,7 @@ checksum = "4da9a32f3fed317401fa3c862968128267c3106685286e15d5aaa3d7389c2f60" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -1452,9 +1452,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.37" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0d04d43504c61aa6c7531f1871dd0d418d91130162063b789da00fd7057a5e" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", @@ -1553,7 +1553,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -1990,7 +1990,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -2147,7 +2147,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.10.0", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -2180,7 +2180,7 @@ checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" dependencies = [ "darling_core 0.20.8", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -2286,7 +2286,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -2437,7 +2437,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -2634,7 +2634,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -2647,7 +2647,7 @@ dependencies = [ "num-traits", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -2658,7 +2658,7 @@ checksum = "6fd000fd6988e73bbe993ea3db9b1aa64906ab88766d654973924340c8cddb42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -2970,7 +2970,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -3471,9 +3471,9 @@ dependencies = [ [[package]] name = "hyper" -version = "1.2.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186548d73ac615b32a73aafe38fb4f56c0d340e110e5a200bcadbaf2e199263a" +checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" dependencies = [ "bytes", "futures-channel", @@ -3529,7 +3529,7 @@ dependencies = [ "futures-util", "http 1.1.0", "http-body 1.0.0", - "hyper 1.2.0", + "hyper 1.3.1", "pin-project-lite", "socket2 0.5.6", "tokio", @@ -3561,7 +3561,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -3711,7 +3711,7 @@ checksum = "d2abdd3a62551e8337af119c5899e600ca0c88ec8f23a46c60ba216c803dcf1a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -3933,9 +3933,9 @@ checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] name = "iri-string" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81669f3b77acd397a241a988f05190b1785cb83f0287d8fb3a05f0648405d65f" +checksum = "7f5f6c2df22c009ac44f6f1499308e7a3ac7ba42cd2378475cc691510e1eef1b" dependencies = [ "memchr", "serde", @@ -4092,7 +4092,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -4638,7 +4638,7 @@ checksum = "38b4faf00617defe497754acde3024865bc143d44a86799b24e191ecff91354f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -4778,7 +4778,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -5050,7 +5050,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -5340,7 +5340,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -5369,7 +5369,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -5544,12 +5544,12 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d3928fb5db768cb86f891ff014f0144589297e3c6a1aba6ed7cecfdace270c7" +checksum = "5ac2cf0f2e4f42b49f5ffd07dae8d746508ef7526c13940e5f524012ae6c6550" dependencies = [ "proc-macro2", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -5609,9 +5609,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.79" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" dependencies = [ "unicode-ident", ] @@ -6026,7 +6026,7 @@ dependencies = [ "http 1.1.0", "http-body 1.0.0", "http-body-util", - "hyper 1.2.0", + "hyper 1.3.1", "hyper-util", "ipnet", "js-sys", @@ -6096,6 +6096,7 @@ dependencies = [ "reth-discv4", "reth-downloaders", "reth-ethereum-payload-builder", + "reth-exex", "reth-interfaces", "reth-network", "reth-network-api", @@ -6200,6 +6201,7 @@ dependencies = [ "reth-rpc-types", "reth-rpc-types-compat", "reth-stages", + "reth-stages-api", "reth-static-file", "reth-tasks", "reth-tokio-util", @@ -6279,7 +6281,7 @@ dependencies = [ "proc-macro2", "quote", "similar-asserts", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -6729,7 +6731,7 @@ dependencies = [ "quote", "regex", "serial_test", - "syn 2.0.58", + "syn 2.0.60", "trybuild", ] @@ -7415,6 +7417,7 @@ dependencies = [ "reth-downloaders", "reth-etl", "reth-evm-ethereum", + "reth-exex", "reth-interfaces", "reth-primitives", "reth-provider", @@ -8182,9 +8185,9 @@ checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" [[package]] name = "serde" -version = "1.0.197" +version = "1.0.198" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc" dependencies = [ "serde_derive", ] @@ -8200,20 +8203,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.198" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] name = "serde_json" -version = "1.0.115" +version = "1.0.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" +checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" dependencies = [ "indexmap 2.2.6", "itoa", @@ -8280,7 +8283,7 @@ dependencies = [ "darling 0.20.8", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -8305,7 +8308,7 @@ checksum = "b93fb4adc70021ac1b47f7d45e8cc4169baaa7ea58483bc5b721d19a26202212" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -8647,7 +8650,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -8660,7 +8663,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -8728,9 +8731,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.58" +version = "2.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" +checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" dependencies = [ "proc-macro2", "quote", @@ -8746,7 +8749,7 @@ dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -8763,7 +8766,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -8855,7 +8858,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -8894,7 +8897,7 @@ checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -9052,7 +9055,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -9113,7 +9116,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.9", + "toml_edit 0.22.11", ] [[package]] @@ -9149,9 +9152,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.9" +version = "0.22.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4" +checksum = "fb686a972ccef8537b39eead3968b0e8616cb5040dbb9bba93007c8e07c9215f" dependencies = [ "indexmap 2.2.6", "serde", @@ -9265,7 +9268,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -9728,7 +9731,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", "wasm-bindgen-shared", ] @@ -9762,7 +9765,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -10121,7 +10124,7 @@ checksum = "9e6936f0cce458098a201c245a11bef556c6a0181129c7034d10d76d1ec3a2b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", "synstructure", ] @@ -10142,7 +10145,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -10162,7 +10165,7 @@ checksum = "e6a647510471d372f2e6c2e6b7219e44d8c574d24fdc11c610a61455782f18c3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", "synstructure", ] @@ -10183,7 +10186,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -10205,7 +10208,7 @@ checksum = "7b4e5997cbf58990550ef1f0e5124a05e47e1ebd33a84af25739be6031a62c20" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] diff --git a/bin/reth/Cargo.toml b/bin/reth/Cargo.toml index bf8922ccf..ea1ee87f0 100644 --- a/bin/reth/Cargo.toml +++ b/bin/reth/Cargo.toml @@ -17,6 +17,7 @@ workspace = true reth-config.workspace = true reth-primitives = { workspace = true, features = ["arbitrary", "clap"] } reth-db = { workspace = true, features = ["mdbx"] } +reth-exex.workspace = true reth-provider = { workspace = true } reth-revm.workspace = true reth-stages.workspace = true @@ -49,7 +50,9 @@ reth-trie = { workspace = true, features = ["metrics"] } reth-nippy-jar.workspace = true reth-node-api.workspace = true reth-node-ethereum.workspace = true -reth-node-optimism = { workspace = true, optional = true, features = ["optimism"] } +reth-node-optimism = { workspace = true, optional = true, features = [ + "optimism", +] } reth-node-core.workspace = true reth-node-builder.workspace = true reth-node-events.workspace = true @@ -81,7 +84,12 @@ ratatui = "0.25.0" human_bytes = "0.4.1" # async -tokio = { workspace = true, features = ["sync", "macros", "time", "rt-multi-thread"] } +tokio = { workspace = true, features = [ + "sync", + "macros", + "time", + "rt-multi-thread", +] } futures.workspace = true # misc diff --git a/bin/reth/src/commands/debug_cmd/execution.rs b/bin/reth/src/commands/debug_cmd/execution.rs index 839e037ef..10f485a73 100644 --- a/bin/reth/src/commands/debug_cmd/execution.rs +++ b/bin/reth/src/commands/debug_cmd/execution.rs @@ -19,6 +19,7 @@ use reth_downloaders::{ bodies::bodies::BodiesDownloaderBuilder, headers::reverse_headers::ReverseHeadersDownloaderBuilder, }; +use reth_exex::ExExManagerHandle; use reth_interfaces::{ consensus::Consensus, p2p::{bodies::client::BodiesClient, headers::client::HeadersClient}, @@ -142,6 +143,7 @@ impl Command { .max(stage_conf.account_hashing.clean_threshold) .max(stage_conf.storage_hashing.clean_threshold), config.prune.clone().map(|prune| prune.segments).unwrap_or_default(), + ExExManagerHandle::empty(), )), ) .build(provider_factory, static_file_producer); diff --git a/bin/reth/src/commands/debug_cmd/merkle.rs b/bin/reth/src/commands/debug_cmd/merkle.rs index 742e51c70..ed8783e96 100644 --- a/bin/reth/src/commands/debug_cmd/merkle.rs +++ b/bin/reth/src/commands/debug_cmd/merkle.rs @@ -15,6 +15,7 @@ use reth_beacon_consensus::BeaconConsensus; use reth_cli_runner::CliContext; use reth_config::Config; use reth_db::{cursor::DbCursorRO, init_db, tables, transaction::DbTx, DatabaseEnv}; +use reth_exex::ExExManagerHandle; use reth_interfaces::{consensus::Consensus, p2p::full_block::FullBlockClient}; use reth_network::NetworkHandle; use reth_network_api::NetworkInfo; @@ -211,6 +212,7 @@ impl Command { }, MERKLE_STAGE_DEFAULT_CLEAN_THRESHOLD, PruneModes::all(), + ExExManagerHandle::empty(), ); let mut account_hashing_stage = AccountHashingStage::default(); diff --git a/bin/reth/src/commands/import.rs b/bin/reth/src/commands/import.rs index d28ebcf40..dc3140924 100644 --- a/bin/reth/src/commands/import.rs +++ b/bin/reth/src/commands/import.rs @@ -19,6 +19,7 @@ use reth_downloaders::{ file_client::{ChunkedFileReader, FileClient, DEFAULT_BYTE_LEN_CHUNK_CHAIN_FILE}, headers::reverse_headers::ReverseHeadersDownloaderBuilder, }; +use reth_exex::ExExManagerHandle; use reth_interfaces::{ consensus::Consensus, p2p::{ @@ -272,7 +273,8 @@ impl ImportCommand { .clean_threshold .max(config.stages.account_hashing.clean_threshold) .max(config.stages.storage_hashing.clean_threshold), - config.prune.clone().map(|prune| prune.segments).unwrap_or_default(), + config.prune.as_ref().map(|prune| prune.segments.clone()).unwrap_or_default(), + ExExManagerHandle::empty(), )) .disable_all_if(STATE_STAGES, || no_state), ) diff --git a/bin/reth/src/commands/stage/dump/merkle.rs b/bin/reth/src/commands/stage/dump/merkle.rs index 32f828b32..08ac0a3aa 100644 --- a/bin/reth/src/commands/stage/dump/merkle.rs +++ b/bin/reth/src/commands/stage/dump/merkle.rs @@ -3,6 +3,7 @@ use crate::utils::DbTool; use eyre::Result; use reth_config::config::EtlConfig; use reth_db::{database::Database, table::TableImporter, tables, DatabaseEnv}; +use reth_exex::ExExManagerHandle; use reth_node_core::dirs::{ChainPath, DataDirPath}; use reth_node_ethereum::EthEvmConfig; use reth_primitives::{stage::StageCheckpoint, BlockNumber, PruneModes}; @@ -95,6 +96,7 @@ async fn unwind_and_copy( }, MERKLE_STAGE_DEFAULT_CLEAN_THRESHOLD, PruneModes::all(), + ExExManagerHandle::empty(), ); exec_stage.unwind( diff --git a/bin/reth/src/commands/stage/run.rs b/bin/reth/src/commands/stage/run.rs index b8f9bc527..43bbe7859 100644 --- a/bin/reth/src/commands/stage/run.rs +++ b/bin/reth/src/commands/stage/run.rs @@ -17,6 +17,7 @@ use reth_beacon_consensus::BeaconConsensus; use reth_config::{config::EtlConfig, Config}; use reth_db::init_db; use reth_downloaders::bodies::bodies::BodiesDownloaderBuilder; +use reth_exex::ExExManagerHandle; use reth_node_ethereum::EthEvmConfig; use reth_primitives::ChainSpec; use reth_provider::{ProviderFactory, StageCheckpointReader, StageCheckpointWriter}; @@ -239,6 +240,7 @@ impl Command { }, config.stages.merkle.clean_threshold, config.prune.map(|prune| prune.segments).unwrap_or_default(), + ExExManagerHandle::empty(), )), None, ) diff --git a/bin/reth/src/commands/stage/unwind.rs b/bin/reth/src/commands/stage/unwind.rs index 8e9141399..7810a4416 100644 --- a/bin/reth/src/commands/stage/unwind.rs +++ b/bin/reth/src/commands/stage/unwind.rs @@ -15,6 +15,7 @@ use reth_downloaders::{ bodies::bodies::BodiesDownloaderBuilder, headers::reverse_headers::ReverseHeadersDownloaderBuilder, }; +use reth_exex::ExExManagerHandle; use reth_interfaces::consensus::Consensus; use reth_node_core::{ args::{get_secret_key, NetworkArgs}, @@ -211,6 +212,7 @@ impl Command { .max(stage_conf.account_hashing.clean_threshold) .max(stage_conf.storage_hashing.clean_threshold), config.prune.clone().map(|prune| prune.segments).unwrap_or_default(), + ExExManagerHandle::empty(), )) .set(AccountHashingStage::default()) .set(StorageHashingStage::default()) diff --git a/crates/consensus/beacon/Cargo.toml b/crates/consensus/beacon/Cargo.toml index 60279a65a..f195c98bd 100644 --- a/crates/consensus/beacon/Cargo.toml +++ b/crates/consensus/beacon/Cargo.toml @@ -15,7 +15,7 @@ workspace = true reth-beacon-consensus-core.workspace = true reth-primitives.workspace = true reth-interfaces.workspace = true -reth-stages.workspace = true +reth-stages-api.workspace = true reth-db.workspace = true reth-provider.workspace = true reth-rpc-types.workspace = true @@ -65,5 +65,5 @@ optimism = [ "reth-interfaces/optimism", "reth-provider/optimism", "reth-blockchain-tree/optimism", - "reth-beacon-consensus-core/optimism" + "reth-beacon-consensus-core/optimism", ] diff --git a/crates/consensus/beacon/src/engine/error.rs b/crates/consensus/beacon/src/engine/error.rs index 925414e03..245199f53 100644 --- a/crates/consensus/beacon/src/engine/error.rs +++ b/crates/consensus/beacon/src/engine/error.rs @@ -1,7 +1,7 @@ use crate::engine::hooks::EngineHookError; use reth_interfaces::RethError; use reth_rpc_types::engine::ForkchoiceUpdateError; -use reth_stages::PipelineError; +use reth_stages_api::PipelineError; /// Beacon engine result. pub type BeaconEngineResult = Result; diff --git a/crates/consensus/beacon/src/engine/mod.rs b/crates/consensus/beacon/src/engine/mod.rs index 8a1a4266a..877e6f450 100644 --- a/crates/consensus/beacon/src/engine/mod.rs +++ b/crates/consensus/beacon/src/engine/mod.rs @@ -33,7 +33,7 @@ use reth_provider::{ use reth_rpc_types::engine::{ CancunPayloadFields, ExecutionPayload, PayloadStatus, PayloadStatusEnum, PayloadValidationError, }; -use reth_stages::{ControlFlow, Pipeline}; +use reth_stages_api::{ControlFlow, Pipeline}; use reth_tasks::TaskSpawner; use reth_tokio_util::EventListeners; use std::{ diff --git a/crates/consensus/beacon/src/engine/sync.rs b/crates/consensus/beacon/src/engine/sync.rs index 1c41c9ffe..96163e996 100644 --- a/crates/consensus/beacon/src/engine/sync.rs +++ b/crates/consensus/beacon/src/engine/sync.rs @@ -12,7 +12,7 @@ use reth_interfaces::p2p::{ headers::client::HeadersClient, }; use reth_primitives::{BlockNumber, ChainSpec, SealedBlock, B256}; -use reth_stages::{ControlFlow, Pipeline, PipelineError, PipelineWithResult}; +use reth_stages_api::{ControlFlow, Pipeline, PipelineError, PipelineWithResult}; use reth_tasks::TaskSpawner; use reth_tokio_util::EventListeners; use std::{ diff --git a/crates/exex/src/manager.rs b/crates/exex/src/manager.rs index 332650607..a89b09171 100644 --- a/crates/exex/src/manager.rs +++ b/crates/exex/src/manager.rs @@ -355,6 +355,26 @@ pub struct ExExManagerHandle { } impl ExExManagerHandle { + /// Creates an empty manager handle. + /// + /// Use this if there is no manager present. + /// + /// The handle will always be ready, and have a capacity of 0. + pub fn empty() -> Self { + let (exex_tx, _) = mpsc::unbounded_channel(); + let (_, is_ready_rx) = watch::channel(true); + let (_, finished_height_rx) = watch::channel(FinishedExExHeight::NoExExs); + + Self { + exex_tx, + num_exexs: 0, + is_ready_receiver: is_ready_rx.clone(), + is_ready: WatchStream::new(is_ready_rx), + current_capacity: Arc::new(AtomicUsize::new(0)), + finished_height: finished_height_rx, + } + } + /// Synchronously send a notification over the channel to all execution extensions. /// /// Senders should call [`Self::has_capacity`] first. diff --git a/crates/node-builder/src/builder.rs b/crates/node-builder/src/builder.rs index 7b84fad6b..161c8c404 100644 --- a/crates/node-builder/src/builder.rs +++ b/crates/node-builder/src/builder.rs @@ -27,7 +27,7 @@ use reth_db::{ test_utils::{create_test_rw_db, TempDatabase}, DatabaseEnv, }; -use reth_exex::{ExExContext, ExExHandle, ExExManager}; +use reth_exex::{ExExContext, ExExHandle, ExExManager, ExExManagerHandle}; use reth_interfaces::p2p::either::EitherDownloader; use reth_network::{NetworkBuilder, NetworkConfig, NetworkEvents, NetworkHandle}; use reth_node_api::{ @@ -711,6 +711,8 @@ where } // Configure the pipeline + let pipeline_exex_handle = + exex_manager_handle.clone().unwrap_or_else(ExExManagerHandle::empty); let (mut pipeline, client) = if config.dev.dev { info!(target: "reth::cli", "Starting Reth in dev mode"); @@ -743,6 +745,7 @@ where max_block, static_file_producer, evm_config, + pipeline_exex_handle, ) .await?; @@ -765,6 +768,7 @@ where max_block, static_file_producer, evm_config, + pipeline_exex_handle, ) .await?; diff --git a/crates/node-builder/src/setup.rs b/crates/node-builder/src/setup.rs index 827f711ce..bb67cad66 100644 --- a/crates/node-builder/src/setup.rs +++ b/crates/node-builder/src/setup.rs @@ -7,6 +7,7 @@ use reth_downloaders::{ bodies::bodies::BodiesDownloaderBuilder, headers::reverse_headers::ReverseHeadersDownloaderBuilder, }; +use reth_exex::ExExManagerHandle; use reth_interfaces::{ consensus::Consensus, p2p::{ @@ -49,6 +50,7 @@ pub async fn build_networked_pipeline( max_block: Option, static_file_producer: StaticFileProducer, evm_config: EvmConfig, + exex_manager_handle: ExExManagerHandle, ) -> eyre::Result> where DB: Database + Unpin + Clone + 'static, @@ -76,6 +78,7 @@ where prune_config, static_file_producer, evm_config, + exex_manager_handle, ) .await?; @@ -96,6 +99,7 @@ pub async fn build_pipeline( prune_config: Option, static_file_producer: StaticFileProducer, evm_config: EvmConfig, + exex_manager_handle: ExExManagerHandle, ) -> eyre::Result> where DB: Database + Clone + 'static, @@ -166,6 +170,7 @@ where .max(stage_config.account_hashing.clean_threshold) .max(stage_config.storage_hashing.clean_threshold), prune_modes.clone(), + exex_manager_handle, ) .with_metrics_tx(metrics_tx), ) diff --git a/crates/stages/Cargo.toml b/crates/stages/Cargo.toml index 00aff1fd6..080b7792d 100644 --- a/crates/stages/Cargo.toml +++ b/crates/stages/Cargo.toml @@ -13,6 +13,7 @@ workspace = true [dependencies] # reth +reth-exex.workspace = true reth-primitives.workspace = true reth-interfaces.workspace = true reth-db.workspace = true @@ -21,7 +22,7 @@ reth-provider.workspace = true reth-trie = { workspace = true, features = ["metrics"] } reth-etl.workspace = true reth-config.workspace = true -reth-stages-api = {workspace = true , features = ["test-utils"]} +reth-stages-api = { workspace = true, features = ["test-utils"] } # async tokio = { workspace = true, features = ["sync"] } @@ -35,7 +36,7 @@ thiserror.workspace = true itertools.workspace = true rayon.workspace = true num-traits = "0.2.15" -tempfile = { workspace = true, optional = true} +tempfile = { workspace = true, optional = true } [dev-dependencies] # reth @@ -64,10 +65,20 @@ criterion = { workspace = true, features = ["async_futures"] } serde_json.workspace = true [target.'cfg(not(target_os = "windows"))'.dev-dependencies] -pprof = { workspace = true, features = ["flamegraph", "frame-pointer", "criterion"] } +pprof = { workspace = true, features = [ + "flamegraph", + "frame-pointer", + "criterion", +] } [features] -test-utils = ["reth-interfaces/test-utils", "reth-db/test-utils", "reth-provider/test-utils", "reth-stages-api/test-utils", "dep:tempfile"] +test-utils = [ + "reth-interfaces/test-utils", + "reth-db/test-utils", + "reth-provider/test-utils", + "reth-stages-api/test-utils", + "dep:tempfile", +] [[bench]] name = "criterion" diff --git a/crates/stages/src/stages/execution.rs b/crates/stages/src/stages/execution.rs index 1bb21228e..ac48a2aeb 100644 --- a/crates/stages/src/stages/execution.rs +++ b/crates/stages/src/stages/execution.rs @@ -1,23 +1,20 @@ use crate::stages::MERKLE_STAGE_DEFAULT_CLEAN_THRESHOLD; use num_traits::Zero; use reth_db::{ - cursor::{DbCursorRO, DbCursorRW, DbDupCursorRO}, - database::Database, - models::BlockNumberAddress, - static_file::HeaderMask, - tables, - transaction::{DbTx, DbTxMut}, + cursor::DbCursorRO, database::Database, static_file::HeaderMask, tables, transaction::DbTx, }; +use reth_exex::ExExManagerHandle; use reth_primitives::{ stage::{ CheckpointBlockRange, EntitiesCheckpoint, ExecutionCheckpoint, StageCheckpoint, StageId, }, - BlockNumber, Header, PruneModes, StaticFileSegment, U256, + BlockNumber, Header, PruneModes, StaticFileSegment, }; use reth_provider::{ providers::{StaticFileProvider, StaticFileProviderRWRefMut, StaticFileWriter}, - BlockReader, DatabaseProviderRW, ExecutorFactory, HeaderProvider, LatestStateProviderRef, - OriginalValuesKnown, ProviderError, StatsReader, TransactionVariant, + BlockReader, CanonStateNotification, Chain, DatabaseProviderRW, ExecutorFactory, + HeaderProvider, LatestStateProviderRef, OriginalValuesKnown, ProviderError, StatsReader, + TransactionVariant, }; use reth_stages_api::{ BlockErrorKind, ExecInput, ExecOutput, MetricEvent, MetricEventsSender, Stage, StageError, @@ -26,6 +23,8 @@ use reth_stages_api::{ use std::{ cmp::Ordering, ops::RangeInclusive, + sync::Arc, + task::{ready, Context, Poll}, time::{Duration, Instant}, }; use tracing::*; @@ -74,6 +73,8 @@ pub struct ExecutionStage { external_clean_threshold: u64, /// Pruning configuration. prune_modes: PruneModes, + /// Handle to communicate with ExEx manager. + exex_manager_handle: ExExManagerHandle, } impl ExecutionStage { @@ -83,6 +84,7 @@ impl ExecutionStage { thresholds: ExecutionStageThresholds, external_clean_threshold: u64, prune_modes: PruneModes, + exex_manager_handle: ExExManagerHandle, ) -> Self { Self { metrics_tx: None, @@ -90,6 +92,7 @@ impl ExecutionStage { executor_factory, thresholds, prune_modes, + exex_manager_handle, } } @@ -102,6 +105,7 @@ impl ExecutionStage { ExecutionStageThresholds::default(), MERKLE_STAGE_DEFAULT_CLEAN_THRESHOLD, PruneModes::none(), + ExExManagerHandle::empty(), ) } @@ -156,6 +160,7 @@ impl ExecutionStage { let mut cumulative_gas = 0; let batch_start = Instant::now(); + let mut blocks = Vec::new(); for block_number in start_block..=max_block { // Fetch the block let fetch_block_start = Instant::now(); @@ -191,9 +196,13 @@ impl ExecutionStage { } stage_progress = block_number; - stage_checkpoint.progress.processed += block.gas_used; + // If we have ExEx's we need to save the block in memory for later + if self.exex_manager_handle.has_exexs() { + blocks.push(block); + } + // Check if we should commit now let bundle_size_hint = executor.size_hint().unwrap_or_default() as u64; if self.thresholds.is_end_of_batch( @@ -209,6 +218,25 @@ impl ExecutionStage { let state = executor.take_output_state(); let write_preparation_duration = time.elapsed(); + // Check if we should send a [`CanonStateNotification`] to execution extensions. + // + // Note: Since we only write to `blocks` if there are any ExEx's we don't need to perform + // the `has_exexs` check here as well + if !blocks.is_empty() { + let chain = Arc::new(Chain::new( + blocks.into_iter().map(|block| { + let hash = block.header.hash_slow(); + block.seal(hash) + }), + state.clone(), + None, + )); + + // NOTE: We can ignore the error here, since an error means that the channel is closed, + // which means the manager has died, which then in turn means the node is shutting down. + let _ = self.exex_manager_handle.send(CanonStateNotification::Commit { new: chain }); + } + let time = Instant::now(); // write output state.write_to_storage( @@ -360,6 +388,16 @@ impl Stage for ExecutionStage { StageId::Execution } + fn poll_execute_ready( + &mut self, + cx: &mut Context<'_>, + _: ExecInput, + ) -> Poll> { + ready!(self.exex_manager_handle.poll_ready(cx)); + + Poll::Ready(Ok(())) + } + /// Execute the stage fn execute( &mut self, @@ -375,74 +413,33 @@ impl Stage for ExecutionStage { provider: &DatabaseProviderRW, input: UnwindInput, ) -> Result { - let tx = provider.tx_ref(); - // Acquire changeset cursors - let mut account_changeset = tx.cursor_dup_write::()?; - let mut storage_changeset = tx.cursor_dup_write::()?; - let (range, unwind_to, _) = input.unwind_block_range_with_threshold(self.thresholds.max_blocks.unwrap_or(u64::MAX)); - if range.is_empty() { return Ok(UnwindOutput { checkpoint: input.checkpoint.with_block_number(input.unwind_to), }) } - // get all batches for account change - // Check if walk and walk_dup would do the same thing - let account_changeset_batch = - account_changeset.walk_range(range.clone())?.collect::, _>>()?; + // Unwind account and storage changesets, as well as receipts. + // + // This also updates `PlainStorageState` and `PlainAccountState`. + let bundle_state_with_receipts = provider.unwind_or_peek_state::(range.clone())?; - // revert all changes to PlainState - for (_, changeset) in account_changeset_batch.into_iter().rev() { - if let Some(account_info) = changeset.info { - tx.put::(changeset.address, account_info)?; - } else { - tx.delete::(changeset.address, None)?; - } + // Construct a `CanonStateNotification` if we have ExEx's installed. + if self.exex_manager_handle.has_exexs() { + // Get the blocks for the unwound range. This is needed for `CanonStateNotification`. + let blocks = provider.get_take_block_range::(range.clone())?; + let chain = Chain::new(blocks, bundle_state_with_receipts, None); + + // NOTE: We can ignore the error here, since an error means that the channel is closed, + // which means the manager has died, which then in turn means the node is shutting down. + let _ = self.exex_manager_handle.send(CanonStateNotification::Reorg { + old: Arc::new(chain), + new: Arc::new(Chain::default()), + }); } - // get all batches for storage change - let storage_changeset_batch = storage_changeset - .walk_range(BlockNumberAddress::range(range.clone()))? - .collect::, _>>()?; - - // revert all changes to PlainStorage - let mut plain_storage_cursor = tx.cursor_dup_write::()?; - - for (key, storage) in storage_changeset_batch.into_iter().rev() { - let address = key.address(); - if let Some(v) = plain_storage_cursor.seek_by_key_subkey(address, storage.key)? { - if v.key == storage.key { - plain_storage_cursor.delete_current()?; - } - } - if storage.value != U256::ZERO { - plain_storage_cursor.upsert(address, storage)?; - } - } - - // Discard unwinded changesets - provider.unwind_table_by_num::(unwind_to)?; - - let mut rev_storage_changeset_walker = storage_changeset.walk_back(None)?; - while let Some((key, _)) = rev_storage_changeset_walker.next().transpose()? { - if key.block_number() < *range.start() { - break - } - // delete all changesets - rev_storage_changeset_walker.delete_current()?; - } - - // Look up the start index for the transaction range - let first_tx_num = provider - .block_body_indices(*range.start())? - .ok_or(ProviderError::BlockBodyIndicesNotFound(*range.start()))? - .first_tx_num(); - - let mut stage_checkpoint = input.checkpoint.execution_stage_checkpoint(); - // Unwind all receipts for transactions in the block range if self.prune_modes.receipts.is_none() && self.prune_modes.receipts_log_filter.is_empty() { // We only use static files for Receipts, if there is no receipt pruning of any kind. @@ -451,34 +448,24 @@ impl Stage for ExecutionStage { // if the expected highest receipt in the files is higher than the database. // Which is essentially what happens here when we unwind this stage. let _static_file_producer = prepare_static_file_producer(provider, *range.start())?; - - // Update the checkpoint. - if let Some(stage_checkpoint) = stage_checkpoint.as_mut() { - for block_number in range { - stage_checkpoint.progress.processed -= provider - .block_by_number(block_number)? - .ok_or_else(|| ProviderError::HeaderNotFound(block_number.into()))? - .gas_used; - } - } } else { - // We use database for Receipts, if there is any kind of receipt pruning/filtering, - // since it is not supported by static files. - let mut cursor = tx.cursor_write::()?; - let mut reverse_walker = cursor.walk_back(None)?; - - while let Some(Ok((tx_number, receipt))) = reverse_walker.next() { - if tx_number < first_tx_num { - break - } - reverse_walker.delete_current()?; - - if let Some(stage_checkpoint) = stage_checkpoint.as_mut() { - stage_checkpoint.progress.processed -= receipt.cumulative_gas_used; - } - } + // If there is any kind of receipt pruning/filtering we use the database, since static + // files do not support filters. + // + // If we hit this case, the receipts have already been unwound by the call to + // `unwind_or_peek_state`. } + // Update the checkpoint. + let mut stage_checkpoint = input.checkpoint.execution_stage_checkpoint(); + if let Some(stage_checkpoint) = stage_checkpoint.as_mut() { + for block_number in range { + stage_checkpoint.progress.processed -= provider + .block_by_number(block_number)? + .ok_or_else(|| ProviderError::HeaderNotFound(block_number.into()))? + .gas_used; + } + } let checkpoint = if let Some(stage_checkpoint) = stage_checkpoint { StageCheckpoint::new(unwind_to).with_execution_stage_checkpoint(stage_checkpoint) } else { @@ -621,17 +608,17 @@ mod tests { use crate::test_utils::TestStageDB; use alloy_rlp::Decodable; use assert_matches::assert_matches; - use reth_db::models::AccountBeforeTx; + use reth_db::{models::AccountBeforeTx, transaction::DbTxMut}; use reth_evm_ethereum::EthEvmConfig; use reth_interfaces::executor::BlockValidationError; use reth_primitives::{ address, hex_literal::hex, keccak256, stage::StageUnitCheckpoint, Account, Address, Bytecode, ChainSpecBuilder, PruneMode, ReceiptsLogPruneConfig, SealedBlock, StorageEntry, - B256, + B256, U256, }; use reth_provider::{test_utils::create_test_provider_factory, AccountReader, ReceiptProvider}; use reth_revm::EvmProcessorFactory; - use std::{collections::BTreeMap, sync::Arc}; + use std::collections::BTreeMap; fn stage() -> ExecutionStage> { let executor_factory = EvmProcessorFactory::new( @@ -648,6 +635,7 @@ mod tests { }, MERKLE_STAGE_DEFAULT_CLEAN_THRESHOLD, PruneModes::none(), + ExExManagerHandle::empty(), ) } diff --git a/crates/stages/src/stages/mod.rs b/crates/stages/src/stages/mod.rs index fe1012f42..a40da1c49 100644 --- a/crates/stages/src/stages/mod.rs +++ b/crates/stages/src/stages/mod.rs @@ -51,6 +51,7 @@ mod tests { AccountsHistory, DatabaseEnv, }; use reth_evm_ethereum::EthEvmConfig; + use reth_exex::ExExManagerHandle; use reth_interfaces::test_utils::generators::{self, random_block}; use reth_primitives::{ address, hex_literal::hex, keccak256, Account, Bytecode, ChainSpecBuilder, PruneMode, @@ -151,6 +152,7 @@ mod tests { }, MERKLE_STAGE_DEFAULT_CLEAN_THRESHOLD, prune_modes.clone(), + ExExManagerHandle::empty(), ); execution_stage.execute(&provider, input).unwrap(); diff --git a/crates/storage/provider/src/bundle_state/bundle_state_with_receipts.rs b/crates/storage/provider/src/bundle_state/bundle_state_with_receipts.rs index 804dcece8..5e595532c 100644 --- a/crates/storage/provider/src/bundle_state/bundle_state_with_receipts.rs +++ b/crates/storage/provider/src/bundle_state/bundle_state_with_receipts.rs @@ -218,11 +218,13 @@ impl BundleStateWithReceipts { self.first_block } - /// Revert to given block number. + /// Revert the state to the given block number. /// - /// If number is in future, or in the past return false + /// Returns false if the block number is not in the bundle state. /// - /// NOTE: Provided block number will stay inside the bundle state. + /// # Note + /// + /// The provided block number will stay inside the bundle state. pub fn revert_to(&mut self, block_number: BlockNumber) -> bool { let Some(index) = self.block_number_to_index(block_number) else { return false }; diff --git a/crates/storage/provider/src/providers/database/provider.rs b/crates/storage/provider/src/providers/database/provider.rs index a2b2ec74a..ba85a4a40 100644 --- a/crates/storage/provider/src/providers/database/provider.rs +++ b/crates/storage/provider/src/providers/database/provider.rs @@ -363,7 +363,6 @@ impl DatabaseProvider { } // TODO(joshie) TEMPORARY should be moved to trait providers - /// Unwind or peek at last N blocks of state recreating the [`BundleStateWithReceipts`]. /// /// If UNWIND it set to true tip and latest state will be unwind @@ -388,7 +387,7 @@ impl DatabaseProvider { /// 1. Take the old value from the changeset /// 2. Take the new value from the local state /// 3. Set the local state to the value in the changeset - fn unwind_or_peek_state( + pub fn unwind_or_peek_state( &self, range: RangeInclusive, ) -> ProviderResult { @@ -706,8 +705,8 @@ impl DatabaseProvider { Ok(block_tx) } - /// Return range of blocks and its execution result - fn get_take_block_range( + /// Get or unwind the given range of blocks. + pub fn get_take_block_range( &self, range: impl RangeBounds + Clone, ) -> ProviderResult> { diff --git a/crates/storage/provider/src/traits/executor.rs b/crates/storage/provider/src/traits/executor.rs index bddfeb03e..f12d64169 100644 --- a/crates/storage/provider/src/traits/executor.rs +++ b/crates/storage/provider/src/traits/executor.rs @@ -4,14 +4,12 @@ use crate::{bundle_state::BundleStateWithReceipts, StateProvider}; use reth_interfaces::executor::BlockExecutionError; use reth_primitives::{BlockNumber, BlockWithSenders, PruneModes, Receipt, U256}; -/// Executor factory that would create the EVM with particular state provider. -/// -/// It can be used to mock executor. +/// A factory capable of creating an executor with the given state provider. pub trait ExecutorFactory: Send + Sync + 'static { /// Executor with [`StateProvider`] fn with_state<'a, SP: StateProvider + 'a>( &'a self, - _sp: SP, + sp: SP, ) -> Box + 'a>; } @@ -19,7 +17,7 @@ pub trait ExecutorFactory: Send + Sync + 'static { /// /// This type is capable of executing (multiple) blocks by applying the state changes made by each /// block. The final state of the executor can extracted using -/// [take_output_state](BlockExecutor::take_output_state). +/// [`Self::take_output_state`]. pub trait BlockExecutor { /// The error type returned by the executor. type Error;