diff --git a/Cargo.lock b/Cargo.lock index 5932cab0fc..71367d9384 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -106,9 +106,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "alloy-chains" -version = "0.1.63" +version = "0.1.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "996564c1782285d4e0299c29b318bc74f24b1d7f456cef3e040810b061ee3256" +checksum = "963fc7ac17f25d92c237448632330eb87b39ba8aa0209d4b517069a05b57db62" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -121,11 +121,11 @@ dependencies = [ [[package]] name = "alloy-consensus" -version = "0.12.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dc8ccab88e40f1fba5d097fecdaa5cd830858aead9b588a8d099e7faf57e97c" +checksum = "1715ed2a977d3ca4b39ffe0fc69f9f5b0e81382b348bdb5172abaa77a10f0b6d" dependencies = [ - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-rlp", "alloy-serde", @@ -145,12 +145,12 @@ dependencies = [ [[package]] name = "alloy-consensus-any" -version = "0.12.0" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f02faf3f83ddd877925a46bc206eb70f718e0c438b3159cd153751cde7ade7a" +checksum = "660705969af143897d83937d73f53c741c1587f49c27c2cfce594e188fcbc1e4" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-rlp", "alloy-serde", @@ -159,9 +159,9 @@ dependencies = [ [[package]] name = "alloy-contract" -version = "0.12.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf43fcacab41dbef6ac3a8140195c1c51ce2613b0d8b4eb0da2f944f54a6b5c4" +checksum = "5362637b25ba5282a921ca139a10f188fa34e1248a7c83c907a21de54d36dce1" dependencies = [ "alloy-dyn-abi", "alloy-json-abi", @@ -241,24 +241,9 @@ dependencies = [ [[package]] name = "alloy-eips" -version = "0.11.1" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5591581ca2ab0b3e7226a4047f9a1bfcf431da1d0cce3752fda609fea3c27e37" -dependencies = [ - "alloy-eip2124", - "alloy-eip2930", - "alloy-eip7702", - "alloy-primitives", - "alloy-rlp", - "auto_impl", - "derive_more 1.0.0", -] - -[[package]] -name = "alloy-eips" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3321230d9d9813227ad26c8f5c80a74011d629823715c0ab2d1afdea1fc204d" +checksum = "d13734f722326c846e7690ce732c9864f5ae82f52c7fb60c871f56654f348d4c" dependencies = [ "alloy-eip2124", "alloy-eip2930", @@ -281,11 +266,11 @@ dependencies = [ [[package]] name = "alloy-evm" version = "0.1.0" -source = "git+https://github.com/alloy-rs/evm?rev=69c77cf#69c77cfcce9468e7b7430c091d7d9bde31a0cdec" +source = "git+https://github.com/alloy-rs/evm?rev=f9ed4d3#f9ed4d335b2e0002e257ead3198eb463a84c5219" dependencies = [ "alloy-consensus", - "alloy-eips 0.11.1", - "alloy-hardforks 0.1.0 (git+https://github.com/alloy-rs/hardforks?rev=ce46371)", + "alloy-eips", + "alloy-hardforks", "alloy-primitives", "alloy-sol-types", "auto_impl", @@ -297,11 +282,11 @@ dependencies = [ [[package]] name = "alloy-genesis" -version = "0.12.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74e35056adaee54cc3cee86d4219d7fe606bee21ad49eb1ad21a3c207f142bb5" +checksum = "738b6d7da21955cfdebeb7bcf300040b79e51c58a22e5f029ae989a8d834a3f3" dependencies = [ - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-serde", "alloy-trie", @@ -311,7 +296,7 @@ dependencies = [ [[package]] name = "alloy-hardforks" version = "0.1.0" -source = "git+https://github.com/alloy-rs/hardforks?rev=42a3427#42a3427e19ec7a7dccfab308b21252ab62c2c5ae" +source = "git+https://github.com/alloy-rs/hardforks?rev=ae4176c#ae4176c0027171d38832644f63f05f4f80861c6e" dependencies = [ "alloy-chains", "alloy-eip2124", @@ -321,18 +306,6 @@ dependencies = [ "serde", ] -[[package]] -name = "alloy-hardforks" -version = "0.1.0" -source = "git+https://github.com/alloy-rs/hardforks?rev=ce46371#ce463717cd43c17411e41152d776f1468e054c3b" -dependencies = [ - "alloy-chains", - "alloy-eip2124", - "alloy-primitives", - "auto_impl", - "dyn-clone", -] - [[package]] name = "alloy-json-abi" version = "0.8.22" @@ -347,9 +320,9 @@ dependencies = [ [[package]] name = "alloy-json-rpc" -version = "0.12.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed237ef5c3910deb2ff7c9a33e856ada57ec44b58562f0354ba4640319906c" +checksum = "e6fbb61c4dfe5def9a065438162faf39503b3e8d90f36d01563418a75f0ef016" dependencies = [ "alloy-primitives", "alloy-sol-types", @@ -361,13 +334,13 @@ dependencies = [ [[package]] name = "alloy-network" -version = "0.12.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15bb3faed4de77ebc2137d3167ef409b2300432e5fe0b191e3308d3740ff4add" +checksum = "f10b0bc0657b018ee4f3758f889d066af6b1f20f57cd825b540182029090c151" dependencies = [ "alloy-consensus", "alloy-consensus-any", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-json-rpc", "alloy-network-primitives", "alloy-primitives", @@ -387,12 +360,12 @@ dependencies = [ [[package]] name = "alloy-network-primitives" -version = "0.12.0" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3dddaef8fc70307e8775be36a853e6118a628842d013f77f2c73ee48497aaf6" +checksum = "6cac4aeeabbbc16623d0745ae3b5a515d727ce8ef4ec4b6a886c3634d8b298fe" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-serde", "serde", @@ -400,9 +373,9 @@ dependencies = [ [[package]] name = "alloy-node-bindings" -version = "0.12.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec4659e84cfc7ad74f71766bfd6a8cf682c2e8b59c28327daaa37e5c45694e4d" +checksum = "d9151507742ac142201c3a56f74fd94c2ceda96115eed60a3dabaeef85e6b64a" dependencies = [ "alloy-genesis", "alloy-network", @@ -421,10 +394,15 @@ dependencies = [ [[package]] name = "alloy-op-evm" version = "0.1.0" -source = "git+https://github.com/alloy-rs/evm?rev=69c77cf#69c77cfcce9468e7b7430c091d7d9bde31a0cdec" +source = "git+https://github.com/alloy-rs/evm?rev=f9ed4d3#f9ed4d335b2e0002e257ead3198eb463a84c5219" dependencies = [ + "alloy-consensus", + "alloy-eips", "alloy-evm", + "alloy-op-hardforks", "alloy-primitives", + "auto_impl", + "op-alloy-consensus", "op-revm", "revm", ] @@ -432,9 +410,9 @@ dependencies = [ [[package]] name = "alloy-op-hardforks" version = "0.1.0" -source = "git+https://github.com/alloy-rs/hardforks?rev=42a3427#42a3427e19ec7a7dccfab308b21252ab62c2c5ae" +source = "git+https://github.com/alloy-rs/hardforks?rev=ae4176c#ae4176c0027171d38832644f63f05f4f80861c6e" dependencies = [ - "alloy-hardforks 0.1.0 (git+https://github.com/alloy-rs/hardforks?rev=42a3427)", + "alloy-hardforks", "auto_impl", "serde", ] @@ -472,13 +450,13 @@ dependencies = [ [[package]] name = "alloy-provider" -version = "0.12.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b08759415890ed63d3f09a3147d5ad8333c1b2a3eb9697604a6c1d54071213d1" +checksum = "d06ffafc44e68c8244feb51919895c679c153a0b143c182e1ffe8cce998abf15" dependencies = [ "alloy-chains", "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-json-rpc", "alloy-network", "alloy-network-primitives", @@ -514,9 +492,9 @@ dependencies = [ [[package]] name = "alloy-pubsub" -version = "0.12.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a28762a95c1980e8d05507f2702f3844d0c7a4b0ce069952d8dd6f30d6288d2" +checksum = "6abe9f9e6be75dc8532bb2bf3f4c700c9e7bce8a3b05ec702a7324abdb118016" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -555,9 +533,9 @@ dependencies = [ [[package]] name = "alloy-rpc-client" -version = "0.12.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9c0d94c4a8f4c094e37799d6576db2f65d1b8640fbf5c82954b13e968c9aaaf" +checksum = "c9ae316fdb92a4546f0dba4919ea4c1c0edb89a876536520c248fada0febac5d" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -581,9 +559,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types" -version = "0.12.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3202eba7d7f4d8c5eb1a7b35617ff6ab1e3b9283642d2c6bd9ca401c6d197f73" +checksum = "61e50cc5a693dfbef452e3dbcea3cd3342840d10eb3ffa018b0a5676967d8b6b" dependencies = [ "alloy-primitives", "alloy-rpc-types-engine", @@ -594,9 +572,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-admin" -version = "0.12.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fe1b06c81a47256c3fb99fa104ba628a401b5bfcfb4ee11b14bedc5b8f6ade2" +checksum = "baf6be84594bde5d0224689ce3b7d00f0c6a816e49b26398ff0fb0874545f53c" dependencies = [ "alloy-genesis", "alloy-primitives", @@ -606,9 +584,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-anvil" -version = "0.12.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0893f46595e522454488f1a1d6c5abe6992878c3d5f07fab14ca98016509302f" +checksum = "2852d7350760c3fbfc60ee3396b95a66ea57afe3aeecee72bf1171ac6b1d5d18" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", @@ -618,9 +596,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-any" -version = "0.12.0" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a84ae770c31d4aae0ce056ff594dffc8bb51cc246d1854ddae5083fbd978ef58" +checksum = "f726ebb03d5918a946d0a6e17829cabd90ffe928664dc3f7fdbba1be511760de" dependencies = [ "alloy-consensus-any", "alloy-rpc-types-eth", @@ -629,11 +607,11 @@ dependencies = [ [[package]] name = "alloy-rpc-types-beacon" -version = "0.12.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb3281fa3c6f60f5aac760a5a88f00748095e1f8ea65af6ae520180a32ea6c9a" +checksum = "51514a8aa768240f1a268391cb4f55625bfaeeb404340de2637d87c79203b1ec" dependencies = [ - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-rpc-types-engine", "ethereum_ssz", @@ -645,9 +623,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-debug" -version = "0.12.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d25220531700aa68369aaa9add165a958b3f93a7324f8ee2964052593b9a1d13" +checksum = "ab1fe2c636a14190fe3c6caf6a20d2fb8691a5824c1789ee495324a14295df82" dependencies = [ "alloy-primitives", "serde", @@ -655,12 +633,12 @@ dependencies = [ [[package]] name = "alloy-rpc-types-engine" -version = "0.12.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "467888f02b5f70a3f12a8e5c211df5abd05895f7aebe10c2f73d51241de66b44" +checksum = "b05bfe640e4708c5a83dfcc65b5e4a0deb6ddcb18897dd49862ddc3964e06ff8" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-rlp", "alloy-serde", @@ -676,13 +654,13 @@ dependencies = [ [[package]] name = "alloy-rpc-types-eth" -version = "0.12.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8e76553a98e04b20d8ac55d95cd6c8aad741958a23949132a4a5f12ca137059" +checksum = "c24a3b6c552b74c4abdbaa45fd467a230f5564f62c6adae16972dd90b6b4dca5" dependencies = [ "alloy-consensus", "alloy-consensus-any", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-network-primitives", "alloy-primitives", "alloy-rlp", @@ -698,11 +676,11 @@ dependencies = [ [[package]] name = "alloy-rpc-types-mev" -version = "0.12.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52fa7a2aadd438fff37cff67de68b741ba479558d1967852d9f17e1513410606" +checksum = "a43132c034c26a75edc5db896fe8dab414084e8503ae0008be98a75c316d675a" dependencies = [ - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-rpc-types-eth", "alloy-serde", @@ -712,9 +690,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-trace" -version = "0.12.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c171d01c2993f616a6cb62b816a9df9836a127174fa6e46b3a5ab0cf2dfe4c19" +checksum = "e25f16f6bfe65c23d873741aa343830de270db42c982822e23689d11f2f4d812" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", @@ -726,9 +704,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-txpool" -version = "0.12.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75de853772bd4fcdaf0a58ac651f543bca934924abf65c4bb38022b8df754d5c" +checksum = "9415e7e3f32a93a38ecb83aa449f7326081b5b362964291463f8f2060b4b8a31" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", @@ -738,9 +716,9 @@ dependencies = [ [[package]] name = "alloy-serde" -version = "0.12.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf75f1bfe9815621add598f84c390871563011d73ab4f7c4c1948773f251aa2d" +checksum = "3aebca035ca670bd7de8165a9494c0d502625e26129dd95d17fdfd70d5521c02" dependencies = [ "alloy-primitives", "arbitrary", @@ -750,9 +728,9 @@ dependencies = [ [[package]] name = "alloy-signer" -version = "0.12.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b9ec56de0faa9aa5def4b41f466819eb41cbe41e007ca31eb6e61248d89a4f9" +checksum = "7abfef2a155c7d6a9f54861159a3fdd29abe1f67f0865b081bce4c2fdc9e83cc" dependencies = [ "alloy-primitives", "async-trait", @@ -765,9 +743,9 @@ dependencies = [ [[package]] name = "alloy-signer-local" -version = "0.12.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25f41056c66da13d6f2ea1605ebdb3d6f0663a1a7b54005dd36cb1d569e4733b" +checksum = "326033310c939b0d00b03fdbe2c243cb45add25c4e195d97b1792883c93a4c4c" dependencies = [ "alloy-consensus", "alloy-network", @@ -853,9 +831,9 @@ dependencies = [ [[package]] name = "alloy-transport" -version = "0.12.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "579917e55a64a5f88b2f46f21480095b0fa8c303716c0c58075a796e89ed0084" +checksum = "463f6cb5234c7420e7e77c248c0460a8e2dea933f2bb4e8f169d5f12510b38e0" dependencies = [ "alloy-json-rpc", "base64 0.22.1", @@ -872,9 +850,9 @@ dependencies = [ [[package]] name = "alloy-transport-http" -version = "0.12.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "054304bed1f26063c6af508819c3bb28b135c633eaca8888c130b289ec4cba44" +checksum = "1eacd1c195c2a706bfbc92113d4bd3481b0dbd1742923a232dbe8a7910ac0fe5" dependencies = [ "alloy-json-rpc", "alloy-transport", @@ -887,9 +865,9 @@ dependencies = [ [[package]] name = "alloy-transport-ipc" -version = "0.12.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28bc5e3e6e72ba3a3e5f580467476b8e8986d425ffdbca7ffe6b00610ecbf371" +checksum = "6c5d3531e65eed82f14f93bb668fb06797c3754d0141c5da042bb63c5c19f13c" dependencies = [ "alloy-json-rpc", "alloy-pubsub", @@ -907,9 +885,9 @@ dependencies = [ [[package]] name = "alloy-transport-ws" -version = "0.12.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd20a6c7d78a6a1030f117f8c74474ef84634594aad327346eee87baa3a87ccb" +checksum = "218e64c375edd8fe8d00d9aa983fb2d85f7cfeebb91f707fe4c7ba52410803f5" dependencies = [ "alloy-pubsub", "alloy-transport", @@ -2409,7 +2387,7 @@ dependencies = [ "crossterm_winapi", "mio", "parking_lot", - "rustix", + "rustix 0.38.44", "signal-hook", "signal-hook-mio", "winapi", @@ -2919,7 +2897,7 @@ name = "ef-tests" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-rlp", "rayon", @@ -3172,7 +3150,8 @@ dependencies = [ name = "example-custom-beacon-withdrawals" version = "0.0.0" dependencies = [ - "alloy-eips 0.12.2", + "alloy-eips", + "alloy-evm", "alloy-sol-macro", "alloy-sol-types", "eyre", @@ -3204,7 +3183,7 @@ dependencies = [ name = "example-custom-engine-types" version = "0.0.0" dependencies = [ - "alloy-eips 0.12.2", + "alloy-eips", "alloy-genesis", "alloy-primitives", "alloy-rpc-types", @@ -3250,7 +3229,7 @@ dependencies = [ name = "example-custom-inspector" version = "0.0.0" dependencies = [ - "alloy-eips 0.12.2", + "alloy-eips", "alloy-evm", "alloy-primitives", "alloy-rpc-types-eth", @@ -3276,7 +3255,7 @@ dependencies = [ name = "example-custom-payload-builder" version = "0.0.0" dependencies = [ - "alloy-eips 0.12.2", + "alloy-eips", "eyre", "futures-util", "reth", @@ -3977,9 +3956,9 @@ checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hermit-abi" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" +checksum = "fbd780fe5cc30f81464441920d82ac8740e2e46b29a6fad543ddd075229ce37e" [[package]] name = "hex" @@ -4581,9 +4560,9 @@ dependencies = [ [[package]] name = "interprocess" -version = "2.2.2" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "894148491d817cb36b6f778017b8ac46b17408d522dd90f539d677ea938362eb" +checksum = "d941b405bd2322993887859a8ee6ac9134945a24ec5ec763a8a962fc64dfec2d" dependencies = [ "doctest-file", "futures-core", @@ -4633,11 +4612,11 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.15" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e19b23d53f35ce9f56aebc7d1bb4e6ac1e9c0db7ac85c8d1760c04379edced37" +checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" dependencies = [ - "hermit-abi 0.4.0", + "hermit-abi 0.5.0", "libc", "windows-sys 0.59.0", ] @@ -5102,6 +5081,12 @@ version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" +[[package]] +name = "linux-raw-sys" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db9c683daf087dc577b7506e9695b3d556a9f3849903fa28186283afd6809e9" + [[package]] name = "litemap" version = "0.7.5" @@ -5678,9 +5663,9 @@ dependencies = [ [[package]] name = "oorandom" -version = "11.1.4" +version = "11.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" +checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" [[package]] name = "op-alloy-consensus" @@ -5689,7 +5674,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d297150146a63778a29400320700e804ec6e1e4d6ec99857cdbbaf17b3de9241" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-network", "alloy-primitives", "alloy-rlp", @@ -5740,7 +5725,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7095f87d34fc814e3de06a7af8ffff9121993f322231647f84df304821cc0275" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-network-primitives", "alloy-primitives", "alloy-rpc-types-eth", @@ -5758,7 +5743,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "955a7d0ef9161f4a2a8461ef5d784526741c325410103d654706863cf4a32736" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-rpc-types-engine", "alloy-serde", @@ -6199,9 +6184,9 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.2.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" dependencies = [ "toml_edit", ] @@ -6248,7 +6233,7 @@ dependencies = [ "flate2", "hex", "procfs-core", - "rustix", + "rustix 0.38.44", ] [[package]] @@ -6453,7 +6438,7 @@ checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.3", - "zerocopy 0.8.22", + "zerocopy 0.8.23", ] [[package]] @@ -6738,7 +6723,7 @@ name = "reth" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-rlp", "alloy-rpc-types", @@ -6808,7 +6793,7 @@ name = "reth-basic-payload-builder" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "futures-core", "futures-util", @@ -6831,7 +6816,7 @@ name = "reth-bench" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-json-rpc", "alloy-primitives", "alloy-provider", @@ -6871,7 +6856,7 @@ name = "reth-chain-state" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-signer", "alloy-signer-local", @@ -6902,7 +6887,8 @@ version = "1.2.2" dependencies = [ "alloy-chains", "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", + "alloy-evm", "alloy-genesis", "alloy-primitives", "alloy-rlp", @@ -6934,7 +6920,7 @@ version = "1.2.2" dependencies = [ "ahash", "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-rlp", "arbitrary", @@ -7009,7 +6995,7 @@ dependencies = [ name = "reth-cli-util" version = "1.2.2" dependencies = [ - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "cfg-if", "eyre", @@ -7029,7 +7015,7 @@ name = "reth-codecs" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-genesis", "alloy-primitives", "alloy-trie", @@ -7091,7 +7077,7 @@ name = "reth-consensus-common" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "rand 0.8.5", "reth-chainspec", @@ -7105,7 +7091,7 @@ name = "reth-consensus-debug-client" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-provider", "alloy-rpc-types-engine", @@ -7219,7 +7205,7 @@ dependencies = [ name = "reth-db-models" version = "1.2.2" dependencies = [ - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "arbitrary", "bytes", @@ -7316,7 +7302,7 @@ name = "reth-downloaders" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-rlp", "assert_matches", @@ -7355,7 +7341,7 @@ name = "reth-e2e-test-utils" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-network", "alloy-primitives", "alloy-rlp", @@ -7463,7 +7449,7 @@ name = "reth-engine-primitives" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-rpc-types-engine", "auto_impl", @@ -7516,7 +7502,8 @@ name = "reth-engine-tree" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", + "alloy-evm", "alloy-primitives", "alloy-rlp", "alloy-rpc-types-engine", @@ -7578,19 +7565,14 @@ name = "reth-engine-util" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", - "alloy-primitives", "alloy-rpc-types-engine", "eyre", "futures", "itertools 0.14.0", "pin-project", "reth-chainspec", - "reth-consensus-common", "reth-engine-primitives", "reth-errors", - "reth-ethereum-forks", - "reth-ethereum-primitives", "reth-evm", "reth-fs-util", "reth-payload-primitives", @@ -7598,9 +7580,6 @@ dependencies = [ "reth-primitives-traits", "reth-provider", "reth-revm", - "reth-trie", - "revm-database", - "revm-primitives", "serde", "serde_json", "tokio", @@ -7624,7 +7603,7 @@ name = "reth-eth-wire" version = "1.2.2" dependencies = [ "alloy-chains", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-rlp", "arbitrary", @@ -7662,7 +7641,7 @@ version = "1.2.2" dependencies = [ "alloy-chains", "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-genesis", "alloy-primitives", "alloy-rlp", @@ -7725,7 +7704,7 @@ name = "reth-ethereum-consensus" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "reth-chainspec", "reth-consensus", @@ -7740,7 +7719,7 @@ dependencies = [ name = "reth-ethereum-engine-primitives" version = "1.2.2" dependencies = [ - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-rlp", "alloy-rpc-types-engine", @@ -7757,7 +7736,7 @@ name = "reth-ethereum-forks" version = "1.2.2" dependencies = [ "alloy-eip2124", - "alloy-hardforks 0.1.0 (git+https://github.com/alloy-rs/hardforks?rev=42a3427)", + "alloy-hardforks", "alloy-primitives", "arbitrary", "auto_impl", @@ -7770,7 +7749,7 @@ name = "reth-ethereum-payload-builder" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-rpc-types-engine", "reth-basic-payload-builder", @@ -7797,7 +7776,7 @@ name = "reth-ethereum-primitives" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-evm", "alloy-network", "alloy-primitives", @@ -7836,7 +7815,7 @@ name = "reth-evm" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-evm", "alloy-primitives", "auto_impl", @@ -7846,8 +7825,6 @@ dependencies = [ "metrics-util", "op-revm", "parking_lot", - "reth-chainspec", - "reth-consensus-common", "reth-ethereum-forks", "reth-ethereum-primitives", "reth-execution-errors", @@ -7866,11 +7843,10 @@ name = "reth-evm-ethereum" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-evm", "alloy-genesis", "alloy-primitives", - "alloy-sol-types", "reth-chainspec", "reth-ethereum-forks", "reth-evm", @@ -7900,7 +7876,8 @@ name = "reth-execution-types" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", + "alloy-evm", "alloy-primitives", "arbitrary", "bincode", @@ -7920,7 +7897,7 @@ name = "reth-exex" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-genesis", "alloy-primitives", "eyre", @@ -7963,7 +7940,7 @@ dependencies = [ name = "reth-exex-test-utils" version = "1.2.2" dependencies = [ - "alloy-eips 0.12.2", + "alloy-eips", "eyre", "futures-util", "rand 0.8.5", @@ -7996,7 +7973,7 @@ dependencies = [ name = "reth-exex-types" version = "1.2.2" dependencies = [ - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "arbitrary", "bincode", @@ -8131,7 +8108,7 @@ name = "reth-network" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-node-bindings", "alloy-primitives", "alloy-provider", @@ -8217,7 +8194,7 @@ name = "reth-network-p2p" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "auto_impl", "derive_more 2.0.1", @@ -8335,7 +8312,7 @@ name = "reth-node-builder" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-rpc-types", "alloy-rpc-types-engine", @@ -8399,7 +8376,7 @@ name = "reth-node-core" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-rpc-types-engine", "clap", @@ -8450,7 +8427,7 @@ version = "1.2.2" dependencies = [ "alloy-consensus", "alloy-contract", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-genesis", "alloy-primitives", "alloy-provider", @@ -8502,7 +8479,7 @@ name = "reth-node-events" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-rpc-types-engine", "derive_more 2.0.1", @@ -8600,7 +8577,7 @@ version = "1.2.2" dependencies = [ "alloy-chains", "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-genesis", "alloy-primitives", "derive_more 2.0.1", @@ -8622,7 +8599,7 @@ name = "reth-optimism-cli" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-rlp", "clap", @@ -8671,7 +8648,7 @@ version = "1.2.2" dependencies = [ "alloy-chains", "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-trie", "op-alloy-consensus", @@ -8701,7 +8678,7 @@ name = "reth-optimism-evm" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-evm", "alloy-genesis", "alloy-op-evm", @@ -8747,7 +8724,7 @@ name = "reth-optimism-node" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-genesis", "alloy-network", "alloy-primitives", @@ -8805,7 +8782,7 @@ name = "reth-optimism-payload-builder" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-rlp", "alloy-rpc-types-debug", @@ -8842,7 +8819,7 @@ name = "reth-optimism-primitives" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-evm", "alloy-network", "alloy-primitives", @@ -8873,7 +8850,7 @@ name = "reth-optimism-rpc" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-rpc-types-debug", "alloy-rpc-types-engine", @@ -8925,7 +8902,7 @@ name = "reth-optimism-storage" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "reth-chainspec", "reth-codecs", @@ -8945,7 +8922,7 @@ name = "reth-optimism-txpool" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-rpc-types-eth", "c-kzg", @@ -9006,7 +8983,7 @@ dependencies = [ name = "reth-payload-primitives" version = "1.2.2" dependencies = [ - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-rpc-types-engine", "assert_matches", @@ -9044,7 +9021,7 @@ name = "reth-primitives" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-genesis", "alloy-primitives", "alloy-rlp", @@ -9068,7 +9045,7 @@ name = "reth-primitives-traits" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-genesis", "alloy-primitives", "alloy-rlp", @@ -9105,7 +9082,7 @@ name = "reth-provider" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-rpc-types-engine", "assert_matches", @@ -9156,7 +9133,7 @@ name = "reth-prune" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "assert_matches", "itertools 0.14.0", @@ -9224,7 +9201,8 @@ version = "1.2.2" dependencies = [ "alloy-consensus", "alloy-dyn-abi", - "alloy-eips 0.12.2", + "alloy-eips", + "alloy-evm", "alloy-genesis", "alloy-network", "alloy-primitives", @@ -9255,7 +9233,6 @@ dependencies = [ "rand 0.8.5", "reth-chainspec", "reth-consensus", - "reth-consensus-common", "reth-engine-primitives", "reth-errors", "reth-evm", @@ -9295,7 +9272,7 @@ dependencies = [ name = "reth-rpc-api" version = "1.2.2" dependencies = [ - "alloy-eips 0.12.2", + "alloy-eips", "alloy-genesis", "alloy-json-rpc", "alloy-primitives", @@ -9320,7 +9297,7 @@ dependencies = [ name = "reth-rpc-api-testing-util" version = "1.2.2" dependencies = [ - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-rpc-types-eth", "alloy-rpc-types-trace", @@ -9339,7 +9316,7 @@ dependencies = [ name = "reth-rpc-builder" version = "1.2.2" dependencies = [ - "alloy-eips 0.12.2", + "alloy-eips", "alloy-network", "alloy-primitives", "alloy-provider", @@ -9392,7 +9369,7 @@ dependencies = [ name = "reth-rpc-engine-api" version = "1.2.2" dependencies = [ - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-rlp", "alloy-rpc-types-engine", @@ -9430,7 +9407,7 @@ version = "1.2.2" dependencies = [ "alloy-consensus", "alloy-dyn-abi", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-json-rpc", "alloy-network", "alloy-primitives", @@ -9473,7 +9450,7 @@ name = "reth-rpc-eth-types" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-rpc-types-eth", "alloy-sol-types", @@ -9533,7 +9510,7 @@ dependencies = [ name = "reth-rpc-server-types" version = "1.2.2" dependencies = [ - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-rpc-types-engine", "jsonrpsee-core", @@ -9562,7 +9539,7 @@ name = "reth-stages" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-rlp", "assert_matches", @@ -9618,7 +9595,7 @@ dependencies = [ name = "reth-stages-api" version = "1.2.2" dependencies = [ - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "aquamarine", "assert_matches", @@ -9701,7 +9678,7 @@ name = "reth-storage-api" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-rpc-types-engine", "auto_impl", @@ -9723,7 +9700,7 @@ dependencies = [ name = "reth-storage-errors" version = "1.2.2" dependencies = [ - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-rlp", "derive_more 2.0.1", @@ -9756,7 +9733,7 @@ name = "reth-testing-utils" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-genesis", "alloy-primitives", "rand 0.8.5", @@ -9793,7 +9770,7 @@ name = "reth-transaction-pool" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-rlp", "aquamarine", @@ -9840,7 +9817,7 @@ name = "reth-trie" version = "1.2.2" dependencies = [ "alloy-consensus", - "alloy-eips 0.12.2", + "alloy-eips", "alloy-primitives", "alloy-rlp", "alloy-trie", @@ -10424,7 +10401,20 @@ dependencies = [ "bitflags 2.9.0", "errno", "libc", - "linux-raw-sys", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustix" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dade4812df5c384711475be5fcd8c162555352945401aed22a35bffeab61f657" +dependencies = [ + "bitflags 2.9.0", + "errno", + "libc", + "linux-raw-sys 0.9.2", "windows-sys 0.59.0", ] @@ -11219,9 +11209,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "symbolic-common" -version = "12.14.0" +version = "12.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "918a8461341098b48201d587de5e059f46a21e3bb871b4c6f2be4f95f01bbe69" +checksum = "66135c8273581acaab470356f808a1c74a707fe7ec24728af019d7247e089e71" dependencies = [ "debugid", "memmap2", @@ -11231,9 +11221,9 @@ dependencies = [ [[package]] name = "symbolic-demangle" -version = "12.14.0" +version = "12.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a41a39f701a19a0f7db09520b2e15c70f59fd16abc1c4f3d34e265ffef9228" +checksum = "42bcacd080282a72e795864660b148392af7babd75691d5ae9a3b77e29c98c77" dependencies = [ "cpp_demangle", "rustc-demangle", @@ -11321,15 +11311,15 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.17.1" +version = "3.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e5a0acb1f3f55f65cc4a866c361b2fb2a0ff6366785ae6fbb5f85df07ba230" +checksum = "2c317e0a526ee6120d8dabad239c8dadca62b24b6f168914bbbc8e2fb1f0e567" dependencies = [ "cfg-if", "fastrand 2.3.0", "getrandom 0.3.1", "once_cell", - "rustix", + "rustix 1.0.1", "windows-sys 0.59.0", ] @@ -11483,9 +11473,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.38" +version = "0.3.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb041120f25f8fbe8fd2dbe4671c7c2ed74d83be2e7a77529bf7e0790ae3f472" +checksum = "dad298b01a40a23aac4580b67e3dbedb7cc8402f3592d7f49469de2ea4aecdd8" dependencies = [ "deranged", "itoa", @@ -11561,9 +11551,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.43.0" +version = "1.44.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" +checksum = "9975ea0f48b5aa3972bf2d888c238182458437cc2a19374b81b25cdf1023fb3a" dependencies = [ "backtrace", "bytes", @@ -12750,11 +12740,11 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.22" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09612fda0b63f7cb9e0af7e5916fe5a1f8cdcb066829f10f36883207628a4872" +checksum = "fd97444d05a4328b90e75e503a34bad781f14e28a823ad3557f0750df1ebcbc6" dependencies = [ - "zerocopy-derive 0.8.22", + "zerocopy-derive 0.8.23", ] [[package]] @@ -12770,9 +12760,9 @@ dependencies = [ [[package]] name = "zerocopy-derive" -version = "0.8.22" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79f81d38d7a2ed52d8f034e62c568e111df9bf8aba2f7cf19ddc5bf7bd89d520" +checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index d060d022aa..d6e3893480 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -448,13 +448,13 @@ revm-inspectors = "0.16" alloy-chains = { version = "0.1.32", default-features = false } alloy-dyn-abi = "0.8.20" alloy-eip2124 = { version = "0.1.0", default-features = false } -alloy-evm = { git = "https://github.com/alloy-rs/evm", rev = "69c77cf", default-features = false } +alloy-evm = { git = "https://github.com/alloy-rs/evm", rev = "f9ed4d3", default-features = false } alloy-primitives = { version = "0.8.20", default-features = false, features = ["map-foldhash"] } alloy-rlp = { version = "0.3.10", default-features = false, features = ["core-net"] } alloy-sol-types = { version = "0.8.20", default-features = false } alloy-trie = { version = "0.7", default-features = false } -alloy-hardforks = { git = "https://github.com/alloy-rs/hardforks", rev = "42a3427" } +alloy-hardforks = { git = "https://github.com/alloy-rs/hardforks", rev = "ae4176c" } alloy-consensus = { version = "0.12.2", default-features = false } alloy-contract = { version = "0.12.2", default-features = false } @@ -486,8 +486,8 @@ alloy-transport-ipc = { version = "0.12.2", default-features = false } alloy-transport-ws = { version = "0.12.2", default-features = false } # op -alloy-op-evm = { git = "https://github.com/alloy-rs/evm", rev = "69c77cf", default-features = false } -alloy-op-hardforks = { git = "https://github.com/alloy-rs/hardforks", rev = "42a3427" } +alloy-op-evm = { git = "https://github.com/alloy-rs/evm", rev = "f9ed4d3", default-features = false } +alloy-op-hardforks = { git = "https://github.com/alloy-rs/hardforks", rev = "ae4176c" } op-alloy-rpc-types = { version = "0.11.0", default-features = false } op-alloy-rpc-types-engine = { version = "0.11.0", default-features = false } op-alloy-network = { version = "0.11.0", default-features = false } diff --git a/crates/chainspec/Cargo.toml b/crates/chainspec/Cargo.toml index 50b63b8bee..6d09d71c63 100644 --- a/crates/chainspec/Cargo.toml +++ b/crates/chainspec/Cargo.toml @@ -18,6 +18,7 @@ alloy-trie = { workspace = true, features = ["ethereum"] } reth-primitives-traits.workspace = true # ethereum +alloy-evm.workspace = true alloy-chains = { workspace = true, features = ["serde", "rlp"] } alloy-eips = { workspace = true, features = ["serde"] } alloy-genesis.workspace = true @@ -51,6 +52,7 @@ std = [ "derive_more/std", "reth-network-peers/std", "serde_json/std", + "alloy-evm/std", ] arbitrary = [ "alloy-chains/arbitrary", diff --git a/crates/chainspec/src/spec.rs b/crates/chainspec/src/spec.rs index 98dc91de59..a30fb59108 100644 --- a/crates/chainspec/src/spec.rs +++ b/crates/chainspec/src/spec.rs @@ -1,4 +1,5 @@ pub use alloy_eips::eip1559::BaseFeeParams; +use alloy_evm::eth::spec::EthExecutorSpec; use crate::{ constants::{MAINNET_DEPOSIT_CONTRACT, MAINNET_PRUNE_DELETE_LIMIT}, @@ -1000,6 +1001,12 @@ impl From<&Arc> for ChainSpecBuilder { } } +impl EthExecutorSpec for ChainSpec { + fn deposit_contract_address(&self) -> Option
{ + self.deposit_contract.map(|deposit_contract| deposit_contract.address) + } +} + /// `PoS` deposit contract details. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DepositContract { @@ -1035,6 +1042,8 @@ pub fn test_fork_ids(spec: &ChainSpec, cases: &[(Head, ForkId)]) { mod tests { use super::*; use alloy_chains::Chain; + use alloy_consensus::constants::ETH_TO_WEI; + use alloy_evm::block::calc::{base_block_reward, block_reward}; use alloy_genesis::{ChainConfig, GenesisAccount}; use alloy_primitives::{b256, hex}; use alloy_trie::{TrieAccount, EMPTY_ROOT_HASH}; @@ -2415,4 +2424,40 @@ Post-merge hard forks (timestamp based): .all(|(expected, actual)| &**expected == *actual)); assert_eq!(expected_hardforks.len(), hardforks.len()); } + + #[test] + fn test_calc_base_block_reward() { + // ((block number, td), reward) + let cases = [ + // Pre-byzantium + ((0, U256::ZERO), Some(ETH_TO_WEI * 5)), + // Byzantium + ((4370000, U256::ZERO), Some(ETH_TO_WEI * 3)), + // Petersburg + ((7280000, U256::ZERO), Some(ETH_TO_WEI * 2)), + // Merge + ((15537394, U256::from(58_750_000_000_000_000_000_000_u128)), None), + ]; + + for ((block_number, _td), expected_reward) in cases { + assert_eq!(base_block_reward(&*MAINNET, block_number), expected_reward); + } + } + + #[test] + fn test_calc_full_block_reward() { + let base_reward = ETH_TO_WEI; + let one_thirty_twoth_reward = base_reward >> 5; + + // (num_ommers, reward) + let cases = [ + (0, base_reward), + (1, base_reward + one_thirty_twoth_reward), + (2, base_reward + one_thirty_twoth_reward * 2), + ]; + + for (num_ommers, expected_reward) in cases { + assert_eq!(block_reward(base_reward, num_ommers), expected_reward); + } + } } diff --git a/crates/consensus/common/Cargo.toml b/crates/consensus/common/Cargo.toml index 10f89a69b1..96dea6c232 100644 --- a/crates/consensus/common/Cargo.toml +++ b/crates/consensus/common/Cargo.toml @@ -16,7 +16,6 @@ reth-chainspec.workspace = true reth-consensus.workspace = true # ethereum -alloy-primitives.workspace = true reth-primitives-traits.workspace = true alloy-consensus.workspace = true alloy-eips.workspace = true @@ -32,9 +31,9 @@ default = ["std"] std = [ "alloy-consensus/std", "alloy-eips/std", - "alloy-primitives/std", "reth-chainspec/std", "reth-consensus/std", "reth-primitives-traits/std", "reth-ethereum-primitives/std", + "alloy-primitives/std", ] diff --git a/crates/consensus/common/src/calc.rs b/crates/consensus/common/src/calc.rs deleted file mode 100644 index 843c021730..0000000000 --- a/crates/consensus/common/src/calc.rs +++ /dev/null @@ -1,152 +0,0 @@ -use alloy_consensus::constants::ETH_TO_WEI; -use alloy_primitives::BlockNumber; -use reth_chainspec::EthereumHardforks; - -/// Calculates the base block reward. -/// -/// The base block reward is defined as: -/// -/// - For Paris and later: `None` -/// - For Petersburg and later: `Some(2 ETH)` -/// - For Byzantium and later: `Some(3 ETH)` -/// - Otherwise: `Some(5 ETH)` -/// -/// # Note -/// -/// This does not include the reward for including ommers. To calculate the full block reward, see -/// [`block_reward`]. -/// -/// # References -/// -/// - Definition: [Yellow Paper][yp] (page 15, 11.3) -/// -/// [yp]: https://ethereum.github.io/yellowpaper/paper.pdf -pub fn base_block_reward( - chain_spec: impl EthereumHardforks, - block_number: BlockNumber, -) -> Option { - if chain_spec.is_paris_active_at_block(block_number) { - None - } else { - Some(base_block_reward_pre_merge(chain_spec, block_number)) - } -} - -/// Calculates the base block reward __before__ the merge (Paris hardfork). -/// -/// Caution: The caller must ensure that the block number is before the merge. -pub fn base_block_reward_pre_merge( - chain_spec: impl EthereumHardforks, - block_number: BlockNumber, -) -> u128 { - if chain_spec.is_constantinople_active_at_block(block_number) { - ETH_TO_WEI * 2 - } else if chain_spec.is_byzantium_active_at_block(block_number) { - ETH_TO_WEI * 3 - } else { - ETH_TO_WEI * 5 - } -} - -/// Calculates the reward for a block, including the reward for ommer inclusion. -/// -/// The base reward should be calculated using [`base_block_reward`]. `ommers` represents the number -/// of ommers included in the block. -/// -/// # Examples -/// -/// ``` -/// # use reth_chainspec::MAINNET; -/// # use reth_consensus_common::calc::{base_block_reward, block_reward}; -/// # use alloy_consensus::constants::ETH_TO_WEI; -/// # use alloy_primitives::U256; -/// # -/// // This is block 126 on mainnet. -/// let block_number = 126; -/// let number_of_ommers = 1; -/// -/// let reward = base_block_reward(&*MAINNET, block_number).map(|reward| block_reward(reward, 1)); -/// -/// // The base block reward is 5 ETH, and the ommer inclusion reward is 1/32th of 5 ETH. -/// assert_eq!(reward.unwrap(), ETH_TO_WEI * 5 + ((ETH_TO_WEI * 5) >> 5)); -/// ``` -/// -/// # References -/// -/// - Definition: [Yellow Paper][yp] (page 15, 11.3) -/// -/// [yp]: https://ethereum.github.io/yellowpaper/paper.pdf -pub const fn block_reward(base_block_reward: u128, ommers: usize) -> u128 { - base_block_reward + (base_block_reward >> 5) * ommers as u128 -} - -/// Calculate the reward for an ommer. -/// -/// # Application -/// -/// Rewards are accumulative, so they should be added to the beneficiary addresses in addition to -/// any other rewards from the same block. -/// -/// From the yellow paper (page 15): -/// -/// > If there are collisions of the beneficiary addresses between ommers and the block (i.e. two -/// > ommers with the same beneficiary address or an ommer with the same beneficiary address as the -/// > present block), additions are applied cumulatively. -/// -/// # References -/// -/// - Implementation: [OpenEthereum][oe] -/// - Definition: [Yellow Paper][yp] (page 15, 11.3) -/// -/// [oe]: https://github.com/openethereum/openethereum/blob/6c2d392d867b058ff867c4373e40850ca3f96969/crates/ethcore/src/ethereum/ethash.rs#L319-L333 -/// [yp]: https://ethereum.github.io/yellowpaper/paper.pdf -pub const fn ommer_reward( - base_block_reward: u128, - block_number: BlockNumber, - ommer_block_number: BlockNumber, -) -> u128 { - ((8 + ommer_block_number - block_number) as u128 * base_block_reward) >> 3 -} - -#[cfg(test)] -mod tests { - use super::*; - use alloy_primitives::U256; - use reth_chainspec::MAINNET; - - #[test] - fn calc_base_block_reward() { - // ((block number, td), reward) - let cases = [ - // Pre-byzantium - ((0, U256::ZERO), Some(ETH_TO_WEI * 5)), - // Byzantium - ((4370000, U256::ZERO), Some(ETH_TO_WEI * 3)), - // Petersburg - ((7280000, U256::ZERO), Some(ETH_TO_WEI * 2)), - // Merge - ((15537394, U256::from(58_750_000_000_000_000_000_000_u128)), None), - ]; - - for ((block_number, _td), expected_reward) in cases { - assert_eq!(base_block_reward(&*MAINNET, block_number), expected_reward); - } - } - - #[test] - fn calc_full_block_reward() { - let base_reward = ETH_TO_WEI; - let one_thirty_twoth_reward = base_reward >> 5; - - // (num_ommers, reward) - let cases = [ - (0, base_reward), - (1, base_reward + one_thirty_twoth_reward), - (2, base_reward + one_thirty_twoth_reward * 2), - ]; - - for (num_ommers, expected_reward) in cases { - assert_eq!(block_reward(base_reward, num_ommers), expected_reward); - } - } -} diff --git a/crates/consensus/common/src/lib.rs b/crates/consensus/common/src/lib.rs index 9e5eb2aaf0..b6971a0d52 100644 --- a/crates/consensus/common/src/lib.rs +++ b/crates/consensus/common/src/lib.rs @@ -11,6 +11,3 @@ /// Collection of consensus validation methods. pub mod validation; - -/// Various calculation methods (e.g. block rewards) -pub mod calc; diff --git a/crates/engine/tree/Cargo.toml b/crates/engine/tree/Cargo.toml index d5bcb5183f..5600aadf03 100644 --- a/crates/engine/tree/Cargo.toml +++ b/crates/engine/tree/Cargo.toml @@ -35,6 +35,7 @@ reth-trie-sparse.workspace = true reth-trie.workspace = true # alloy +alloy-evm.workspace = true alloy-consensus.workspace = true alloy-eips.workspace = true alloy-primitives.workspace = true diff --git a/crates/engine/tree/benches/state_root_task.rs b/crates/engine/tree/benches/state_root_task.rs index bec13ab3ff..aeb4fb4b13 100644 --- a/crates/engine/tree/benches/state_root_task.rs +++ b/crates/engine/tree/benches/state_root_task.rs @@ -4,6 +4,7 @@ #![allow(missing_docs)] use alloy_consensus::constants::KECCAK_EMPTY; +use alloy_evm::block::StateChangeSource; use alloy_primitives::{Address, B256}; use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; use proptest::test_runner::TestRunner; @@ -14,7 +15,7 @@ use reth_db_common::init::init_genesis; use reth_engine_tree::tree::{ executor::WorkloadExecutor, PayloadProcessor, StateProviderBuilder, TreeConfig, }; -use reth_evm::system_calls::{OnStateHook, StateChangeSource}; +use reth_evm::OnStateHook; use reth_evm_ethereum::EthEvmConfig; use reth_primitives_traits::{Account as RethAccount, StorageEntry}; use reth_provider::{ diff --git a/crates/engine/tree/src/tree/payload_processor/mod.rs b/crates/engine/tree/src/tree/payload_processor/mod.rs index ae8360a164..c128186022 100644 --- a/crates/engine/tree/src/tree/payload_processor/mod.rs +++ b/crates/engine/tree/src/tree/payload_processor/mod.rs @@ -10,15 +10,13 @@ use crate::tree::{ StateProviderBuilder, TreeConfig, }; use alloy_consensus::{transaction::Recovered, BlockHeader}; +use alloy_evm::block::StateChangeSource; use alloy_primitives::B256; use executor::WorkloadExecutor; use multiproof::*; use parking_lot::RwLock; use prewarm::PrewarmMetrics; -use reth_evm::{ - system_calls::{OnStateHook, StateChangeSource}, - ConfigureEvm, ConfigureEvmEnvFor, -}; +use reth_evm::{ConfigureEvm, ConfigureEvmEnvFor, OnStateHook}; use reth_primitives_traits::{NodePrimitives, SealedHeaderFor}; use reth_provider::{ providers::ConsistentDbView, BlockReader, DatabaseProviderFactory, StateCommitmentProvider, @@ -392,10 +390,11 @@ mod tests { }, StateProviderBuilder, TreeConfig, }; + use alloy_evm::block::StateChangeSource; use reth_chainspec::ChainSpec; use reth_db_common::init::init_genesis; use reth_ethereum_primitives::EthPrimitives; - use reth_evm::system_calls::{OnStateHook, StateChangeSource}; + use reth_evm::OnStateHook; use reth_evm_ethereum::EthEvmConfig; use reth_primitives_traits::{Account, StorageEntry}; use reth_provider::{ diff --git a/crates/engine/tree/src/tree/payload_processor/multiproof.rs b/crates/engine/tree/src/tree/payload_processor/multiproof.rs index 9d699ff41b..9de43695ff 100644 --- a/crates/engine/tree/src/tree/payload_processor/multiproof.rs +++ b/crates/engine/tree/src/tree/payload_processor/multiproof.rs @@ -1,11 +1,11 @@ //! Multiproof task related functionality. use crate::tree::payload_processor::{executor::WorkloadExecutor, sparse_trie::SparseTrieEvent}; +use alloy_evm::block::StateChangeSource; use alloy_primitives::{keccak256, map::HashSet, B256}; use derive_more::derive::Deref; use metrics::Histogram; use reth_errors::ProviderError; -use reth_evm::system_calls::StateChangeSource; use reth_metrics::Metrics; use reth_provider::{ providers::ConsistentDbView, BlockReader, DatabaseProviderFactory, StateCommitmentProvider, diff --git a/crates/engine/util/Cargo.toml b/crates/engine/util/Cargo.toml index fd8c18ed4b..795e476034 100644 --- a/crates/engine/util/Cargo.toml +++ b/crates/engine/util/Cargo.toml @@ -12,26 +12,18 @@ workspace = true [dependencies] # reth -reth-ethereum-primitives.workspace = true reth-primitives.workspace = true reth-primitives-traits.workspace = true reth-errors.workspace = true reth-chainspec.workspace = true -reth-consensus-common.workspace = true reth-fs-util.workspace = true reth-engine-primitives.workspace = true reth-evm.workspace = true reth-revm.workspace = true reth-provider.workspace = true -reth-ethereum-forks.workspace = true -revm-primitives.workspace = true -revm-database.workspace = true -reth-trie.workspace = true reth-payload-primitives.workspace = true # alloy -alloy-eips.workspace = true -alloy-primitives.workspace = true alloy-rpc-types-engine.workspace = true alloy-consensus.workspace = true diff --git a/crates/engine/util/src/lib.rs b/crates/engine/util/src/lib.rs index 7377de4a9c..72ee0d315b 100644 --- a/crates/engine/util/src/lib.rs +++ b/crates/engine/util/src/lib.rs @@ -1,5 +1,13 @@ //! Collection of various stream utilities for consensus engine. +#![doc( + html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", + html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", + issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" +)] +#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +#![cfg_attr(not(test), warn(unused_crate_dependencies))] + use futures::Stream; use reth_engine_primitives::{BeaconEngineMessage, EngineTypes}; use std::path::PathBuf; diff --git a/crates/ethereum/evm/Cargo.toml b/crates/ethereum/evm/Cargo.toml index 718becc24f..69e4d79db3 100644 --- a/crates/ethereum/evm/Cargo.toml +++ b/crates/ethereum/evm/Cargo.toml @@ -23,7 +23,6 @@ reth-primitives.workspace = true alloy-primitives.workspace = true alloy-eips.workspace = true alloy-evm.workspace = true -alloy-sol-types.workspace = true alloy-consensus.workspace = true [dev-dependencies] @@ -52,6 +51,5 @@ std = [ "reth-execution-types/std", "reth-evm/std", "reth-primitives-traits/std", - "alloy-sol-types/std", "revm/std", ] diff --git a/crates/ethereum/evm/src/build.rs b/crates/ethereum/evm/src/build.rs index d34917077c..5726ed1bd1 100644 --- a/crates/ethereum/evm/src/build.rs +++ b/crates/ethereum/evm/src/build.rs @@ -1,9 +1,9 @@ -use crate::execute::EthBlockExecutionCtx; use alloc::sync::Arc; use alloy_consensus::{ proofs, Block, BlockBody, BlockHeader, Header, Transaction, TxReceipt, EMPTY_OMMER_ROOT_HASH, }; use alloy_eips::merge::BEACON_NONCE; +use alloy_evm::{block::BlockExecutorFactory, eth::EthBlockExecutionCtx}; use alloy_primitives::Bytes; use reth_chainspec::{EthChainSpec, EthereumHardforks}; use reth_evm::execute::{ @@ -32,7 +32,7 @@ impl BlockAssembler for EthBlockAssembler where Evm: for<'a> BlockExecutionStrategyFactory< Primitives = EthPrimitives, - ExecutionCtx<'a> = EthBlockExecutionCtx<'a>, + BlockExecutorFactory: BlockExecutorFactory = EthBlockExecutionCtx<'a>>, >, ChainSpec: EthChainSpec + EthereumHardforks, { diff --git a/crates/ethereum/evm/src/dao_fork.rs b/crates/ethereum/evm/src/dao_fork.rs deleted file mode 100644 index e767958eeb..0000000000 --- a/crates/ethereum/evm/src/dao_fork.rs +++ /dev/null @@ -1,128 +0,0 @@ -//! DAO Fork related constants from [EIP-779](https://eips.ethereum.org/EIPS/eip-779). -//! It happened on Ethereum block 1_920_000 - -use alloy_primitives::{address, Address}; - -/// Dao hardfork beneficiary that received ether from accounts from DAO and DAO creator children. -pub static DAO_HARDFORK_BENEFICIARY: Address = - address!("0xbf4ed7b27f1d666546e30d74d50d173d20bca754"); - -/// DAO hardfork account that ether was taken and added to beneficiary -pub static DAO_HARDFORK_ACCOUNTS: [Address; 116] = [ - address!("0xd4fe7bc31cedb7bfb8a345f31e668033056b2728"), - address!("0xb3fb0e5aba0e20e5c49d252dfd30e102b171a425"), - address!("0x2c19c7f9ae8b751e37aeb2d93a699722395ae18f"), - address!("0xecd135fa4f61a655311e86238c92adcd779555d2"), - address!("0x1975bd06d486162d5dc297798dfc41edd5d160a7"), - address!("0xa3acf3a1e16b1d7c315e23510fdd7847b48234f6"), - address!("0x319f70bab6845585f412ec7724b744fec6095c85"), - address!("0x06706dd3f2c9abf0a21ddcc6941d9b86f0596936"), - address!("0x5c8536898fbb74fc7445814902fd08422eac56d0"), - address!("0x6966ab0d485353095148a2155858910e0965b6f9"), - address!("0x779543a0491a837ca36ce8c635d6154e3c4911a6"), - address!("0x2a5ed960395e2a49b1c758cef4aa15213cfd874c"), - address!("0x5c6e67ccd5849c0d29219c4f95f1a7a93b3f5dc5"), - address!("0x9c50426be05db97f5d64fc54bf89eff947f0a321"), - address!("0x200450f06520bdd6c527622a273333384d870efb"), - address!("0xbe8539bfe837b67d1282b2b1d61c3f723966f049"), - address!("0x6b0c4d41ba9ab8d8cfb5d379c69a612f2ced8ecb"), - address!("0xf1385fb24aad0cd7432824085e42aff90886fef5"), - address!("0xd1ac8b1ef1b69ff51d1d401a476e7e612414f091"), - address!("0x8163e7fb499e90f8544ea62bbf80d21cd26d9efd"), - address!("0x51e0ddd9998364a2eb38588679f0d2c42653e4a6"), - address!("0x627a0a960c079c21c34f7612d5d230e01b4ad4c7"), - address!("0xf0b1aa0eb660754448a7937c022e30aa692fe0c5"), - address!("0x24c4d950dfd4dd1902bbed3508144a54542bba94"), - address!("0x9f27daea7aca0aa0446220b98d028715e3bc803d"), - address!("0xa5dc5acd6a7968a4554d89d65e59b7fd3bff0f90"), - address!("0xd9aef3a1e38a39c16b31d1ace71bca8ef58d315b"), - address!("0x63ed5a272de2f6d968408b4acb9024f4cc208ebf"), - address!("0x6f6704e5a10332af6672e50b3d9754dc460dfa4d"), - address!("0x77ca7b50b6cd7e2f3fa008e24ab793fd56cb15f6"), - address!("0x492ea3bb0f3315521c31f273e565b868fc090f17"), - address!("0x0ff30d6de14a8224aa97b78aea5388d1c51c1f00"), - address!("0x9ea779f907f0b315b364b0cfc39a0fde5b02a416"), - address!("0xceaeb481747ca6c540a000c1f3641f8cef161fa7"), - address!("0xcc34673c6c40e791051898567a1222daf90be287"), - address!("0x579a80d909f346fbfb1189493f521d7f48d52238"), - address!("0xe308bd1ac5fda103967359b2712dd89deffb7973"), - address!("0x4cb31628079fb14e4bc3cd5e30c2f7489b00960c"), - address!("0xac1ecab32727358dba8962a0f3b261731aad9723"), - address!("0x4fd6ace747f06ece9c49699c7cabc62d02211f75"), - address!("0x440c59b325d2997a134c2c7c60a8c61611212bad"), - address!("0x4486a3d68fac6967006d7a517b889fd3f98c102b"), - address!("0x9c15b54878ba618f494b38f0ae7443db6af648ba"), - address!("0x27b137a85656544b1ccb5a0f2e561a5703c6a68f"), - address!("0x21c7fdb9ed8d291d79ffd82eb2c4356ec0d81241"), - address!("0x23b75c2f6791eef49c69684db4c6c1f93bf49a50"), - address!("0x1ca6abd14d30affe533b24d7a21bff4c2d5e1f3b"), - address!("0xb9637156d330c0d605a791f1c31ba5890582fe1c"), - address!("0x6131c42fa982e56929107413a9d526fd99405560"), - address!("0x1591fc0f688c81fbeb17f5426a162a7024d430c2"), - address!("0x542a9515200d14b68e934e9830d91645a980dd7a"), - address!("0xc4bbd073882dd2add2424cf47d35213405b01324"), - address!("0x782495b7b3355efb2833d56ecb34dc22ad7dfcc4"), - address!("0x58b95c9a9d5d26825e70a82b6adb139d3fd829eb"), - address!("0x3ba4d81db016dc2890c81f3acec2454bff5aada5"), - address!("0xb52042c8ca3f8aa246fa79c3feaa3d959347c0ab"), - address!("0xe4ae1efdfc53b73893af49113d8694a057b9c0d1"), - address!("0x3c02a7bc0391e86d91b7d144e61c2c01a25a79c5"), - address!("0x0737a6b837f97f46ebade41b9bc3e1c509c85c53"), - address!("0x97f43a37f595ab5dd318fb46e7a155eae057317a"), - address!("0x52c5317c848ba20c7504cb2c8052abd1fde29d03"), - address!("0x4863226780fe7c0356454236d3b1c8792785748d"), - address!("0x5d2b2e6fcbe3b11d26b525e085ff818dae332479"), - address!("0x5f9f3392e9f62f63b8eac0beb55541fc8627f42c"), - address!("0x057b56736d32b86616a10f619859c6cd6f59092a"), - address!("0x9aa008f65de0b923a2a4f02012ad034a5e2e2192"), - address!("0x304a554a310c7e546dfe434669c62820b7d83490"), - address!("0x914d1b8b43e92723e64fd0a06f5bdb8dd9b10c79"), - address!("0x4deb0033bb26bc534b197e61d19e0733e5679784"), - address!("0x07f5c1e1bc2c93e0402f23341973a0e043f7bf8a"), - address!("0x35a051a0010aba705c9008d7a7eff6fb88f6ea7b"), - address!("0x4fa802324e929786dbda3b8820dc7834e9134a2a"), - address!("0x9da397b9e80755301a3b32173283a91c0ef6c87e"), - address!("0x8d9edb3054ce5c5774a420ac37ebae0ac02343c6"), - address!("0x0101f3be8ebb4bbd39a2e3b9a3639d4259832fd9"), - address!("0x5dc28b15dffed94048d73806ce4b7a4612a1d48f"), - address!("0xbcf899e6c7d9d5a215ab1e3444c86806fa854c76"), - address!("0x12e626b0eebfe86a56d633b9864e389b45dcb260"), - address!("0xa2f1ccba9395d7fcb155bba8bc92db9bafaeade7"), - address!("0xec8e57756626fdc07c63ad2eafbd28d08e7b0ca5"), - address!("0xd164b088bd9108b60d0ca3751da4bceb207b0782"), - address!("0x6231b6d0d5e77fe001c2a460bd9584fee60d409b"), - address!("0x1cba23d343a983e9b5cfd19496b9a9701ada385f"), - address!("0xa82f360a8d3455c5c41366975bde739c37bfeb8a"), - address!("0x9fcd2deaff372a39cc679d5c5e4de7bafb0b1339"), - address!("0x005f5cee7a43331d5a3d3eec71305925a62f34b6"), - address!("0x0e0da70933f4c7849fc0d203f5d1d43b9ae4532d"), - address!("0xd131637d5275fd1a68a3200f4ad25c71a2a9522e"), - address!("0xbc07118b9ac290e4622f5e77a0853539789effbe"), - address!("0x47e7aa56d6bdf3f36be34619660de61275420af8"), - address!("0xacd87e28b0c9d1254e868b81cba4cc20d9a32225"), - address!("0xadf80daec7ba8dcf15392f1ac611fff65d94f880"), - address!("0x5524c55fb03cf21f549444ccbecb664d0acad706"), - address!("0x40b803a9abce16f50f36a77ba41180eb90023925"), - address!("0xfe24cdd8648121a43a7c86d289be4dd2951ed49f"), - address!("0x17802f43a0137c506ba92291391a8a8f207f487d"), - address!("0x253488078a4edf4d6f42f113d1e62836a942cf1a"), - address!("0x86af3e9626fce1957c82e88cbf04ddf3a2ed7915"), - address!("0xb136707642a4ea12fb4bae820f03d2562ebff487"), - address!("0xdbe9b615a3ae8709af8b93336ce9b477e4ac0940"), - address!("0xf14c14075d6c4ed84b86798af0956deef67365b5"), - address!("0xca544e5c4687d109611d0f8f928b53a25af72448"), - address!("0xaeeb8ff27288bdabc0fa5ebb731b6f409507516c"), - address!("0xcbb9d3703e651b0d496cdefb8b92c25aeb2171f7"), - address!("0x6d87578288b6cb5549d5076a207456a1f6a63dc0"), - address!("0xb2c6f0dfbb716ac562e2d85d6cb2f8d5ee87603e"), - address!("0xaccc230e8a6e5be9160b8cdf2864dd2a001c28b6"), - address!("0x2b3455ec7fedf16e646268bf88846bd7a2319bb2"), - address!("0x4613f3bca5c44ea06337a9e439fbc6d42e501d0a"), - address!("0xd343b217de44030afaa275f54d31a9317c7f441e"), - address!("0x84ef4b2357079cd7a7c69fd7a37cd0609a679106"), - address!("0xda2fef9e4a3230988ff17df2165440f37e8b1708"), - address!("0xf4c64518ea10f995918a454158c6b61407ea345c"), - address!("0x7602b46df5390e432ef1c307d4f2c9ff6d65cc97"), - address!("0xbb9bc244d798123fde783fcc1c72d3bb8c189413"), - address!("0x807640a13483f8ac783c557fcdf27be11ea4ac7a"), -]; diff --git a/crates/ethereum/evm/src/eip6110.rs b/crates/ethereum/evm/src/eip6110.rs deleted file mode 100644 index 6ae22bf321..0000000000 --- a/crates/ethereum/evm/src/eip6110.rs +++ /dev/null @@ -1,206 +0,0 @@ -//! EIP-6110 deposit requests parsing -use alloc::{string::ToString, vec::Vec}; -use alloy_eips::eip6110::MAINNET_DEPOSIT_CONTRACT_ADDRESS; -use alloy_primitives::{Address, Bytes, Log}; -use alloy_sol_types::{sol, SolEvent}; -use reth_chainspec::{ChainSpec, EthChainSpec}; -use reth_evm::execute::BlockValidationError; -use reth_primitives::Receipt; - -/// The size of a deposit request in bytes. While the event fields emit -/// bytestrings, those bytestrings are fixed size. The fields are: 48-byte -/// pubkey, 32-byte withdrawal credentials, 8-byte amount, 96-byte signature, -/// and 8-byte index. -const DEPOSIT_BYTES_SIZE: usize = 48 + 32 + 8 + 96 + 8; - -sol! { - #[allow(missing_docs)] - event DepositEvent( - bytes pubkey, - bytes withdrawal_credentials, - bytes amount, - bytes signature, - bytes index - ); -} - -/// Accumulate a deposit request from a log. containing a [`DepositEvent`]. -pub fn accumulate_deposit_from_log(log: &Log, out: &mut Vec) { - out.reserve(DEPOSIT_BYTES_SIZE); - out.extend_from_slice(log.pubkey.as_ref()); - out.extend_from_slice(log.withdrawal_credentials.as_ref()); - out.extend_from_slice(log.amount.as_ref()); - out.extend_from_slice(log.signature.as_ref()); - out.extend_from_slice(log.index.as_ref()); -} - -/// Accumulate deposits from an iterator of logs. -pub fn accumulate_deposits_from_logs<'a>( - address: Address, - logs: impl IntoIterator, - out: &mut Vec, -) -> Result<(), BlockValidationError> { - logs.into_iter() - // filter logs by address - .filter(|log| log.address == address) - // explicitly filter logs by the DepositEvent's signature hash (first topic) - .filter(|log| { - // 0x649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5 - log.topics().first() == Some(&DepositEvent::SIGNATURE_HASH) - }) - .try_for_each(|log| { - // We assume that the log is valid because it was emitted by the - // deposit contract. - let decoded_log = - DepositEvent::decode_log(log, false).map_err(|err: alloy_sol_types::Error| { - BlockValidationError::DepositRequestDecode(err.to_string()) - })?; - accumulate_deposit_from_log(&decoded_log, out); - Ok(()) - }) -} - -/// Accumulate deposits from a receipt. Iterates over the logs in the receipt -/// and accumulates the deposit request bytestrings. -pub fn accumulate_deposits_from_receipt( - address: Address, - receipt: &Receipt, - out: &mut Vec, -) -> Result<(), BlockValidationError> { - accumulate_deposits_from_logs(address, &receipt.logs, out) -} - -/// Accumulate deposits from a list of receipts. Iterates over the logs in the -/// receipts and accumulates the deposit request bytestrings. -pub fn accumulate_deposits_from_receipts<'a, I>( - address: Address, - receipts: I, - out: &mut Vec, -) -> Result<(), BlockValidationError> -where - I: IntoIterator, -{ - receipts - .into_iter() - .try_for_each(|receipt| accumulate_deposits_from_receipt(address, receipt, out)) -} - -/// Find deposit logs in a list of receipts, and return the concatenated -/// deposit request bytestring. -/// -/// The address of the deposit contract is taken from the chain spec, and -/// defaults to [`MAINNET_DEPOSIT_CONTRACT_ADDRESS`] if not specified in -/// the chain spec. -pub fn parse_deposits_from_receipts<'a, I>( - chainspec: &ChainSpec, - receipts: I, -) -> Result -where - I: IntoIterator, -{ - let mut out = Vec::new(); - accumulate_deposits_from_receipts( - chainspec.deposit_contract().map(|c| c.address).unwrap_or(MAINNET_DEPOSIT_CONTRACT_ADDRESS), - receipts, - &mut out, - )?; - Ok(out.into()) -} - -#[cfg(test)] -mod tests { - use super::*; - use alloy_primitives::{b256, bytes}; - use reth_chainspec::MAINNET; - use reth_primitives::TxType; - - #[test] - fn check_deposit_sig() { - let expected = b256!("0x649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5"); - assert_eq!(expected, DepositEvent::SIGNATURE_HASH); - } - - #[test] - fn test_parse_deposit_from_log() { - let receipts = vec![ - // https://etherscan.io/tx/0xa5239d4c542063d29022545835815b78b09f571f2bf1c8427f4765d6f5abbce9 - Receipt { - // these don't matter - tx_type: TxType::Legacy, - success: true, - cumulative_gas_used: 0, - logs: serde_json::from_str( - r#"[{"address":"0x00000000219ab540356cbb839cbe05303d7705fa","topics":["0x649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5"],"data":"0x00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030998c8086669bf65e24581cda47d8537966e9f5066fc6ffdcba910a1bfb91eae7a4873fcce166a1c4ea217e6b1afd396200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002001000000000000000000000001c340fb72ed14d4eaa71f7633ee9e33b88d4f3900000000000000000000000000000000000000000000000000000000000000080040597307000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006098ddbffd700c1aac324cfdf0492ff289223661eb26718ce3651ba2469b22f480d56efab432ed91af05a006bde0c1ea68134e0acd8cacca0c13ad1f716db874b44abfcc966368019753174753bca3af2ea84bc569c46f76592a91e97f311eddec0000000000000000000000000000000000000000000000000000000000000008e474160000000000000000000000000000000000000000000000000000000000","blockHash":"0x8d1289c5a7e0965b1d1bb75cdc4c3f73dda82d4ebb94ff5b98d1389cebd53b56","blockNumber":"0x12f0d8d","transactionHash":"0xa5239d4c542063d29022545835815b78b09f571f2bf1c8427f4765d6f5abbce9","transactionIndex":"0xc4","logIndex":"0x18f","removed":false}]"# - ).unwrap(), - }, - // https://etherscan.io/tx/0xd9734d4e3953bcaa939fd1c1d80950ee54aeecc02eef6ae8179f47f5b7103338 - Receipt { - // these don't matter - tx_type: TxType::Legacy, - success: true, - cumulative_gas_used: 0, - logs: serde_json::from_str( - r#"[{"address":"0x00000000219ab540356cbb839cbe05303d7705fa","topics":["0x649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5"],"data":"0x00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030a1a2ba870a90e889aa594a0cc1c6feffb94c2d8f65646c937f1f456a315ef649533e25a4614d8f4f66ebdb06481b90af0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200100000000000000000000000a0f04a231efbc29e1db7d086300ff550211c2f6000000000000000000000000000000000000000000000000000000000000000800405973070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060ad416d590e1a7f52baff770a12835b68904efad22cc9f8ba531e50cbbd26f32b9c7373cf6538a0577f501e4d3e3e63e208767bcccaae94e1e3720bfb734a286f9c017d17af46536545ccb7ca94d71f295e71f6d25bf978c09ada6f8d3f7ba0390000000000000000000000000000000000000000000000000000000000000008e374160000000000000000000000000000000000000000000000000000000000","blockHash":"0x8d1289c5a7e0965b1d1bb75cdc4c3f73dda82d4ebb94ff5b98d1389cebd53b56","blockNumber":"0x12f0d8d","transactionHash":"0xd9734d4e3953bcaa939fd1c1d80950ee54aeecc02eef6ae8179f47f5b7103338","transactionIndex":"0x7c","logIndex":"0xe2","removed":false}]"#, - ).unwrap(), - }, - ]; - - let request_data = parse_deposits_from_receipts(&MAINNET, &receipts).unwrap(); - assert_eq!( - request_data, - bytes!( - "998c8086669bf65e24581cda47d8537966e9f5066fc6ffdcba910a1bfb91eae7a4873fcce166a1c4ea217e6b1afd396201000000000000000000000001c340fb72ed14d4eaa71f7633ee9e33b88d4f39004059730700000098ddbffd700c1aac324cfdf0492ff289223661eb26718ce3651ba2469b22f480d56efab432ed91af05a006bde0c1ea68134e0acd8cacca0c13ad1f716db874b44abfcc966368019753174753bca3af2ea84bc569c46f76592a91e97f311eddece474160000000000a1a2ba870a90e889aa594a0cc1c6feffb94c2d8f65646c937f1f456a315ef649533e25a4614d8f4f66ebdb06481b90af0100000000000000000000000a0f04a231efbc29e1db7d086300ff550211c2f60040597307000000ad416d590e1a7f52baff770a12835b68904efad22cc9f8ba531e50cbbd26f32b9c7373cf6538a0577f501e4d3e3e63e208767bcccaae94e1e3720bfb734a286f9c017d17af46536545ccb7ca94d71f295e71f6d25bf978c09ada6f8d3f7ba039e374160000000000" - ) - ); - } - - #[test] - fn test_parse_deposit_from_log_extra() { - let receipts = vec![ - Receipt { - // these don't matter - tx_type: TxType::Legacy, - success: true, - cumulative_gas_used: 0, - // Transfer + Deposit - logs: serde_json::from_str( - r#"[ - { - "address": "0x00000000219ab540356cbb839cbe05303d7705fa", - "topics": [ - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", - "0x0000000000000000000000008b0c2c4c8eb078bc6c01f48523764c8942c0c6c4", - "0x0000000000000000000000000000000000000000000000000000000000000000" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000001", - "blockNumber": "0x158c89", - "transactionHash": "0xfcd133f57d5bab8cea211bab0361379456b9115a66bd242d62582aab0bb5fe71", - "transactionIndex": "0x0", - "blockHash": "0xe826da725061cdd2ab7638d4c4b5f25a07491f131d05b89628c4613cad07a246", - "logIndex": "0x0", - "removed": false - }, - {"address":"0x00000000219ab540356cbb839cbe05303d7705fa","topics":["0x649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5"],"data":"0x00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030998c8086669bf65e24581cda47d8537966e9f5066fc6ffdcba910a1bfb91eae7a4873fcce166a1c4ea217e6b1afd396200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002001000000000000000000000001c340fb72ed14d4eaa71f7633ee9e33b88d4f3900000000000000000000000000000000000000000000000000000000000000080040597307000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006098ddbffd700c1aac324cfdf0492ff289223661eb26718ce3651ba2469b22f480d56efab432ed91af05a006bde0c1ea68134e0acd8cacca0c13ad1f716db874b44abfcc966368019753174753bca3af2ea84bc569c46f76592a91e97f311eddec0000000000000000000000000000000000000000000000000000000000000008e474160000000000000000000000000000000000000000000000000000000000","blockHash":"0x8d1289c5a7e0965b1d1bb75cdc4c3f73dda82d4ebb94ff5b98d1389cebd53b56","blockNumber":"0x12f0d8d","transactionHash":"0xa5239d4c542063d29022545835815b78b09f571f2bf1c8427f4765d6f5abbce9","transactionIndex":"0xc4","logIndex":"0x18f","removed":false}]"# - ).unwrap(), - }, - // https://etherscan.io/tx/0xd9734d4e3953bcaa939fd1c1d80950ee54aeecc02eef6ae8179f47f5b7103338 - Receipt { - // these don't matter - tx_type: TxType::Legacy, - success: true, - cumulative_gas_used: 0, - logs: serde_json::from_str( - r#"[{"address":"0x00000000219ab540356cbb839cbe05303d7705fa","topics":["0x649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5"],"data":"0x00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030a1a2ba870a90e889aa594a0cc1c6feffb94c2d8f65646c937f1f456a315ef649533e25a4614d8f4f66ebdb06481b90af0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200100000000000000000000000a0f04a231efbc29e1db7d086300ff550211c2f6000000000000000000000000000000000000000000000000000000000000000800405973070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060ad416d590e1a7f52baff770a12835b68904efad22cc9f8ba531e50cbbd26f32b9c7373cf6538a0577f501e4d3e3e63e208767bcccaae94e1e3720bfb734a286f9c017d17af46536545ccb7ca94d71f295e71f6d25bf978c09ada6f8d3f7ba0390000000000000000000000000000000000000000000000000000000000000008e374160000000000000000000000000000000000000000000000000000000000","blockHash":"0x8d1289c5a7e0965b1d1bb75cdc4c3f73dda82d4ebb94ff5b98d1389cebd53b56","blockNumber":"0x12f0d8d","transactionHash":"0xd9734d4e3953bcaa939fd1c1d80950ee54aeecc02eef6ae8179f47f5b7103338","transactionIndex":"0x7c","logIndex":"0xe2","removed":false}]"#, - ).unwrap(), - }, - ]; - - let request_data = parse_deposits_from_receipts(&MAINNET, &receipts).unwrap(); - assert_eq!( - request_data, - bytes!( - "998c8086669bf65e24581cda47d8537966e9f5066fc6ffdcba910a1bfb91eae7a4873fcce166a1c4ea217e6b1afd396201000000000000000000000001c340fb72ed14d4eaa71f7633ee9e33b88d4f39004059730700000098ddbffd700c1aac324cfdf0492ff289223661eb26718ce3651ba2469b22f480d56efab432ed91af05a006bde0c1ea68134e0acd8cacca0c13ad1f716db874b44abfcc966368019753174753bca3af2ea84bc569c46f76592a91e97f311eddece474160000000000a1a2ba870a90e889aa594a0cc1c6feffb94c2d8f65646c937f1f456a315ef649533e25a4614d8f4f66ebdb06481b90af0100000000000000000000000a0f04a231efbc29e1db7d086300ff550211c2f60040597307000000ad416d590e1a7f52baff770a12835b68904efad22cc9f8ba531e50cbbd26f32b9c7373cf6538a0577f501e4d3e3e63e208767bcccaae94e1e3720bfb734a286f9c017d17af46536545ccb7ca94d71f295e71f6d25bf978c09ada6f8d3f7ba039e374160000000000" - ) - ); - } -} diff --git a/crates/ethereum/evm/src/execute.rs b/crates/ethereum/evm/src/execute.rs index e0e6ddc9c5..1da1d99458 100644 --- a/crates/ethereum/evm/src/execute.rs +++ b/crates/ethereum/evm/src/execute.rs @@ -1,32 +1,18 @@ //! Ethereum block execution strategy. -use crate::{ - dao_fork::{DAO_HARDFORK_ACCOUNTS, DAO_HARDFORK_BENEFICIARY}, - EthBlockAssembler, EthEvmConfig, +use crate::{EthBlockAssembler, EthEvmConfig, RethReceiptBuilder}; +use alloc::{borrow::Cow, sync::Arc}; +use alloy_evm::{ + eth::{EthBlockExecutionCtx, EthBlockExecutorFactory}, + FromRecoveredTx, }; -use alloc::{borrow::Cow, boxed::Box, sync::Arc, vec::Vec}; -use alloy_consensus::{Header, Transaction}; -use alloy_eips::{eip4895::Withdrawals, eip6110, eip7685::Requests}; -use alloy_evm::FromRecoveredTx; -use alloy_primitives::B256; -use reth_chainspec::{ChainSpec, EthereumHardfork, EthereumHardforks}; +use reth_chainspec::ChainSpec; use reth_evm::{ - execute::{ - balance_increment_state, BasicBlockExecutorProvider, BlockExecutionError, - BlockExecutionStrategy, BlockExecutionStrategyFactory, BlockValidationError, - }, - state_change::post_block_balance_increments, - system_calls::{OnStateHook, StateChangePostBlockSource, StateChangeSource, SystemCaller}, - Database, Evm, EvmFactory, EvmFor, InspectorFor, TransactionEnv, -}; -use reth_execution_types::BlockExecutionResult; -use reth_primitives::{ - EthPrimitives, Receipt, Recovered, SealedBlock, SealedHeader, TransactionSigned, -}; -use revm::{ - context::result::ExecutionResult, context_interface::result::ResultAndState, database::State, - specification::hardfork::SpecId, DatabaseCommit, + execute::{BasicBlockExecutorProvider, BlockExecutionStrategyFactory}, + EvmFactory, TransactionEnv, }; +use reth_primitives::{EthPrimitives, SealedBlock, SealedHeader, TransactionSigned}; +use revm::specification::hardfork::SpecId; impl BlockExecutionStrategyFactory for EthEvmConfig where @@ -38,16 +24,18 @@ where + 'static, { type Primitives = EthPrimitives; - type Strategy<'a, DB: Database + 'a, I: InspectorFor<&'a mut State, Self> + 'a> = - EthExecutionStrategy<'a, EvmFor, I>>; - type ExecutionCtx<'a> = EthBlockExecutionCtx<'a>; + type BlockExecutorFactory = EthBlockExecutorFactory, EvmF>; type BlockAssembler = EthBlockAssembler; + fn block_executor_factory(&self) -> &Self::BlockExecutorFactory { + &self.executor_factory + } + fn block_assembler(&self) -> &Self::BlockAssembler { &self.block_assembler } - fn context_for_block<'a>(&self, block: &'a SealedBlock) -> Self::ExecutionCtx<'a> { + fn context_for_block<'a>(&self, block: &'a SealedBlock) -> EthBlockExecutionCtx<'a> { EthBlockExecutionCtx { parent_hash: block.header().parent_hash, parent_beacon_block_root: block.header().parent_beacon_block_root, @@ -60,7 +48,7 @@ where &self, parent: &SealedHeader, attributes: Self::NextBlockEnvCtx, - ) -> Self::ExecutionCtx<'_> { + ) -> EthBlockExecutionCtx<'_> { EthBlockExecutionCtx { parent_hash: parent.hash(), parent_beacon_block_root: attributes.parent_beacon_block_root, @@ -68,197 +56,6 @@ where withdrawals: attributes.withdrawals.map(Cow::Owned), } } - - fn create_strategy<'a, DB, I>( - &'a self, - evm: EvmFor, I>, - ctx: Self::ExecutionCtx<'a>, - ) -> Self::Strategy<'a, DB, I> - where - DB: Database, - I: InspectorFor<&'a mut State, Self> + 'a, - { - EthExecutionStrategy::new(evm, ctx, &self.chain_spec) - } -} - -/// Context for Ethereum block execution. -#[derive(Debug, Clone)] -pub struct EthBlockExecutionCtx<'a> { - /// Parent block hash. - pub parent_hash: B256, - /// Parent beacon block root. - pub parent_beacon_block_root: Option, - /// Block ommers - pub ommers: &'a [Header], - /// Block withdrawals. - pub withdrawals: Option>, -} - -/// Block execution strategy for Ethereum. -#[derive(Debug)] -pub struct EthExecutionStrategy<'a, Evm> { - /// Reference to the [`ChainSpec`]. - chain_spec: &'a ChainSpec, - - /// Context for block execution. - pub ctx: EthBlockExecutionCtx<'a>, - /// The EVM used by strategy. - evm: Evm, - /// Utility to call system smart contracts. - system_caller: SystemCaller<&'a ChainSpec>, - - /// Receipts of executed transactions. - receipts: Vec, - /// Total gas used by transactions in this block. - gas_used: u64, -} - -impl<'a, Evm> EthExecutionStrategy<'a, Evm> { - /// Creates a new [`EthExecutionStrategy`] - pub fn new(evm: Evm, ctx: EthBlockExecutionCtx<'a>, chain_spec: &'a ChainSpec) -> Self { - Self { - evm, - chain_spec, - ctx, - receipts: Vec::new(), - gas_used: 0, - system_caller: SystemCaller::new(chain_spec), - } - } -} - -impl<'db, DB, E> BlockExecutionStrategy for EthExecutionStrategy<'_, E> -where - DB: Database + 'db, - E: Evm, Tx: FromRecoveredTx>, -{ - type Transaction = TransactionSigned; - type Receipt = Receipt; - type Evm = E; - - fn apply_pre_execution_changes(&mut self) -> Result<(), BlockExecutionError> { - // 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(self.evm.block().number); - self.evm.db_mut().set_state_clear_flag(state_clear_flag); - self.system_caller.apply_blockhashes_contract_call(self.ctx.parent_hash, &mut self.evm)?; - self.system_caller - .apply_beacon_root_contract_call(self.ctx.parent_beacon_block_root, &mut self.evm)?; - - Ok(()) - } - - fn execute_transaction_with_result_closure( - &mut self, - tx: Recovered<&TransactionSigned>, - f: impl FnOnce(&ExecutionResult<::HaltReason>), - ) -> Result { - // 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 = self.evm.block().gas_limit - self.gas_used; - if tx.gas_limit() > block_available_gas { - return Err(BlockValidationError::TransactionGasLimitMoreThanAvailableBlockGas { - transaction_gas_limit: tx.gas_limit(), - block_available_gas, - } - .into()) - } - - let hash = tx.hash(); - - // Execute transaction. - let result_and_state = - self.evm.transact(tx).map_err(move |err| BlockExecutionError::evm(err, *hash))?; - self.system_caller - .on_state(StateChangeSource::Transaction(self.receipts.len()), &result_and_state.state); - let ResultAndState { result, state } = result_and_state; - self.evm.db_mut().commit(state); - - f(&result); - - let gas_used = result.gas_used(); - - // append gas used - self.gas_used += gas_used; - - // Push transaction changeset and calculate header bloom filter for receipt. - self.receipts.push(Receipt { - tx_type: tx.tx_type(), - // Success flag was added in `EIP-658: Embedding transaction status code in - // receipts`. - success: result.is_success(), - cumulative_gas_used: self.gas_used, - logs: result.into_logs(), - }); - - Ok(gas_used) - } - - fn finish(mut self) -> Result<(Self::Evm, BlockExecutionResult), BlockExecutionError> { - let requests = if self.chain_spec.is_prague_active_at_timestamp(self.evm.block().timestamp) - { - // Collect all EIP-6110 deposits - let deposit_requests = - crate::eip6110::parse_deposits_from_receipts(self.chain_spec, &self.receipts)?; - - let mut requests = Requests::default(); - - if !deposit_requests.is_empty() { - requests.push_request_with_type(eip6110::DEPOSIT_REQUEST_TYPE, deposit_requests); - } - - requests.extend(self.system_caller.apply_post_execution_changes(&mut self.evm)?); - requests - } else { - Requests::default() - }; - - let mut balance_increments = post_block_balance_increments( - self.chain_spec, - self.evm.block(), - self.ctx.ommers, - self.ctx.withdrawals.as_deref(), - ); - - // Irregular state change at Ethereum DAO hardfork - if self.chain_spec.fork(EthereumHardfork::Dao).transitions_at_block(self.evm.block().number) - { - // drain balances from hardcoded addresses. - let drained_balance: u128 = self - .evm - .db_mut() - .drain_balances(DAO_HARDFORK_ACCOUNTS) - .map_err(|_| BlockValidationError::IncrementBalanceFailed)? - .into_iter() - .sum(); - - // return balance to DAO beneficiary. - *balance_increments.entry(DAO_HARDFORK_BENEFICIARY).or_default() += drained_balance; - } - // increment balances - self.evm - .db_mut() - .increment_balances(balance_increments.clone()) - .map_err(|_| BlockValidationError::IncrementBalanceFailed)?; - // call state hook with changes due to balance increments. - let balance_state = balance_increment_state(&balance_increments, self.evm.db_mut())?; - self.system_caller.on_state( - StateChangeSource::PostBlock(StateChangePostBlockSource::BalanceIncrements), - &balance_state, - ); - - let gas_used = self.receipts.last().map(|r| r.cumulative_gas_used).unwrap_or_default(); - Ok((self.evm, BlockExecutionResult { receipts: self.receipts, requests, gas_used })) - } - - fn with_state_hook(&mut self, hook: Option>) { - self.system_caller.with_state_hook(hook); - } - - fn evm_mut(&mut self) -> &mut Self::Evm { - &mut self.evm - } } /// Helper type with backwards compatible methods to obtain Ethereum executor @@ -289,8 +86,9 @@ mod tests { eip7002::{WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS, WITHDRAWAL_REQUEST_PREDEPLOY_CODE}, eip7685::EMPTY_REQUESTS_HASH, }; + use alloy_evm::block::BlockValidationError; use alloy_primitives::{b256, fixed_bytes, keccak256, Bytes, TxKind, B256, U256}; - use reth_chainspec::{ChainSpecBuilder, ForkCondition, MAINNET}; + use reth_chainspec::{ChainSpecBuilder, EthereumHardfork, ForkCondition, MAINNET}; use reth_evm::execute::{BasicBlockExecutorProvider, BlockExecutorProvider, Executor}; use reth_execution_types::BlockExecutionResult; use reth_primitives::{Block, BlockBody, RecoveredBlock, Transaction}; diff --git a/crates/ethereum/evm/src/lib.rs b/crates/ethereum/evm/src/lib.rs index 65efeae6ea..114f7e9a18 100644 --- a/crates/ethereum/evm/src/lib.rs +++ b/crates/ethereum/evm/src/lib.rs @@ -20,7 +20,7 @@ extern crate alloc; use alloc::sync::Arc; use alloy_consensus::{BlockHeader, Header}; pub use alloy_evm::EthEvm; -use alloy_evm::{EthEvmFactory, FromRecoveredTx}; +use alloy_evm::{eth::EthBlockExecutorFactory, EthEvmFactory, FromRecoveredTx}; use alloy_primitives::{Bytes, U256}; use core::{convert::Infallible, fmt::Debug}; use reth_chainspec::{ChainSpec, EthChainSpec, MAINNET}; @@ -44,18 +44,16 @@ pub mod execute; mod build; pub use build::EthBlockAssembler; -/// Ethereum DAO hardfork state change data. -pub mod dao_fork; - -/// [EIP-6110](https://eips.ethereum.org/EIPS/eip-6110) handling. -pub mod eip6110; +mod receipt; +pub use receipt::RethReceiptBuilder; /// Ethereum-related EVM configuration. #[derive(Debug, Clone)] pub struct EthEvmConfig { - chain_spec: Arc, - evm_factory: EvmFactory, - block_assembler: EthBlockAssembler, + /// Inner [`EthBlockExecutorFactory`]. + pub executor_factory: EthBlockExecutorFactory, EvmFactory>, + /// Ethereum block assembler. + pub block_assembler: EthBlockAssembler, } impl EthEvmConfig { @@ -80,14 +78,17 @@ impl EthEvmConfig { pub fn new_with_evm_factory(chain_spec: Arc, evm_factory: EvmFactory) -> Self { Self { block_assembler: EthBlockAssembler::new(chain_spec.clone()), - chain_spec, - evm_factory, + executor_factory: EthBlockExecutorFactory::new( + RethReceiptBuilder::default(), + chain_spec, + evm_factory, + ), } } /// Returns the chain spec associated with this configuration. pub const fn chain_spec(&self) -> &Arc { - &self.chain_spec + self.executor_factory.spec() } /// Sets the extra data for the block assembler. @@ -116,7 +117,7 @@ where let spec = config::revm_spec(self.chain_spec(), header); // configure evm env based on parent block - let cfg_env = CfgEnv::new().with_chain_id(self.chain_spec.chain().id()).with_spec(spec); + let cfg_env = CfgEnv::new().with_chain_id(self.chain_spec().chain().id()).with_spec(spec); let block_env = BlockEnv { number: header.number(), @@ -142,34 +143,35 @@ where ) -> Result { // ensure we're not missing any timestamp based hardforks let spec_id = revm_spec_by_timestamp_and_block_number( - &self.chain_spec, + self.chain_spec(), attributes.timestamp, parent.number() + 1, ); // configure evm env based on parent block - let cfg = CfgEnv::new().with_chain_id(self.chain_spec.chain().id()).with_spec(spec_id); + let cfg = CfgEnv::new().with_chain_id(self.chain_spec().chain().id()).with_spec(spec_id); // if the parent block did not have excess blob gas (i.e. it was pre-cancun), but it is // cancun now, we need to set the excess blob gas to the default value(0) let blob_excess_gas_and_price = parent .maybe_next_block_excess_blob_gas( - self.chain_spec.blob_params_at_timestamp(attributes.timestamp), + self.chain_spec().blob_params_at_timestamp(attributes.timestamp), ) .or_else(|| (spec_id == SpecId::CANCUN).then_some(0)) .map(|gas| BlobExcessGasAndPrice::new(gas, spec_id >= SpecId::PRAGUE)); let mut basefee = parent.next_block_base_fee( - self.chain_spec.base_fee_params_at_timestamp(attributes.timestamp), + self.chain_spec().base_fee_params_at_timestamp(attributes.timestamp), ); let mut gas_limit = attributes.gas_limit; // If we are on the London fork boundary, we need to multiply the parent's gas limit by the // elasticity multiplier to get the new gas limit. - if self.chain_spec.fork(EthereumHardfork::London).transitions_at_block(parent.number + 1) { + if self.chain_spec().fork(EthereumHardfork::London).transitions_at_block(parent.number + 1) + { let elasticity_multiplier = self - .chain_spec + .chain_spec() .base_fee_params_at_timestamp(attributes.timestamp) .elasticity_multiplier; @@ -208,7 +210,7 @@ where type EvmFactory = EvmF; fn evm_factory(&self) -> &Self::EvmFactory { - &self.evm_factory + self.executor_factory.evm_factory() } } diff --git a/crates/ethereum/evm/src/receipt.rs b/crates/ethereum/evm/src/receipt.rs new file mode 100644 index 0000000000..5b320e980c --- /dev/null +++ b/crates/ethereum/evm/src/receipt.rs @@ -0,0 +1,29 @@ +use alloy_evm::eth::receipt_builder::{ReceiptBuilder, ReceiptBuilderCtx}; +use reth_evm::Evm; +use reth_primitives::{Receipt, TransactionSigned}; + +/// A builder that operates on Reth primitive types, specifically [`TransactionSigned`] and +/// [`Receipt`]. +#[derive(Debug, Clone, Copy, Default)] +#[non_exhaustive] +pub struct RethReceiptBuilder; + +impl ReceiptBuilder for RethReceiptBuilder { + type Transaction = TransactionSigned; + type Receipt = Receipt; + + fn build_receipt( + &self, + ctx: ReceiptBuilderCtx<'_, Self::Transaction, E>, + ) -> Self::Receipt { + let ReceiptBuilderCtx { tx, result, cumulative_gas_used, .. } = ctx; + Receipt { + tx_type: tx.tx_type(), + // Success flag was added in `EIP-658: Embedding transaction status code in + // receipts`. + success: result.is_success(), + cumulative_gas_used, + logs: result.into_logs(), + } + } +} diff --git a/crates/evm/Cargo.toml b/crates/evm/Cargo.toml index 83dbef27f1..0e0f3deb33 100644 --- a/crates/evm/Cargo.toml +++ b/crates/evm/Cargo.toml @@ -12,8 +12,6 @@ workspace = true [dependencies] # reth -reth-chainspec.workspace = true -reth-consensus-common.workspace = true reth-execution-errors.workspace = true reth-execution-types.workspace = true reth-metrics = { workspace = true, optional = true } @@ -57,8 +55,6 @@ std = [ "revm/std", "reth-ethereum-forks/std", "reth-ethereum-primitives?/std", - "reth-chainspec/std", - "reth-consensus-common/std", "alloy-evm/std", "revm-database/std", "op-revm?/std", @@ -77,8 +73,6 @@ metrics = [ ] test-utils = [ "dep:parking_lot", - "dep:reth-ethereum-primitives", - "reth-chainspec/test-utils", "reth-ethereum-primitives/test-utils", "reth-primitives-traits/test-utils", "revm/test-utils", diff --git a/crates/evm/execution-errors/src/lib.rs b/crates/evm/execution-errors/src/lib.rs index 0727328262..b8ddd1b446 100644 --- a/crates/evm/execution-errors/src/lib.rs +++ b/crates/evm/execution-errors/src/lib.rs @@ -11,227 +11,9 @@ extern crate alloc; -use alloc::{ - boxed::Box, - string::{String, ToString}, -}; -use alloy_evm::{EvmError, InvalidTxError}; -use alloy_primitives::B256; -use reth_storage_errors::provider::ProviderError; -use thiserror::Error; - pub mod trie; pub use trie::*; -/// Transaction validation errors -#[derive(Error, Debug)] -pub enum BlockValidationError { - /// EVM error with transaction hash and message - #[error("EVM reported invalid transaction ({hash}): {error}")] - InvalidTx { - /// The hash of the transaction - hash: B256, - /// The EVM error. - error: Box, - }, - /// Error when incrementing balance in post execution - #[error("incrementing balance in post execution failed")] - IncrementBalanceFailed, - /// Error when transaction gas limit exceeds available block gas - #[error( - "transaction gas limit {transaction_gas_limit} is more than blocks available gas {block_available_gas}" - )] - TransactionGasLimitMoreThanAvailableBlockGas { - /// The transaction's gas limit - transaction_gas_limit: u64, - /// The available block gas - block_available_gas: u64, - }, - /// Error for EIP-4788 when parent beacon block root is missing - #[error("EIP-4788 parent beacon block root missing for active Cancun block")] - MissingParentBeaconBlockRoot, - /// Error for Cancun genesis block when parent beacon block root is not zero - #[error( - "the parent beacon block root is not zero for Cancun genesis block: {parent_beacon_block_root}" - )] - CancunGenesisParentBeaconBlockRootNotZero { - /// The beacon block root - parent_beacon_block_root: B256, - }, - /// EVM error during [EIP-4788] beacon root contract call. - /// - /// [EIP-4788]: https://eips.ethereum.org/EIPS/eip-4788 - #[error("failed to apply beacon root contract call at {parent_beacon_block_root}: {message}")] - BeaconRootContractCall { - /// The beacon block root - parent_beacon_block_root: Box, - /// The error message. - message: String, - }, - /// EVM error during [EIP-2935] blockhash contract call. - /// - /// [EIP-2935]: https://eips.ethereum.org/EIPS/eip-2935 - #[error("failed to apply blockhash contract call: {message}")] - BlockHashContractCall { - /// The error message. - message: String, - }, - /// EVM error during withdrawal requests contract call [EIP-7002] - /// - /// [EIP-7002]: https://eips.ethereum.org/EIPS/eip-7002 - #[error("failed to apply withdrawal requests contract call: {message}")] - WithdrawalRequestsContractCall { - /// The error message. - message: String, - }, - /// EVM error during consolidation requests contract call [EIP-7251] - /// - /// [EIP-7251]: https://eips.ethereum.org/EIPS/eip-7251 - #[error("failed to apply consolidation requests contract call: {message}")] - ConsolidationRequestsContractCall { - /// The error message. - message: String, - }, - /// Error when decoding deposit requests from receipts [EIP-6110] - /// - /// [EIP-6110]: https://eips.ethereum.org/EIPS/eip-6110 - #[error("failed to decode deposit requests from receipts: {_0}")] - DepositRequestDecode(String), -} - -/// `BlockExecutor` Errors -#[derive(Error, Debug)] -pub enum BlockExecutionError { - /// Validation error, transparently wrapping [`BlockValidationError`] - #[error(transparent)] - Validation(#[from] BlockValidationError), - /// Internal, i.e. non consensus or validation related Block Executor Errors - #[error(transparent)] - Internal(#[from] InternalBlockExecutionError), -} - -impl BlockExecutionError { - /// Create a new [`BlockExecutionError::Internal`] variant, containing a - /// [`InternalBlockExecutionError::Other`] error. - pub fn other(error: E) -> Self - where - E: core::error::Error + Send + Sync + 'static, - { - Self::Internal(InternalBlockExecutionError::other(error)) - } - - /// Create a new [`BlockExecutionError::Internal`] variant, containing a - /// [`InternalBlockExecutionError::Other`] error with the given message. - pub fn msg(msg: impl core::fmt::Display) -> Self { - Self::Internal(InternalBlockExecutionError::msg(msg)) - } - - /// Returns the inner `BlockValidationError` if the error is a validation error. - pub const fn as_validation(&self) -> Option<&BlockValidationError> { - match self { - Self::Validation(err) => Some(err), - _ => None, - } - } - - /// Handles an EVM error occurred when executing a transaction. - /// - /// If an error matches [`EvmError::InvalidTransaction`], it will be wrapped into - /// [`BlockValidationError::InvalidTx`], otherwise into [`InternalBlockExecutionError::EVM`]. - pub fn evm(error: E, hash: B256) -> Self { - match error.try_into_invalid_tx_err() { - Ok(err) => { - Self::Validation(BlockValidationError::InvalidTx { hash, error: Box::new(err) }) - } - Err(err) => { - Self::Internal(InternalBlockExecutionError::EVM { hash, error: Box::new(err) }) - } - } - } -} - -impl From for BlockExecutionError { - fn from(error: ProviderError) -> Self { - Self::other(error) - } -} - -/// Internal (i.e., not validation or consensus related) `BlockExecutor` Errors -#[derive(Error, Debug)] -pub enum InternalBlockExecutionError { - /// EVM error occurred when executing transaction. This is different from - /// [`BlockValidationError::InvalidTx`] because it will only contain EVM errors which are not - /// transaction validation errors and are assumed to be fatal. - #[error("internal EVM error occurred when executing transaction {hash}: {error}")] - EVM { - /// The hash of the transaction - hash: B256, - /// The EVM error. - error: Box, - }, - /// Arbitrary Block Executor Errors - #[error(transparent)] - Other(Box), -} - -impl InternalBlockExecutionError { - /// Create a new [`InternalBlockExecutionError::Other`] variant. - pub fn other(error: E) -> Self - where - E: core::error::Error + Send + Sync + 'static, - { - Self::Other(Box::new(error)) - } - - /// Create a new [`InternalBlockExecutionError::Other`] from a given message. - pub fn msg(msg: impl core::fmt::Display) -> Self { - Self::Other(msg.to_string().into()) - } - - /// Returns the arbitrary error if it is [`InternalBlockExecutionError::Other`] - pub fn as_other(&self) -> Option<&(dyn core::error::Error + Send + Sync + 'static)> { - match self { - Self::Other(err) => Some(&**err), - _ => None, - } - } - - /// Attempts to downcast the [`InternalBlockExecutionError::Other`] variant to a concrete type - pub fn downcast(self) -> Result, Self> { - match self { - Self::Other(err) => err.downcast().map_err(Self::Other), - err => Err(err), - } - } - - /// Returns a reference to the [`InternalBlockExecutionError::Other`] value if this type is a - /// [`InternalBlockExecutionError::Other`] of that type. Returns None otherwise. - pub fn downcast_other(&self) -> Option<&T> { - let other = self.as_other()?; - other.downcast_ref() - } - - /// Returns true if the this type is a [`InternalBlockExecutionError::Other`] of that error - /// type. Returns false otherwise. - pub fn is_other(&self) -> bool { - self.as_other().map(|err| err.is::()).unwrap_or(false) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[derive(thiserror::Error, Debug)] - #[error("err")] - struct E; - - #[test] - fn other_downcast() { - let err = InternalBlockExecutionError::other(E); - assert!(err.is_other::()); - - assert!(err.downcast_other::().is_some()); - assert!(err.downcast::().is_ok()); - } -} +pub use alloy_evm::block::{ + BlockExecutionError, BlockValidationError, InternalBlockExecutionError, +}; diff --git a/crates/evm/execution-types/Cargo.toml b/crates/evm/execution-types/Cargo.toml index 26f6c520db..7648e0f319 100644 --- a/crates/evm/execution-types/Cargo.toml +++ b/crates/evm/execution-types/Cargo.toml @@ -19,6 +19,7 @@ revm.workspace = true revm-database.workspace = true # alloy +alloy-evm.workspace = true alloy-consensus.workspace = true alloy-primitives.workspace = true alloy-eips.workspace = true @@ -70,4 +71,5 @@ std = [ "reth-ethereum-primitives/std", "reth-trie-common/std", "revm-database/std", + "alloy-evm/std", ] diff --git a/crates/evm/execution-types/src/execute.rs b/crates/evm/execution-types/src/execute.rs index 0f4da96e5b..37b347602f 100644 --- a/crates/evm/execution-types/src/execute.rs +++ b/crates/evm/execution-types/src/execute.rs @@ -1,17 +1,6 @@ -use alloc::vec::Vec; -use alloy_eips::eip7685::Requests; use revm_database::BundleState; -/// The result of executing a block. -#[derive(Debug, Clone, Default, PartialEq, Eq)] -pub struct BlockExecutionResult { - /// All the receipts of the transactions in the block. - pub receipts: Vec, - /// All the EIP-7685 requests in the block. - pub requests: Requests, - /// The total gas used by the block. - pub gas_used: u64, -} +pub use alloy_evm::block::BlockExecutionResult; /// [`BlockExecutionResult`] combined with state. #[derive( diff --git a/crates/evm/src/either.rs b/crates/evm/src/either.rs index 45767eef61..3e988bb4eb 100644 --- a/crates/evm/src/either.rs +++ b/crates/evm/src/either.rs @@ -2,8 +2,7 @@ use crate::{ execute::{BlockExecutorProvider, Executor}, - system_calls::OnStateHook, - Database, + Database, OnStateHook, }; // re-export Either diff --git a/crates/evm/src/execute.rs b/crates/evm/src/execute.rs index 486c8983c0..45afc4ee5c 100644 --- a/crates/evm/src/execute.rs +++ b/crates/evm/src/execute.rs @@ -1,14 +1,15 @@ //! Traits for execution. -use alloy_consensus::BlockHeader; -use alloy_evm::{Evm, EvmEnv}; -use reth_storage_api::StateProvider; -use reth_trie_common::{updates::TrieUpdates, HashedPostState}; -// Re-export execution types use crate::{ - system_calls::OnStateHook, ConfigureEvmFor, Database, EvmFor, HaltReasonFor, InspectorFor, + ConfigureEvmFor, Database, EvmEnvFor, EvmFor, HaltReasonFor, InspectorFor, OnStateHook, }; use alloc::{boxed::Box, vec::Vec}; +use alloy_consensus::BlockHeader; +pub use alloy_evm::block::BlockExecutor; +use alloy_evm::{ + block::{BlockExecutorFactory, BlockExecutorFor}, + Evm, +}; use alloy_primitives::{ map::{DefaultHashBuilder, HashMap}, Address, B256, @@ -22,10 +23,11 @@ use reth_primitives_traits::{ BlockTy, HeaderTy, NodePrimitives, ReceiptTy, Recovered, RecoveredBlock, SealedBlock, SealedHeader, TxTy, }; +use reth_storage_api::StateProvider; pub use reth_storage_errors::provider::ProviderError; +use reth_trie_common::{updates::TrieUpdates, HashedPostState}; use revm::{ context::result::ExecutionResult, - inspector::NoOpInspector, state::{Account, AccountStatus, EvmState}, }; use revm_database::{states::bundle_state::BundleRetention, BundleState, State}; @@ -174,84 +176,10 @@ pub struct ExecuteOutput { pub gas_used: u64, } -/// A helper trait to bound [`BlockExecutionStrategy`] ATs to [`NodePrimitives`]. -pub trait BlockExecutionStrategyFor: - BlockExecutionStrategy -{ -} -impl BlockExecutionStrategyFor for T -where - N: NodePrimitives, - T: BlockExecutionStrategy, -{ -} - -/// Defines the strategy for executing a single block. -/// -/// The current abstraction assumes that block execution consists of the following steps: -/// 1. Apply pre-execution changes. Those might include system calls, irregular state transitions -/// (DAO fork), etc. -/// 2. Apply block transactions to the state. -/// 3. Apply post-execution changes and finalize the state. This might include other system calls, -/// block rewards, etc. -/// -/// The output of [`BlockExecutionStrategy::apply_post_execution_changes`] is a -/// [`BlockExecutionResult`] which contains all relevant information about the block execution. -pub trait BlockExecutionStrategy { - /// Input transaction type. - type Transaction; - /// Receipt type this strategy produces. - type Receipt; - /// EVM used by the strategy. - type Evm: Evm; - - /// Applies any necessary changes before executing the block's transactions. - fn apply_pre_execution_changes(&mut self) -> Result<(), BlockExecutionError>; - - /// Executes a single transaction and applies execution result to internal state. - /// - /// Returns the gas used by the transaction. - fn execute_transaction( - &mut self, - tx: Recovered<&Self::Transaction>, - ) -> Result { - self.execute_transaction_with_result_closure(tx, |_| ()) - } - - /// Executes a single transaction and applies execution result to internal state. Invokes the - /// given closure with an internal [`ExecutionResult`] produced by the EVM. - fn execute_transaction_with_result_closure( - &mut self, - tx: Recovered<&Self::Transaction>, - f: impl FnOnce(&ExecutionResult<::HaltReason>), - ) -> Result; - - /// Applies any necessary changes after executing the block's transactions. - fn apply_post_execution_changes( - self, - ) -> Result, BlockExecutionError> - where - Self: Sized, - { - self.finish().map(|(_, result)| result) - } - - /// Sets a hook to be called after each state change during execution. - fn with_state_hook(&mut self, hook: Option>); - - /// Exposes mutable reference to EVM. - fn evm_mut(&mut self) -> &mut Self::Evm; - - /// Completes execution and returns the underlying EVM along with execution result. - fn finish( - self, - ) -> Result<(Self::Evm, BlockExecutionResult), BlockExecutionError>; -} - /// A factory that can create block execution strategies. /// /// This trait extends [`crate::ConfigureEvm`] and provides a way to construct a -/// [`BlockExecutionStrategy`]. Strategy is expected to derive most of the context for block +/// [`BlockExecutor`]. Strategy is expected to derive most of the context for block /// execution from the EVM (which includes [`revm::context::BlockEnv`]), and any additional context /// should be contained in configured [`ExecutionCtx`]. /// @@ -259,65 +187,67 @@ pub trait BlockExecutionStrategy { /// [`SealedBlock`] (in case of execution of an externally obtained block), or from a parent header /// along with [`crate::ConfigureEvmEnv::NextBlockEnvCtx`] (in the case of block building). /// -/// For more context on the strategy design, see the documentation for [`BlockExecutionStrategy`]. +/// For more context on the strategy design, see the documentation for [`BlockExecutor`]. /// /// Additionally, trait implementations are expected to define a [`BlockAssembler`] type that is /// used to assemble blocks. Assembler combined with strategy are used to create a [`BlockBuilder`]. /// [`BlockBuilder`] exposes a simple API for building blocks and can be consumed by payload /// builder. /// -/// [`ExecutionCtx`]: BlockExecutionStrategyFactory::ExecutionCtx +/// [`ExecutionCtx`]: BlockExecutorFactory::ExecutionCtx pub trait BlockExecutionStrategyFactory: ConfigureEvmFor + 'static { /// Primitive types used by the strategy. type Primitives: NodePrimitives; - /// Strategy this factory produces. - type Strategy<'a, DB: Database + 'a, I: InspectorFor<&'a mut State, Self> + 'a>: BlockExecutionStrategyFor, I>, + /// Block executor factory. + type BlockExecutorFactory: BlockExecutorFactory< + EvmFactory = Self::EvmFactory, + Transaction = TxTy, + Receipt = ReceiptTy, >; - /// Context required for block execution. - /// - /// This is similar to [`alloy_evm::EvmEnv`], but only contains context unrelated to EVM and - /// required for execution of an entire block. - type ExecutionCtx<'a>: Clone; - /// A type that knows how to build a block. type BlockAssembler: BlockAssembler; + /// Provides reference to configured [`BlockExecutorFactory`]. + fn block_executor_factory(&self) -> &Self::BlockExecutorFactory; + /// Provides reference to configured [`BlockAssembler`]. fn block_assembler(&self) -> &Self::BlockAssembler; - /// Returns the configured [`BlockExecutionStrategyFactory::ExecutionCtx`] for a given block. + /// Returns the configured [`BlockExecutorFactory::ExecutionCtx`] for a given block. fn context_for_block<'a>( &self, block: &'a SealedBlock<::Block>, - ) -> Self::ExecutionCtx<'a>; + ) -> ::ExecutionCtx<'a>; - /// Returns the configured [`BlockExecutionStrategyFactory::ExecutionCtx`] for `parent + 1` + /// Returns the configured [`BlockExecutorFactory::ExecutionCtx`] for `parent + 1` /// block. fn context_for_next_block( &self, parent: &SealedHeader<::BlockHeader>, attributes: Self::NextBlockEnvCtx, - ) -> Self::ExecutionCtx<'_>; + ) -> ::ExecutionCtx<'_>; /// Creates a strategy with given EVM and execution context. fn create_strategy<'a, DB, I>( &'a self, evm: EvmFor, I>, - ctx: Self::ExecutionCtx<'a>, - ) -> Self::Strategy<'a, DB, I> + ctx: ::ExecutionCtx<'a>, + ) -> impl BlockExecutorFor<'a, Self::BlockExecutorFactory, DB, I> where DB: Database, - I: InspectorFor<&'a mut State, Self> + 'a; + I: InspectorFor<&'a mut State, Self> + 'a, + { + self.block_executor_factory().create_executor(evm, ctx) + } /// Creates a strategy for execution of a given block. fn strategy_for_block<'a, DB: Database>( &'a self, db: &'a mut State, block: &'a SealedBlock<::Block>, - ) -> Self::Strategy<'a, DB, NoOpInspector> { + ) -> impl BlockExecutorFor<'a, Self::BlockExecutorFactory, DB> { let evm = self.evm_for_block(db, block.header()); let ctx = self.context_for_block(block); self.create_strategy(evm, ctx) @@ -325,21 +255,24 @@ pub trait BlockExecutionStrategyFactory: ConfigureEvmFor + 'st /// Creates a [`BlockBuilder`]. Should be used when building a new block. /// - /// Block builder wraps an inner [`BlockExecutionStrategy`] and has a similar interface. Builder + /// Block builder wraps an inner [`BlockExecutor`] and has a similar interface. Builder /// collects all of the executed transactions, and once [`BlockBuilder::finish`] is called, it /// invokes the configured [`BlockAssembler`] to create a block. fn create_block_builder<'a, DB, I>( &'a self, evm: EvmFor, I>, parent: &'a SealedHeader>, - ctx: Self::ExecutionCtx<'a>, - ) -> impl BlockBuilder> + ctx: ::ExecutionCtx<'a>, + ) -> impl BlockBuilder< + Primitives = Self::Primitives, + Executor: BlockExecutorFor<'a, Self::BlockExecutorFactory, DB, I>, + > where DB: Database, I: InspectorFor<&'a mut State, Self> + 'a, { BasicBlockBuilder { - strategy: self.create_strategy(evm, ctx.clone()), + executor: self.create_strategy(evm, ctx.clone()), ctx, assembler: self.block_assembler(), parent, @@ -369,9 +302,9 @@ pub struct BlockAssemblerInput<'a, 'b, Evm: BlockExecutionStrategyFactory> { /// Configuration of EVM used when executing the block. /// /// Contains context relevant to EVM such as [`revm::context::BlockEnv`]. - pub evm_env: EvmEnv, - /// [`BlockExecutionStrategyFactory::ExecutionCtx`] used to execute the block. - pub execution_ctx: Evm::ExecutionCtx<'a>, + pub evm_env: EvmEnvFor, + /// [`BlockExecutorFactory::ExecutionCtx`] used to execute the block. + pub execution_ctx: ::ExecutionCtx<'a>, /// Parent block header. pub parent: &'a SealedHeader>, /// Transactions that were executed in this block. @@ -412,30 +345,31 @@ pub struct BlockBuilderOutcome { /// A type that knows how to execute and build a block. /// -/// It wraps an inner [`BlockExecutionStrategy`] and provides a way to execute transactions and +/// It wraps an inner [`BlockExecutor`] and provides a way to execute transactions and /// construct a block. /// /// This is a helper to erase `BasicBlockBuilder` type. pub trait BlockBuilder { - /// The primitive types used by the inner [`BlockExecutionStrategy`]. + /// The primitive types used by the inner [`BlockExecutor`]. type Primitives: NodePrimitives; - /// Inner [`BlockExecutionStrategy`]. - type Strategy: BlockExecutionStrategyFor; + /// Inner [`BlockExecutor`]. + type Executor: BlockExecutor< + Transaction = TxTy, + Receipt = ReceiptTy, + >; - /// Invokes [`BlockExecutionStrategy::apply_pre_execution_changes`]. + /// Invokes [`BlockExecutor::apply_pre_execution_changes`]. fn apply_pre_execution_changes(&mut self) -> Result<(), BlockExecutionError>; - /// Invokes [`BlockExecutionStrategy::execute_transaction_with_result_closure`] and saves the + /// Invokes [`BlockExecutor::execute_transaction_with_result_closure`] and saves the /// transaction in internal state. fn execute_transaction_with_result_closure( &mut self, tx: Recovered>, - f: impl FnOnce( - &ExecutionResult<<::Evm as Evm>::HaltReason>, - ), + f: impl FnOnce(&ExecutionResult<<::Evm as Evm>::HaltReason>), ) -> Result; - /// Invokes [`BlockExecutionStrategy::execute_transaction`] and saves the transaction in + /// Invokes [`BlockExecutor::execute_transaction`] and saves the transaction in /// internal state. fn execute_transaction( &mut self, @@ -450,52 +384,54 @@ pub trait BlockBuilder { state_provider: impl StateProvider, ) -> Result, BlockExecutionError>; - /// Provides mutable access to the inner [`BlockExecutionStrategy`]. - fn strategy_mut(&mut self) -> &mut Self::Strategy; + /// Provides mutable access to the inner [`BlockExecutor`]. + fn executor_mut(&mut self) -> &mut Self::Executor; - /// Helper to access inner [`BlockExecutionStrategy::Evm`]. - fn evm_mut(&mut self) -> &mut ::Evm { - self.strategy_mut().evm_mut() + /// Helper to access inner [`BlockExecutor::Evm`]. + fn evm_mut(&mut self) -> &mut ::Evm { + self.executor_mut().evm_mut() } - /// Consumes the type and returns the underlying [`BlockExecutionStrategy`]. - fn into_strategy(self) -> Self::Strategy; + /// Consumes the type and returns the underlying [`BlockExecutor`]. + fn into_executor(self) -> Self::Executor; } -struct BasicBlockBuilder<'a, Evm, DB, I, Builder> +struct BasicBlockBuilder<'a, Evm, Executor, Builder> where Evm: BlockExecutionStrategyFactory, - DB: Database + 'a, - I: InspectorFor<&'a mut State, Evm> + 'a, { - strategy: Evm::Strategy<'a, DB, I>, + executor: Executor, transactions: Vec>>, - ctx: Evm::ExecutionCtx<'a>, + ctx: ::ExecutionCtx<'a>, parent: &'a SealedHeader>, assembler: Builder, } -impl<'a, Evm, DB, I, Builder> BlockBuilder for BasicBlockBuilder<'a, Evm, DB, I, Builder> +impl<'a, E, DB, Executor, Builder> BlockBuilder for BasicBlockBuilder<'a, E, Executor, Builder> where - Evm: BlockExecutionStrategyFactory, + E: BlockExecutionStrategyFactory, + Executor: BlockExecutor< + Receipt = ReceiptTy, + Transaction = TxTy, + Evm: Evm, DB = &'a mut State>, + >, DB: Database + 'a, - I: InspectorFor<&'a mut State, Evm> + 'a, - Builder: BlockAssembler, + Builder: BlockAssembler, { - type Primitives = Evm::Primitives; - type Strategy = Evm::Strategy<'a, DB, I>; + type Primitives = E::Primitives; + type Executor = Executor; fn apply_pre_execution_changes(&mut self) -> Result<(), BlockExecutionError> { - self.strategy.apply_pre_execution_changes() + self.executor.apply_pre_execution_changes() } fn execute_transaction_with_result_closure( &mut self, tx: Recovered>, - f: impl FnOnce(&ExecutionResult>), + f: impl FnOnce(&ExecutionResult>), ) -> Result { let gas_used = - self.strategy.execute_transaction_with_result_closure(tx.as_recovered_ref(), f)?; + self.executor.execute_transaction_with_result_closure(tx.as_recovered_ref(), f)?; self.transactions.push(tx); Ok(gas_used) } @@ -503,8 +439,8 @@ where fn finish( self, state: impl StateProvider, - ) -> Result, BlockExecutionError> { - let (evm, result) = self.strategy.finish()?; + ) -> Result, BlockExecutionError> { + let (evm, result) = self.executor.finish()?; let (db, evm_env) = evm.finish(); // merge all transitions into bundle state @@ -512,7 +448,9 @@ where // calculate the state root let hashed_state = state.hashed_post_state(&db.bundle_state); - let (state_root, trie_updates) = state.state_root_with_updates(hashed_state.clone())?; + let (state_root, trie_updates) = state + .state_root_with_updates(hashed_state.clone()) + .map_err(BlockExecutionError::other)?; let (transactions, senders) = self.transactions.into_iter().map(|tx| tx.into_parts()).unzip(); @@ -533,12 +471,12 @@ where Ok(BlockBuilderOutcome { execution_result: result, hashed_state, trie_updates, block }) } - fn strategy_mut(&mut self) -> &mut Self::Strategy { - &mut self.strategy + fn executor_mut(&mut self) -> &mut Self::Executor { + &mut self.executor } - fn into_strategy(self) -> Self::Strategy { - self.strategy + fn into_executor(self) -> Self::Executor { + self.executor } } @@ -580,7 +518,7 @@ where } } -/// A generic block executor that uses a [`BlockExecutionStrategy`] to +/// A generic block executor that uses a [`BlockExecutor`] to /// execute blocks. #[allow(missing_debug_implementations, dead_code)] pub struct BasicBlockExecutor { @@ -633,8 +571,10 @@ where where H: OnStateHook + 'static, { - let mut strategy = self.strategy_factory.strategy_for_block(&mut self.db, block); - strategy.with_state_hook(Some(Box::new(state_hook))); + let mut strategy = self + .strategy_factory + .strategy_for_block(&mut self.db, block) + .with_state_hook(Some(Box::new(state_hook))); strategy.apply_pre_execution_changes()?; for tx in block.transactions_recovered() { diff --git a/crates/evm/src/lib.rs b/crates/evm/src/lib.rs index 9ced3fefe6..80f0505f3b 100644 --- a/crates/evm/src/lib.rs +++ b/crates/evm/src/lib.rs @@ -35,13 +35,16 @@ pub use aliases::*; #[cfg(feature = "metrics")] pub mod metrics; pub mod noop; -pub mod state_change; -pub mod system_calls; #[cfg(any(test, feature = "test-utils"))] /// test helpers for mocking executor pub mod test_utils; -pub use alloy_evm::{Database, Evm, EvmEnv, EvmError, FromRecoveredTx, InvalidTxError}; +pub use alloy_evm::{ + block::{state_changes, system_calls, OnStateHook}, + Database, Evm, EvmEnv, EvmError, FromRecoveredTx, InvalidTxError, +}; + +pub use alloy_evm::block::state_changes as state_change; /// Alias for `EvmEnv<::Spec>` pub type EvmEnvFor = EvmEnv<::Spec>; diff --git a/crates/evm/src/metrics.rs b/crates/evm/src/metrics.rs index 4bc1b1356c..023d44dacc 100644 --- a/crates/evm/src/metrics.rs +++ b/crates/evm/src/metrics.rs @@ -2,12 +2,9 @@ //! //! Block processing related to syncing should take care to update the metrics by using either //! [`ExecutorMetrics::execute_metered`] or [`ExecutorMetrics::metered_one`]. -use crate::{ - execute::Executor, - system_calls::{OnStateHook, StateChangeSource}, - Database, -}; +use crate::{execute::Executor, Database, OnStateHook}; use alloy_consensus::BlockHeader; +use alloy_evm::block::StateChangeSource; use metrics::{Counter, Gauge, Histogram}; use reth_execution_types::BlockExecutionOutput; use reth_metrics::Metrics; diff --git a/crates/evm/src/noop.rs b/crates/evm/src/noop.rs index e522f2a95d..41e78db448 100644 --- a/crates/evm/src/noop.rs +++ b/crates/evm/src/noop.rs @@ -2,8 +2,7 @@ use crate::{ execute::{BlockExecutorProvider, Executor}, - system_calls::OnStateHook, - Database, + Database, OnStateHook, }; use reth_execution_errors::BlockExecutionError; use reth_execution_types::BlockExecutionResult; diff --git a/crates/evm/src/state_change.rs b/crates/evm/src/state_change.rs deleted file mode 100644 index 8fb4f06b78..0000000000 --- a/crates/evm/src/state_change.rs +++ /dev/null @@ -1,321 +0,0 @@ -//! State changes that are not related to transactions. - -use alloy_consensus::BlockHeader; -use alloy_eips::eip4895::{Withdrawal, Withdrawals}; -use alloy_primitives::{map::HashMap, Address}; -use reth_chainspec::EthereumHardforks; -use reth_consensus_common::calc; -use revm::context::BlockEnv; - -/// Collect all balance changes at the end of the block. -/// -/// Balance changes might include the block reward, uncle rewards, withdrawals, or irregular -/// state changes (DAO fork). -#[inline] -pub fn post_block_balance_increments( - chain_spec: impl EthereumHardforks, - block_env: &BlockEnv, - ommers: &[H], - withdrawals: Option<&Withdrawals>, -) -> HashMap -where - H: BlockHeader, -{ - let mut balance_increments = HashMap::default(); - - // Add block rewards if they are enabled. - if let Some(base_block_reward) = calc::base_block_reward(&chain_spec, block_env.number) { - // Ommer rewards - for ommer in ommers { - *balance_increments.entry(ommer.beneficiary()).or_default() += - calc::ommer_reward(base_block_reward, block_env.number, ommer.number()); - } - - // Full block reward - *balance_increments.entry(block_env.beneficiary).or_default() += - calc::block_reward(base_block_reward, ommers.len()); - } - - // process withdrawals - insert_post_block_withdrawals_balance_increments( - chain_spec, - block_env.timestamp, - withdrawals.map(|w| w.as_slice()), - &mut balance_increments, - ); - - balance_increments -} - -/// Returns a map of addresses to their balance increments if the Shanghai hardfork is active at the -/// given timestamp. -/// -/// Zero-valued withdrawals are filtered out. -#[inline] -pub fn post_block_withdrawals_balance_increments( - chain_spec: &ChainSpec, - block_timestamp: u64, - withdrawals: &[Withdrawal], -) -> HashMap { - let mut balance_increments = - HashMap::with_capacity_and_hasher(withdrawals.len(), Default::default()); - insert_post_block_withdrawals_balance_increments( - chain_spec, - block_timestamp, - Some(withdrawals), - &mut balance_increments, - ); - balance_increments -} - -/// Applies all withdrawal balance increments if shanghai is active at the given timestamp to the -/// given `balance_increments` map. -/// -/// Zero-valued withdrawals are filtered out. -#[inline] -pub fn insert_post_block_withdrawals_balance_increments( - chain_spec: impl EthereumHardforks, - block_timestamp: u64, - withdrawals: Option<&[Withdrawal]>, - balance_increments: &mut HashMap, -) { - // Process withdrawals - if chain_spec.is_shanghai_active_at_timestamp(block_timestamp) { - if let Some(withdrawals) = withdrawals { - for withdrawal in withdrawals { - if withdrawal.amount > 0 { - *balance_increments.entry(withdrawal.address).or_default() += - withdrawal.amount_wei().to::(); - } - } - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use alloy_consensus::constants::GWEI_TO_WEI; - use reth_chainspec::ChainSpec; - use reth_ethereum_forks::{ChainHardforks, EthereumHardfork, ForkCondition}; - - /// Tests that the function correctly inserts balance increments when the Shanghai hardfork is - /// active and there are withdrawals. - #[test] - fn test_insert_post_block_withdrawals_balance_increments_shanghai_active_with_withdrawals() { - // Arrange - // Create a ChainSpec with the Shanghai hardfork active at timestamp 100 - let chain_spec = ChainSpec { - hardforks: ChainHardforks::new(vec![( - Box::new(EthereumHardfork::Shanghai), - ForkCondition::Timestamp(100), - )]), - ..Default::default() - }; - - // Define the block timestamp and withdrawals - let block_timestamp = 1000; - let withdrawals = vec![ - Withdrawal { - address: Address::from([1; 20]), - amount: 1000, - index: 45, - validator_index: 12, - }, - Withdrawal { - address: Address::from([2; 20]), - amount: 500, - index: 412, - validator_index: 123, - }, - ]; - - // Create an empty HashMap to hold the balance increments - let mut balance_increments = HashMap::default(); - - // Act - // Call the function with the prepared inputs - insert_post_block_withdrawals_balance_increments( - &chain_spec, - block_timestamp, - Some(&withdrawals), - &mut balance_increments, - ); - - // Assert - // Verify that the balance increments map has the correct number of entries - assert_eq!(balance_increments.len(), 2); - // Verify that the balance increments map contains the correct values for each address - assert_eq!( - *balance_increments.get(&Address::from([1; 20])).unwrap(), - (1000 * GWEI_TO_WEI).into() - ); - assert_eq!( - *balance_increments.get(&Address::from([2; 20])).unwrap(), - (500 * GWEI_TO_WEI).into() - ); - } - - /// Tests that the function correctly handles the case when Shanghai is active but there are no - /// withdrawals. - #[test] - fn test_insert_post_block_withdrawals_balance_increments_shanghai_active_no_withdrawals() { - // Arrange - // Create a ChainSpec with the Shanghai hardfork active - let chain_spec = ChainSpec { - hardforks: ChainHardforks::new(vec![( - Box::new(EthereumHardfork::Shanghai), - ForkCondition::Timestamp(100), - )]), - ..Default::default() - }; - - // Define the block timestamp and an empty list of withdrawals - let block_timestamp = 1000; - let withdrawals = Vec::::new(); - - // Create an empty HashMap to hold the balance increments - let mut balance_increments = HashMap::default(); - - // Act - // Call the function with the prepared inputs - insert_post_block_withdrawals_balance_increments( - &chain_spec, - block_timestamp, - Some(&withdrawals), - &mut balance_increments, - ); - - // Assert - // Verify that the balance increments map is empty - assert!(balance_increments.is_empty()); - } - - /// Tests that the function correctly handles the case when Shanghai is not active even if there - /// are withdrawals. - #[test] - fn test_insert_post_block_withdrawals_balance_increments_shanghai_not_active_with_withdrawals() - { - // Arrange - // Create a ChainSpec without the Shanghai hardfork active - let chain_spec = ChainSpec::default(); // Mock chain spec with Shanghai not active - - // Define the block timestamp and withdrawals - let block_timestamp = 1000; - let withdrawals = vec![ - Withdrawal { - address: Address::from([1; 20]), - amount: 1000, - index: 45, - validator_index: 12, - }, - Withdrawal { - address: Address::from([2; 20]), - amount: 500, - index: 412, - validator_index: 123, - }, - ]; - - // Create an empty HashMap to hold the balance increments - let mut balance_increments = HashMap::default(); - - // Act - // Call the function with the prepared inputs - insert_post_block_withdrawals_balance_increments( - &chain_spec, - block_timestamp, - Some(&withdrawals), - &mut balance_increments, - ); - - // Assert - // Verify that the balance increments map is empty - assert!(balance_increments.is_empty()); - } - - /// Tests that the function correctly handles the case when Shanghai is active but all - /// withdrawals have zero amounts. - #[test] - fn test_insert_post_block_withdrawals_balance_increments_shanghai_active_with_zero_withdrawals() - { - // Arrange - // Create a ChainSpec with the Shanghai hardfork active - let chain_spec = ChainSpec { - hardforks: ChainHardforks::new(vec![( - Box::new(EthereumHardfork::Shanghai), - ForkCondition::Timestamp(100), - )]), - ..Default::default() - }; - - // Define the block timestamp and withdrawals with zero amounts - let block_timestamp = 1000; - let withdrawals = vec![ - Withdrawal { - address: Address::from([1; 20]), - amount: 0, // Zero withdrawal amount - index: 45, - validator_index: 12, - }, - Withdrawal { - address: Address::from([2; 20]), - amount: 0, // Zero withdrawal amount - index: 412, - validator_index: 123, - }, - ]; - - // Create an empty HashMap to hold the balance increments - let mut balance_increments = HashMap::default(); - - // Act - // Call the function with the prepared inputs - insert_post_block_withdrawals_balance_increments( - &chain_spec, - block_timestamp, - Some(&withdrawals), - &mut balance_increments, - ); - - // Assert - // Verify that the balance increments map is empty - assert!(balance_increments.is_empty()); - } - - /// Tests that the function correctly handles the case when Shanghai is active but there are no - /// withdrawals provided. - #[test] - fn test_insert_post_block_withdrawals_balance_increments_shanghai_active_with_empty_withdrawals( - ) { - // Arrange - // Create a ChainSpec with the Shanghai hardfork active - let chain_spec = ChainSpec { - hardforks: ChainHardforks::new(vec![( - Box::new(EthereumHardfork::Shanghai), - ForkCondition::Timestamp(100), - )]), - ..Default::default() - }; - - // Define the block timestamp and no withdrawals - let block_timestamp = 1000; - let withdrawals = None; // No withdrawals provided - - // Create an empty HashMap to hold the balance increments - let mut balance_increments = HashMap::default(); - - // Act - // Call the function with the prepared inputs - insert_post_block_withdrawals_balance_increments( - &chain_spec, - block_timestamp, - withdrawals, - &mut balance_increments, - ); - - // Assert - // Verify that the balance increments map is empty - assert!(balance_increments.is_empty()); - } -} diff --git a/crates/evm/src/system_calls/eip2935.rs b/crates/evm/src/system_calls/eip2935.rs deleted file mode 100644 index dbd3d0d922..0000000000 --- a/crates/evm/src/system_calls/eip2935.rs +++ /dev/null @@ -1,59 +0,0 @@ -//! [EIP-2935](https://eips.ethereum.org/EIPS/eip-2935) system call implementation. - -use crate::Evm; -use alloc::string::ToString; -use alloy_eips::eip2935::HISTORY_STORAGE_ADDRESS; -use alloy_primitives::B256; -use reth_chainspec::EthereumHardforks; -use reth_execution_errors::{BlockExecutionError, BlockValidationError}; -use revm::context_interface::result::ResultAndState; - -/// Applies the pre-block call to the [EIP-2935] blockhashes contract, using the given block, -/// chain specification, and EVM. -/// -/// If Prague is not activated, or the block is the genesis block, then this is a no-op, and no -/// state changes are made. -/// -/// Note: this does not commit the state changes to the database, it only transact the call. -/// -/// Returns `None` if Prague is not active or the block is the genesis block, otherwise returns the -/// result of the call. -/// -/// [EIP-2935]: https://eips.ethereum.org/EIPS/eip-2935 -#[inline] -pub(crate) fn transact_blockhashes_contract_call( - chain_spec: impl EthereumHardforks, - parent_block_hash: B256, - evm: &mut impl Evm, -) -> Result>, BlockExecutionError> { - if !chain_spec.is_prague_active_at_timestamp(evm.block().timestamp) { - return Ok(None) - } - - // if the block number is zero (genesis block) then no system transaction may occur as per - // EIP-2935 - if evm.block().number == 0 { - return Ok(None) - } - - let mut res = match evm.transact_system_call( - alloy_eips::eip4788::SYSTEM_ADDRESS, - HISTORY_STORAGE_ADDRESS, - parent_block_hash.0.into(), - ) { - Ok(res) => res, - Err(e) => { - return Err(BlockValidationError::BlockHashContractCall { message: e.to_string() }.into()) - } - }; - - // NOTE: Revm currently marks these accounts as "touched" when we do the above transact calls, - // and includes them in the result. - // - // There should be no state changes to these addresses anyways as a result of this system call, - // so we can just remove them from the state returned. - res.state.remove(&alloy_eips::eip4788::SYSTEM_ADDRESS); - res.state.remove(&evm.block().beneficiary); - - Ok(Some(res)) -} diff --git a/crates/evm/src/system_calls/eip4788.rs b/crates/evm/src/system_calls/eip4788.rs deleted file mode 100644 index f6f7989a86..0000000000 --- a/crates/evm/src/system_calls/eip4788.rs +++ /dev/null @@ -1,69 +0,0 @@ -//! [EIP-4788](https://eips.ethereum.org/EIPS/eip-4788) system call implementation. -use crate::Evm; -use alloc::{boxed::Box, string::ToString}; -use alloy_eips::eip4788::BEACON_ROOTS_ADDRESS; -use alloy_primitives::B256; -use core::fmt::Display; -use reth_chainspec::EthereumHardforks; -use reth_execution_errors::{BlockExecutionError, BlockValidationError}; -use revm::context_interface::result::ResultAndState; - -/// Applies the pre-block call to the [EIP-4788] beacon block root contract, using the given block, -/// chain spec, EVM. -/// -/// Note: this does not commit the state changes to the database, it only transact the call. -/// -/// Returns `None` if Cancun is not active or the block is the genesis block, otherwise returns the -/// result of the call. -/// -/// [EIP-4788]: https://eips.ethereum.org/EIPS/eip-4788 -#[inline] -pub(crate) fn transact_beacon_root_contract_call( - chain_spec: impl EthereumHardforks, - parent_beacon_block_root: Option, - evm: &mut impl Evm, -) -> Result>, BlockExecutionError> { - if !chain_spec.is_cancun_active_at_timestamp(evm.block().timestamp) { - return Ok(None) - } - - let parent_beacon_block_root = - parent_beacon_block_root.ok_or(BlockValidationError::MissingParentBeaconBlockRoot)?; - - // if the block number is zero (genesis block) then the parent beacon block root must - // be 0x0 and no system transaction may occur as per EIP-4788 - if evm.block().number == 0 { - if !parent_beacon_block_root.is_zero() { - return Err(BlockValidationError::CancunGenesisParentBeaconBlockRootNotZero { - parent_beacon_block_root, - } - .into()) - } - return Ok(None) - } - - let mut res = match evm.transact_system_call( - alloy_eips::eip4788::SYSTEM_ADDRESS, - BEACON_ROOTS_ADDRESS, - parent_beacon_block_root.0.into(), - ) { - Ok(res) => res, - Err(e) => { - return Err(BlockValidationError::BeaconRootContractCall { - parent_beacon_block_root: Box::new(parent_beacon_block_root), - message: e.to_string(), - } - .into()) - } - }; - - // NOTE: Revm currently marks these accounts as "touched" when we do the above transact calls, - // and includes them in the result. - // - // There should be no state changes to these addresses anyways as a result of this system call, - // so we can just remove them from the state returned. - res.state.remove(&alloy_eips::eip4788::SYSTEM_ADDRESS); - res.state.remove(&evm.block().beneficiary); - - Ok(Some(res)) -} diff --git a/crates/evm/src/system_calls/eip7002.rs b/crates/evm/src/system_calls/eip7002.rs deleted file mode 100644 index 177fb51b2d..0000000000 --- a/crates/evm/src/system_calls/eip7002.rs +++ /dev/null @@ -1,73 +0,0 @@ -//! [EIP-7002](https://eips.ethereum.org/EIPS/eip-7002) system call implementation. -use crate::Evm; -use alloc::format; -use alloy_eips::eip7002::WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS; -use alloy_primitives::Bytes; -use core::fmt::{Debug, Display}; -use reth_execution_errors::{BlockExecutionError, BlockValidationError}; -use revm::context_interface::result::{ExecutionResult, ResultAndState}; - -/// Applies the post-block call to the EIP-7002 withdrawal requests contract. -/// -/// If Prague is not active at the given timestamp, then this is a no-op. -/// -/// Note: this does not commit the state changes to the database, it only transact the call. -#[inline] -pub(crate) fn transact_withdrawal_requests_contract_call( - evm: &mut impl Evm, -) -> Result, BlockExecutionError> { - // Execute EIP-7002 withdrawal requests contract message data. - // - // This requirement for the withdrawal requests contract call defined by - // [EIP-7002](https://eips.ethereum.org/EIPS/eip-7002) is: - // - // At the end of processing any execution block where `block.timestamp >= FORK_TIMESTAMP` (i.e. - // after processing all transactions and after performing the block body withdrawal requests - // validations), call the contract as `SYSTEM_ADDRESS`. - let mut res = match evm.transact_system_call( - alloy_eips::eip7002::SYSTEM_ADDRESS, - WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS, - Bytes::new(), - ) { - Ok(res) => res, - Err(e) => { - return Err(BlockValidationError::WithdrawalRequestsContractCall { - message: format!("execution failed: {e}"), - } - .into()) - } - }; - - // NOTE: Revm currently marks these accounts as "touched" when we do the above transact calls, - // and includes them in the result. - // - // There should be no state changes to these addresses anyways as a result of this system call, - // so we can just remove them from the state returned. - res.state.remove(&alloy_eips::eip7002::SYSTEM_ADDRESS); - res.state.remove(&evm.block().beneficiary); - - Ok(res) -} - -/// Calls the withdrawals requests system contract, and returns the requests from the execution -/// output. -#[inline] -pub(crate) fn post_commit( - result: ExecutionResult, -) -> Result { - match result { - ExecutionResult::Success { output, .. } => Ok(output.into_data()), - ExecutionResult::Revert { output, .. } => { - Err(BlockValidationError::WithdrawalRequestsContractCall { - message: format!("execution reverted: {output}"), - } - .into()) - } - ExecutionResult::Halt { reason, .. } => { - Err(BlockValidationError::WithdrawalRequestsContractCall { - message: format!("execution halted: {reason:?}"), - } - .into()) - } - } -} diff --git a/crates/evm/src/system_calls/eip7251.rs b/crates/evm/src/system_calls/eip7251.rs deleted file mode 100644 index 700b826d1b..0000000000 --- a/crates/evm/src/system_calls/eip7251.rs +++ /dev/null @@ -1,75 +0,0 @@ -//! [EIP-7251](https://eips.ethereum.org/EIPS/eip-7251) system call implementation. -use crate::Evm; -use alloc::format; -use alloy_eips::eip7251::CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS; -use alloy_primitives::Bytes; -use core::fmt::{Debug, Display}; -use reth_execution_errors::{BlockExecutionError, BlockValidationError}; -use revm::context_interface::result::{ExecutionResult, ResultAndState}; - -/// Applies the post-block call to the EIP-7251 consolidation requests contract. -/// -/// If Prague is not active at the given timestamp, then this is a no-op, and an empty vector is -/// returned. Otherwise, the consolidation requests are returned. -/// -/// Note: this does not commit the state changes to the database, it only transact the call. -#[inline] -pub(crate) fn transact_consolidation_requests_contract_call( - evm: &mut impl Evm, -) -> Result, BlockExecutionError> { - // Execute EIP-7251 consolidation requests contract message data. - // - // This requirement for the consolidation requests contract call defined by - // [EIP-7251](https://eips.ethereum.org/EIPS/eip-7251) is: - // - // At the end of processing any execution block where block.timestamp >= FORK_TIMESTAMP (i.e. - // after processing all transactions and after performing the block body requests validations) - // clienst software MUST [..] call the contract as `SYSTEM_ADDRESS` and empty input data to - // trigger the system subroutine execute. - let mut res = match evm.transact_system_call( - alloy_eips::eip7002::SYSTEM_ADDRESS, - CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS, - Bytes::new(), - ) { - Ok(res) => res, - Err(e) => { - return Err(BlockValidationError::ConsolidationRequestsContractCall { - message: format!("execution failed: {e}"), - } - .into()) - } - }; - - // NOTE: Revm currently marks these accounts as "touched" when we do the above transact calls, - // and includes them in the result. - // - // There should be no state changes to these addresses anyways as a result of this system call, - // so we can just remove them from the state returned. - res.state.remove(&alloy_eips::eip7002::SYSTEM_ADDRESS); - res.state.remove(&evm.block().beneficiary); - - Ok(res) -} - -/// Calls the consolidation requests system contract, and returns the requests from the execution -/// output. -#[inline] -pub(crate) fn post_commit( - result: ExecutionResult, -) -> Result { - match result { - ExecutionResult::Success { output, .. } => Ok(output.into_data()), - ExecutionResult::Revert { output, .. } => { - Err(BlockValidationError::ConsolidationRequestsContractCall { - message: format!("execution reverted: {output}"), - } - .into()) - } - ExecutionResult::Halt { reason, .. } => { - Err(BlockValidationError::ConsolidationRequestsContractCall { - message: format!("execution halted: {reason:?}"), - } - .into()) - } - } -} diff --git a/crates/evm/src/system_calls/mod.rs b/crates/evm/src/system_calls/mod.rs deleted file mode 100644 index 959861b8cc..0000000000 --- a/crates/evm/src/system_calls/mod.rs +++ /dev/null @@ -1,236 +0,0 @@ -//! System contract call functions. - -use crate::Evm; -use alloc::boxed::Box; -use alloy_consensus::BlockHeader; -use alloy_eips::{ - eip7002::WITHDRAWAL_REQUEST_TYPE, eip7251::CONSOLIDATION_REQUEST_TYPE, eip7685::Requests, -}; -use alloy_primitives::{Bytes, B256}; -use core::fmt::Display; -use reth_chainspec::EthereumHardforks; -use reth_execution_errors::BlockExecutionError; -use revm::{state::EvmState, DatabaseCommit}; - -mod eip2935; -mod eip4788; -mod eip7002; -mod eip7251; - -/// A hook that is called after each state change. -pub trait OnStateHook: Send + 'static { - /// Invoked with the source of the change and the state after each system call. - fn on_state(&mut self, source: StateChangeSource, state: &EvmState); -} - -/// Source of the state change -#[derive(Debug, Clone, Copy)] -pub enum StateChangeSource { - /// Transaction with its index - Transaction(usize), - /// Pre-block state transition - PreBlock(StateChangePreBlockSource), - /// Post-block state transition - PostBlock(StateChangePostBlockSource), -} - -/// Source of the pre-block state change -#[derive(Debug, Clone, Copy)] -pub enum StateChangePreBlockSource { - /// EIP-2935 blockhashes contract - BlockHashesContract, - /// EIP-4788 beacon root contract - BeaconRootContract, - /// EIP-7002 withdrawal requests contract - WithdrawalRequestsContract, -} - -/// Source of the post-block state change -#[derive(Debug, Clone, Copy)] -pub enum StateChangePostBlockSource { - /// Balance increments from block rewards and withdrawals - BalanceIncrements, - /// EIP-7002 withdrawal requests contract - WithdrawalRequestsContract, - /// EIP-7251 consolidation requests contract - ConsolidationRequestsContract, -} - -impl OnStateHook for F -where - F: FnMut(StateChangeSource, &EvmState) + Send + 'static, -{ - fn on_state(&mut self, source: StateChangeSource, state: &EvmState) { - self(source, state) - } -} - -/// An [`OnStateHook`] that does nothing. -#[derive(Default, Debug, Clone)] -#[non_exhaustive] -pub struct NoopHook; - -impl OnStateHook for NoopHook { - fn on_state(&mut self, _source: StateChangeSource, _state: &EvmState) {} -} - -/// An ephemeral helper type for executing system calls. -/// -/// This can be used to chain system transaction calls. -#[derive(derive_more::Debug)] -pub struct SystemCaller { - chain_spec: ChainSpec, - /// Optional hook to be called after each state change. - #[debug(skip)] - hook: Option>, -} - -impl SystemCaller { - /// Create a new system caller with the given EVM config, database, and chain spec, and creates - /// the EVM with the given initialized config and block environment. - pub const fn new(chain_spec: ChainSpec) -> Self { - Self { chain_spec, hook: None } - } - - /// Installs a custom hook to be called after each state change. - pub fn with_state_hook(&mut self, hook: Option>) -> &mut Self { - self.hook = hook; - self - } - - /// Convenience method to consume the type and drop borrowed fields - pub fn finish(self) {} -} - -impl SystemCaller -where - Chainspec: EthereumHardforks, -{ - /// Apply pre execution changes. - pub fn apply_pre_execution_changes( - &mut self, - header: impl BlockHeader, - evm: &mut impl Evm, - ) -> Result<(), BlockExecutionError> { - self.apply_blockhashes_contract_call(header.parent_hash(), evm)?; - self.apply_beacon_root_contract_call(header.parent_beacon_block_root(), evm)?; - - Ok(()) - } - - /// Apply post execution changes. - pub fn apply_post_execution_changes( - &mut self, - evm: &mut impl Evm, - ) -> Result { - let mut requests = Requests::default(); - - // Collect all EIP-7685 requests - let withdrawal_requests = self.apply_withdrawal_requests_contract_call(evm)?; - if !withdrawal_requests.is_empty() { - requests.push_request_with_type(WITHDRAWAL_REQUEST_TYPE, withdrawal_requests); - } - - // Collect all EIP-7251 requests - let consolidation_requests = self.apply_consolidation_requests_contract_call(evm)?; - if !consolidation_requests.is_empty() { - requests.push_request_with_type(CONSOLIDATION_REQUEST_TYPE, consolidation_requests); - } - - Ok(requests) - } - - /// Applies the pre-block call to the EIP-2935 blockhashes contract. - pub fn apply_blockhashes_contract_call( - &mut self, - parent_block_hash: B256, - evm: &mut impl Evm, - ) -> Result<(), BlockExecutionError> { - let result_and_state = - eip2935::transact_blockhashes_contract_call(&self.chain_spec, parent_block_hash, evm)?; - - if let Some(res) = result_and_state { - if let Some(hook) = &mut self.hook { - hook.on_state( - StateChangeSource::PreBlock(StateChangePreBlockSource::BlockHashesContract), - &res.state, - ); - } - evm.db_mut().commit(res.state); - } - - Ok(()) - } - - /// Applies the pre-block call to the EIP-4788 beacon root contract. - pub fn apply_beacon_root_contract_call( - &mut self, - parent_beacon_block_root: Option, - evm: &mut impl Evm, - ) -> Result<(), BlockExecutionError> { - let result_and_state = eip4788::transact_beacon_root_contract_call( - &self.chain_spec, - parent_beacon_block_root, - evm, - )?; - - if let Some(res) = result_and_state { - if let Some(hook) = &mut self.hook { - hook.on_state( - StateChangeSource::PreBlock(StateChangePreBlockSource::BeaconRootContract), - &res.state, - ); - } - evm.db_mut().commit(res.state); - } - - Ok(()) - } - - /// Applies the post-block call to the EIP-7002 withdrawal request contract. - pub fn apply_withdrawal_requests_contract_call( - &mut self, - evm: &mut impl Evm, - ) -> Result { - let result_and_state = eip7002::transact_withdrawal_requests_contract_call(evm)?; - - if let Some(ref mut hook) = &mut self.hook { - hook.on_state( - StateChangeSource::PostBlock( - StateChangePostBlockSource::WithdrawalRequestsContract, - ), - &result_and_state.state, - ); - } - evm.db_mut().commit(result_and_state.state); - - eip7002::post_commit(result_and_state.result) - } - - /// Applies the post-block call to the EIP-7251 consolidation requests contract. - pub fn apply_consolidation_requests_contract_call( - &mut self, - evm: &mut impl Evm, - ) -> Result { - let result_and_state = eip7251::transact_consolidation_requests_contract_call(evm)?; - - if let Some(ref mut hook) = &mut self.hook { - hook.on_state( - StateChangeSource::PostBlock( - StateChangePostBlockSource::ConsolidationRequestsContract, - ), - &result_and_state.state, - ); - } - evm.db_mut().commit(result_and_state.state); - - eip7251::post_commit(result_and_state.result) - } - - /// Delegate to stored `OnStateHook`, noop if hook is `None`. - pub fn on_state(&mut self, source: StateChangeSource, state: &EvmState) { - if let Some(hook) = &mut self.hook { - hook.on_state(source, state); - } - } -} diff --git a/crates/evm/src/test_utils.rs b/crates/evm/src/test_utils.rs index 5432358f99..5d9f18714f 100644 --- a/crates/evm/src/test_utils.rs +++ b/crates/evm/src/test_utils.rs @@ -2,8 +2,7 @@ use crate::{ execute::{BasicBlockExecutor, BlockExecutionOutput, BlockExecutorProvider, Executor}, - system_calls::OnStateHook, - Database, + Database, OnStateHook, }; use alloc::{sync::Arc, vec::Vec}; use alloy_eips::eip7685::Requests; diff --git a/crates/exex/exex/src/backfill/job.rs b/crates/exex/exex/src/backfill/job.rs index 1dc668ac0d..98c2c67877 100644 --- a/crates/exex/exex/src/backfill/job.rs +++ b/crates/exex/exex/src/backfill/job.rs @@ -77,7 +77,9 @@ where ); let mut executor = self.executor.executor(StateProviderDatabase::new( - self.provider.history_by_block_number(self.range.start().saturating_sub(1))?, + self.provider + .history_by_block_number(self.range.start().saturating_sub(1)) + .map_err(BlockExecutionError::other)?, )); let mut fetch_block_duration = Duration::default(); @@ -94,8 +96,10 @@ where // we need the block's transactions along with their hashes let block = self .provider - .sealed_block_with_senders(block_number.into(), TransactionVariant::WithHash)? - .ok_or_else(|| ProviderError::HeaderNotFound(block_number.into()))?; + .sealed_block_with_senders(block_number.into(), TransactionVariant::WithHash) + .map_err(BlockExecutionError::other)? + .ok_or_else(|| ProviderError::HeaderNotFound(block_number.into())) + .map_err(BlockExecutionError::other)?; fetch_block_duration += fetch_block_start.elapsed(); @@ -206,12 +210,16 @@ where // Fetch the block with senders for execution. let block_with_senders = self .provider - .recovered_block(block_number.into(), TransactionVariant::WithHash)? - .ok_or_else(|| ProviderError::HeaderNotFound(block_number.into()))?; + .recovered_block(block_number.into(), TransactionVariant::WithHash) + .map_err(BlockExecutionError::other)? + .ok_or_else(|| ProviderError::HeaderNotFound(block_number.into())) + .map_err(BlockExecutionError::other)?; // Configure the executor to use the previous block's state. let executor = self.executor.executor(StateProviderDatabase::new( - self.provider.history_by_block_number(block_number.saturating_sub(1))?, + self.provider + .history_by_block_number(block_number.saturating_sub(1)) + .map_err(BlockExecutionError::other)?, )); trace!(target: "exex::backfill", number = block_number, txs = block_with_senders.body().transaction_count(), "Executing block"); diff --git a/crates/optimism/evm/src/build.rs b/crates/optimism/evm/src/build.rs index 22497242f3..d11e026bfa 100644 --- a/crates/optimism/evm/src/build.rs +++ b/crates/optimism/evm/src/build.rs @@ -1,9 +1,10 @@ -use crate::{OpBlockExecutionCtx, OpNextBlockEnvAttributes}; use alloc::sync::Arc; use alloy_consensus::{ constants::EMPTY_WITHDRAWALS, proofs, BlockBody, Header, TxReceipt, EMPTY_OMMER_ROOT_HASH, }; use alloy_eips::merge::BEACON_NONCE; +use alloy_evm::block::BlockExecutorFactory; +use alloy_op_evm::OpBlockExecutionCtx; use alloy_primitives::logs_bloom; use reth_evm::execute::{BlockAssembler, BlockAssemblerInput, BlockExecutionStrategyFactory}; use reth_execution_errors::BlockExecutionError; @@ -43,8 +44,7 @@ where BlockBody = alloy_consensus::BlockBody, SignedTx = T, >, - NextBlockEnvCtx = OpNextBlockEnvAttributes, - ExecutionCtx<'a> = OpBlockExecutionCtx, + BlockExecutorFactory: BlockExecutorFactory = OpBlockExecutionCtx>, >, { fn assemble_block( @@ -72,7 +72,10 @@ where let withdrawals_root = if self.chain_spec.is_isthmus_active_at_timestamp(timestamp) { // withdrawals root field in block header is used for storage root of L2 predeploy // `l2tol1-message-passer` - Some(isthmus::withdrawals_root(bundle_state, state_provider)?) + Some( + isthmus::withdrawals_root(bundle_state, state_provider) + .map_err(BlockExecutionError::other)?, + ) } else if self.chain_spec.is_canyon_active_at_timestamp(timestamp) { Some(EMPTY_WITHDRAWALS) } else { diff --git a/crates/optimism/evm/src/error.rs b/crates/optimism/evm/src/error.rs index c5175ee5bd..9b694243fa 100644 --- a/crates/optimism/evm/src/error.rs +++ b/crates/optimism/evm/src/error.rs @@ -52,9 +52,6 @@ pub enum OpBlockExecutionError { /// Thrown when force deploy of create2deployer code fails. #[error("failed to force create2deployer account code")] ForceCreate2DeployerFail, - /// Thrown when a blob transaction is included in a sequencer's block. - #[error("blob transaction included in sequencer block")] - BlobTransactionRejected, /// Thrown when a database account could not be loaded. #[error("failed to load account {_0}")] AccountLoadFailed(alloy_primitives::Address), diff --git a/crates/optimism/evm/src/execute.rs b/crates/optimism/evm/src/execute.rs index 8c3235bb89..66fb1d92e3 100644 --- a/crates/optimism/evm/src/execute.rs +++ b/crates/optimism/evm/src/execute.rs @@ -1,66 +1,46 @@ //! Optimism block execution strategy. -use crate::{ - l1::ensure_create2_deployer, BasicOpReceiptBuilder, OpBlockAssembler, OpBlockExecutionError, - OpEvmConfig, OpReceiptBuilder, ReceiptBuilderCtx, -}; -use alloc::{boxed::Box, sync::Arc, vec::Vec}; -use alloy_consensus::{ - transaction::Recovered, BlockHeader, Eip658Value, Header, Receipt, Transaction, TxReceipt, -}; -use alloy_eips::Encodable2718; +use crate::{OpBlockAssembler, OpEvmConfig, OpRethReceiptBuilder}; +use alloc::sync::Arc; +use alloy_consensus::{BlockHeader, Header}; use alloy_evm::FromRecoveredTx; -use alloy_primitives::Bytes; -use op_alloy_consensus::OpDepositReceipt; -use reth_chainspec::EthChainSpec; -use reth_evm::{ - execute::{ - balance_increment_state, BasicBlockExecutorProvider, BlockExecutionError, - BlockExecutionStrategy, BlockExecutionStrategyFactory, BlockValidationError, - }, - state_change::post_block_balance_increments, - system_calls::{OnStateHook, StateChangePostBlockSource, StateChangeSource, SystemCaller}, - Database, Evm, EvmFor, InspectorFor, +use alloy_op_evm::{ + block::receipt_builder::OpReceiptBuilder, OpBlockExecutionCtx, OpBlockExecutorFactory, }; -use reth_execution_types::BlockExecutionResult; +use reth_chainspec::EthChainSpec; +use reth_evm::execute::{BasicBlockExecutorProvider, BlockExecutionStrategyFactory}; use reth_optimism_chainspec::OpChainSpec; use reth_optimism_forks::OpHardforks; -use reth_optimism_primitives::{transaction::signed::OpTransaction, DepositReceipt}; +use reth_optimism_primitives::DepositReceipt; use reth_primitives_traits::{NodePrimitives, SealedBlock, SealedHeader, SignedTransaction}; -use revm::{context::TxEnv, context_interface::result::ResultAndState, DatabaseCommit}; -use revm_database::State; -use revm_primitives::B256; -use tracing::trace; +use revm::context::TxEnv; -impl BlockExecutionStrategyFactory for OpEvmConfig +impl BlockExecutionStrategyFactory for OpEvmConfig where - ChainSpec: EthChainSpec + OpHardforks + 'static, - T: SignedTransaction + OpTransaction, + ChainSpec: EthChainSpec + OpHardforks, N: NodePrimitives< - Receipt: DepositReceipt, - SignedTx = T, + Receipt = R::Receipt, + SignedTx = R::Transaction, BlockHeader = Header, - BlockBody = alloy_consensus::BlockBody, + BlockBody = alloy_consensus::BlockBody, >, - op_revm::OpTransaction: FromRecoveredTx, + op_revm::OpTransaction: FromRecoveredTx, + R: OpReceiptBuilder, + Self: Send + Sync + Unpin + Clone + 'static, { type Primitives = N; - type Strategy<'a, DB: Database + 'a, I: InspectorFor<&'a mut State, Self> + 'a> = - OpExecutionStrategy< - 'a, - EvmFor, I>, - N::SignedTx, - N::Receipt, - &'a ChainSpec, - >; - type ExecutionCtx<'a> = OpBlockExecutionCtx; + type BlockExecutorFactory = OpBlockExecutorFactory>; type BlockAssembler = OpBlockAssembler; + fn block_executor_factory(&self) -> &Self::BlockExecutorFactory { + &self.executor_factory + } + fn block_assembler(&self) -> &Self::BlockAssembler { &self.block_assembler } - fn context_for_block<'a>(&self, block: &'a SealedBlock) -> Self::ExecutionCtx<'a> { + fn context_for_block(&self, block: &'_ SealedBlock) -> OpBlockExecutionCtx { OpBlockExecutionCtx { parent_hash: block.header().parent_hash(), parent_beacon_block_root: block.header().parent_beacon_block_root(), @@ -72,241 +52,13 @@ where &self, parent: &SealedHeader, attributes: Self::NextBlockEnvCtx, - ) -> Self::ExecutionCtx<'_> { + ) -> OpBlockExecutionCtx { OpBlockExecutionCtx { parent_hash: parent.hash(), parent_beacon_block_root: attributes.parent_beacon_block_root, extra_data: attributes.extra_data, } } - - fn create_strategy<'a, DB, I>( - &'a self, - evm: EvmFor, I>, - ctx: Self::ExecutionCtx<'a>, - ) -> Self::Strategy<'a, DB, I> - where - DB: Database, - I: reth_evm::InspectorFor<&'a mut State, Self> + 'a, - { - OpExecutionStrategy::new(evm, ctx, self.chain_spec.as_ref(), self.receipt_builder.as_ref()) - } -} - -/// Context for OP block execution. -#[derive(Debug, Clone)] -pub struct OpBlockExecutionCtx { - /// Parent block hash. - pub parent_hash: B256, - /// Parent beacon block root. - pub parent_beacon_block_root: Option, - /// The block's extra data. - pub extra_data: Bytes, -} - -/// Block execution strategy for Optimism. -#[derive(Debug)] -pub struct OpExecutionStrategy<'a, E: Evm, Tx, R, ChainSpec> { - /// Chainspec. - chain_spec: ChainSpec, - /// Receipt builder. - receipt_builder: &'a dyn OpReceiptBuilder, - - /// Context for block execution. - ctx: OpBlockExecutionCtx, - /// The EVM used by strategy. - evm: E, - /// Receipts of executed transactions. - receipts: Vec, - /// Total gas used by executed transactions. - gas_used: u64, - /// Whether Regolith hardfork is active. - is_regolith: bool, - /// Utility to call system smart contracts. - system_caller: SystemCaller, -} - -impl<'a, E, Tx, R, ChainSpec> OpExecutionStrategy<'a, E, Tx, R, ChainSpec> -where - E: Evm, - ChainSpec: OpHardforks + Clone, -{ - /// Creates a new [`OpExecutionStrategy`] - pub fn new( - evm: E, - ctx: OpBlockExecutionCtx, - chain_spec: ChainSpec, - receipt_builder: &'a dyn OpReceiptBuilder, - ) -> Self { - Self { - is_regolith: chain_spec.is_regolith_active_at_timestamp(evm.block().timestamp), - evm, - system_caller: SystemCaller::new(chain_spec.clone()), - chain_spec, - receipt_builder, - receipts: Vec::new(), - gas_used: 0, - ctx, - } - } -} - -impl<'db, DB, E, Tx, R, ChainSpec> BlockExecutionStrategy - for OpExecutionStrategy<'_, E, Tx, R, ChainSpec> -where - DB: Database + 'db, - Tx: Transaction + OpTransaction + Encodable2718, - R: TxReceipt + Unpin + 'static, - E: Evm, Tx: FromRecoveredTx>, - ChainSpec: OpHardforks, -{ - type Transaction = Tx; - type Receipt = R; - type Evm = E; - - fn apply_pre_execution_changes(&mut self) -> Result<(), BlockExecutionError> { - // 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(self.evm.block().number); - self.evm.db_mut().set_state_clear_flag(state_clear_flag); - - self.system_caller.apply_blockhashes_contract_call(self.ctx.parent_hash, &mut self.evm)?; - self.system_caller - .apply_beacon_root_contract_call(self.ctx.parent_beacon_block_root, &mut self.evm)?; - - // Ensure that the create2deployer is force-deployed at the canyon transition. Optimism - // blocks will always have at least a single transaction in them (the L1 info transaction), - // so we can safely assume that this will always be triggered upon the transition and that - // the above check for empty blocks will never be hit on OP chains. - ensure_create2_deployer(&self.chain_spec, self.evm.block().timestamp, self.evm.db_mut()) - .map_err(|_| OpBlockExecutionError::ForceCreate2DeployerFail)?; - - Ok(()) - } - - fn execute_transaction_with_result_closure( - &mut self, - tx: Recovered<&Tx>, - f: impl FnOnce(&revm::context::result::ExecutionResult<::HaltReason>), - ) -> Result { - // 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 = self.evm.block().gas_limit - self.gas_used; - if tx.gas_limit() > block_available_gas && (self.is_regolith || !tx.is_deposit()) { - return Err(BlockValidationError::TransactionGasLimitMoreThanAvailableBlockGas { - transaction_gas_limit: tx.gas_limit(), - block_available_gas, - } - .into()) - } - - // Cache the depositor account prior to the state transition for the deposit nonce. - // - // Note that this *only* needs to be done post-regolith hardfork, as deposit nonces - // were not introduced in Bedrock. In addition, regular transactions don't have deposit - // nonces, so we don't need to touch the DB for those. - let depositor = (self.is_regolith && tx.is_deposit()) - .then(|| { - self.evm - .db_mut() - .load_cache_account(tx.signer()) - .map(|acc| acc.account_info().unwrap_or_default()) - }) - .transpose() - .map_err(|_| OpBlockExecutionError::AccountLoadFailed(tx.signer()))?; - - let hash = tx.trie_hash(); - - // Execute transaction. - let result_and_state = - self.evm.transact(tx).map_err(move |err| BlockExecutionError::evm(err, hash))?; - - trace!( - target: "evm", - ?tx, - "Executed transaction" - ); - self.system_caller - .on_state(StateChangeSource::Transaction(self.receipts.len()), &result_and_state.state); - let ResultAndState { result, state } = result_and_state; - self.evm.db_mut().commit(state); - - f(&result); - - let gas_used = result.gas_used(); - - // append gas used - self.gas_used += gas_used; - - self.receipts.push( - match self.receipt_builder.build_receipt(ReceiptBuilderCtx { - tx: tx.inner(), - result, - cumulative_gas_used: self.gas_used, - }) { - Ok(receipt) => receipt, - Err(ctx) => { - let receipt = Receipt { - // Success flag was added in `EIP-658: Embedding transaction status code - // in receipts`. - status: Eip658Value::Eip658(ctx.result.is_success()), - cumulative_gas_used: self.gas_used, - logs: ctx.result.into_logs(), - }; - - self.receipt_builder.build_deposit_receipt(OpDepositReceipt { - inner: receipt, - deposit_nonce: depositor.map(|account| account.nonce), - // The deposit receipt version was introduced in Canyon to indicate an - // update to how receipt hashes should be computed - // when set. The state transition process ensures - // this is only set for post-Canyon deposit - // transactions. - deposit_receipt_version: (tx.is_deposit() && - self.chain_spec - .is_canyon_active_at_timestamp(self.evm.block().timestamp)) - .then_some(1), - }) - } - }, - ); - - Ok(gas_used) - } - - fn finish(mut self) -> Result<(Self::Evm, BlockExecutionResult), BlockExecutionError> { - let balance_increments = - post_block_balance_increments::
(&self.chain_spec, self.evm.block(), &[], None); - // increment balances - self.evm - .db_mut() - .increment_balances(balance_increments.clone()) - .map_err(|_| BlockValidationError::IncrementBalanceFailed)?; - // call state hook with changes due to balance increments. - let balance_state = balance_increment_state(&balance_increments, self.evm.db_mut())?; - self.system_caller.on_state( - StateChangeSource::PostBlock(StateChangePostBlockSource::BalanceIncrements), - &balance_state, - ); - - let gas_used = self.receipts.last().map(|r| r.cumulative_gas_used()).unwrap_or_default(); - Ok(( - self.evm, - BlockExecutionResult { - receipts: self.receipts, - requests: Default::default(), - gas_used, - }, - )) - } - - fn with_state_hook(&mut self, hook: Option>) { - self.system_caller.with_state_hook(hook); - } - - fn evm_mut(&mut self) -> &mut Self::Evm { - &mut self.evm - } } /// Helper type with backwards compatible methods to obtain executor providers. @@ -318,7 +70,7 @@ impl OpExecutorProvider { pub fn optimism(chain_spec: Arc) -> BasicBlockExecutorProvider { BasicBlockExecutorProvider::new(OpEvmConfig::new( chain_spec, - BasicOpReceiptBuilder::default(), + OpRethReceiptBuilder::default(), )) } } @@ -371,7 +123,7 @@ mod tests { fn executor_provider(chain_spec: Arc) -> BasicBlockExecutorProvider { BasicBlockExecutorProvider::new(OpEvmConfig::new( chain_spec, - BasicOpReceiptBuilder::default(), + OpRethReceiptBuilder::default(), )) } diff --git a/crates/optimism/evm/src/l1.rs b/crates/optimism/evm/src/l1.rs index 9b96a6d6f3..e51138f2db 100644 --- a/crates/optimism/evm/src/l1.rs +++ b/crates/optimism/evm/src/l1.rs @@ -2,23 +2,11 @@ use crate::{error::L1BlockInfoError, OpBlockExecutionError}; use alloy_consensus::Transaction; -use alloy_primitives::{address, b256, hex, Address, Bytes, B256, U256}; +use alloy_primitives::{hex, U256}; use op_revm::{L1BlockInfo, OpSpecId}; use reth_execution_errors::BlockExecutionError; use reth_optimism_forks::OpHardforks; use reth_primitives_traits::BlockBody; -use revm::{primitives::HashMap, state::Bytecode, DatabaseCommit}; -use tracing::trace; - -/// The address of the create2 deployer -const CREATE_2_DEPLOYER_ADDR: Address = address!("0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2"); - -/// The codehash of the create2 deployer contract. -const CREATE_2_DEPLOYER_CODEHASH: B256 = - b256!("0xb0550b5b431e30d38000efb7107aaa0ade03d48a7198a140edda9d27134468b2"); - -/// The raw bytecode of the create2 deployer contract. -const CREATE_2_DEPLOYER_BYTECODE: [u8; 1584] = hex!("6080604052600436106100435760003560e01c8063076c37b21461004f578063481286e61461007157806356299481146100ba57806366cfa057146100da57600080fd5b3661004a57005b600080fd5b34801561005b57600080fd5b5061006f61006a366004610327565b6100fa565b005b34801561007d57600080fd5b5061009161008c366004610327565b61014a565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100c657600080fd5b506100916100d5366004610349565b61015d565b3480156100e657600080fd5b5061006f6100f53660046103ca565b610172565b61014582826040518060200161010f9061031a565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052610183565b505050565b600061015683836102e7565b9392505050565b600061016a8484846102f0565b949350505050565b61017d838383610183565b50505050565b6000834710156101f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f437265617465323a20696e73756666696369656e742062616c616e636500000060448201526064015b60405180910390fd5b815160000361025f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f437265617465323a2062797465636f6465206c656e677468206973207a65726f60448201526064016101eb565b8282516020840186f5905073ffffffffffffffffffffffffffffffffffffffff8116610156576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f790000000000000060448201526064016101eb565b60006101568383305b6000604051836040820152846020820152828152600b8101905060ff815360559020949350505050565b61014e806104ad83390190565b6000806040838503121561033a57600080fd5b50508035926020909101359150565b60008060006060848603121561035e57600080fd5b8335925060208401359150604084013573ffffffffffffffffffffffffffffffffffffffff8116811461039057600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000606084860312156103df57600080fd5b8335925060208401359150604084013567ffffffffffffffff8082111561040557600080fd5b818601915086601f83011261041957600080fd5b81358181111561042b5761042b61039b565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156104715761047161039b565b8160405282815289602084870101111561048a57600080fd5b826020860160208301376000602084830101528095505050505050925092509256fe608060405234801561001057600080fd5b5061012e806100206000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063249cb3fa14602d575b600080fd5b603c603836600460b1565b604e565b60405190815260200160405180910390f35b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205460ff16608857600060aa565b7fa2ef4600d742022d532d4747cb3547474667d6f13804902513b2ec01c848f4b45b9392505050565b6000806040838503121560c357600080fd5b82359150602083013573ffffffffffffffffffffffffffffffffffffffff8116811460ed57600080fd5b80915050925092905056fea26469706673582212205ffd4e6cede7d06a5daf93d48d0541fc68189eeb16608c1999a82063b666eb1164736f6c63430008130033a2646970667358221220fdc4a0fe96e3b21c108ca155438d37c9143fb01278a3c1d274948bad89c564ba64736f6c63430008130033"); /// The function selector of the "setL1BlockValuesEcotone" function in the `L1Block` contract. const L1_BLOCK_ECOTONE_SELECTOR: [u8; 4] = hex!("440a5e20"); @@ -307,45 +295,6 @@ impl RethL1BlockInfo for L1BlockInfo { } } -/// The Canyon hardfork issues an irregular state transition that force-deploys the create2 -/// deployer contract. This is done by directly setting the code of the create2 deployer account -/// prior to executing any transactions on the timestamp activation of the fork. -pub fn ensure_create2_deployer( - chain_spec: impl OpHardforks, - timestamp: u64, - db: &mut revm_database::State, -) -> Result<(), DB::Error> -where - DB: revm::Database, -{ - // If the canyon hardfork is active at the current timestamp, and it was not active at the - // previous block timestamp (heuristically, block time is not perfectly constant at 2s), and the - // chain is an optimism chain, then we need to force-deploy the create2 deployer contract. - if chain_spec.is_canyon_active_at_timestamp(timestamp) && - !chain_spec.is_canyon_active_at_timestamp(timestamp.saturating_sub(2)) - { - trace!(target: "evm", "Forcing create2 deployer contract deployment on Canyon transition"); - - // Load the create2 deployer account from the cache. - let acc = db.load_cache_account(CREATE_2_DEPLOYER_ADDR)?; - - // Update the account info with the create2 deployer codehash and bytecode. - let mut acc_info = acc.account_info().unwrap_or_default(); - acc_info.code_hash = CREATE_2_DEPLOYER_CODEHASH; - acc_info.code = Some(Bytecode::new_raw(Bytes::from_static(&CREATE_2_DEPLOYER_BYTECODE))); - - // Convert the cache account back into a revm account and mark it as touched. - let mut revm_acc: revm::state::Account = acc_info.into(); - revm_acc.mark_touch(); - - // Commit the create2 deployer account to the database. - db.commit(HashMap::from_iter([(CREATE_2_DEPLOYER_ADDR, revm_acc)])); - return Ok(()) - } - - Ok(()) -} - #[cfg(test)] mod tests { use super::*; diff --git a/crates/optimism/evm/src/lib.rs b/crates/optimism/evm/src/lib.rs index 46ae0326ae..79ecd5f7cc 100644 --- a/crates/optimism/evm/src/lib.rs +++ b/crates/optimism/evm/src/lib.rs @@ -13,11 +13,11 @@ extern crate alloc; use alloc::sync::Arc; use alloy_consensus::BlockHeader; use alloy_evm::FromRecoveredTx; -use alloy_op_evm::OpEvmFactory; +use alloy_op_evm::{OpBlockExecutorFactory, OpEvmFactory}; use alloy_primitives::U256; use core::fmt::Debug; use op_alloy_consensus::EIP1559ParamError; -use op_revm::{OpHaltReason, OpSpecId, OpTransaction}; +use op_revm::{OpSpecId, OpTransaction}; use reth_chainspec::EthChainSpec; use reth_evm::{ConfigureEvm, ConfigureEvmEnv, EvmEnv}; use reth_optimism_chainspec::OpChainSpec; @@ -47,20 +47,22 @@ pub use error::OpBlockExecutionError; /// Optimism-related EVM configuration. #[derive(Debug)] -pub struct OpEvmConfig { - chain_spec: Arc, - evm_factory: OpEvmFactory, - receipt_builder: Arc>, +pub struct OpEvmConfig< + ChainSpec = OpChainSpec, + N: NodePrimitives = OpPrimitives, + R = OpRethReceiptBuilder, +> { + executor_factory: OpBlockExecutorFactory>, block_assembler: OpBlockAssembler, + _pd: core::marker::PhantomData, } -impl Clone for OpEvmConfig { +impl Clone for OpEvmConfig { fn clone(&self) -> Self { Self { - chain_spec: self.chain_spec.clone(), - evm_factory: OpEvmFactory::default(), - receipt_builder: self.receipt_builder.clone(), + executor_factory: self.executor_factory.clone(), block_assembler: self.block_assembler.clone(), + _pd: self._pd, } } } @@ -68,35 +70,36 @@ impl Clone for OpEvmConfig { impl OpEvmConfig { /// Creates a new [`OpEvmConfig`] with the given chain spec for OP chains. pub fn optimism(chain_spec: Arc) -> Self { - Self::new(chain_spec, BasicOpReceiptBuilder::default()) + Self::new(chain_spec, OpRethReceiptBuilder::default()) } } -impl OpEvmConfig { +impl OpEvmConfig { /// Creates a new [`OpEvmConfig`] with the given chain spec. - pub fn new( - chain_spec: Arc, - receipt_builder: impl OpReceiptBuilder, - ) -> Self { + pub fn new(chain_spec: Arc, receipt_builder: R) -> Self { Self { block_assembler: OpBlockAssembler::new(chain_spec.clone()), - chain_spec, - evm_factory: OpEvmFactory::default(), - receipt_builder: Arc::new(receipt_builder), + executor_factory: OpBlockExecutorFactory::new( + receipt_builder, + chain_spec, + OpEvmFactory::default(), + ), + _pd: core::marker::PhantomData, } } /// Returns the chain spec associated with this configuration. pub const fn chain_spec(&self) -> &Arc { - &self.chain_spec + self.executor_factory.spec() } } -impl ConfigureEvmEnv for OpEvmConfig +impl ConfigureEvmEnv for OpEvmConfig where ChainSpec: EthChainSpec + OpHardforks, N: NodePrimitives, OpTransaction: FromRecoveredTx, + Self: Send + Sync + Unpin + Clone, { type Header = N::BlockHeader; type Transaction = N::SignedTx; @@ -108,7 +111,7 @@ where fn evm_env(&self, header: &Self::Header) -> EvmEnv { let spec = config::revm_spec(self.chain_spec(), header); - let cfg_env = CfgEnv::new().with_chain_id(self.chain_spec.chain().id()).with_spec(spec); + let cfg_env = CfgEnv::new().with_chain_id(self.chain_spec().chain().id()).with_spec(spec); let block_env = BlockEnv { number: header.number(), @@ -141,10 +144,11 @@ where attributes: &Self::NextBlockEnvCtx, ) -> Result, Self::Error> { // ensure we're not missing any timestamp based hardforks - let spec_id = revm_spec_by_timestamp_after_bedrock(&self.chain_spec, attributes.timestamp); + let spec_id = revm_spec_by_timestamp_after_bedrock(self.chain_spec(), attributes.timestamp); // configure evm env based on parent block - let cfg_env = CfgEnv::new().with_chain_id(self.chain_spec.chain().id()).with_spec(spec_id); + let cfg_env = + CfgEnv::new().with_chain_id(self.chain_spec().chain().id()).with_spec(spec_id); // if the parent block did not have excess blob gas (i.e. it was pre-cancun), but it is // cancun now, we need to set the excess blob gas to the default value(0) @@ -163,7 +167,7 @@ where prevrandao: Some(attributes.prev_randao), gas_limit: attributes.gas_limit, // calculate basefee based on parent block's gas usage - basefee: next_block_base_fee(&self.chain_spec, parent, attributes.timestamp)?, + basefee: next_block_base_fee(self.chain_spec(), parent, attributes.timestamp)?, // calculate excess gas based on parent block's blob gas usage blob_excess_gas_and_price, }; @@ -172,16 +176,17 @@ where } } -impl ConfigureEvm for OpEvmConfig +impl ConfigureEvm for OpEvmConfig where ChainSpec: EthChainSpec + OpHardforks, N: NodePrimitives, OpTransaction: FromRecoveredTx, + Self: Send + Sync + Unpin + Clone, { type EvmFactory = OpEvmFactory; fn evm_factory(&self) -> &Self::EvmFactory { - &self.evm_factory + self.executor_factory.evm_factory() } } diff --git a/crates/optimism/evm/src/receipts.rs b/crates/optimism/evm/src/receipts.rs index 64e7b3f9e7..50ca3679cc 100644 --- a/crates/optimism/evm/src/receipts.rs +++ b/crates/optimism/evm/src/receipts.rs @@ -1,50 +1,24 @@ use alloy_consensus::{Eip658Value, Receipt}; -use core::fmt; +use alloy_evm::eth::receipt_builder::ReceiptBuilderCtx; +use alloy_op_evm::block::receipt_builder::OpReceiptBuilder; use op_alloy_consensus::{OpDepositReceipt, OpTxType}; +use reth_evm::Evm; use reth_optimism_primitives::{OpReceipt, OpTransactionSigned}; -use revm::context_interface::result::ExecutionResult; -/// Context for building a receipt. -#[derive(Debug)] -pub struct ReceiptBuilderCtx<'a, T, Halt> { - /// Transaction - pub tx: &'a T, - /// Result of transaction execution. - pub result: ExecutionResult, - /// Cumulative gas used. - pub cumulative_gas_used: u64, -} - -/// Type that knows how to build a receipt based on execution result. -pub trait OpReceiptBuilder: fmt::Debug + Send + Sync + Unpin + 'static { - /// Receipt type. - type Receipt: Send + Sync + Clone + Unpin + 'static; - - /// Builds a receipt given a transaction and the result of the execution. - /// - /// Note: this method should return `Err` if the transaction is a deposit transaction. In that - /// case, the `build_deposit_receipt` method will be called. - fn build_receipt<'a>( - &self, - ctx: ReceiptBuilderCtx<'a, T, Halt>, - ) -> Result>; - - /// Builds receipt for a deposit transaction. - fn build_deposit_receipt(&self, inner: OpDepositReceipt) -> Self::Receipt; -} - -/// Basic builder for receipts of [`OpTransactionSigned`]. +/// A builder that operates on op-reth primitive types, specifically [`OpTransactionSigned`] and +/// [`OpReceipt`]. #[derive(Debug, Default, Clone, Copy)] #[non_exhaustive] -pub struct BasicOpReceiptBuilder; +pub struct OpRethReceiptBuilder; -impl OpReceiptBuilder for BasicOpReceiptBuilder { +impl OpReceiptBuilder for OpRethReceiptBuilder { + type Transaction = OpTransactionSigned; type Receipt = OpReceipt; - fn build_receipt<'a>( + fn build_receipt<'a, E: Evm>( &self, - ctx: ReceiptBuilderCtx<'a, OpTransactionSigned, Halt>, - ) -> Result> { + ctx: ReceiptBuilderCtx<'a, OpTransactionSigned, E>, + ) -> Result> { match ctx.tx.tx_type() { OpTxType::Deposit => Err(ctx), ty => { diff --git a/crates/optimism/payload/src/builder.rs b/crates/optimism/payload/src/builder.rs index 06ef922534..85707a6818 100644 --- a/crates/optimism/payload/src/builder.rs +++ b/crates/optimism/payload/src/builder.rs @@ -17,8 +17,8 @@ use reth_chain_state::{ExecutedBlock, ExecutedBlockWithTrieUpdates}; use reth_chainspec::{ChainSpecProvider, EthChainSpec}; use reth_evm::{ execute::{ - BlockBuilder, BlockBuilderOutcome, BlockExecutionError, BlockExecutionStrategy, - BlockExecutionStrategyFactory, BlockValidationError, + BlockBuilder, BlockBuilderOutcome, BlockExecutionError, BlockExecutionStrategyFactory, + BlockExecutor, BlockValidationError, }, Database, Evm, }; @@ -378,7 +378,7 @@ impl OpBuilder<'_, Txs> { builder.apply_pre_execution_changes().map_err(PayloadBuilderError::evm)?; ctx.execute_sequencer_transactions(&mut builder)?; - builder.into_strategy().apply_post_execution_changes().map_err(PayloadBuilderError::evm)?; + builder.into_executor().apply_post_execution_changes().map_err(PayloadBuilderError::evm)?; let ExecutionWitnessRecord { hashed_state, codes, keys } = ExecutionWitnessRecord::from_executed_state(&db); diff --git a/crates/rpc/rpc-eth-types/src/simulate.rs b/crates/rpc/rpc-eth-types/src/simulate.rs index 954bdddbc6..76a76aa28b 100644 --- a/crates/rpc/rpc-eth-types/src/simulate.rs +++ b/crates/rpc/rpc-eth-types/src/simulate.rs @@ -8,7 +8,7 @@ use alloy_rpc_types_eth::{ }; use jsonrpsee_types::ErrorObject; use reth_evm::{ - execute::{BlockBuilder, BlockBuilderOutcome, BlockExecutionStrategy}, + execute::{BlockBuilder, BlockBuilderOutcome, BlockExecutor}, Evm, }; use reth_primitives::{Recovered, RecoveredBlock, TxTy}; @@ -54,7 +54,7 @@ impl ToRpcError for EthSimulateError { } /// Converts all [`TransactionRequest`]s into [`Recovered`] transactions and applies them to the -/// given [`BlockExecutionStrategy`]. +/// given [`BlockExecutor`]. /// /// Returns all executed transactions and the result of the execution. #[expect(clippy::type_complexity)] @@ -68,14 +68,12 @@ pub fn execute_transactions( ) -> Result< ( BlockBuilderOutcome, - Vec::Evm as Evm>::HaltReason>>, + Vec::Evm as Evm>::HaltReason>>, ), EthApiError, > where - S: BlockBuilder< - Strategy: BlockExecutionStrategy>>>, - >, + S: BlockBuilder>>>>, T: TransactionCompat>, { builder.apply_pre_execution_changes()?; diff --git a/crates/rpc/rpc/Cargo.toml b/crates/rpc/rpc/Cargo.toml index 40e975d66d..6001a82aba 100644 --- a/crates/rpc/rpc/Cargo.toml +++ b/crates/rpc/rpc/Cargo.toml @@ -27,7 +27,6 @@ reth-network-api.workspace = true reth-rpc-engine-api.workspace = true reth-revm = { workspace = true, features = ["witness"] } reth-tasks = { workspace = true, features = ["rayon"] } -reth-consensus-common.workspace = true reth-rpc-types-compat.workspace = true revm-inspectors.workspace = true reth-network-peers = { workspace = true, features = ["secp256k1"] } @@ -39,6 +38,7 @@ reth-consensus.workspace = true reth-node-api.workspace = true # ethereum +alloy-evm.workspace = true alloy-consensus.workspace = true alloy-signer.workspace = true alloy-signer-local.workspace = true diff --git a/crates/rpc/rpc/src/trace.rs b/crates/rpc/rpc/src/trace.rs index bc0d3621e8..7bd8cefbe4 100644 --- a/crates/rpc/rpc/src/trace.rs +++ b/crates/rpc/rpc/src/trace.rs @@ -1,5 +1,6 @@ use alloy_consensus::BlockHeader as _; use alloy_eips::BlockId; +use alloy_evm::block::calc::{base_block_reward_pre_merge, block_reward, ommer_reward}; use alloy_primitives::{map::HashSet, Bytes, B256, U256}; use alloy_rpc_types_eth::{ state::{EvmOverrides, StateOverride}, @@ -15,7 +16,6 @@ use alloy_rpc_types_trace::{ use async_trait::async_trait; use jsonrpsee::core::RpcResult; use reth_chainspec::{EthChainSpec, EthereumHardfork, MAINNET, SEPOLIA}; -use reth_consensus_common::calc::{base_block_reward_pre_merge, block_reward, ommer_reward}; use reth_evm::ConfigureEvmEnv; use reth_primitives_traits::{BlockBody, BlockHeader}; use reth_provider::{BlockNumReader, BlockReader, ChainSpecProvider}; diff --git a/examples/custom-beacon-withdrawals/Cargo.toml b/examples/custom-beacon-withdrawals/Cargo.toml index 450dec1b66..807be2a3f4 100644 --- a/examples/custom-beacon-withdrawals/Cargo.toml +++ b/examples/custom-beacon-withdrawals/Cargo.toml @@ -13,6 +13,7 @@ reth-chainspec.workspace = true reth-evm.workspace = true reth-primitives.workspace = true +alloy-evm.workspace = true alloy-sol-macro.workspace = true alloy-sol-types.workspace = true alloy-eips.workspace = true diff --git a/examples/custom-beacon-withdrawals/src/main.rs b/examples/custom-beacon-withdrawals/src/main.rs index 70b2e0bdc5..cbd0aab470 100644 --- a/examples/custom-beacon-withdrawals/src/main.rs +++ b/examples/custom-beacon-withdrawals/src/main.rs @@ -4,6 +4,11 @@ #![warn(unused_crate_dependencies)] use alloy_eips::eip4895::Withdrawal; +use alloy_evm::{ + block::{BlockExecutorFactory, BlockExecutorFor}, + eth::{EthBlockExecutionCtx, EthBlockExecutor}, + EthEvm, EthEvmFactory, +}; use alloy_sol_macro::sol; use alloy_sol_types::SolCall; use reth::{ @@ -12,7 +17,7 @@ use reth::{ cli::Cli, providers::BlockExecutionResult, revm::{ - context::result::ExecutionResult, + context::{result::ExecutionResult, TxEnv}, db::State, primitives::{address, Address}, DatabaseCommit, @@ -21,21 +26,17 @@ use reth::{ use reth_chainspec::ChainSpec; use reth_evm::{ execute::{ - BlockExecutionError, BlockExecutionStrategy, BlockExecutionStrategyFactory, + BlockExecutionError, BlockExecutionStrategyFactory, BlockExecutor, InternalBlockExecutionError, }, - ConfigureEvmEnv, Database, Evm, EvmEnv, EvmFor, FromRecoveredTx, InspectorFor, - NextBlockEnvAttributes, -}; -use reth_evm_ethereum::{ - execute::{EthBlockExecutionCtx, EthExecutionStrategy}, - EthBlockAssembler, EthEvmConfig, + ConfigureEvmEnv, Database, Evm, EvmEnv, InspectorFor, NextBlockEnvAttributes, OnStateHook, }; +use reth_evm_ethereum::{EthBlockAssembler, EthEvmConfig, RethReceiptBuilder}; use reth_node_ethereum::{node::EthereumAddOns, BasicBlockExecutorProvider, EthereumNode}; use reth_primitives::{ EthPrimitives, Receipt, Recovered, SealedBlock, SealedHeader, TransactionSigned, }; -use std::fmt::Display; +use std::{fmt::Display, sync::Arc}; pub const SYSTEM_ADDRESS: Address = address!("0xfffffffffffffffffffffffffffffffffffffffe"); pub const WITHDRAWALS_ADDRESS: Address = address!("0x4200000000000000000000000000000000000000"); @@ -118,18 +119,50 @@ impl ConfigureEvm for CustomEvmConfig { } } +impl BlockExecutorFactory for CustomEvmConfig { + type EvmFactory = EthEvmFactory; + type ExecutionCtx<'a> = EthBlockExecutionCtx<'a>; + type Transaction = TransactionSigned; + type Receipt = Receipt; + + fn evm_factory(&self) -> &Self::EvmFactory { + self.inner.evm_factory() + } + + fn create_executor<'a, DB, I>( + &'a self, + evm: EthEvm<&'a mut State, I>, + ctx: EthBlockExecutionCtx<'a>, + ) -> impl BlockExecutorFor<'a, Self, DB, I> + where + DB: Database + 'a, + I: InspectorFor<&'a mut State, Self> + 'a, + { + CustomBlockExecutor { + inner: EthBlockExecutor::new( + evm, + ctx, + self.inner.chain_spec(), + self.inner.executor_factory.receipt_builder(), + ), + } + } +} + impl BlockExecutionStrategyFactory for CustomEvmConfig { type Primitives = EthPrimitives; - type ExecutionCtx<'a> = EthBlockExecutionCtx<'a>; - type Strategy<'a, DB: Database + 'a, I: InspectorFor<&'a mut State, Self> + 'a> = - CustomExecutorStrategy<'a, EvmFor, I>>; + type BlockExecutorFactory = Self; type BlockAssembler = EthBlockAssembler; + fn block_executor_factory(&self) -> &Self::BlockExecutorFactory { + self + } + fn block_assembler(&self) -> &Self::BlockAssembler { self.inner.block_assembler() } - fn context_for_block<'a>(&self, block: &'a SealedBlock) -> Self::ExecutionCtx<'a> { + fn context_for_block<'a>(&self, block: &'a SealedBlock) -> EthBlockExecutionCtx<'a> { self.inner.context_for_block(block) } @@ -137,32 +170,20 @@ impl BlockExecutionStrategyFactory for CustomEvmConfig { &self, parent: &SealedHeader, attributes: Self::NextBlockEnvCtx, - ) -> Self::ExecutionCtx<'_> { + ) -> EthBlockExecutionCtx<'_> { self.inner.context_for_next_block(parent, attributes) } - - fn create_strategy<'a, DB, I>( - &'a self, - evm: EvmFor, I>, - ctx: Self::ExecutionCtx<'a>, - ) -> Self::Strategy<'a, DB, I> - where - DB: Database, - I: InspectorFor<&'a mut State, Self> + 'a, - { - CustomExecutorStrategy { inner: self.inner.create_strategy(evm, ctx) } - } } -pub struct CustomExecutorStrategy<'a, Evm> { +pub struct CustomBlockExecutor<'a, Evm> { /// Inner Ethereum execution strategy. - inner: EthExecutionStrategy<'a, Evm>, + inner: EthBlockExecutor<'a, Evm, &'a Arc, &'a RethReceiptBuilder>, } -impl<'db, DB, E> BlockExecutionStrategy for CustomExecutorStrategy<'_, E> +impl<'db, DB, E> BlockExecutor for CustomBlockExecutor<'_, E> where DB: Database + 'db, - E: Evm, Tx: FromRecoveredTx>, + E: Evm, Tx = TxEnv>, { type Transaction = TransactionSigned; type Receipt = Receipt; @@ -189,8 +210,8 @@ where self.inner.finish() } - fn with_state_hook(&mut self, _hook: Option>) { - self.inner.with_state_hook(_hook) + fn set_state_hook(&mut self, _hook: Option>) { + self.inner.set_state_hook(_hook) } fn evm_mut(&mut self) -> &mut Self::Evm {