From 4d481b24b0d655e131b12d4cc631ca7ca9e6a4a6 Mon Sep 17 00:00:00 2001 From: Hai Nguyen Date: Tue, 24 Sep 2024 07:05:03 +0700 Subject: [PATCH] wip: pevm integration for historical sync till Cancun --- Cargo.lock | 264 +++++++++++++++---- Cargo.toml | 9 +- crates/ethereum/evm/Cargo.toml | 2 + crates/ethereum/evm/src/execute.rs | 128 ++++++--- crates/ethereum/payload/src/lib.rs | 14 +- crates/evm/src/either.rs | 14 +- crates/evm/src/execute.rs | 24 +- crates/evm/src/noop.rs | 10 +- crates/payload/basic/src/lib.rs | 20 +- crates/storage/libmdbx-rs/src/transaction.rs | 16 +- 10 files changed, 371 insertions(+), 130 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5b2e8aabb97f..d544ad6db420 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -61,6 +61,7 @@ dependencies = [ "cfg-if", "getrandom 0.2.15", "once_cell", + "serde", "version_check", "zerocopy", ] @@ -97,9 +98,9 @@ checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "alloy-chains" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abf770dad29577cd3580f3dd09005799224a912b8cdfdd6dc04d030d42b3df4e" +checksum = "805f7a974de5804f5c053edc6ca43b20883bdd3a733b3691200ae3a4b454a2db" dependencies = [ "alloy-rlp", "arbitrary", @@ -1701,9 +1702,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.17" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac" +checksum = "b0956a43b323ac1afaffc053ed5c4b7c1f1800bacd1683c353aabbb752515dd3" dependencies = [ "clap_builder", "clap_derive", @@ -1711,9 +1712,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.17" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73" +checksum = "4d72166dd41634086d5803a47eb71ae740e61d84709c36f3c34110173db3961b" dependencies = [ "anstream", "anstyle", @@ -1723,9 +1724,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.13" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ "heck", "proc-macro2", @@ -2574,6 +2575,15 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" +[[package]] +name = "encoding_rs" +version = "0.8.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +dependencies = [ + "cfg-if", +] + [[package]] name = "endian-type" version = "0.1.2" @@ -3057,6 +3067,21 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -3629,6 +3654,22 @@ dependencies = [ "webpki-roots", ] +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + [[package]] name = "hyper-util" version = "0.1.8" @@ -4316,9 +4357,9 @@ dependencies = [ [[package]] name = "k256" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" dependencies = [ "cfg-if", "ecdsa", @@ -4410,7 +4451,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -4825,9 +4866,9 @@ checksum = "1fafa6961cabd9c63bcd77a45d7e3b7f3b552b70417831fb0f56db717e72407e" [[package]] name = "multiaddr" -version = "0.18.1" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b852bc02a2da5feed68cd14fa50d0774b92790a5bdbfa932a813926c8472070" +checksum = "fe6351f60b488e04c1d21bc69e56b89cb3f5e8f5d22557d6e8031bdfd79b6961" dependencies = [ "arrayref", "byteorder", @@ -4838,7 +4879,7 @@ dependencies = [ "percent-encoding", "serde", "static_assertions", - "unsigned-varint", + "unsigned-varint 0.8.0", "url", ] @@ -4860,7 +4901,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "076d548d76a0e2a0d4ab471d0b1c36c577786dfc4471242035d97a12a735c492" dependencies = [ "core2", - "unsigned-varint", + "unsigned-varint 0.7.2", +] + +[[package]] +name = "native-tls" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", ] [[package]] @@ -5212,12 +5270,50 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" +[[package]] +name = "openssl" +version = "0.10.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" +dependencies = [ + "bitflags 2.6.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + [[package]] name = "openssl-probe" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +[[package]] +name = "openssl-sys" +version = "0.9.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "option-ext" version = "0.2.0" @@ -5376,15 +5472,43 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.12" +version = "2.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c73c26c01b8c87956cea613c907c9d6ecffd8d18a2a5908e5de0adfaa185cea" +checksum = "fdbef9d1d47087a895abd220ed25eb4ad973a5e26f6a4367b038c25e28dfc2d9" dependencies = [ "memchr", "thiserror", "ucd-trie", ] +[[package]] +name = "pevm" +version = "0.1.0" +source = "git+https://github.com/risechain/pevm?rev=4dce71ffdeea076a6c0ea8a7bc900e66e00db72f#4dce71ffdeea076a6c0ea8a7bc900e66e00db72f" +dependencies = [ + "ahash", + "alloy-chains", + "alloy-consensus", + "alloy-primitives", + "alloy-provider", + "alloy-rlp", + "alloy-rpc-types", + "alloy-transport", + "alloy-transport-http", + "alloy-trie", + "bincode", + "bitflags 2.6.0", + "bitvec", + "clap", + "dashmap 6.1.0", + "reqwest", + "revm", + "serde", + "serde_json", + "smallvec", + "tokio", +] + [[package]] name = "pharos" version = "0.5.3" @@ -5481,9 +5605,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "plain_hasher" @@ -5542,9 +5666,9 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265" +checksum = "d30538d42559de6b034bc76fd6dd4c38961b1ee5c6c56e3808c50128fdbc22ce" [[package]] name = "powerfmt" @@ -6119,18 +6243,22 @@ checksum = "f8f4955649ef5c38cc7f9e8aa41761d48fb9677197daea9984dc54f56aad5e63" dependencies = [ "base64 0.22.1", "bytes", + "encoding_rs", "futures-core", "futures-util", + "h2", "http", "http-body", "http-body-util", "hyper", "hyper-rustls", + "hyper-tls", "hyper-util", "ipnet", "js-sys", "log", "mime", + "native-tls", "once_cell", "percent-encoding", "pin-project-lite", @@ -6143,7 +6271,9 @@ dependencies = [ "serde_json", "serde_urlencoded", "sync_wrapper 1.0.1", + "system-configuration", "tokio", + "tokio-native-tls", "tokio-rustls", "tokio-util", "tower-service", @@ -7274,6 +7404,7 @@ version = "1.0.7" dependencies = [ "alloy-eips", "alloy-sol-types", + "pevm", "reth-chainspec", "reth-ethereum-consensus", "reth-ethereum-forks", @@ -9026,11 +9157,11 @@ dependencies = [ [[package]] name = "revm" version = "14.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9f3f55d0414c3d73902d876ba3d55a654f05fe937089fbf5f34b1ced26d78d5" +source = "git+https://github.com/risechain/revm?rev=3d71d81a33722653073ef760860613b3af4dcb23#3d71d81a33722653073ef760860613b3af4dcb23" dependencies = [ "auto_impl", "cfg-if", + "dashmap 6.1.0", "dyn-clone", "revm-interpreter", "revm-precompile", @@ -9040,9 +9171,8 @@ dependencies = [ [[package]] name = "revm-inspectors" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48294aab02ed5d1940ad9b06f2a3230c3f0d98db6eacd618878cf143e204f6b0" +version = "0.7.6" +source = "git+https://github.com/risechain/revm-inspectors?rev=48a2bcfadcd0f3879c279077ca4061138a177677#48a2bcfadcd0f3879c279077ca4061138a177677" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", @@ -9060,8 +9190,7 @@ dependencies = [ [[package]] name = "revm-interpreter" version = "10.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "713dbb271acd13afb06dcd460c1dc43da211e7ac9bc73cdf13528f615f55f96b" +source = "git+https://github.com/risechain/revm?rev=3d71d81a33722653073ef760860613b3af4dcb23#3d71d81a33722653073ef760860613b3af4dcb23" dependencies = [ "revm-primitives", "serde", @@ -9070,8 +9199,7 @@ dependencies = [ [[package]] name = "revm-precompile" version = "11.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73010c271d53fa7904e9845338e95f3955eb1200a0355e0abfdb89c41aaa9cd" +source = "git+https://github.com/risechain/revm?rev=3d71d81a33722653073ef760860613b3af4dcb23#3d71d81a33722653073ef760860613b3af4dcb23" dependencies = [ "aurora-engine-modexp", "blst", @@ -9090,8 +9218,7 @@ dependencies = [ [[package]] name = "revm-primitives" version = "9.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7a6bff9dbde3370a5ac9555104117f7e6039b3cc76e8d5d9d01899088beca2a" +source = "git+https://github.com/risechain/revm?rev=3d71d81a33722653073ef760860613b3af4dcb23#3d71d81a33722653073ef760860613b3af4dcb23" dependencies = [ "alloy-eips", "alloy-primitives", @@ -9517,9 +9644,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.11.1" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" +checksum = "ea4a292869320c0272d7bc55a5a6aafaff59b4f63404a003887b679a2e05b4b6" dependencies = [ "core-foundation-sys", "libc", @@ -10116,6 +10243,27 @@ dependencies = [ "windows 0.52.0", ] +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags 2.6.0", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "tap" version = "1.0.1" @@ -10209,18 +10357,18 @@ checksum = "a38c90d48152c236a3ab59271da4f4ae63d678c5d7ad6b7714d7cb9760be5e4b" [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", @@ -10404,6 +10552,16 @@ dependencies = [ "syn 2.0.77", ] +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + [[package]] name = "tokio-rustls" version = "0.26.0" @@ -10692,9 +10850,9 @@ dependencies = [ [[package]] name = "tracy-client" -version = "0.17.3" +version = "0.17.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "373db47331c3407b343538df77eea2516884a0b126cdfb4b135acfd400015dd7" +checksum = "746b078c6a09ebfd5594609049e07116735c304671eaab06ce749854d23435bc" dependencies = [ "loom", "once_cell", @@ -10704,9 +10862,9 @@ dependencies = [ [[package]] name = "tracy-client-sys" -version = "0.24.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49cf0064dcb31c99aa1244c1b93439359e53f72ed217eef5db50abd442241e9a" +checksum = "68613466112302fdbeabc5fa55f7d57462a0b247d5a6b7d7e09401fb471a144d" dependencies = [ "cc", ] @@ -10886,15 +11044,15 @@ dependencies = [ [[package]] name = "unicode-width" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "unicode-xid" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "universal-hash" @@ -10912,6 +11070,12 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6889a77d49f1f013504cec6bf97a2c730394adedaeb1deb5ea08949a50541105" +[[package]] +name = "unsigned-varint" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb066959b24b5196ae73cb057f45598450d2c5f71460e98c49b738086eff9c06" + [[package]] name = "untrusted" version = "0.9.0" @@ -10969,6 +11133,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "vergen" version = "8.3.2" @@ -11162,7 +11332,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 959bcd36a661..29ad177ec734 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -405,16 +405,16 @@ reth-trie-common = { path = "crates/trie/common" } reth-trie-db = { path = "crates/trie/db" } reth-trie-parallel = { path = "crates/trie/parallel" } -# revm -revm = { version = "14.0.1", features = [ + +revm = { git = "https://github.com/risechain/revm", rev = "3d71d81a33722653073ef760860613b3af4dcb23", features = [ "std", "secp256k1", "blst", ], default-features = false } -revm-inspectors = "0.7" -revm-primitives = { version = "9.0.2", features = [ +revm-primitives = { git = "https://github.com/risechain/revm", rev = "3d71d81a33722653073ef760860613b3af4dcb23", features = [ "std", ], default-features = false } +revm-inspectors = { git = "https://github.com/risechain/revm-inspectors", rev = "48a2bcfadcd0f3879c279077ca4061138a177677" } # eth alloy-chains = "0.1.32" @@ -613,3 +613,4 @@ tracy-client = "0.17.3" #alloy-transport-http = { git = "https://github.com/alloy-rs/alloy", rev = "8c499409"} #alloy-transport-ipc = { git = "https://github.com/alloy-rs/alloy", rev = "8c499409"} #alloy-transport-ws = { git = "https://github.com/alloy-rs/alloy", rev = "8c499409"} +# revm diff --git a/crates/ethereum/evm/Cargo.toml b/crates/ethereum/evm/Cargo.toml index 25f2d9c6af78..83716318073f 100644 --- a/crates/ethereum/evm/Cargo.toml +++ b/crates/ethereum/evm/Cargo.toml @@ -28,6 +28,8 @@ revm-primitives.workspace = true alloy-eips.workspace = true alloy-sol-types.workspace = true +pevm = { git = "https://github.com/risechain/pevm", rev = "4dce71ffdeea076a6c0ea8a7bc900e66e00db72f" } + [dev-dependencies] reth-testing-utils.workspace = true reth-revm = { workspace = true, features = ["test-utils"] } diff --git a/crates/ethereum/evm/src/execute.rs b/crates/ethereum/evm/src/execute.rs index 096b44d0e828..ac2aec8f4793 100644 --- a/crates/ethereum/evm/src/execute.rs +++ b/crates/ethereum/evm/src/execute.rs @@ -5,7 +5,8 @@ use crate::{ EthEvmConfig, }; use alloc::{boxed::Box, sync::Arc, vec, vec::Vec}; -use core::fmt::Display; +use core::{fmt::Display, num::NonZeroUsize}; +use pevm::{chain::PevmEthereum, Pevm}; use reth_chainspec::{ChainSpec, EthereumHardforks, MAINNET}; use reth_ethereum_consensus::validate_block_post_execution; use reth_evm::{ @@ -34,7 +35,7 @@ use reth_revm::{ Evm, }; use revm_primitives::{ - db::{Database, DatabaseCommit}, + db::{DatabaseCommit, DatabaseRef}, BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ResultAndState, }; use std::collections::hash_map::Entry; @@ -71,12 +72,15 @@ where { fn eth_executor(&self, db: DB) -> EthBlockExecutor where - DB: Database>, + DB: DatabaseRef + Display> + Send + Sync, { EthBlockExecutor::new( self.chain_spec.clone(), self.evm_config.clone(), State::builder().with_database(db).with_bundle_update().without_state_clear().build(), + Pevm::default(), + PevmEthereum::mainnet(), + NonZeroUsize::new(8).unwrap(), ) } } @@ -85,22 +89,22 @@ impl BlockExecutorProvider for EthExecutorProvider where EvmConfig: ConfigureEvm
, { - type Executor + Display>> = + type Executor + Display> + Send + Sync> = EthBlockExecutor; - type BatchExecutor + Display>> = + type BatchExecutor + Display> + Send + Sync> = EthBatchExecutor; fn executor(&self, db: DB) -> Self::Executor where - DB: Database + Display>, + DB: DatabaseRef + Display> + Send + Sync, { self.eth_executor(db) } fn batch_executor(&self, db: DB) -> Self::BatchExecutor where - DB: Database + Display>, + DB: DatabaseRef + Display> + Send + Sync, { let executor = self.eth_executor(db); EthBatchExecutor { executor, batch_record: BlockBatchRecord::default() } @@ -138,14 +142,13 @@ where /// /// It does __not__ apply post-execution changes that do not require an [EVM](Evm), for that see /// [`EthBlockExecutor::post_execution`]. - fn execute_state_transitions( + fn _execute_state_transitions( &self, block: &BlockWithSenders, mut evm: Evm<'_, Ext, &mut State>, - ) -> Result + ) -> Result<(EthExecuteOutput, Vec), BlockExecutionError> where - DB: Database, - DB::Error: Into + Display, + DB: DatabaseRef + Display> + Send + Sync, { // apply pre execution changes apply_beacon_root_contract_call( @@ -168,6 +171,7 @@ where // execute transactions let mut cumulative_gas_used = 0; let mut receipts = Vec::with_capacity(block.body.len()); + let mut results = Vec::with_capacity(block.body.len()); for (sender, transaction) in block.transactions_with_sender() { // The sum of the transaction’s gas limit, Tg, and the gas utilized in this block prior, // must be no greater than the block’s gasLimit. @@ -177,13 +181,13 @@ where transaction_gas_limit: transaction.gas_limit(), block_available_gas, } - .into()) + .into()); } self.evm_config.fill_tx_env(evm.tx_mut(), transaction, *sender); // Execute transaction. - let ResultAndState { result, state } = evm.transact().map_err(move |err| { + let result_and_state = evm.transact().map_err(move |err| { let new_err = err.map_db_err(|e| e.into()); // Ensure hash is calculated for error log, if not already done BlockValidationError::EVM { @@ -191,10 +195,11 @@ where error: Box::new(new_err), } })?; - evm.db_mut().commit(state); + results.push(result_and_state.clone()); + evm.db_mut().commit(result_and_state.state); // append gas used - cumulative_gas_used += result.gas_used(); + cumulative_gas_used += result_and_state.result.gas_used(); // Push transaction changeset and calculate header bloom filter for receipt. receipts.push( @@ -203,10 +208,10 @@ where tx_type: transaction.tx_type(), // Success flag was added in `EIP-658: Embedding transaction status code in // receipts`. - success: result.is_success(), + success: result_and_state.result.is_success(), cumulative_gas_used, // convert to reth log - logs: result.into_logs(), + logs: result_and_state.result.into_logs(), ..Default::default() }, ); @@ -230,7 +235,7 @@ where vec![] }; - Ok(EthExecuteOutput { receipts, requests, gas_used: cumulative_gas_used }) + Ok((EthExecuteOutput { receipts, requests, gas_used: cumulative_gas_used }, results)) } } @@ -245,12 +250,29 @@ pub struct EthBlockExecutor { executor: EthEvmExecutor, /// The state to use for execution state: State, + /// Parallel executor + pevm: Pevm, + chain: PevmEthereum, + concurrency_level: NonZeroUsize, } impl EthBlockExecutor { /// Creates a new Ethereum block executor. - pub const fn new(chain_spec: Arc, evm_config: EvmConfig, state: State) -> Self { - Self { executor: EthEvmExecutor { chain_spec, evm_config }, state } + pub const fn new( + chain_spec: Arc, + evm_config: EvmConfig, + state: State, + pevm: Pevm, + chain: PevmEthereum, + concurrency_level: NonZeroUsize, + ) -> Self { + Self { + executor: EthEvmExecutor { chain_spec, evm_config }, + state, + pevm, + chain, + concurrency_level, + } } #[inline] @@ -268,14 +290,14 @@ impl EthBlockExecutor { impl EthBlockExecutor where EvmConfig: ConfigureEvm
, - DB: Database + Display>, + DB: DatabaseRef + Display> + Send + Sync, { /// Configures a new evm configuration and block environment for the given block. /// /// # Caution /// /// This does not initialize the tx environment. - fn evm_env_for_block(&self, header: &Header, total_difficulty: U256) -> EnvWithHandlerCfg { + fn _evm_env_for_block(&self, header: &Header, total_difficulty: U256) -> EnvWithHandlerCfg { let mut cfg = CfgEnvWithHandlerCfg::new(Default::default(), Default::default()); let mut block_env = BlockEnv::default(); self.executor.evm_config.fill_cfg_and_block_env( @@ -303,16 +325,60 @@ where self.on_new_block(&block.header); // 2. configure the evm and execute - let env = self.evm_env_for_block(&block.header, total_difficulty); - let output = { - let evm = self.executor.evm_config.evm_with_env(&mut self.state, env); - self.executor.execute_state_transitions(block, evm) - }?; + let spec_id = crate::config::revm_spec( + self.chain_spec(), + &reth_chainspec::Head { + number: block.header.number, + timestamp: block.header.timestamp, + difficulty: block.header.difficulty, + total_difficulty, + hash: Default::default(), + }, + ); + let mut block_env = BlockEnv::default(); + self.executor.evm_config.fill_block_env( + &mut block_env, + &block.header, + spec_id >= revm_primitives::SpecId::MERGE, + ); + let mut tx_envs = Vec::with_capacity(block.body.len()); + for (sender, transaction) in block.transactions_with_sender() { + let mut tx_env = revm_primitives::TxEnv::default(); + self.executor.evm_config.fill_tx_env(&mut tx_env, transaction, *sender); + tx_envs.push(tx_env); + } + let results = + if tx_envs.len() < self.concurrency_level.into() || block.header.gas_used < 4_000_000 { + pevm::execute_revm_sequential(&self.state, &self.chain, spec_id, block_env, tx_envs) + } else { + self.pevm.execute_revm_parallel( + &self.state, + &self.chain, + spec_id, + block_env, + tx_envs, + self.concurrency_level, + ) + } + .unwrap_or_else(|err| panic!("{:?}", err)); + let mut cumulative_gas_used = 0; + let mut receipts = Vec::with_capacity(block.body.len()); + for (tx, ResultAndState { result, state }) in block.transactions().zip(results) { + cumulative_gas_used += result.gas_used(); + receipts.push(Receipt { + tx_type: tx.tx_type(), + success: result.is_success(), + cumulative_gas_used, + logs: result.into_logs(), + ..Default::default() + }); + self.state.commit(state); + } // 3. apply post execution changes self.post_execution(block, total_difficulty)?; - Ok(output) + Ok(EthExecuteOutput { receipts, requests: Vec::new(), gas_used: cumulative_gas_used }) } /// Apply settings before a new block is executed. @@ -357,7 +423,7 @@ where impl Executor for EthBlockExecutor where EvmConfig: ConfigureEvm
, - DB: Database + Display>, + DB: DatabaseRef + Display> + Send + Sync, { type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>; type Output = BlockExecutionOutput; @@ -392,7 +458,7 @@ pub struct BlockAccessListExecutor { impl Executor for BlockAccessListExecutor where EvmConfig: ConfigureEvm
, - DB: Database + Display>, + DB: DatabaseRef + Display> + Send + Sync, { type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>; type Output = BlockExecutionOutput; @@ -486,7 +552,7 @@ impl EthBatchExecutor { impl BatchExecutor for EthBatchExecutor where EvmConfig: ConfigureEvm
, - DB: Database + Display>, + DB: DatabaseRef + Display> + Send + Sync, { type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>; type Output = ExecutionOutcome; diff --git a/crates/ethereum/payload/src/lib.rs b/crates/ethereum/payload/src/lib.rs index 9cd7981ff367..14deab71d60a 100644 --- a/crates/ethereum/payload/src/lib.rs +++ b/crates/ethereum/payload/src/lib.rs @@ -208,12 +208,12 @@ where // which also removes all dependent transaction from the iterator before we can // continue best_txs.mark_invalid(&pool_tx); - continue + continue; } // check if the job was cancelled, if so we can exit early if cancel.is_cancelled() { - return Ok(BuildOutcome::Cancelled) + return Ok(BuildOutcome::Cancelled); } // convert tx to a signed transaction @@ -230,7 +230,7 @@ where // for regular transactions above. trace!(target: "payload_builder", tx=?tx.hash, ?sum_blob_gas_used, ?tx_blob_gas, "skipping blob transaction because it would exceed the max data gas per block"); best_txs.mark_invalid(&pool_tx); - continue + continue; } } @@ -258,11 +258,11 @@ where best_txs.mark_invalid(&pool_tx); } - continue + continue; } err => { // this is an error that we should treat as fatal for this attempt - return Err(PayloadBuilderError::EvmExecutionError(err)) + return Err(PayloadBuilderError::EvmExecutionError(err)); } } } @@ -312,7 +312,7 @@ where // check if we have a better block if !is_better_payload(best_payload.as_ref(), total_fees) { // can skip building the block - return Ok(BuildOutcome::Aborted { fees: total_fees, cached_reads }) + return Ok(BuildOutcome::Aborted { fees: total_fees, cached_reads }); } // calculate the requests and the requests root @@ -363,7 +363,7 @@ where // calculate the state root let hashed_state = HashedPostState::from_bundle_state(&execution_outcome.state().state); let (state_root, trie_output) = { - let state_provider = db.database.0.inner.borrow_mut(); + let state_provider = db.database.inner.borrow_mut(); state_provider.db.state_root_with_updates(hashed_state.clone()).inspect_err(|err| { warn!(target: "payload_builder", parent_hash=%parent_block.hash(), diff --git a/crates/evm/src/either.rs b/crates/evm/src/either.rs index 84e1733e4812..75de68c0fdee 100644 --- a/crates/evm/src/either.rs +++ b/crates/evm/src/either.rs @@ -8,7 +8,7 @@ use reth_execution_types::{BlockExecutionInput, BlockExecutionOutput, ExecutionO use reth_primitives::{BlockNumber, BlockWithSenders, Receipt}; use reth_prune_types::PruneModes; use reth_storage_errors::provider::ProviderError; -use revm_primitives::db::Database; +use revm::DatabaseRef; // re-export Either pub use futures_util::future::Either; @@ -18,15 +18,15 @@ where A: BlockExecutorProvider, B: BlockExecutorProvider, { - type Executor + Display>> = + type Executor + Display> + Send + Sync> = Either, B::Executor>; - type BatchExecutor + Display>> = + type BatchExecutor + Display> + Send + Sync> = Either, B::BatchExecutor>; fn executor(&self, db: DB) -> Self::Executor where - DB: Database + Display>, + DB: DatabaseRef + Display> + Send + Sync, { match self { Self::Left(a) => Either::Left(a.executor(db)), @@ -36,7 +36,7 @@ where fn batch_executor(&self, db: DB) -> Self::BatchExecutor where - DB: Database + Display>, + DB: DatabaseRef + Display> + Send + Sync, { match self { Self::Left(a) => Either::Left(a.batch_executor(db)), @@ -59,7 +59,7 @@ where Output = BlockExecutionOutput, Error = BlockExecutionError, >, - DB: Database + Display>, + DB: DatabaseRef + Display>, { type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>; type Output = BlockExecutionOutput; @@ -87,7 +87,7 @@ where Output = ExecutionOutcome, Error = BlockExecutionError, >, - DB: Database + Display>, + DB: DatabaseRef + Display>, { type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>; type Output = ExecutionOutcome; diff --git a/crates/evm/src/execute.rs b/crates/evm/src/execute.rs index 2109d557f8ec..2d36990a8e7c 100644 --- a/crates/evm/src/execute.rs +++ b/crates/evm/src/execute.rs @@ -9,7 +9,7 @@ use core::fmt::Display; use reth_primitives::{BlockNumber, BlockWithSenders, Receipt}; use reth_prune_types::PruneModes; -use revm_primitives::db::Database; +use revm_primitives::db::DatabaseRef; /// A general purpose executor trait that executes an input (e.g. block) and produces an output /// (e.g. state changes and receipts). @@ -107,7 +107,7 @@ pub trait BlockExecutorProvider: Send + Sync + Clone + Unpin + 'static { /// /// It is not expected to validate the state trie root, this must be done by the caller using /// the returned state. - type Executor + Display>>: for<'a> Executor< + type Executor + Display> + Send + Sync>: for<'a> Executor< DB, Input<'a> = BlockExecutionInput<'a, BlockWithSenders>, Output = BlockExecutionOutput, @@ -115,7 +115,7 @@ pub trait BlockExecutorProvider: Send + Sync + Clone + Unpin + 'static { >; /// An executor that can execute a batch of blocks given a database. - type BatchExecutor + Display>>: for<'a> BatchExecutor< + type BatchExecutor + Display> + Send + Sync>: for<'a> BatchExecutor< DB, Input<'a> = BlockExecutionInput<'a, BlockWithSenders>, Output = ExecutionOutcome, @@ -127,7 +127,7 @@ pub trait BlockExecutorProvider: Send + Sync + Clone + Unpin + 'static { /// This is used to execute a single block and get the changed state. fn executor(&self, db: DB) -> Self::Executor where - DB: Database + Display>; + DB: DatabaseRef + Display> + Send + Sync; /// Creates a new batch executor with the given database and pruning modes. /// @@ -135,7 +135,7 @@ pub trait BlockExecutorProvider: Send + Sync + Clone + Unpin + 'static { /// during historical sync which involves executing multiple blocks in sequence. fn batch_executor(&self, db: DB) -> Self::BatchExecutor where - DB: Database + Display>; + DB: DatabaseRef + Display> + Send + Sync; } #[cfg(test)] @@ -150,19 +150,21 @@ mod tests { struct TestExecutorProvider; impl BlockExecutorProvider for TestExecutorProvider { - type Executor + Display>> = TestExecutor; - type BatchExecutor + Display>> = TestExecutor; + type Executor + Display> + Send + Sync> = + TestExecutor; + type BatchExecutor + Display> + Send + Sync> = + TestExecutor; - fn executor(&self, _db: DB) -> Self::Executor + fn executor(&self, _db: DB) -> Self::Executor where - DB: Database + Display>, + DB: DatabaseRef + Display>, { TestExecutor(PhantomData) } - fn batch_executor(&self, _db: DB) -> Self::BatchExecutor + fn batch_executor(&self, _db: DB) -> Self::BatchExecutor where - DB: Database + Display>, + DB: DatabaseRef + Display>, { TestExecutor(PhantomData) } diff --git a/crates/evm/src/noop.rs b/crates/evm/src/noop.rs index ff8e893b2b6b..538ea0d2e8f6 100644 --- a/crates/evm/src/noop.rs +++ b/crates/evm/src/noop.rs @@ -7,7 +7,7 @@ use reth_execution_types::{BlockExecutionInput, BlockExecutionOutput, ExecutionO use reth_primitives::{BlockNumber, BlockWithSenders, Receipt}; use reth_prune_types::PruneModes; use reth_storage_errors::provider::ProviderError; -use revm_primitives::db::Database; +use revm::DatabaseRef; use crate::execute::{BatchExecutor, BlockExecutorProvider, Executor}; @@ -19,20 +19,20 @@ const UNAVAILABLE_FOR_NOOP: &str = "execution unavailable for noop"; pub struct NoopBlockExecutorProvider; impl BlockExecutorProvider for NoopBlockExecutorProvider { - type Executor + Display>> = Self; + type Executor + Display> + Send + Sync> = Self; - type BatchExecutor + Display>> = Self; + type BatchExecutor + Display> + Send + Sync> = Self; fn executor(&self, _: DB) -> Self::Executor where - DB: Database + Display>, + DB: DatabaseRef + Display> + Send + Sync, { Self } fn batch_executor(&self, _: DB) -> Self::BatchExecutor where - DB: Database + Display>, + DB: DatabaseRef + Display> + Send + Sync, { Self } diff --git a/crates/payload/basic/src/lib.rs b/crates/payload/basic/src/lib.rs index 6a03c35c1954..1e5f1739fcc6 100644 --- a/crates/payload/basic/src/lib.rs +++ b/crates/payload/basic/src/lib.rs @@ -28,7 +28,7 @@ use reth_provider::{ use reth_revm::state_change::post_block_withdrawals_balance_increments; use reth_tasks::TaskSpawner; use reth_transaction_pool::TransactionPool; -use revm::{Database, State}; +use revm::{DatabaseRef, State}; use std::{ fmt, future::Future, @@ -408,7 +408,7 @@ where // check if the deadline is reached if this.deadline.as_mut().poll(cx).is_ready() { trace!(target: "payload_builder", "payload building deadline reached"); - return Poll::Ready(Ok(())) + return Poll::Ready(Ok(())); } // check if the interval is reached @@ -466,7 +466,7 @@ where fn best_payload(&self) -> Result { if let Some(ref payload) = self.best_payload { - return Ok(payload.clone()) + return Ok(payload.clone()); } // No payload has been built yet, but we need to return something that the CL then can // deliver, so we need to return an empty payload. @@ -584,14 +584,14 @@ where this.maybe_better = None; if let Ok(BuildOutcome::Better { payload, .. }) = res { debug!(target: "payload_builder", "resolving better payload"); - return Poll::Ready(Ok(payload)) + return Poll::Ready(Ok(payload)); } } } if let Some(best) = this.best_payload.take() { debug!(target: "payload_builder", "resolving best payload"); - return Poll::Ready(Ok(best)) + return Poll::Ready(Ok(best)); } if let Some(fut) = Pin::new(&mut this.empty_payload).as_pin_mut() { @@ -607,12 +607,12 @@ where Poll::Ready(res) } Err(err) => Poll::Ready(Err(err.into())), - } + }; } } if this.is_empty() { - return Poll::Ready(Err(PayloadBuilderError::MissingPayload)) + return Poll::Ready(Err(PayloadBuilderError::MissingPayload)); } Poll::Pending @@ -912,18 +912,18 @@ impl WithdrawalsOutcome { /// Returns the withdrawals root. /// /// Returns `None` values pre shanghai -pub fn commit_withdrawals>( +pub fn commit_withdrawals>( db: &mut State, chain_spec: &ChainSpec, timestamp: u64, withdrawals: Withdrawals, ) -> Result { if !chain_spec.is_shanghai_active_at_timestamp(timestamp) { - return Ok(WithdrawalsOutcome::pre_shanghai()) + return Ok(WithdrawalsOutcome::pre_shanghai()); } if withdrawals.is_empty() { - return Ok(WithdrawalsOutcome::empty()) + return Ok(WithdrawalsOutcome::empty()); } let balance_increments = diff --git a/crates/storage/libmdbx-rs/src/transaction.rs b/crates/storage/libmdbx-rs/src/transaction.rs index 88236ebe9914..497d66f7b053 100644 --- a/crates/storage/libmdbx-rs/src/transaction.rs +++ b/crates/storage/libmdbx-rs/src/transaction.rs @@ -524,7 +524,7 @@ impl Transaction { /// Begins a new nested transaction inside of this transaction. pub fn begin_nested_txn(&mut self) -> Result { if self.inner.env.is_write_map() { - return Err(Error::NestedTransactionsUnsupportedWithWriteMap) + return Err(Error::NestedTransactionsUnsupportedWithWriteMap); } self.txn_execute(|txn| { let (tx, rx) = sync_channel(0); @@ -580,12 +580,12 @@ impl TransactionPtr { if let Some(lock) = self.lock.try_lock() { lock } else { - tracing::debug!( - target: "libmdbx", - txn = %self.txn as usize, - backtrace = %std::backtrace::Backtrace::force_capture(), - "Transaction lock is already acquired, blocking..." - ); + // tracing::debug!( + // target: "libmdbx", + // txn = %self.txn as usize, + // backtrace = %std::backtrace::Backtrace::force_capture(), + // "Transaction lock is already acquired, blocking..." + // ); self.lock.lock() } } @@ -605,7 +605,7 @@ impl TransactionPtr { // to the `mdbx_txn_reset`. #[cfg(feature = "read-tx-timeouts")] if self.is_timed_out() { - return Err(Error::ReadTransactionTimeout) + return Err(Error::ReadTransactionTimeout); } Ok((f)(self.txn))