diff --git a/.changeset/spotty-dryers-study.md b/.changeset/spotty-dryers-study.md new file mode 100644 index 000000000..41fe7f1e9 --- /dev/null +++ b/.changeset/spotty-dryers-study.md @@ -0,0 +1,5 @@ +--- +"@nomicfoundation/edr": minor +--- + +Added InvalidEXTCALLTarget to ExceptionalHalt diff --git a/Cargo.lock b/Cargo.lock index 876cc91f6..480d69a36 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -46,14 +46,14 @@ checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] name = "alloy-dyn-abi" -version = "0.7.7" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413902aa18a97569e60f679c23f46a18db1656d87ab4d4e49d0e1e52042f66df" +checksum = "4004925bff5ba0a11739ae84dbb6601a981ea692f3bd45b626935ee90a6b8471" dependencies = [ "alloy-json-abi", - "alloy-primitives 0.7.7", + "alloy-primitives", "alloy-sol-type-parser", - "alloy-sol-types 0.7.7", + "alloy-sol-types", "const-hex", "derive_more", "itoa", @@ -63,58 +63,62 @@ dependencies = [ ] [[package]] -name = "alloy-eips" -version = "0.2.0" +name = "alloy-eip2930" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d32a3e14fa0d152d00bd8daf605eb74ad397efb0f54bd7155585823dddb4401e" +checksum = "0069cf0642457f87a01a014f6dc29d5d893cd4fd8fddf0c3cdfad1bb3ebafc41" dependencies = [ - "alloy-primitives 0.7.7", + "alloy-primitives", "alloy-rlp", - "alloy-serde", - "c-kzg", - "k256", - "once_cell", "serde", ] [[package]] -name = "alloy-json-abi" -version = "0.7.7" +name = "alloy-eip7702" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc05b04ac331a9f07e3a4036ef7926e49a8bf84a99a1ccfc7e2ab55a5fcbb372" +checksum = "37d319bb544ca6caeab58c39cea8921c55d924d4f68f2c60f24f914673f9a74a" dependencies = [ - "alloy-primitives 0.7.7", - "alloy-sol-type-parser", + "alloy-primitives", + "alloy-rlp", + "k256", "serde", - "serde_json", ] [[package]] -name = "alloy-primitives" -version = "0.5.4" +name = "alloy-eips" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c234f92024707f224510ff82419b2be0e1d8e1fd911defcac5a085cd7f83898" +checksum = "2f6c5c0a383f14519531cf58d8440e74f10b938e289f803af870be6f79223110" dependencies = [ + "alloy-eip2930", + "alloy-eip7702", + "alloy-primitives", "alloy-rlp", - "bytes", - "cfg-if", - "const-hex", + "alloy-serde", + "c-kzg", "derive_more", - "hex-literal", - "itoa", - "keccak-asm", - "proptest", - "rand", - "ruint", + "once_cell", "serde", - "tiny-keccak", +] + +[[package]] +name = "alloy-json-abi" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9996daf962fd0a90d3c93b388033228865953b92de7bb1959b891d78750a4091" +dependencies = [ + "alloy-primitives", + "alloy-sol-type-parser", + "serde", + "serde_json", ] [[package]] name = "alloy-primitives" -version = "0.7.7" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccb3ead547f4532bc8af961649942f0b9c16ee9226e26caa3f38420651cc0bf4" +checksum = "411aff151f2a73124ee473708e82ed51b2535f68928b6a1caa8bc1246ae6f7cd" dependencies = [ "alloy-rlp", "bytes", @@ -157,42 +161,24 @@ dependencies = [ [[package]] name = "alloy-serde" -version = "0.2.0" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15c5b9057acc02aee1b8aac2b5a0729cb0f73d080082c111313e5d1f92a96630" +checksum = "6b95b6f024a558593dd3b8628af03f7df2ca50e4c56839293ad0a7546e471db0" dependencies = [ - "alloy-primitives 0.7.7", + "alloy-primitives", "serde", "serde_json", ] [[package]] name = "alloy-sol-macro" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "970e5cf1ca089e964d4f7f7afc7c9ad642bfb1bdc695a20b0cba3b3c28954774" -dependencies = [ - "const-hex", - "dunce", - "heck 0.4.1", - "indexmap 2.2.6", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.58", - "syn-solidity 0.5.4", - "tiny-keccak", -] - -[[package]] -name = "alloy-sol-macro" -version = "0.7.7" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b40397ddcdcc266f59f959770f601ce1280e699a91fc1862f29cef91707cd09" +checksum = "0458ccb02a564228fcd76efb8eb5a520521a8347becde37b402afec9a1b83859" dependencies = [ "alloy-sol-macro-expander", "alloy-sol-macro-input", - "proc-macro-error", + "proc-macro-error2", "proc-macro2", "quote", "syn 2.0.58", @@ -200,27 +186,27 @@ dependencies = [ [[package]] name = "alloy-sol-macro-expander" -version = "0.7.7" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "867a5469d61480fea08c7333ffeca52d5b621f5ca2e44f271b117ec1fc9a0525" +checksum = "2bc65475025fc1e84bf86fc840f04f63fcccdcf3cf12053c99918e4054dfbc69" dependencies = [ "alloy-sol-macro-input", "const-hex", "heck 0.5.0", "indexmap 2.2.6", - "proc-macro-error", + "proc-macro-error2", "proc-macro2", "quote", "syn 2.0.58", - "syn-solidity 0.7.7", + "syn-solidity", "tiny-keccak", ] [[package]] name = "alloy-sol-macro-input" -version = "0.7.7" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e482dc33a32b6fadbc0f599adea520bd3aaa585c141a80b404d0a3e3fa72528" +checksum = "6ed10f0715a0b69fde3236ff3b9ae5f6f7c97db5a387747100070d3016b9266b" dependencies = [ "const-hex", "dunce", @@ -228,14 +214,14 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.58", - "syn-solidity 0.7.7", + "syn-solidity", ] [[package]] name = "alloy-sol-type-parser" -version = "0.7.7" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbcba3ca07cf7975f15d871b721fb18031eec8bce51103907f6dcce00b255d98" +checksum = "3edae8ea1de519ccba896b6834dec874230f72fe695ff3c9c118e90ec7cff783" dependencies = [ "serde", "winnow 0.6.8", @@ -243,24 +229,13 @@ dependencies = [ [[package]] name = "alloy-sol-types" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a059d4d2c78f8f21e470772c75f9abd9ac6d48c2aaf6b278d1ead06ed9ac664" -dependencies = [ - "alloy-primitives 0.5.4", - "alloy-sol-macro 0.5.4", - "const-hex", - "serde", -] - -[[package]] -name = "alloy-sol-types" -version = "0.7.7" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a91ca40fa20793ae9c3841b83e74569d1cc9af29a2f5237314fd3452d51e38c7" +checksum = "1eb88e4da0a1b697ed6a9f811fdba223cf4d5c21410804fd1707836af73a462b" dependencies = [ - "alloy-primitives 0.7.7", - "alloy-sol-macro 0.7.7", + "alloy-json-abi", + "alloy-primitives", + "alloy-sol-macro", "const-hex", "serde", ] @@ -297,9 +272,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.81" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" [[package]] name = "archery" @@ -604,19 +579,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "bls12_381" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7bc6d6292be3a19e6379786dac800f551e5865a5bb51ebbe3064ab80433f403" -dependencies = [ - "ff", - "group", - "pairing", - "rand_core", - "subtle", -] - [[package]] name = "blst" version = "0.3.11" @@ -658,15 +620,16 @@ dependencies = [ [[package]] name = "c-kzg" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdf100c4cea8f207e883ff91ca886d621d8a166cb04971dfaa9bb8fd99ed95df" +checksum = "f0307f72feab3300336fb803a57134159f6e20139af1357f36c54cb90d8e8928" dependencies = [ "blst", "cc", "glob", "hex", "libc", + "once_cell", "serde", ] @@ -819,12 +782,6 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - [[package]] name = "convert_case" version = "0.6.0" @@ -1014,15 +971,23 @@ dependencies = [ [[package]] name = "derive_more" -version = "0.99.17" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ - "convert_case 0.4.0", "proc-macro2", "quote", - "rustc_version 0.4.0", - "syn 1.0.109", + "syn 2.0.58", + "unicode-xid", ] [[package]] @@ -1172,8 +1137,6 @@ dependencies = [ "log", "parking_lot 0.12.1", "paste", - "revm", - "revm-primitives", "serde", "serde_json", "serial_test", @@ -1245,6 +1208,7 @@ dependencies = [ "parking_lot 0.12.1", "paste", "revm", + "revm-optimism", "serde", "serde_json", "serial_test", @@ -1257,7 +1221,7 @@ name = "edr_provider" version = "0.3.5" dependencies = [ "alloy-dyn-abi", - "alloy-sol-types 0.5.4", + "alloy-sol-types", "anyhow", "auto_impl", "cargo_toml", @@ -1323,6 +1287,7 @@ dependencies = [ name = "edr_rpc_eth" version = "0.3.5" dependencies = [ + "alloy-eips", "alloy-serde", "anyhow", "assert-json-diff", @@ -1458,7 +1423,6 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ - "bitvec", "rand_core", "subtle", ] @@ -2028,21 +1992,6 @@ dependencies = [ "sha3-asm", ] -[[package]] -name = "kzg-rs" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd9920cd4460ce3cbca19c62f3bb9a9611562478a4dc9d2c556f4a7d049c5b6b" -dependencies = [ - "bls12_381", - "glob", - "hex", - "once_cell", - "serde", - "serde_derive", - "serde_yaml", -] - [[package]] name = "lazy_static" version = "1.4.0" @@ -2201,9 +2150,9 @@ dependencies = [ [[package]] name = "napi" -version = "2.16.1" +version = "2.16.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4ca998356d8ff9fba7a070dae4508a2298439c98c9f3bc9c07669538b999e8f" +checksum = "04409e8c2d61995696e44d2181b79b68c1dd41f7e24a17cde60bbd9f54ddddef" dependencies = [ "anyhow", "bitflags 2.6.0", @@ -2224,12 +2173,12 @@ checksum = "2f9130fccc5f763cf2069b34a089a18f0d0883c66aceb81f2fad541a3d823c43" [[package]] name = "napi-derive" -version = "2.16.1" +version = "2.16.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b138cecf1141ae0ff5d62f4aa0e2f269aec339f66070f346ba6fb4279f1fc178" +checksum = "17435f7a00bfdab20b0c27d9c56f58f6499e418252253081bfff448099da31d1" dependencies = [ "cfg-if", - "convert_case 0.6.0", + "convert_case", "napi-derive-backend", "proc-macro2", "quote", @@ -2238,11 +2187,11 @@ dependencies = [ [[package]] name = "napi-derive-backend" -version = "1.0.63" +version = "1.0.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce5126b64f6ad9e28e30e6d15213dd378626b38f556454afebc42f7f02a90902" +checksum = "967c485e00f0bf3b1bdbe510a38a4606919cf1d34d9a37ad41f25a81aa077abe" dependencies = [ - "convert_case 0.6.0", + "convert_case", "once_cell", "proc-macro2", "quote", @@ -2253,9 +2202,9 @@ dependencies = [ [[package]] name = "napi-sys" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2503fa6af34dc83fb74888df8b22afe933b58d37daf7d80424b1c60c68196b8b" +checksum = "427802e8ec3a734331fec1035594a210ce1ff4dc5bc1950530920ab717964ea3" dependencies = [ "libloading", ] @@ -2479,15 +2428,6 @@ dependencies = [ "sha2", ] -[[package]] -name = "pairing" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fec4625e73cf41ef4bb6846cafa6d44736525f442ba45e407c4a000a13996f" -dependencies = [ - "group", -] - [[package]] name = "parity-scale-codec" version = "3.6.9" @@ -2715,6 +2655,28 @@ dependencies = [ "version_check", ] +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn 2.0.58", +] + [[package]] name = "proc-macro2" version = "1.0.79" @@ -2994,13 +2956,12 @@ dependencies = [ [[package]] name = "revm" -version = "12.1.0" -source = "git+https://github.com/Wodann/revm?rev=a500675#a5006752ca98c65c005fbbec082862b67af9dab5" +version = "14.0.1" +source = "git+https://github.com/Wodann/revm?rev=f260074#f2600745f9f2c8c62af710393a5c0a8dc3461b07" dependencies = [ "auto_impl", "derive-where", "dyn-clone", - "enumn", "revm-interpreter", "revm-precompile", "serde", @@ -3009,18 +2970,29 @@ dependencies = [ [[package]] name = "revm-interpreter" -version = "8.1.0" -source = "git+https://github.com/Wodann/revm?rev=a500675#a5006752ca98c65c005fbbec082862b67af9dab5" +version = "10.0.1" +source = "git+https://github.com/Wodann/revm?rev=f260074#f2600745f9f2c8c62af710393a5c0a8dc3461b07" dependencies = [ "derive-where", "revm-primitives", "serde", ] +[[package]] +name = "revm-optimism" +version = "1.0.0" +source = "git+https://github.com/Wodann/revm?rev=f260074#f2600745f9f2c8c62af710393a5c0a8dc3461b07" +dependencies = [ + "enumn", + "revm", + "revm-precompile", + "serde", +] + [[package]] name = "revm-precompile" -version = "9.2.0" -source = "git+https://github.com/Wodann/revm?rev=a500675#a5006752ca98c65c005fbbec082862b67af9dab5" +version = "11.0.1" +source = "git+https://github.com/Wodann/revm?rev=f260074#f2600745f9f2c8c62af710393a5c0a8dc3461b07" dependencies = [ "aurora-engine-modexp", "c-kzg", @@ -3037,24 +3009,20 @@ dependencies = [ [[package]] name = "revm-primitives" -version = "7.1.0" -source = "git+https://github.com/Wodann/revm?rev=a500675#a5006752ca98c65c005fbbec082862b67af9dab5" +version = "9.0.1" +source = "git+https://github.com/Wodann/revm?rev=f260074#f2600745f9f2c8c62af710393a5c0a8dc3461b07" dependencies = [ "alloy-eips", - "alloy-primitives 0.7.7", + "alloy-primitives", "auto_impl", "bitflags 2.6.0", "bitvec", "c-kzg", "cfg-if", - "derive-where", - "derive_more", "dyn-clone", "enumn", "hashbrown 0.14.3", "hex", - "kzg-rs", - "once_cell", "serde", ] @@ -3354,19 +3322,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_yaml" -version = "0.9.34+deprecated" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" -dependencies = [ - "indexmap 2.2.6", - "itoa", - "ryu", - "serde", - "unsafe-libyaml", -] - [[package]] name = "serial_test" version = "2.0.0" @@ -3544,21 +3499,9 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ede2e5b2c6bfac4bc0ff4499957a11725dc12a7ddb86270e827ef575892553" -dependencies = [ - "paste", - "proc-macro2", - "quote", - "syn 2.0.58", -] - -[[package]] -name = "syn-solidity" -version = "0.7.7" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c837dc8852cb7074e46b444afb81783140dab12c58867b49fb3898fbafedf7ea" +checksum = "4b95156f8b577cb59dc0b1df15c6f29a10afc5f8a7ac9786b0b5c68c19149278" dependencies = [ "paste", "proc-macro2", @@ -4007,10 +3950,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" [[package]] -name = "unsafe-libyaml" -version = "0.2.11" +name = "unicode-xid" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" +checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a" [[package]] name = "url" diff --git a/Cargo.toml b/Cargo.toml index 967a4a7fb..bc20b740f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ nonstandard_style = "warn" rust_2018_idioms = "warn" [workspace.lints.clippy] -all = "warn" +all = { level = "warn", priority = -1 } await_holding_lock = "warn" bool-to-int-with-if = "warn" cast_lossless = "warn" diff --git a/book/src/04_multichain/01_chain_spec.md b/book/src/04_multichain/01_chain_spec.md index 3b5eebcdf..d7c2841ff 100644 --- a/book/src/04_multichain/01_chain_spec.md +++ b/book/src/04_multichain/01_chain_spec.md @@ -10,11 +10,11 @@ This is achieved through the usage of multiple traits, some of which are supertr - Adds an additional function to `revm_primitives::EvmWiring` that depends on the `Evm`. - Header builder: `edr_eth::EthHeaderConstants` - RPC client: `edr_rpc_eth::RpcSpec` -- EVM runtime: `edr_evm::ChainSpec` +- EVM runtime: `edr_evm::RuntimeSpec` - EVM provider: `edr_provider::ProviderSpec` - EDR N-API bindings: `edr_napi::SyncNapiSpec` -Most of these traits have a `Sync*` equivalent (e.g. `SyncChainSpec`) which is automatically implemented for types that are `Send` and `Sync`. +Most of these traits have a `Sync*` equivalent (e.g. `SyncRuntimeSpec`) which is automatically implemented for types that are `Send` and `Sync`. ## Supported Chain Types diff --git a/crates/edr_eth/Cargo.toml b/crates/edr_eth/Cargo.toml index a7bce4ba9..2233c8dc5 100644 --- a/crates/edr_eth/Cargo.toml +++ b/crates/edr_eth/Cargo.toml @@ -4,10 +4,10 @@ version = "0.3.5" edition = "2021" [dependencies] -anyhow = "1.0.75" -alloy-eips = { version = "0.2", default-features = false } +anyhow = "1.0.89" +alloy-eips = { version = "0.3", default-features = false } alloy-rlp = { version = "0.3", default-features = false, features = ["derive"] } -c-kzg = { version = "1.0.2", default-features = false } +c-kzg = { version = "1.0.3", default-features = false } derive-where = { version = "1.2.7", default-features = false } hash-db = { version = "0.15.2", default-features = false } hash256-std-hasher = { version = "0.15.2", default-features = false } @@ -16,9 +16,9 @@ hex = { version = "0.4.3", default-features = false, features = ["alloc"] } itertools = { version = "0.10.5", default-features = false, features = ["use_alloc"] } k256 = { version = "0.13.1", default-features = false, features = ["arithmetic", "ecdsa", "pkcs8", ] } log = { version = "0.4.17", default-features = false } -once_cell = { version = "1.18.0", default-features = false, features = ["alloc", "race", "std"] } -revm = { git = "https://github.com/Wodann/revm", rev = "a500675", version = "12.1", default-features = false, features = ["c-kzg", "dev", "serde"] } -revm-primitives = { git = "https://github.com/Wodann/revm", rev = "a500675", version = "7.1", default-features = false, features = ["c-kzg", "hashbrown"] } +once_cell = { version = "1.19.0", default-features = false, features = ["alloc", "race", "std"] } +revm = { git = "https://github.com/Wodann/revm", rev = "f260074", version = "14.0", default-features = false, features = ["c-kzg", "dev", "serde"] } +revm-primitives = { git = "https://github.com/Wodann/revm", rev = "f260074", version = "9.0", default-features = false, features = ["c-kzg", "hashbrown", "rand"] } serde = { version = "1.0.209", default-features = false, features = ["derive"], optional = true } sha2 = { version = "0.10.8", default-features = false } sha3 = { version = "0.10.8", default-features = false } @@ -27,7 +27,7 @@ tracing = { version = "0.1.37", features = ["attributes", "std"], optional = tru triehash = { version = "0.8.4", default-features = false } [dev-dependencies] -anyhow = "1.0.75" +anyhow = "1.0.89" assert-json-diff = "2.0.2" edr_defaults = { version = "0.3.5", path = "../edr_defaults" } edr_rpc_eth = { version = "0.3.5", path = "../edr_rpc_eth" } @@ -41,7 +41,6 @@ tokio = { version = "1.23.0", features = ["macros"] } [features] default = ["std"] -rand = ["revm-primitives/rand"] serde = ["dep:serde", "c-kzg/serde", "revm/serde", "revm-primitives/serde"] std = ["alloy-eips/std", "hash256-std-hasher/std", "hash-db/std", "hex/std", "itertools/use_std", "k256/std", "k256/precomputed-tables", "revm/std", "revm-primitives/std", "serde?/std", "sha2/std", "sha3/std", "triehash/std"] test-remote = [] diff --git a/crates/edr_eth/src/block.rs b/crates/edr_eth/src/block.rs index 8786cf77f..e21884ad2 100644 --- a/crates/edr_eth/src/block.rs +++ b/crates/edr_eth/src/block.rs @@ -23,8 +23,7 @@ pub use self::{ reward::miner_reward, }; use crate::{ - chain_spec::EthHeaderConstants, trie::KECCAK_NULL_RLP, Address, Bloom, Bytes, SpecId, B256, - B64, U256, + spec::EthHeaderConstants, trie::KECCAK_NULL_RLP, Address, Bloom, Bytes, SpecId, B256, B64, U256, }; /// ethereum block header diff --git a/crates/edr_eth/src/block/difficulty.rs b/crates/edr_eth/src/block/difficulty.rs index 2c4748ea0..8f6c0a1ae 100644 --- a/crates/edr_eth/src/block/difficulty.rs +++ b/crates/edr_eth/src/block/difficulty.rs @@ -1,6 +1,4 @@ -use crate::{ - block::Header, chain_spec::EthHeaderConstants, trie::KECCAK_RLP_EMPTY_ARRAY, SpecId, U256, -}; +use crate::{block::Header, spec::EthHeaderConstants, trie::KECCAK_RLP_EMPTY_ARRAY, SpecId, U256}; fn bomb_delay(spec_id: SpecId) -> u64 { match spec_id { diff --git a/crates/edr_eth/src/eips/eip1559.rs b/crates/edr_eth/src/eips/eip1559.rs index c90eee3b5..2b4a8b703 100644 --- a/crates/edr_eth/src/eips/eip1559.rs +++ b/crates/edr_eth/src/eips/eip1559.rs @@ -1,37 +1,34 @@ pub use alloy_eips::eip1559::BaseFeeParams as ConstantBaseFeeParams; -use derive_where::derive_where; -use revm_primitives::EvmWiring; +use revm_primitives::HardforkTrait; /// A mapping of hardfork to [`ConstantBaseFeeParams`]. This is used to specify /// dynamic EIP-1559 parameters for chains like Optimism. -#[derive_where(Clone, Debug, PartialEq, Eq; ChainSpecT::Hardfork)] -pub struct ForkBaseFeeParams { - activations: &'static [(ChainSpecT::Hardfork, ConstantBaseFeeParams)], +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct ForkBaseFeeParams { + activations: &'static [(HardforkT, ConstantBaseFeeParams)], } -impl ForkBaseFeeParams { +impl ForkBaseFeeParams { /// Constructs a new instance from the provided mapping. - pub const fn new( - activations: &'static [(ChainSpecT::Hardfork, ConstantBaseFeeParams)], - ) -> Self { + pub const fn new(activations: &'static [(HardforkT, ConstantBaseFeeParams)]) -> Self { Self { activations } } } /// Type that allows specifying constant or dynamic EIP-1559 parameters based on /// the active hardfork. -pub enum BaseFeeParams { +pub enum BaseFeeParams { /// Constant [`ConstantBaseFeeParams`]; used for chains that don't have /// dynamic EIP-1559 parameters Constant(ConstantBaseFeeParams), /// Variable [`ConstantBaseFeeParams`]; used for chains that have dynamic /// EIP-1559 parameters like Optimism - Variable(ForkBaseFeeParams), + Variable(ForkBaseFeeParams), } -impl> BaseFeeParams { +impl BaseFeeParams { /// Retrieves the [`ConstantBaseFeeParams`] for the given hardfork, if any. - pub fn at_hardfork(&self, hardfork: ChainSpecT::Hardfork) -> Option<&ConstantBaseFeeParams> { + pub fn at_hardfork(&self, hardfork: HardforkT) -> Option<&ConstantBaseFeeParams> { match self { Self::Constant(params) => Some(params), Self::Variable(params) => params @@ -44,14 +41,14 @@ impl> BaseFeeParams { } } -impl From for BaseFeeParams { +impl From for BaseFeeParams { fn from(params: ConstantBaseFeeParams) -> Self { Self::Constant(params) } } -impl From> for BaseFeeParams { - fn from(params: ForkBaseFeeParams) -> Self { +impl From> for BaseFeeParams { + fn from(params: ForkBaseFeeParams) -> Self { Self::Variable(params) } } diff --git a/crates/edr_eth/src/lib.rs b/crates/edr_eth/src/lib.rs index 58cc71124..ab811f993 100644 --- a/crates/edr_eth/src/lib.rs +++ b/crates/edr_eth/src/lib.rs @@ -13,8 +13,6 @@ pub mod beacon; pub mod block; /// Ethereum block spec mod block_spec; -/// Ethereum L1 chain spec -pub mod chain_spec; /// Types and functions related to EIPs pub mod eips; /// Ethereum fee history types @@ -33,6 +31,8 @@ pub mod rlp; pub mod serde; /// Ethereum signature types pub mod signature; +/// Ethereum L1 chain spec +pub mod spec; /// Ethereum state types and functions pub mod state; /// Ethereum transaction types @@ -48,8 +48,8 @@ pub use revm_primitives::{ address, alloy_primitives::{Bloom, BloomInput, ChainId, B512, B64, U128, U160, U64, U8}, bytes, db, env, hex, hex_literal, result, specification, AccessList, AccessListItem, - AccountInfo, Address, Bytecode, Bytes, HashMap, HashSet, Precompile, SpecId, B256, - KECCAK_EMPTY, MAX_INITCODE_SIZE, U256, + AccountInfo, Address, Bytecode, Bytes, HashMap, HashSet, Precompile, SignedAuthorization, + SpecId, B256, KECCAK_EMPTY, MAX_INITCODE_SIZE, U256, }; pub use self::block_spec::{BlockSpec, BlockTag, Eip1898BlockSpec, PreEip1898BlockSpec}; diff --git a/crates/edr_eth/src/receipt.rs b/crates/edr_eth/src/receipt.rs index fb7609569..f7a0fe8bc 100644 --- a/crates/edr_eth/src/receipt.rs +++ b/crates/edr_eth/src/receipt.rs @@ -12,7 +12,7 @@ pub mod execution; mod transaction; use revm::db::StateRef; -use revm_primitives::EvmWiring; +use revm_primitives::{HaltReasonTrait, HardforkTrait, Transaction, TransactionValidation}; pub use self::{block::BlockReceipt, transaction::TransactionReceipt}; use crate::{block::PartialHeader, Bloom, B256}; @@ -28,23 +28,28 @@ pub enum Execution { } /// Trait for a builder that constructs an execution receipt. -pub trait ExecutionReceiptBuilder: Sized { +pub trait ExecutionReceiptBuilder: Sized +where + HaltReasonT: HaltReasonTrait, + HardforkT: HardforkTrait, + TransactionT: Transaction + TransactionValidation, +{ /// The receipt type that the builder constructs. type Receipt; /// Creates a new builder with the given pre-execution state. fn new_receipt_builder( pre_execution_state: StateT, - transaction: &ChainSpecT::Transaction, + transaction: &TransactionT, ) -> Result; /// Builds a receipt using the provided information. fn build_receipt( self, header: &PartialHeader, - transaction: &ChainSpecT::Transaction, - result: &revm_primitives::ExecutionResult, - hardfork: ChainSpecT::Hardfork, + transaction: &TransactionT, + result: &revm_primitives::ExecutionResult, + hardfork: HardforkT, ) -> Self::Receipt; } diff --git a/crates/edr_eth/src/receipt/execution.rs b/crates/edr_eth/src/receipt/execution.rs index 19722d5a0..9ed6de5f9 100644 --- a/crates/edr_eth/src/receipt/execution.rs +++ b/crates/edr_eth/src/receipt/execution.rs @@ -2,11 +2,10 @@ mod eip658; mod legacy; use alloy_rlp::{RlpDecodable, RlpEncodable}; -use revm_primitives::EvmWiring; +use revm_primitives::{ExecutionResult, HaltReason}; use super::{Execution, ExecutionReceiptBuilder, MapReceiptLogs, Receipt}; use crate::{ - chain_spec::L1ChainSpec, eips::eip2718::TypedEnvelope, log::ExecutionLog, transaction::{self, TransactionType as _}, @@ -118,12 +117,12 @@ where pub struct Builder; -impl ExecutionReceiptBuilder for Builder { +impl ExecutionReceiptBuilder for Builder { type Receipt = TypedEnvelope>; fn new_receipt_builder( _pre_execution_state: StateT, - _transaction: &::Transaction, + _transaction: &transaction::Signed, ) -> Result { Ok(Self) } @@ -132,7 +131,7 @@ impl ExecutionReceiptBuilder for Builder { self, header: &crate::block::PartialHeader, transaction: &transaction::Signed, - result: &revm_primitives::ExecutionResult, + result: &ExecutionResult, hardfork: SpecId, ) -> Self::Receipt { let logs = result.logs().to_vec(); diff --git a/crates/edr_eth/src/receipt/transaction.rs b/crates/edr_eth/src/receipt/transaction.rs index b60b46bc5..d4a62d372 100644 --- a/crates/edr_eth/src/receipt/transaction.rs +++ b/crates/edr_eth/src/receipt/transaction.rs @@ -1,7 +1,7 @@ use std::marker::PhantomData; use alloy_rlp::BufMut; -use revm_primitives::{EvmWiring, ExecutionResult, Output}; +use revm_primitives::{ExecutionResult, HaltReasonTrait, HardforkTrait, Output}; use super::{MapReceiptLogs, Receipt}; use crate::{ @@ -50,16 +50,17 @@ impl, LogT> TransactionReceipt, LogT> TransactionReceipt { /// Constructs a new instance using the provided execution receipt an /// transaction - pub fn new( + pub fn new( execution_receipt: ExecutionReceiptT, transaction: &(impl Transaction + ExecutableTransaction), - result: &ExecutionResult, + result: &ExecutionResult, transaction_index: u64, block_base_fee: U256, - hardfork: ChainSpecT::Hardfork, + hardfork: HardforkT, ) -> Self where - ChainSpecT: EvmWiring, + HaltReasonT: HaltReasonTrait, + HardforkT: HardforkTrait, { let contract_address = if let ExecutionResult::Success { output: Output::Create(_, address), diff --git a/crates/edr_eth/src/chain_spec.rs b/crates/edr_eth/src/spec.rs similarity index 61% rename from crates/edr_eth/src/chain_spec.rs rename to crates/edr_eth/src/spec.rs index 255fe0968..6c969ffc6 100644 --- a/crates/edr_eth/src/chain_spec.rs +++ b/crates/edr_eth/src/spec.rs @@ -1,5 +1,5 @@ use alloy_rlp::RlpEncodable; -pub use revm_primitives::EvmWiring; +pub use revm_primitives::{ChainSpec, EvmWiring, HaltReasonTrait, HardforkTrait}; use crate::{ eips::eip1559::{BaseFeeParams, ConstantBaseFeeParams}, @@ -10,38 +10,25 @@ use crate::{ #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, RlpEncodable)] pub struct L1ChainSpec; -impl EvmWiring for L1ChainSpec { +impl ChainSpec for L1ChainSpec { + type ChainContext = (); type Block = revm_primitives::BlockEnv; - + type Transaction = transaction::Signed; type Hardfork = revm_primitives::SpecId; - type HaltReason = revm_primitives::HaltReason; - - type Transaction = transaction::Signed; -} - -impl revm::EvmWiring for L1ChainSpec { - type Context = (); - - fn handler<'evm, EXT, DB>(hardfork: Self::Hardfork) -> revm::EvmHandler<'evm, Self, EXT, DB> - where - DB: revm::Database, - { - revm::EvmHandler::mainnet_with_spec(hardfork) - } } /// Constants for constructing Ethereum headers. -pub trait EthHeaderConstants: revm_primitives::EvmWiring { +pub trait EthHeaderConstants: ChainSpec { /// Parameters for the EIP-1559 base fee calculation. - const BASE_FEE_PARAMS: BaseFeeParams; + const BASE_FEE_PARAMS: BaseFeeParams; /// The minimum difficulty for the Ethash proof-of-work algorithm. const MIN_ETHASH_DIFFICULTY: u64; } impl EthHeaderConstants for L1ChainSpec { - const BASE_FEE_PARAMS: BaseFeeParams = + const BASE_FEE_PARAMS: BaseFeeParams = BaseFeeParams::Constant(ConstantBaseFeeParams::ethereum()); const MIN_ETHASH_DIFFICULTY: u64 = 131072; diff --git a/crates/edr_eth/src/transaction.rs b/crates/edr_eth/src/transaction.rs index a02c5117b..e40d5b669 100644 --- a/crates/edr_eth/src/transaction.rs +++ b/crates/edr_eth/src/transaction.rs @@ -14,7 +14,9 @@ pub mod signed; use std::str::FromStr; -pub use revm_primitives::{alloy_primitives::TxKind, Transaction, TransactionValidation}; +pub use revm_primitives::{ + alloy_primitives::TxKind, AuthorizationList, Transaction, TransactionValidation, +}; use revm_primitives::{ruint, B256}; use crate::{signature::Signature, Bytes, U256, U8}; diff --git a/crates/edr_eth/tests/receipt.rs b/crates/edr_eth/tests/receipt.rs index d7171aa45..d6970ec94 100644 --- a/crates/edr_eth/tests/receipt.rs +++ b/crates/edr_eth/tests/receipt.rs @@ -12,10 +12,10 @@ mod remote { #[serial] async fn []() -> anyhow::Result<()> { use edr_eth::{ - chain_spec::L1ChainSpec, eips::eip2718::TypedEnvelope, log::FilterLog, receipt, + spec::L1ChainSpec, trie::ordered_trie_root, PreEip1898BlockSpec, }; @@ -69,10 +69,10 @@ mod remote { async fn []() -> anyhow::Result<()> { use alloy_rlp::Decodable as _; use edr_eth::{ - chain_spec::L1ChainSpec, eips::eip2718::TypedEnvelope, log::{ExecutionLog, FilterLog}, receipt::{self, MapReceiptLogs as _}, + spec::L1ChainSpec, B256 }; use edr_rpc_eth::{client::EthRpcClient}; diff --git a/crates/edr_evm/Cargo.toml b/crates/edr_evm/Cargo.toml index e40abd966..883e931fe 100644 --- a/crates/edr_evm/Cargo.toml +++ b/crates/edr_evm/Cargo.toml @@ -4,7 +4,7 @@ version = "0.3.5" edition = "2021" [dependencies] -anyhow = { version = "1.0.75", optional = true } +anyhow = { version = "1.0.89", optional = true } alloy-rlp = { version = "0.3", default-features = false, features = ["derive"] } async-rwlock = { version = "1.3.0", default-features = false } auto_impl = { version = "1.2", default-features = false } @@ -16,12 +16,12 @@ hasher = { version = "0.1.4", default-features = false, features = ["hash-keccak indexmap = { version = "2.0.0", default-features = false, features = ["std"] } itertools = { version = "0.11.0", default-features = false, features = ["use_alloc", "use_std"] } log = { version = "0.4.17", default-features = false } -once_cell = { version = "1.18.0", default-features = false, features = ["alloc", "race", "std"] } +once_cell = { version = "1.19.0", default-features = false, features = ["alloc", "race", "std"] } parking_lot = { version = "0.12.1", default-features = false } edr_defaults = { version = "0.3.5", path = "../edr_defaults" } -edr_eth = { version = "0.3.5", path = "../edr_eth", features = ["rand", "serde"] } +edr_eth = { version = "0.3.5", path = "../edr_eth", features = ["serde"] } edr_rpc_eth = { version = "0.3.5", path = "../edr_rpc_eth" } -revm = { git = "https://github.com/Wodann/revm", rev = "a500675", version = "12.1", default-features = false, features = ["c-kzg", "dev", "serde", "std"] } +revm = { git = "https://github.com/Wodann/revm", rev = "f260074", version = "14.0", default-features = false, features = ["c-kzg", "dev", "serde", "std"] } rpds = { version = "1.1.0", default-features = false, features = ["std"] } serde = { version = "1.0.209", default-features = false, features = ["std"] } serde_json = { version = "1.0.127", default-features = false, features = ["std"] } @@ -30,7 +30,7 @@ tokio = { version = "1.21.2", default-features = false, features = ["macros", "r tracing = { version = "0.1.37", features = ["attributes", "std"], optional = true } [dev-dependencies] -anyhow = "1.0.75" +anyhow = "1.0.89" criterion = { version = "0.4.0", default-features = false, features = ["cargo_bench_support", "html_reports", "plotters"] } edr_test_utils = { version = "0.3.5", path = "../edr_test_utils" } lazy_static = "1.4.0" diff --git a/crates/edr_evm/src/block.rs b/crates/edr_evm/src/block.rs index 37762bff5..129890d1e 100644 --- a/crates/edr_evm/src/block.rs +++ b/crates/edr_evm/src/block.rs @@ -24,7 +24,7 @@ pub use self::{ local::LocalBlock, remote::{ConversionError as RemoteBlockConversionError, EthRpcBlock, RemoteBlock}, }; -use crate::chain_spec::ChainSpec; +use crate::spec::RuntimeSpec; /// A block receipt with filter logs for the specified RPC specification. pub type BlockReceipt = edr_eth::receipt::BlockReceipt< @@ -33,7 +33,7 @@ pub type BlockReceipt = edr_eth::receipt::BlockReceipt< /// Trait for implementations of an Ethereum block. #[auto_impl(Arc)] -pub trait Block: Debug { +pub trait Block: Debug { /// The blockchain error type. type Error; @@ -62,19 +62,19 @@ pub trait Block: Debug { /// Trait that meets all requirements for a synchronous block. pub trait SyncBlock: Block + Send + Sync where - ChainSpecT: ChainSpec, + ChainSpecT: RuntimeSpec, { } impl SyncBlock for BlockT where BlockT: Block + Send + Sync, - ChainSpecT: ChainSpec, + ChainSpecT: RuntimeSpec, { } /// A type containing the relevant data for an Ethereum block. -pub struct EthBlockData { +pub struct EthBlockData { /// The block's header. pub header: edr_eth::block::Header, /// The block's transactions. @@ -89,7 +89,7 @@ pub struct EthBlockData { pub rlp_size: u64, } -impl TryFrom> +impl TryFrom> for EthBlockData { type Error = RemoteBlockConversionError; @@ -154,14 +154,14 @@ impl TryFrom { +pub struct BlockAndTotalDifficulty { /// The block pub block: Arc>, /// The total difficulty with the block pub total_difficulty: Option, } -impl +impl From> for edr_rpc_eth::Block { fn from(value: BlockAndTotalDifficulty) -> Self { diff --git a/crates/edr_evm/src/block/builder.rs b/crates/edr_evm/src/block/builder.rs index c77955429..566148cfb 100644 --- a/crates/edr_evm/src/block/builder.rs +++ b/crates/edr_evm/src/block/builder.rs @@ -5,6 +5,7 @@ use std::{ use edr_eth::{ block::{BlobGas, BlockOptions, PartialHeader}, + env::{CfgEnv, Env}, log::ExecutionLog, receipt::{ExecutionReceiptBuilder as _, Receipt as _, TransactionReceipt}, result::InvalidTransaction, @@ -14,8 +15,7 @@ use edr_eth::{ Address, Bloom, U256, }; use revm::{ - db::{DatabaseComponents, StateRef}, - handler::{CfgEnvWithEvmWiring, EnvWithEvmWiring}, + db::{DatabaseComponents, StateRef, WrapDatabaseRef}, primitives::{ ExecutionResult, ResultAndState, SpecId, Transaction as _, TransactionValidation, MAX_BLOB_GAS_PER_BLOCK, @@ -26,8 +26,8 @@ use revm::{ use super::local::LocalBlock; use crate::{ blockchain::SyncBlockchain, - chain_spec::{BlockEnvConstructor, ChainSpec}, debug::{DebugContext, EvmContext}, + spec::{BlockEnvConstructor, RuntimeSpec}, state::{AccountModifierFn, StateDebug, StateDiff, SyncState}, transaction::TransactionError, SyncBlock, @@ -37,7 +37,7 @@ use crate::{ #[derive(Debug, thiserror::Error)] pub enum BlockBuilderCreationError where - ChainSpecT: ChainSpec, + ChainSpecT: RuntimeSpec, { /// Unsupported hardfork. Hardforks older than Byzantium are not supported #[error("Unsupported hardfork: {0:?}. Hardforks older than Byzantium are not supported.")] @@ -48,7 +48,7 @@ where #[derive(Debug, thiserror::Error)] pub enum BlockTransactionError where - ChainSpecT: revm::primitives::EvmWiring, + ChainSpecT: revm::primitives::ChainSpec, { /// Transaction has higher gas limit than is remaining in block #[error("Transaction has a higher gas limit than the remaining gas in the block")] @@ -65,17 +65,15 @@ where /// was executed. pub struct ExecutionResultWithContext< 'evm, - ChainSpecT, + ChainSpecT: RuntimeSpec>>, BlockchainErrorT, StateErrorT, DebugDataT, StateT: StateRef, -> where - ChainSpecT: revm::EvmWiring, -{ +> { /// The result of executing the transaction. pub result: Result< - ExecutionResult, + ExecutionResult, BlockTransactionError, >, /// The context in which the transaction was executed. @@ -83,7 +81,7 @@ pub struct ExecutionResultWithContext< } /// The result of building a block, using the [`BlockBuilder`]. -pub struct BuildBlockResult { +pub struct BuildBlockResult { /// Built block pub block: LocalBlock, /// State diff @@ -91,8 +89,9 @@ pub struct BuildBlockResult { } /// A builder for constructing Ethereum blocks. -pub struct BlockBuilder { - cfg: CfgEnvWithEvmWiring, +pub struct BlockBuilder { + cfg: CfgEnv, + hardfork: ChainSpecT::Hardfork, header: PartialHeader, transactions: Vec, state_diff: StateDiff, @@ -103,17 +102,19 @@ pub struct BlockBuilder { impl BlockBuilder where - ChainSpecT: ChainSpec, + ChainSpecT: RuntimeSpec, { /// Creates an intance of [`BlockBuilder`]. #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))] pub fn new( - cfg: CfgEnvWithEvmWiring, + cfg: CfgEnv, + hardfork: ChainSpecT::Hardfork, parent: &dyn SyncBlock, mut options: BlockOptions, ) -> Result> { - if cfg.spec_id.into() < SpecId::BYZANTIUM { - return Err(BlockBuilderCreationError::UnsupportedHardfork(cfg.spec_id)); + let evm_spec_id = hardfork.into(); + if evm_spec_id < SpecId::BYZANTIUM { + return Err(BlockBuilderCreationError::UnsupportedHardfork(hardfork)); } let parent_header = parent.header(); @@ -124,7 +125,7 @@ where }; let withdrawals = std::mem::take(&mut options.withdrawals).or_else(|| { - if cfg.spec_id.into() >= SpecId::SHANGHAI { + if evm_spec_id >= SpecId::SHANGHAI { Some(Vec::new()) } else { None @@ -132,10 +133,11 @@ where }); options.parent_hash = Some(*parent.hash()); - let header = PartialHeader::new::(cfg.spec_id, options, Some(parent_header)); + let header = PartialHeader::new::(hardfork, options, Some(parent_header)); Ok(Self { cfg, + hardfork, header, transactions: Vec::new(), state_diff: StateDiff::default(), @@ -146,12 +148,17 @@ where } } -impl BlockBuilder { +impl BlockBuilder { /// Retrieves the config of the block builder. - pub fn config(&self) -> &CfgEnvWithEvmWiring { + pub fn config(&self) -> &CfgEnv { &self.cfg } + /// Retrieves the hardfork of the block builder. + pub fn hardfork(&self) -> ChainSpecT::Hardfork { + self.hardfork + } + /// Retrieves the amount of gas used in the block, so far. pub fn gas_used(&self) -> u64 { self.header.gas_used @@ -168,7 +175,7 @@ impl BlockBuilder { } } -impl BlockBuilder { +impl BlockBuilder { /// Finalizes the block, returning the block and the callers of the /// transactions. #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))] @@ -240,7 +247,7 @@ impl BlockBuilder { impl BlockBuilder where - ChainSpecT: ChainSpec< + ChainSpecT: RuntimeSpec< Block: Default, Transaction: Clone + Default @@ -296,8 +303,7 @@ where } } - let spec_id = self.cfg.spec_id; - let block = ChainSpecT::Block::new_block_env(&self.header, spec_id); + let block = ChainSpecT::Block::new_block_env(&self.header, self.hardfork.into()); let receipt_builder = { let builder = ChainSpecT::ReceiptBuilder::new_receipt_builder(&state, &transaction); @@ -316,12 +322,11 @@ where } }; - let env = EnvWithEvmWiring::new_with_cfg_env(self.cfg.clone(), block, transaction.clone()); - - let db = DatabaseComponents { + let env = Env::boxed(self.cfg.clone(), block, transaction.clone()); + let db = WrapDatabaseRef(DatabaseComponents { state, block_hash: blockchain, - }; + }); let ( mut evm_context, @@ -331,11 +336,11 @@ where }, ) = { if let Some(debug_context) = debug_context { - let mut evm = Evm::builder() - .with_chain_spec::() - .with_ref_db(db) + let mut evm = Evm::>::builder() + .with_db(db) .with_external_context(debug_context.data) - .with_env_with_handler_cfg(env) + .with_env(env) + .with_spec_id(self.hardfork) .append_handler_register(debug_context.register_handles_fn) .build(); @@ -367,10 +372,11 @@ where } } } else { - let mut evm = Evm::builder() - .with_chain_spec::() - .with_ref_db(db) - .with_env_with_handler_cfg(env) + let mut evm = Evm::>::builder() + .with_db(db) + .with_external_context(()) + .with_env(env) + .with_spec_id(self.hardfork) .build(); let result = evm.transact(); @@ -412,14 +418,15 @@ where *gas_used += blob_gas_used; } - let receipt = receipt_builder.build_receipt(&self.header, &transaction, &result, spec_id); + let receipt = + receipt_builder.build_receipt(&self.header, &transaction, &result, self.hardfork); let receipt = TransactionReceipt::new( receipt, &transaction, &result, self.transactions.len() as u64, self.header.base_fee.unwrap_or(U256::ZERO), - spec_id, + self.hardfork, ); self.receipts.push(receipt); diff --git a/crates/edr_evm/src/block/local.rs b/crates/edr_evm/src/block/local.rs index 1deb62cc9..3dcdf32de 100644 --- a/crates/edr_evm/src/block/local.rs +++ b/crates/edr_evm/src/block/local.rs @@ -16,7 +16,7 @@ use revm::primitives::keccak256; use crate::{ blockchain::BlockchainError, - chain_spec::{ChainSpec, SyncChainSpec}, + spec::{RuntimeSpec, SyncRuntimeSpec}, transaction::DetailedTransaction, Block, SyncBlock, }; @@ -25,7 +25,7 @@ use crate::{ #[derive(PartialEq, Eq, RlpEncodable)] #[derive_where(Clone, Debug; ChainSpecT::ExecutionReceipt, ChainSpecT::Transaction)] #[rlp(trailing)] -pub struct LocalBlock { +pub struct LocalBlock { header: block::Header, transactions: Vec, #[rlp(skip)] @@ -38,7 +38,7 @@ pub struct LocalBlock { hash: B256, } -impl LocalBlock { +impl LocalBlock { /// Constructs an empty block, i.e. no transactions. pub fn empty(spec_id: ChainSpecT::Hardfork, partial_header: PartialHeader) -> Self { let withdrawals = if spec_id.into() >= SpecId::SHANGHAI { @@ -117,7 +117,7 @@ impl LocalBlock { } } -impl Block for LocalBlock { +impl Block for LocalBlock { type Error = BlockchainError; fn hash(&self) -> &B256 { @@ -154,7 +154,7 @@ impl Block for LocalBlock { } } -fn transaction_to_block_receipts( +fn transaction_to_block_receipts( block_hash: &B256, block_number: u64, receipts: Vec, ExecutionLog>>, @@ -199,7 +199,7 @@ fn transaction_to_block_receipts( impl From> for Arc>> where - ChainSpecT: SyncChainSpec, + ChainSpecT: SyncRuntimeSpec, { fn from(value: LocalBlock) -> Self { Arc::new(value) diff --git a/crates/edr_evm/src/block/remote.rs b/crates/edr_evm/src/block/remote.rs index bc5560033..ffd8646c3 100644 --- a/crates/edr_evm/src/block/remote.rs +++ b/crates/edr_evm/src/block/remote.rs @@ -10,14 +10,14 @@ use tokio::runtime; use super::BlockReceipt; use crate::{ blockchain::{BlockchainError, ForkedBlockchainError}, - chain_spec::{ChainSpec, SyncChainSpec}, + spec::{RuntimeSpec, SyncRuntimeSpec}, Block, EthBlockData, SyncBlock, }; /// Error that occurs when trying to convert the JSON-RPC `Block` type. #[derive(thiserror::Error)] #[derive_where(Debug; ChainSpecT::RpcTransactionConversionError)] -pub enum ConversionError { +pub enum ConversionError { /// Missing hash #[error("Missing hash")] MissingHash, @@ -40,7 +40,7 @@ pub enum ConversionError { /// A remote block, which lazily loads receipts. #[derive_where(Clone, Debug; ChainSpecT::Transaction)] -pub struct RemoteBlock { +pub struct RemoteBlock { header: Header, transactions: Vec, /// The receipts of the block's transactions @@ -58,7 +58,7 @@ pub struct RemoteBlock { runtime: runtime::Handle, } -impl RemoteBlock { +impl RemoteBlock { /// Tries to construct a new instance from a JSON-RPC block. pub fn new( block: ChainSpecT::RpcBlock, @@ -81,7 +81,7 @@ impl RemoteBlock { } } -impl Block for RemoteBlock { +impl Block for RemoteBlock { type Error = BlockchainError; fn hash(&self) -> &B256 { @@ -142,7 +142,7 @@ impl Block for RemoteBlock { impl From> for Arc>> where - ChainSpecT: SyncChainSpec, + ChainSpecT: SyncRuntimeSpec, { fn from(value: RemoteBlock) -> Self { Arc::new(value) diff --git a/crates/edr_evm/src/block/transaction.rs b/crates/edr_evm/src/block/transaction.rs index 12bc16c35..c2f90bced 100644 --- a/crates/edr_evm/src/block/transaction.rs +++ b/crates/edr_evm/src/block/transaction.rs @@ -1,15 +1,15 @@ use std::sync::Arc; use derive_where::derive_where; -use edr_eth::{chain_spec::L1ChainSpec, transaction::SignedTransaction as _, SpecId}; +use edr_eth::{spec::L1ChainSpec, transaction::SignedTransaction as _, SpecId}; use edr_rpc_eth::RpcTypeFrom; use super::SyncBlock; -use crate::{blockchain::BlockchainError, chain_spec::ChainSpec}; +use crate::{blockchain::BlockchainError, spec::RuntimeSpec}; /// The result returned by requesting a transaction. #[derive_where(Clone, Debug; ChainSpecT::Transaction)] -pub struct TransactionAndBlock { +pub struct TransactionAndBlock { /// The transaction. pub transaction: ChainSpecT::Transaction, /// Block data in which the transaction is found if it has been mined. @@ -20,7 +20,7 @@ pub struct TransactionAndBlock { /// Block metadata for a transaction. #[derive_where(Clone, Debug)] -pub struct BlockDataForTransaction { +pub struct BlockDataForTransaction { /// The block in which the transaction is found. pub block: Arc>>, /// The index of the transaction in the block. diff --git a/crates/edr_evm/src/blockchain.rs b/crates/edr_evm/src/blockchain.rs index 98228b0b9..2cb2d3bd9 100644 --- a/crates/edr_evm/src/blockchain.rs +++ b/crates/edr_evm/src/blockchain.rs @@ -21,8 +21,8 @@ pub use self::{ local::{CreationError as LocalCreationError, GenesisBlockOptions, LocalBlockchain}, }; use crate::{ - chain_spec::{ChainSpec, SyncChainSpec}, hardfork::Activations, + spec::{RuntimeSpec, SyncRuntimeSpec}, state::{StateDiff, StateOverride, SyncState}, Block, BlockAndTotalDifficulty, BlockReceipt, LocalBlock, SyncBlock, }; @@ -30,7 +30,7 @@ use crate::{ /// Combinatorial error for the blockchain API. #[derive(thiserror::Error)] #[derive_where(Debug; ChainSpecT::Hardfork, ChainSpecT::RpcBlockConversionError)] -pub enum BlockchainError { +pub enum BlockchainError { /// Forked blockchain error #[error(transparent)] Forked(#[from] ForkedBlockchainError), @@ -83,7 +83,7 @@ pub enum BlockchainError { #[auto_impl(&)] pub trait Blockchain where - ChainSpecT: SyncChainSpec, + ChainSpecT: SyncRuntimeSpec, { /// The blockchain's error type type BlockchainError; @@ -187,7 +187,7 @@ where } /// Trait for implementations of a mutable Ethereum blockchain -pub trait BlockchainMut { +pub trait BlockchainMut { /// The blockchain's error type type Error; @@ -218,7 +218,7 @@ pub trait SyncBlockchain: + Debug where BlockchainErrorT: Debug + Send, - ChainSpecT: SyncChainSpec, + ChainSpecT: SyncRuntimeSpec, { } @@ -232,11 +232,11 @@ where + Sync + Debug, BlockchainErrorT: Debug + Send, - ChainSpecT: SyncChainSpec, + ChainSpecT: SyncRuntimeSpec, { } -fn compute_state_at_block + Clone, ChainSpecT: ChainSpec>( +fn compute_state_at_block + Clone, ChainSpecT: RuntimeSpec>( state: &mut dyn DatabaseCommit, local_storage: &ReservableSparseBlockchainStorage, first_local_block_number: u64, @@ -271,7 +271,7 @@ fn compute_state_at_block + Clone, ChainSpecT: ChainSp } /// Validates whether a block is a valid next block. -fn validate_next_block( +fn validate_next_block( spec_id: ChainSpecT::Hardfork, last_block: &dyn Block>, next_block: &dyn Block>, diff --git a/crates/edr_evm/src/blockchain/forked.rs b/crates/edr_evm/src/blockchain/forked.rs index 7198a2109..89a5ce8b6 100644 --- a/crates/edr_evm/src/blockchain/forked.rs +++ b/crates/edr_evm/src/blockchain/forked.rs @@ -27,8 +27,8 @@ use super::{ }; use crate::{ block::EthRpcBlock, - chain_spec::{ChainSpec, SyncChainSpec}, hardfork::Activations, + spec::{RuntimeSpec, SyncRuntimeSpec}, state::{ForkState, IrregularState, StateDiff, StateError, StateOverride, SyncState}, Block, BlockAndTotalDifficulty, BlockReceipt, LocalBlock, RandomHashGenerator, SyncBlock, }; @@ -37,7 +37,7 @@ use crate::{ #[derive(Debug, thiserror::Error)] pub enum CreationError where - ChainSpecT: ChainSpec, + ChainSpecT: RuntimeSpec, { /// JSON-RPC error #[error(transparent)] @@ -65,7 +65,7 @@ where /// Error type for [`ForkedBlockchain`]. #[derive(thiserror::Error)] #[derive_where(Debug; ChainSpecT::RpcBlockConversionError, ChainSpecT::RpcReceiptConversionError)] -pub enum ForkedBlockchainError { +pub enum ForkedBlockchainError { /// Remote block creation error #[error(transparent)] BlockCreation(ChainSpecT::RpcBlockConversionError), @@ -93,7 +93,7 @@ pub enum ForkedBlockchainError { #[derive_where(Debug; ChainSpecT::Hardfork)] pub struct ForkedBlockchain where - ChainSpecT: SyncChainSpec, + ChainSpecT: SyncRuntimeSpec, { local_storage: ReservableSparseBlockchainStorage< Arc>>, @@ -119,7 +119,7 @@ where impl ForkedBlockchain where - ChainSpecT: SyncChainSpec, + ChainSpecT: SyncRuntimeSpec, { /// Constructs a new instance. #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))] @@ -274,7 +274,7 @@ where impl BlockHashRef for ForkedBlockchain where - ChainSpecT: SyncChainSpec, + ChainSpecT: SyncRuntimeSpec, { type Error = BlockchainError; @@ -296,7 +296,7 @@ where impl Blockchain for ForkedBlockchain where - ChainSpecT: SyncChainSpec, + ChainSpecT: SyncRuntimeSpec, { type BlockchainError = BlockchainError; @@ -569,7 +569,7 @@ where impl BlockchainMut for ForkedBlockchain where - ChainSpecT: SyncChainSpec, + ChainSpecT: SyncRuntimeSpec, { type Error = BlockchainError; diff --git a/crates/edr_evm/src/blockchain/local.rs b/crates/edr_evm/src/blockchain/local.rs index 6b984c97d..bbea54bb0 100644 --- a/crates/edr_evm/src/blockchain/local.rs +++ b/crates/edr_evm/src/blockchain/local.rs @@ -25,7 +25,7 @@ use super::{ Blockchain, BlockchainError, BlockchainMut, }; use crate::{ - chain_spec::SyncChainSpec, + spec::SyncRuntimeSpec, state::{StateDebug, StateDiff, StateError, StateOverride, SyncState, TrieState}, Block, BlockAndTotalDifficulty, BlockReceipt, LocalBlock, SyncBlock, }; @@ -79,7 +79,7 @@ impl From for BlockOptions { #[derive_where(Debug; ChainSpecT::Hardfork)] pub struct LocalBlockchain where - ChainSpecT: SyncChainSpec, + ChainSpecT: SyncRuntimeSpec, { storage: ReservableSparseBlockchainStorage< Arc>>, @@ -91,7 +91,7 @@ where impl LocalBlockchain where - ChainSpecT: SyncChainSpec, + ChainSpecT: SyncRuntimeSpec, { /// Constructs a new instance using the provided arguments to build a /// genesis block. @@ -219,7 +219,7 @@ where impl Blockchain for LocalBlockchain where - ChainSpecT: SyncChainSpec, + ChainSpecT: SyncRuntimeSpec, { type BlockchainError = BlockchainError; @@ -343,7 +343,7 @@ where impl BlockchainMut for LocalBlockchain where - ChainSpecT: SyncChainSpec, + ChainSpecT: SyncRuntimeSpec, { type Error = BlockchainError; @@ -413,7 +413,7 @@ where impl BlockHashRef for LocalBlockchain where - ChainSpecT: SyncChainSpec, + ChainSpecT: SyncRuntimeSpec, { type Error = BlockchainError; @@ -428,7 +428,7 @@ where #[cfg(test)] mod tests { - use edr_eth::{chain_spec::L1ChainSpec, AccountInfo, HashMap}; + use edr_eth::{spec::L1ChainSpec, AccountInfo, HashMap}; use revm::primitives::{Account, AccountStatus}; use super::*; diff --git a/crates/edr_evm/src/blockchain/remote.rs b/crates/edr_evm/src/blockchain/remote.rs index 89e6cf2bb..da7509de3 100644 --- a/crates/edr_evm/src/blockchain/remote.rs +++ b/crates/edr_evm/src/blockchain/remote.rs @@ -11,7 +11,7 @@ use tokio::runtime; use super::storage::SparseBlockchainStorage; use crate::{ - blockchain::ForkedBlockchainError, chain_spec::ChainSpec, + blockchain::ForkedBlockchainError, spec::RuntimeSpec, transaction::remote::EthRpcTransaction as _, Block, BlockReceipt, EthRpcBlock as _, RemoteBlock, }; @@ -20,7 +20,7 @@ use crate::{ pub struct RemoteBlockchain where BlockT: Block + Clone, - ChainSpecT: ChainSpec, + ChainSpecT: RuntimeSpec, { client: Arc>, cache: RwLock>, @@ -31,7 +31,7 @@ impl RemoteBlockchain where BlockT: Block + Clone + From>, - ChainSpecT: ChainSpec, + ChainSpecT: RuntimeSpec, { /// Constructs a new instance with the provided RPC client. pub fn new(client: Arc>, runtime: runtime::Handle) -> Self { @@ -261,7 +261,7 @@ where #[cfg(all(test, feature = "test-remote"))] mod tests { - use edr_eth::chain_spec::L1ChainSpec; + use edr_eth::spec::L1ChainSpec; use edr_test_utils::env::get_alchemy_url; use super::*; diff --git a/crates/edr_evm/src/blockchain/storage/reservable.rs b/crates/edr_evm/src/blockchain/storage/reservable.rs index 45b2b9296..e459b6d20 100644 --- a/crates/edr_evm/src/blockchain/storage/reservable.rs +++ b/crates/edr_evm/src/blockchain/storage/reservable.rs @@ -6,12 +6,12 @@ use parking_lot::{RwLock, RwLockUpgradableReadGuard, RwLockWriteGuard}; use revm::primitives::{HashMap, HashSet}; use super::{sparse, InsertError, SparseBlockchainStorage}; -use crate::{chain_spec::ChainSpec, state::StateDiff, Block, BlockReceipt, LocalBlock}; +use crate::{spec::RuntimeSpec, state::StateDiff, Block, BlockReceipt, LocalBlock}; /// A reservation for a sequence of blocks that have not yet been inserted into /// storage. #[derive_where(Debug; ChainSpecT::Hardfork)] -struct Reservation { +struct Reservation { first_number: u64, last_number: u64, interval: u64, @@ -27,8 +27,8 @@ struct Reservation { #[derive_where(Debug; BlockT, ChainSpecT::Hardfork)] pub struct ReservableSparseBlockchainStorage where - BlockT: Block + Clone + ?Sized, - ChainSpecT: ChainSpec, + BlockT: Block + Clone, + ChainSpecT: RuntimeSpec, { reservations: RwLock>>, storage: RwLock>, @@ -44,7 +44,7 @@ where impl ReservableSparseBlockchainStorage where BlockT: Block + Clone, - ChainSpecT: ChainSpec, + ChainSpecT: RuntimeSpec, { /// Constructs a new instance with the provided block as genesis block. #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))] @@ -235,7 +235,7 @@ where impl ReservableSparseBlockchainStorage where BlockT: Block + Clone + From>, - ChainSpecT: ChainSpec, + ChainSpecT: RuntimeSpec, { /// Retrieves the block by number, if it exists. #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))] @@ -343,7 +343,7 @@ fn calculate_timestamp_for_reserved_block( ) -> u64 where BlockT: Block + Clone, - ChainSpecT: ChainSpec, + ChainSpecT: RuntimeSpec, { let previous_block_number = reservation.first_number - 1; let previous_timestamp = @@ -365,7 +365,7 @@ where previous_timestamp + reservation.interval * (block_number - reservation.first_number + 1) } -fn find_reservation( +fn find_reservation( reservations: &[Reservation], number: u64, ) -> Option<&Reservation> { diff --git a/crates/edr_evm/src/blockchain/storage/sparse.rs b/crates/edr_evm/src/blockchain/storage/sparse.rs index 75106758b..8db2eeb2f 100644 --- a/crates/edr_evm/src/blockchain/storage/sparse.rs +++ b/crates/edr_evm/src/blockchain/storage/sparse.rs @@ -10,14 +10,14 @@ use edr_eth::{ use revm::primitives::{hash_map::OccupiedError, HashMap, HashSet}; use super::InsertError; -use crate::{chain_spec::ChainSpec, Block}; +use crate::{spec::RuntimeSpec, Block}; /// A storage solution for storing a subset of a Blockchain's blocks in-memory. #[derive_where(Debug; BlockT)] pub struct SparseBlockchainStorage where - BlockT: Block + Clone + ?Sized, - ChainSpecT: ChainSpec, + BlockT: Block + Clone, + ChainSpecT: RuntimeSpec, { hash_to_block: HashMap, hash_to_total_difficulty: HashMap, @@ -30,8 +30,8 @@ where impl SparseBlockchainStorage where - BlockT: Block + Clone + ?Sized, - ChainSpecT: ChainSpec, + BlockT: Block + Clone, + ChainSpecT: RuntimeSpec, { /// Constructs a new instance with the provided block. #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))] @@ -226,7 +226,7 @@ where impl Default for SparseBlockchainStorage where BlockT: Block + Clone, - ChainSpecT: ChainSpec, + ChainSpecT: RuntimeSpec, { fn default() -> Self { Self { @@ -250,7 +250,7 @@ pub fn logs( ) -> Result, BlockT::Error> where BlockT: Block + Clone, - ChainSpecT: ChainSpec, + ChainSpecT: RuntimeSpec, { let mut logs = Vec::new(); let addresses: HashSet
= addresses.iter().copied().collect(); diff --git a/crates/edr_evm/src/debug.rs b/crates/edr_evm/src/debug.rs index e6cae1bc4..c93d1b8b3 100644 --- a/crates/edr_evm/src/debug.rs +++ b/crates/edr_evm/src/debug.rs @@ -1,18 +1,27 @@ use auto_impl::auto_impl; -use revm::db::{DatabaseComponents, StateRef, WrapDatabaseRef}; +use edr_eth::result::InvalidTransaction; +use revm::{ + db::{DatabaseComponents, StateRef, WrapDatabaseRef}, + primitives::TransactionValidation, +}; -use crate::blockchain::SyncBlockchain; +use crate::{blockchain::SyncBlockchain, spec::RuntimeSpec}; /// Type for registering handles, specialised for EDR database component types. pub type HandleRegister<'evm, ChainSpecT, BlockchainErrorT, DebugDataT, StateT> = revm::handler::register::HandleRegister< - ChainSpecT, - DebugDataT, - WrapDatabaseRef< - DatabaseComponents< - StateT, - &'evm dyn SyncBlockchain::Error>, + ::EvmWiring< + WrapDatabaseRef< + DatabaseComponents< + StateT, + &'evm dyn SyncBlockchain< + ChainSpecT, + BlockchainErrorT, + ::Error, + >, + >, >, + DebugDataT, >, >; @@ -20,7 +29,8 @@ pub type HandleRegister<'evm, ChainSpecT, BlockchainErrorT, DebugDataT, StateT> /// `EvmBuilder`. pub struct DebugContext<'evm, ChainSpecT, BlockchainErrorT, DebugDataT, StateT> where - ChainSpecT: revm::EvmWiring, + ChainSpecT: + RuntimeSpec>>, StateT: StateRef, { /// The contextual data. @@ -31,7 +41,8 @@ where pub struct EvmContext<'evm, ChainSpecT, BlockchainErrorT, DebugDataT, StateT> where - ChainSpecT: revm::EvmWiring, + ChainSpecT: + RuntimeSpec>>, StateT: StateRef, { pub debug: Option>, diff --git a/crates/edr_evm/src/debug_trace.rs b/crates/edr_evm/src/debug_trace.rs index 259e5006a..42cd04f84 100644 --- a/crates/edr_evm/src/debug_trace.rs +++ b/crates/edr_evm/src/debug_trace.rs @@ -1,42 +1,43 @@ -use std::{collections::HashMap, fmt::Debug, marker::PhantomData, sync::Arc}; - -use edr_eth::{transaction::ExecutableTransaction as _, utils::u256_to_padded_hex, B256}; +use std::{collections::HashMap, fmt::Debug, sync::Arc}; + +use edr_eth::{ + env::{CfgEnv, Env}, + result::InvalidTransaction, + spec::ChainSpec, + transaction::ExecutableTransaction as _, + utils::u256_to_padded_hex, + B256, +}; use revm::{ - db::DatabaseComponents, - handler::{register::EvmHandler, CfgEnvWithEvmWiring}, + db::{DatabaseComponents, WrapDatabaseRef}, + handler::register::EvmHandler, interpreter::{ opcode::{self, DynInstruction, OpCode}, Interpreter, InterpreterResult, }, primitives::{ - hex, Address, Block as _, Bytes, ExecutionResult, InvalidTransaction, ResultAndState, - SpecId, TransactionValidation, U256, + hex, Address, Block as _, Bytes, ExecutionResult, HaltReasonTrait, ResultAndState, SpecId, + TransactionValidation, U256, }, - Context, Database, Evm, EvmContext, JournalEntry, + Context, Database, Evm, EvmContext, EvmWiring, JournalEntry, }; use crate::{ blockchain::SyncBlockchain, - chain_spec::ChainSpec, debug::GetContextData, + spec::RuntimeSpec, state::SyncState, trace::{register_trace_collector_handles, Trace, TraceCollector}, transaction::TransactionError, }; /// EIP-3155 and raw tracers. -pub struct Eip3155AndRawTracers -where - ChainSpecT: revm::EvmWiring, -{ - eip3155: TracerEip3155, - raw: TraceCollector, +pub struct Eip3155AndRawTracers { + eip3155: TracerEip3155, + raw: TraceCollector, } -impl Eip3155AndRawTracers -where - ChainSpecT: revm::EvmWiring, -{ +impl Eip3155AndRawTracers { /// Creates a new instance. pub fn new(config: DebugTraceConfig, verbose_tracing: bool) -> Self { Self { @@ -46,34 +47,33 @@ where } } -impl GetContextData> for Eip3155AndRawTracers -where - ChainSpecT: revm::EvmWiring, +impl GetContextData> + for Eip3155AndRawTracers { - fn get_context_data(&mut self) -> &mut TraceCollector { + fn get_context_data(&mut self) -> &mut TraceCollector { &mut self.raw } } -impl GetContextData> for Eip3155AndRawTracers -where - ChainSpecT: revm::EvmWiring, +impl GetContextData + for Eip3155AndRawTracers { - fn get_context_data(&mut self) -> &mut TracerEip3155 { + fn get_context_data(&mut self) -> &mut TracerEip3155 { &mut self.eip3155 } } /// Register EIP-3155 and trace collector handles. pub fn register_eip_3155_and_raw_tracers_handles< - ChainSpecT: revm::EvmWiring, - DatabaseT: Database, - ContextT: GetContextData> + GetContextData>, + EvmWiringT: revm::EvmWiring< + ExternalContext: GetContextData< + TraceCollector<::HaltReason>, + > + GetContextData, + Database: Database, + >, >( - handler: &mut EvmHandler<'_, ChainSpecT, ContextT, DatabaseT>, -) where - DatabaseT::Error: Debug, -{ + handler: &mut EvmHandler<'_, EvmWiringT>, +) { register_trace_collector_handles(handler); register_eip_3155_tracer_handles(handler); } @@ -85,29 +85,30 @@ pub fn debug_trace_transaction( blockchain: &dyn SyncBlockchain, // Take ownership of the state so that we can apply throw-away modifications on it mut state: Box>, - evm_config: CfgEnvWithEvmWiring, + evm_config: CfgEnv, + hardfork: ChainSpecT::Hardfork, trace_config: DebugTraceConfig, block: ChainSpecT::Block, transactions: Vec, transaction_hash: &B256, verbose_tracing: bool, ) -> Result< - DebugTraceResultWithTraces, + DebugTraceResultWithTraces, DebugTraceError, > where - ChainSpecT: ChainSpec< - Block: Clone + Default, + ChainSpecT: RuntimeSpec< + Block: Clone, Transaction: Default + TransactionValidation>, >, BlockchainErrorT: Debug + Send, StateErrorT: Debug + Send, { - let l1_spec_id = evm_config.spec_id.into(); - if l1_spec_id < SpecId::SPURIOUS_DRAGON { + let evm_spec_id = hardfork.into(); + if evm_spec_id < SpecId::SPURIOUS_DRAGON { // Matching Hardhat Network behaviour: https://github.com/NomicFoundation/hardhat/blob/af7e4ce6a18601ec9cd6d4aa335fa7e24450e638/packages/hardhat-core/src/internal/hardhat-network/provider/vm/ethereumjs.ts#L427 return Err(DebugTraceError::InvalidSpecId { - spec_id: l1_spec_id, + spec_id: evm_spec_id, }); } @@ -116,17 +117,17 @@ where let mut tracer = Eip3155AndRawTracers::new(trace_config, verbose_tracing); let ResultAndState { result, .. } = { - let mut evm = Evm::builder() - .with_chain_spec::() - .with_ref_db(DatabaseComponents { + let env = Env::boxed(evm_config, block, transaction); + + let mut evm = Evm::>::builder() + .with_db(WrapDatabaseRef(DatabaseComponents { state: state.as_ref(), block_hash: blockchain, - }) + })) .with_external_context(&mut tracer) - .with_cfg_env_with_handler_cfg(evm_config) + .with_env(env) + .with_spec_id(hardfork) .append_handler_register(register_eip_3155_and_raw_tracers_handles) - .with_block_env(block) - .with_tx_env(transaction) .build(); evm.transact().map_err(TransactionError::from)? @@ -135,15 +136,16 @@ where return Ok(execution_result_to_debug_result(result, tracer)); } else { let ResultAndState { state: changes, .. } = { - let mut evm = Evm::builder() - .with_chain_spec::() - .with_ref_db(DatabaseComponents { + let env = Env::boxed(evm_config.clone(), block.clone(), transaction); + + let mut evm = Evm::>::builder() + .with_db(WrapDatabaseRef(DatabaseComponents { state: state.as_ref(), block_hash: blockchain, - }) - .with_cfg_env_with_handler_cfg(evm_config.clone()) - .with_block_env(block.clone()) - .with_tx_env(transaction) + })) + .with_external_context(()) + .with_env(env) + .with_spec_id(hardfork) .build(); evm.transact().map_err(TransactionError::from)? @@ -160,13 +162,10 @@ where } /// Convert an `ExecutionResult` to a `DebugTraceResult`. -pub fn execution_result_to_debug_result( - execution_result: ExecutionResult, - tracer: Eip3155AndRawTracers, -) -> DebugTraceResultWithTraces -where - ChainSpecT: revm::EvmWiring, -{ +pub fn execution_result_to_debug_result( + execution_result: ExecutionResult, + tracer: Eip3155AndRawTracers, +) -> DebugTraceResultWithTraces { let Eip3155AndRawTracers { eip3155, raw } = tracer; let traces = raw.into_traces(); @@ -211,7 +210,7 @@ pub struct DebugTraceConfig { #[derive(Debug, thiserror::Error)] pub enum DebugTraceError where - ChainSpecT: revm::EvmWiring, + ChainSpecT: revm::primitives::ChainSpec, { /// Invalid hardfork spec argument. #[error("Invalid spec id: {spec_id:?}. `debug_traceTransaction` is not supported prior to Spurious Dragon")] @@ -248,11 +247,11 @@ pub struct DebugTraceResult { } /// Result of a `debug_traceTransaction` call with traces. -pub struct DebugTraceResultWithTraces { +pub struct DebugTraceResultWithTraces { /// The result of the transaction. pub result: DebugTraceResult, /// The raw traces of the debugged transaction. - pub traces: Vec>, + pub traces: Vec>, } /// The output of an EIP-3155 trace. @@ -293,11 +292,9 @@ pub struct DebugTraceLogItem { /// Register EIP-3155 tracer handles. pub fn register_eip_3155_tracer_handles< - ChainSpecT: revm::EvmWiring, - DatabaseT: Database, - ContextT: GetContextData>, + EvmWiringT: revm::EvmWiring>, >( - handler: &mut EvmHandler<'_, ChainSpecT, ContextT, DatabaseT>, + handler: &mut EvmHandler<'_, EvmWiringT>, ) { let table = &mut handler.instruction_table; @@ -324,15 +321,11 @@ pub fn register_eip_3155_tracer_handles< } /// Outer closure that calls tracer for every instruction. -fn instruction_handler( - prev: &DynInstruction<'_, Context>, +fn instruction_handler>>( + prev: &DynInstruction<'_, Context>, interpreter: &mut Interpreter, - host: &mut Context, -) where - ChainSpecT: revm::EvmWiring, - ContextT: GetContextData>, - DatabaseT: Database, -{ + host: &mut Context, +) { // SAFETY: as the PC was already incremented we need to subtract 1 to preserve // the old Inspector behavior. interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.sub(1) }; @@ -352,10 +345,7 @@ fn instruction_handler( /// An EIP-3155 compatible EVM tracer. #[derive(Debug)] -pub struct TracerEip3155 -where - ChainSpecT: revm::EvmWiring, -{ +pub struct TracerEip3155 { config: DebugTraceConfig, logs: Vec, contract_address: Address, @@ -367,13 +357,9 @@ where stack: Vec, // Contract-specific storage storage: HashMap>, - phantom: PhantomData, } -impl TracerEip3155 -where - ChainSpecT: revm::EvmWiring, -{ +impl TracerEip3155 { /// Create a new tracer. pub fn new(config: DebugTraceConfig) -> Self { Self { @@ -387,7 +373,6 @@ where memory: Vec::default(), mem_size: 0, storage: HashMap::default(), - phantom: PhantomData, } } @@ -410,10 +395,10 @@ where self.pc = interp.program_counter(); } - fn step_end( + fn step_end( &mut self, interp: &Interpreter, - context: &EvmContext, + context: &EvmContext, ) { let depth = context.journaled_state.depth(); @@ -500,11 +485,8 @@ where } } -impl GetContextData> for TracerEip3155 -where - ChainSpecT: revm::EvmWiring, -{ - fn get_context_data(&mut self) -> &mut TracerEip3155 { +impl GetContextData for TracerEip3155 { + fn get_context_data(&mut self) -> &mut TracerEip3155 { self } } diff --git a/crates/edr_evm/src/hardfork.rs b/crates/edr_evm/src/hardfork.rs index 3b709ea44..7f77f4b96 100644 --- a/crates/edr_evm/src/hardfork.rs +++ b/crates/edr_evm/src/hardfork.rs @@ -3,7 +3,7 @@ pub mod l1; use derive_where::derive_where; -use crate::chain_spec::ChainSpec; +use crate::spec::RuntimeSpec; /// Fork condition for a hardfork. #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] @@ -16,12 +16,12 @@ pub enum ForkCondition { /// A struct that stores the hardforks for a chain. #[derive_where(Clone, Debug; ChainSpecT::Hardfork)] -pub struct Activations { +pub struct Activations { /// (Start block number -> `SpecId`) mapping hardforks: Vec<(ForkCondition, ChainSpecT::Hardfork)>, } -impl Activations { +impl Activations { /// Constructs a new instance with the provided hardforks. pub fn new(hardforks: Vec<(ForkCondition, ChainSpecT::Hardfork)>) -> Self { Self { hardforks } @@ -58,7 +58,7 @@ impl Activations { /// Views the activations as for a different chain spec (that shares the /// underlying hardforks). - pub fn as_chain_spec>( + pub fn as_chain_spec>( &'static self, ) -> &'static Activations { // SAFETY: The layout is the same as we're using the same struct and the @@ -68,7 +68,7 @@ impl Activations { } } -impl From<&[(ForkCondition, ChainSpecT::Hardfork)]> +impl From<&[(ForkCondition, ChainSpecT::Hardfork)]> for Activations { fn from(hardforks: &[(ForkCondition, ChainSpecT::Hardfork)]) -> Self { @@ -80,7 +80,7 @@ impl From<&[(ForkCondition, ChainSpecT::Hardfork)]> impl<'deserializer, ChainSpecT> serde::Deserialize<'deserializer> for Activations where - ChainSpecT: ChainSpec>, + ChainSpecT: RuntimeSpec>, { fn deserialize(deserializer: D) -> Result where @@ -93,7 +93,7 @@ where impl serde::Serialize for Activations where - ChainSpecT: ChainSpec, + ChainSpecT: RuntimeSpec, { fn serialize(&self, serializer: S) -> Result where @@ -104,7 +104,7 @@ where } /// Type that stores the configuration for a chain. -pub struct ChainConfig { +pub struct ChainConfig { /// Chain name pub name: String, /// Hardfork activations for the chain diff --git a/crates/edr_evm/src/hardfork/l1.rs b/crates/edr_evm/src/hardfork/l1.rs index eaa027c80..e60309561 100644 --- a/crates/edr_evm/src/hardfork/l1.rs +++ b/crates/edr_evm/src/hardfork/l1.rs @@ -1,6 +1,6 @@ use std::sync::OnceLock; -use edr_eth::{chain_spec::L1ChainSpec, HashMap, SpecId}; +use edr_eth::{spec::L1ChainSpec, HashMap, SpecId}; use super::{Activations, ChainConfig, ForkCondition}; diff --git a/crates/edr_evm/src/lib.rs b/crates/edr_evm/src/lib.rs index cfd295491..c10966495 100644 --- a/crates/edr_evm/src/lib.rs +++ b/crates/edr_evm/src/lib.rs @@ -31,8 +31,6 @@ pub mod trace; /// Types for Ethereum blocks. pub mod block; -/// Types for chain specification. -pub mod chain_spec; pub(crate) mod collections; mod debug; mod debug_trace; @@ -44,6 +42,8 @@ mod miner; mod precompiles; pub(crate) mod random; mod runtime; +/// Types for chain specification. +pub mod spec; /// Utilities for testing #[cfg(any(test, feature = "test-utils"))] pub mod test_utils; diff --git a/crates/edr_evm/src/mempool.rs b/crates/edr_evm/src/mempool.rs index c0dc9ea22..9f74956d6 100644 --- a/crates/edr_evm/src/mempool.rs +++ b/crates/edr_evm/src/mempool.rs @@ -11,10 +11,10 @@ use revm::{ primitives::{AccountInfo, HashMap, Transaction}, }; -use crate::chain_spec::ChainSpec; +use crate::spec::RuntimeSpec; /// An iterator over pending transactions. -pub struct PendingTransactions +pub struct PendingTransactions where ComparatorT: Fn(&OrderedTransaction, &OrderedTransaction) -> Ordering, { @@ -24,7 +24,7 @@ where impl PendingTransactions where - ChainSpecT: ChainSpec, + ChainSpecT: RuntimeSpec, ComparatorT: Fn(&OrderedTransaction, &OrderedTransaction) -> Ordering, { /// Removes all pending transactions of the account corresponding to the @@ -39,7 +39,7 @@ where impl Debug for PendingTransactions where - ChainSpecT: ChainSpec, + ChainSpecT: RuntimeSpec, ComparatorT: Fn(&OrderedTransaction, &OrderedTransaction) -> Ordering, { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { @@ -51,7 +51,7 @@ where impl Iterator for PendingTransactions where - ChainSpecT: ChainSpec, + ChainSpecT: RuntimeSpec, ComparatorT: Fn(&OrderedTransaction, &OrderedTransaction) -> Ordering, { type Item = ChainSpecT::Transaction; @@ -143,12 +143,12 @@ pub enum MemPoolAddTransactionError { /// A pending transaction with an order ID. #[derive_where(Clone, Debug; ChainSpecT::Transaction)] -pub struct OrderedTransaction { +pub struct OrderedTransaction { order_id: usize, transaction: ChainSpecT::Transaction, } -impl OrderedTransaction { +impl OrderedTransaction { /// Retrieves the order ID of the pending transaction. pub fn order_id(&self) -> usize { self.order_id @@ -174,7 +174,7 @@ impl OrderedTransaction { /// The mempool contains transactions pending inclusion in the blockchain. #[derive_where(Clone, Debug; ChainSpecT::Transaction)] -pub struct MemPool { +pub struct MemPool { /// The block's gas limit block_gas_limit: NonZeroU64, /// Transactions that can be executed now @@ -187,7 +187,7 @@ pub struct MemPool { next_order_id: usize, } -impl MemPool { +impl MemPool { /// Constructs a new [`MemPool`] with the specified block gas limit. pub fn new(block_gas_limit: NonZeroU64) -> Self { Self { @@ -562,7 +562,7 @@ impl MemPool { /// Calculates the next nonce of the account corresponding to the provided /// address. -pub fn account_next_nonce( +pub fn account_next_nonce( mem_pool: &MemPool, state: &StateT, address: &Address, @@ -578,7 +578,7 @@ pub fn account_next_nonce( } /// Whether the mempool has any transactions. -pub fn has_transactions(mem_pool: &MemPool) -> bool { +pub fn has_transactions(mem_pool: &MemPool) -> bool { mem_pool.has_future_transactions() || mem_pool.has_pending_transactions() } diff --git a/crates/edr_evm/src/miner.rs b/crates/edr_evm/src/miner.rs index 414806bdb..2aa40fa71 100644 --- a/crates/edr_evm/src/miner.rs +++ b/crates/edr_evm/src/miner.rs @@ -2,22 +2,20 @@ use std::{cmp::Ordering, fmt::Debug, sync::Arc}; use edr_eth::{ block::{calculate_next_base_fee_per_blob_gas, BlockOptions}, + env::CfgEnv, signature::SignatureError, transaction::{ExecutableTransaction as _, Transaction}, U256, }; -use revm::{ - handler::CfgEnvWithEvmWiring, - primitives::{ExecutionResult, InvalidTransaction, TransactionValidation}, -}; +use revm::primitives::{ExecutionResult, InvalidTransaction, TransactionValidation}; use serde::{Deserialize, Serialize}; use crate::{ block::BlockBuilderCreationError, blockchain::SyncBlockchain, - chain_spec::{ChainSpec, SyncChainSpec}, debug::DebugContext, mempool::OrderedTransaction, + spec::{RuntimeSpec, SyncRuntimeSpec}, state::{StateDiff, SyncState}, trace::Trace, transaction::TransactionError, @@ -29,19 +27,19 @@ use crate::{ #[derive(Debug)] pub struct MineBlockResult where - ChainSpecT: revm::primitives::EvmWiring, + ChainSpecT: RuntimeSpec, { /// Mined block pub block: Arc>, /// Transaction results - pub transaction_results: Vec>, + pub transaction_results: Vec>, /// Transaction traces - pub transaction_traces: Vec>, + pub transaction_traces: Vec>, } impl Clone for MineBlockResult where - ChainSpecT: revm::primitives::EvmWiring, + ChainSpecT: RuntimeSpec, { fn clone(&self) -> Self { Self { @@ -56,7 +54,7 @@ where /// inserted into the blockchain to be persistent. pub struct MineBlockResultAndState where - ChainSpecT: ChainSpec, + ChainSpecT: RuntimeSpec, { /// Mined block pub block: LocalBlock, @@ -65,7 +63,7 @@ where /// State diff applied by block pub state_diff: StateDiff, /// Transaction results - pub transaction_results: Vec>, + pub transaction_results: Vec>, } /// The type of ordering to use when selecting blocks to mine. @@ -81,7 +79,7 @@ pub enum MineOrdering { #[derive(Debug, thiserror::Error)] pub enum MineBlockError where - ChainSpecT: ChainSpec, + ChainSpecT: RuntimeSpec, { /// An error that occurred while constructing a block builder. #[error(transparent)] @@ -110,7 +108,8 @@ pub fn mine_block<'blockchain, 'evm, ChainSpecT, DebugDataT, BlockchainErrorT, S blockchain: &'blockchain dyn SyncBlockchain, mut state: Box>, mem_pool: &MemPool, - cfg: &CfgEnvWithEvmWiring, + cfg: &CfgEnv, + hardfork: ChainSpecT::Hardfork, options: BlockOptions, min_gas_price: U256, mine_ordering: MineOrdering, @@ -130,13 +129,9 @@ pub fn mine_block<'blockchain, 'evm, ChainSpecT, DebugDataT, BlockchainErrorT, S > where 'blockchain: 'evm, - ChainSpecT: SyncChainSpec< - Block: Default, + ChainSpecT: SyncRuntimeSpec< Hardfork: Debug, - Transaction: Default - + TransactionValidation< - ValidationError: From + PartialEq, - >, + Transaction: TransactionValidation + PartialEq>, >, BlockchainErrorT: Debug + Send, StateErrorT: Debug + Send, @@ -145,7 +140,7 @@ where .last_block() .map_err(MineBlockError::Blockchain)?; - let mut block_builder = BlockBuilder::new(cfg.clone(), &parent_block, options)?; + let mut block_builder = BlockBuilder::new(cfg.clone(), hardfork, &parent_block, options)?; let mut pending_transactions = { type MineOrderComparator = dyn Fn(&OrderedTransaction, &OrderedTransaction) -> Ordering @@ -217,7 +212,7 @@ where #[derive(Debug, thiserror::Error)] pub enum MineTransactionError where - ChainSpecT: ChainSpec, + ChainSpecT: RuntimeSpec, { /// An error that occurred while constructing a block builder. #[error(transparent)] @@ -308,7 +303,8 @@ pub fn mine_block_with_single_transaction< blockchain: &'blockchain dyn SyncBlockchain, state: Box>, transaction: ChainSpecT::Transaction, - cfg: &CfgEnvWithEvmWiring, + cfg: &CfgEnv, + hardfork: ChainSpecT::Hardfork, options: BlockOptions, min_gas_price: U256, reward: U256, @@ -327,13 +323,9 @@ pub fn mine_block_with_single_transaction< > where 'blockchain: 'evm, - ChainSpecT: SyncChainSpec< - Block: Default, + ChainSpecT: SyncRuntimeSpec< Hardfork: Debug, - Transaction: Default - + TransactionValidation< - ValidationError: From + PartialEq, - >, + Transaction: TransactionValidation + PartialEq>, >, BlockchainErrorT: Debug + Send, StateErrorT: Debug + Send, @@ -404,7 +396,8 @@ where } } - let mut block_builder = BlockBuilder::new(cfg.clone(), parent_block.as_ref(), options)?; + let mut block_builder = + BlockBuilder::new(cfg.clone(), hardfork, parent_block.as_ref(), options)?; let ExecutionResultWithContext { result, @@ -439,14 +432,14 @@ fn effective_miner_fee(transaction: &impl Transaction, base_fee: Option) - }) } -fn first_in_first_out_comparator( +fn first_in_first_out_comparator( lhs: &OrderedTransaction, rhs: &OrderedTransaction, ) -> Ordering { lhs.order_id().cmp(&rhs.order_id()) } -fn priority_comparator( +fn priority_comparator( lhs: &OrderedTransaction, rhs: &OrderedTransaction, base_fee: Option, diff --git a/crates/edr_evm/src/precompiles.rs b/crates/edr_evm/src/precompiles.rs index 83a43ae22..97cd548a3 100644 --- a/crates/edr_evm/src/precompiles.rs +++ b/crates/edr_evm/src/precompiles.rs @@ -1,16 +1,13 @@ -use std::{fmt::Debug, sync::Arc}; +use std::sync::Arc; use edr_eth::{Address, HashMap}; -use revm::{db::Database, ContextPrecompile, EvmHandler}; +use revm::{ContextPrecompile, EvmHandler, EvmWiring}; /// Registers custom precompiles. -pub fn register_precompiles_handles( - handler: &mut EvmHandler<'_, ChainSpecT, ContextT, DatabaseT>, - precompiles: HashMap>, -) where - ChainSpecT: revm::EvmWiring, - DatabaseT: Database, -{ +pub fn register_precompiles_handles( + handler: &mut EvmHandler<'_, EvmWiringT>, + precompiles: HashMap>, +) { let old_handle = handler.pre_execution.load_precompiles(); handler.pre_execution.load_precompiles = Arc::new(move || { let mut new_handle = old_handle.clone(); diff --git a/crates/edr_evm/src/runtime.rs b/crates/edr_evm/src/runtime.rs index 0e7c2a2f6..eeacec9a4 100644 --- a/crates/edr_evm/src/runtime.rs +++ b/crates/edr_evm/src/runtime.rs @@ -2,22 +2,16 @@ use std::fmt::Debug; use edr_eth::{ db::{DatabaseComponents, StateRef}, + env::{CfgEnv, Env}, result::{ExecutionResult, InvalidTransaction, ResultAndState}, transaction::{ExecutableTransaction as _, TransactionValidation}, Address, HashMap, Precompile, SpecId, }; -use revm::{ - handler::{CfgEnvWithEvmWiring, EnvWithEvmWiring}, - ContextPrecompile, DatabaseCommit, Evm, -}; +use revm::{db::WrapDatabaseRef, ContextPrecompile, DatabaseCommit, Evm}; use crate::{ - blockchain::SyncBlockchain, - chain_spec::ChainSpec, - debug::DebugContext, - precompiles::register_precompiles_handles, - state::{StateOverrides, StateRefOverrider, SyncState}, - transaction::TransactionError, + blockchain::SyncBlockchain, debug::DebugContext, precompiles::register_precompiles_handles, + spec::RuntimeSpec, transaction::TransactionError, }; /// Asynchronous implementation of the Database super-trait @@ -29,66 +23,48 @@ pub type SyncDatabase<'blockchain, 'state, ChainSpecT, BlockchainErrorT, StateEr /// Runs a transaction without committing the state. // `DebugContext` cannot be simplified further -#[allow(clippy::too_many_arguments, clippy::type_complexity)] +#[allow(clippy::too_many_arguments)] #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))] -pub fn dry_run< - 'blockchain, - 'evm, - 'overrides, - 'state, - ChainSpecT, - DebugDataT, - BlockchainErrorT, - StateErrorT, ->( - blockchain: &'blockchain dyn SyncBlockchain, - state: &'state dyn SyncState, - state_overrides: &'overrides StateOverrides, - cfg: CfgEnvWithEvmWiring, +pub fn dry_run<'blockchain, 'evm, ChainSpecT, DebugDataT, BlockchainErrorT, StateT>( + blockchain: &'blockchain dyn SyncBlockchain, + state: StateT, + cfg: CfgEnv, + hardfork: ChainSpecT::Hardfork, transaction: ChainSpecT::Transaction, block: ChainSpecT::Block, custom_precompiles: &HashMap, - debug_context: Option< - DebugContext< - 'evm, - ChainSpecT, - BlockchainErrorT, - DebugDataT, - StateRefOverrider<'overrides, &'evm dyn SyncState>, - >, - >, -) -> Result, TransactionError> + debug_context: Option>, +) -> Result< + ResultAndState, + TransactionError, +> where 'blockchain: 'evm, - 'state: 'evm, - ChainSpecT: ChainSpec< - Block: Default, - Transaction: Default + TransactionValidation>, - >, + ChainSpecT: + RuntimeSpec>>, BlockchainErrorT: Debug + Send, - StateErrorT: Debug + Send, + StateT: StateRef, { - validate_configuration::(cfg.spec_id, &transaction)?; - - let state_overrider = StateRefOverrider::new(state_overrides, state); + validate_configuration::(hardfork, &transaction)?; - let env = EnvWithEvmWiring::new_with_cfg_env(cfg, block, transaction); + let env = Env::boxed(cfg, block, transaction); let result = { - let evm_builder = Evm::builder().with_ref_db(DatabaseComponents { - state: state_overrider, - block_hash: blockchain, - }); - - let precompiles: HashMap> = custom_precompiles - .iter() - .map(|(address, precompile)| (*address, ContextPrecompile::from(precompile.clone()))) - .collect(); - if let Some(debug_context) = debug_context { - let mut evm = evm_builder - .with_chain_spec::() + let precompiles: HashMap> = custom_precompiles + .iter() + .map(|(address, precompile)| { + (*address, ContextPrecompile::from(precompile.clone())) + }) + .collect(); + + let mut evm = Evm::>::builder() + .with_db(WrapDatabaseRef(DatabaseComponents { + state, + block_hash: blockchain, + })) .with_external_context(debug_context.data) - .with_env_with_handler_cfg(env) + .with_env(env) + .with_spec_id(hardfork) .append_handler_register(debug_context.register_handles_fn) .append_handler_register_box(Box::new(move |handler| { register_precompiles_handles(handler, precompiles.clone()); @@ -97,9 +73,21 @@ where evm.transact() } else { - let mut evm = evm_builder - .with_chain_spec::() - .with_env_with_handler_cfg(env) + let precompiles: HashMap> = custom_precompiles + .iter() + .map(|(address, precompile)| { + (*address, ContextPrecompile::from(precompile.clone())) + }) + .collect(); + + let mut evm = Evm::>::builder() + .with_db(WrapDatabaseRef(DatabaseComponents { + state, + block_hash: blockchain, + })) + .with_external_context(()) + .with_env(env) + .with_spec_id(hardfork) .append_handler_register_box(Box::new(move |handler| { register_precompiles_handles(handler, precompiles.clone()); })) @@ -115,44 +103,36 @@ where /// Runs a transaction without committing the state, while disabling balance /// checks and creating accounts for new addresses. // `DebugContext` cannot be simplified further -#[allow(clippy::too_many_arguments, clippy::type_complexity)] +#[allow(clippy::too_many_arguments)] #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))] pub fn guaranteed_dry_run< 'blockchain, 'evm, - 'overrides, 'state, ChainSpecT, DebugDataT, BlockchainErrorT, - StateErrorT, + StateT, >( - blockchain: &'blockchain dyn SyncBlockchain, - state: &'state dyn SyncState, - state_overrides: &'overrides StateOverrides, - mut cfg: CfgEnvWithEvmWiring, + blockchain: &'blockchain dyn SyncBlockchain, + state: StateT, + mut cfg: CfgEnv, + hardfork: ChainSpecT::Hardfork, transaction: ChainSpecT::Transaction, block: ChainSpecT::Block, custom_precompiles: &HashMap, - debug_context: Option< - DebugContext< - 'evm, - ChainSpecT, - BlockchainErrorT, - DebugDataT, - StateRefOverrider<'overrides, &'evm dyn SyncState>, - >, - >, -) -> Result, TransactionError> + debug_context: Option>, +) -> Result< + ResultAndState, + TransactionError, +> where 'blockchain: 'evm, 'state: 'evm, - ChainSpecT: ChainSpec< - Block: Default, - Transaction: Default + TransactionValidation>, - >, + ChainSpecT: + RuntimeSpec>>, BlockchainErrorT: Debug + Send, - StateErrorT: Debug + Send, + StateT: StateRef, { cfg.disable_balance_check = true; cfg.disable_block_gas_limit = true; @@ -160,8 +140,8 @@ where dry_run( blockchain, state, - state_overrides, cfg, + hardfork, transaction, block, custom_precompiles, @@ -171,49 +151,49 @@ where /// Runs a transaction, committing the state in the process. #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))] +#[allow(clippy::too_many_arguments)] pub fn run<'blockchain, 'evm, ChainSpecT, BlockchainErrorT, DebugDataT, StateT>( blockchain: &'blockchain dyn SyncBlockchain, state: StateT, - cfg: CfgEnvWithEvmWiring, + cfg: CfgEnv, + hardfork: ChainSpecT::Hardfork, transaction: ChainSpecT::Transaction, block: ChainSpecT::Block, custom_precompiles: &HashMap, debug_context: Option>, ) -> Result< - ExecutionResult, + ExecutionResult, TransactionError, > where 'blockchain: 'evm, - ChainSpecT: ChainSpec< - Block: Default, - Transaction: Default + TransactionValidation>, - >, + ChainSpecT: + RuntimeSpec>>, BlockchainErrorT: Debug + Send, StateT: StateRef + DatabaseCommit, StateT::Error: Debug + Send, { - validate_configuration::( - cfg.spec_id, - &transaction, - )?; + validate_configuration::(hardfork, &transaction)?; - let env = EnvWithEvmWiring::new_with_cfg_env(cfg, block, transaction); - let evm_builder = Evm::builder().with_ref_db(DatabaseComponents { - state, - block_hash: blockchain, - }); - - let precompiles: HashMap> = custom_precompiles - .iter() - .map(|(address, precompile)| (*address, ContextPrecompile::from(precompile.clone()))) - .collect(); + let env = Env::boxed(cfg, block, transaction); let result = if let Some(debug_context) = debug_context { - let mut evm = evm_builder - .with_chain_spec::() + let precompiles: HashMap>> = + custom_precompiles + .iter() + .map(|(address, precompile)| { + (*address, ContextPrecompile::from(precompile.clone())) + }) + .collect(); + + let mut evm = Evm::>::builder() + .with_db(WrapDatabaseRef(DatabaseComponents { + state, + block_hash: blockchain, + })) .with_external_context(debug_context.data) - .with_env_with_handler_cfg(env) + .with_env(env) + .with_spec_id(hardfork) .append_handler_register(debug_context.register_handles_fn) .append_handler_register_box(Box::new(move |handler| { register_precompiles_handles(handler, precompiles.clone()); @@ -222,9 +202,22 @@ where evm.transact_commit() } else { - let mut evm = evm_builder - .with_chain_spec::() - .with_env_with_handler_cfg(env) + let precompiles: HashMap>> = + custom_precompiles + .iter() + .map(|(address, precompile)| { + (*address, ContextPrecompile::from(precompile.clone())) + }) + .collect(); + + let mut evm = Evm::>::builder() + .with_db(WrapDatabaseRef(DatabaseComponents { + state, + block_hash: blockchain, + })) + .with_external_context(()) + .with_env(env) + .with_spec_id(hardfork) .append_handler_register_box(Box::new(move |handler| { register_precompiles_handles(handler, precompiles.clone()); })) @@ -236,7 +229,7 @@ where Ok(result) } -fn validate_configuration( +fn validate_configuration( hardfork: ChainSpecT::Hardfork, transaction: &ChainSpecT::Transaction, ) -> Result<(), TransactionError> { diff --git a/crates/edr_evm/src/chain_spec.rs b/crates/edr_evm/src/spec.rs similarity index 75% rename from crates/edr_evm/src/chain_spec.rs rename to crates/edr_evm/src/spec.rs index 7d8af77de..cb4ac63d5 100644 --- a/crates/edr_evm/src/chain_spec.rs +++ b/crates/edr_evm/src/spec.rs @@ -1,18 +1,21 @@ -use std::fmt::Debug; +use std::{fmt::Debug, marker::PhantomData}; use edr_eth::{ block::{self, BlobGas, PartialHeader}, - chain_spec::{EthHeaderConstants, L1ChainSpec}, env::{BlobExcessGasAndPrice, BlockEnv}, log::{ExecutionLog, FilterLog}, receipt::{ExecutionReceiptBuilder, MapReceiptLogs}, result::InvalidTransaction, + spec::{EthHeaderConstants, L1ChainSpec}, transaction::ExecutableTransaction, SpecId, B256, U256, }; use edr_rpc_eth::{spec::RpcSpec, RpcTypeFrom, TransactionConversionError}; -use revm::primitives::TransactionValidation; pub use revm::EvmWiring; +use revm::{ + primitives::{ChainSpec, TransactionValidation}, + Database, +}; use crate::{ block::transaction::TransactionAndBlock, @@ -24,15 +27,16 @@ use crate::{ /// A trait for defining a chain's associated types. // Bug: https://github.com/rust-lang/rust-clippy/issues/12927 #[allow(clippy::trait_duplication_in_bounds)] -pub trait ChainSpec: +pub trait RuntimeSpec: alloy_rlp::Encodable // Defines the chain's internal types like blocks/headers or transactions + EthHeaderConstants - + EvmWiring< - Block: BlockEnvConstructor + BlockEnvConstructor, + + revm::primitives::ChainSpec< + Block: BlockEnvConstructor + BlockEnvConstructor + Default, Transaction: alloy_rlp::Encodable + Clone + Debug + + Default + PartialEq + Eq + ExecutableTransaction @@ -48,7 +52,7 @@ pub trait ChainSpec: + TryInto, Error = Self::RpcReceiptConversionError>, RpcTransaction: EthRpcTransaction + RpcTypeFrom, Hardfork = Self::Hardfork> - + TryInto<::Transaction, Error = Self::RpcTransactionConversionError>, + + TryInto<::Transaction, Error = Self::RpcTransactionConversionError>, > + RpcSpec: Debug> + RpcSpec< @@ -57,9 +61,14 @@ pub trait ChainSpec: RpcBlock: EthRpcBlock, > { + /// Type representing an implementation of `EvmWiring` for this chain. + type EvmWiring: EvmWiring; + /// Type representing a builder that constructs an execution receipt. type ReceiptBuilder: ExecutionReceiptBuilder< - Self, + Self::HaltReason, + Self::Hardfork, + Self::Transaction, Receipt = Self::ExecutionReceipt, >; @@ -91,12 +100,12 @@ pub trait ChainSpec: } /// A trait for constructing a (partial) block header into an EVM block. -pub trait BlockEnvConstructor { +pub trait BlockEnvConstructor { /// Converts the instance into an EVM block. - fn new_block_env(header: &HeaderT, hardfork: ChainSpecT::Hardfork) -> Self; + fn new_block_env(header: &HeaderT, hardfork: SpecId) -> Self; } -impl BlockEnvConstructor for BlockEnv { +impl BlockEnvConstructor for BlockEnv { fn new_block_env(header: &PartialHeader, hardfork: SpecId) -> Self { Self { number: U256::from(header.number), @@ -118,7 +127,7 @@ impl BlockEnvConstructor for BlockEnv { } } -impl BlockEnvConstructor for BlockEnv { +impl BlockEnvConstructor for BlockEnv { fn new_block_env(header: &block::Header, hardfork: SpecId) -> Self { Self { number: U256::from(header.number), @@ -140,9 +149,9 @@ impl BlockEnvConstructor for BlockEnv { } } -/// A supertrait for [`ChainSpec`] that is safe to send between threads. -pub trait SyncChainSpec: - ChainSpec< +/// A supertrait for [`RuntimeSpec`] that is safe to send between threads. +pub trait SyncRuntimeSpec: + RuntimeSpec< ExecutionReceipt: Send + Sync, HaltReason: Send + Sync, Hardfork: Send + Sync, @@ -155,8 +164,8 @@ pub trait SyncChainSpec: { } -impl SyncChainSpec for ChainSpecT where - ChainSpecT: ChainSpec< +impl SyncRuntimeSpec for ChainSpecT where + ChainSpecT: RuntimeSpec< ExecutionReceipt: Send + Sync, HaltReason: Send + Sync, Hardfork: Send + Sync, @@ -169,7 +178,39 @@ impl SyncChainSpec for ChainSpecT where { } -impl ChainSpec for L1ChainSpec { +/// EVM wiring for L1 chains. +pub struct L1Wiring { + _phantom: PhantomData<(ChainSpecT, DatabaseT, ExternalContextT)>, +} + +impl edr_eth::spec::EvmWiring + for L1Wiring +{ + type ChainSpec = ChainSpecT; + type ExternalContext = ExternalContextT; + type Database = DatabaseT; +} + +impl revm::EvmWiring + for L1Wiring +where + ChainSpecT: ChainSpec< + Block: Default, + Transaction: Default + TransactionValidation>, + >, + DatabaseT: Database, +{ + fn handler<'evm>( + hardfork: ::Hardfork, + ) -> revm::EvmHandler<'evm, Self> { + revm::EvmHandler::mainnet_with_spec(hardfork) + } +} + +impl RuntimeSpec for L1ChainSpec { + type EvmWiring = + L1Wiring; + type ReceiptBuilder = edr_eth::receipt::execution::Builder; type RpcBlockConversionError = RemoteBlockConversionError; type RpcReceiptConversionError = edr_rpc_eth::receipt::ConversionError; diff --git a/crates/edr_evm/src/state/fork.rs b/crates/edr_evm/src/state/fork.rs index 85976278a..c41fe1a91 100644 --- a/crates/edr_evm/src/state/fork.rs +++ b/crates/edr_evm/src/state/fork.rs @@ -228,7 +228,7 @@ mod tests { str::FromStr, }; - use edr_eth::{chain_spec::L1ChainSpec, PreEip1898BlockSpec}; + use edr_eth::{spec::L1ChainSpec, PreEip1898BlockSpec}; use edr_test_utils::env::get_alchemy_url; use super::*; diff --git a/crates/edr_evm/src/state/remote.rs b/crates/edr_evm/src/state/remote.rs index 26178d295..94ab9699f 100644 --- a/crates/edr_evm/src/state/remote.rs +++ b/crates/edr_evm/src/state/remote.rs @@ -16,7 +16,7 @@ use revm::{ use tokio::runtime; use super::StateError; -use crate::{chain_spec::ChainSpec, EthRpcBlock as _}; +use crate::{spec::RuntimeSpec, EthRpcBlock as _}; /// A state backed by a remote Ethereum node #[derive_where(Debug)] @@ -60,7 +60,7 @@ impl RemoteState { } } -impl RemoteState { +impl RemoteState { /// Retrieve the state root of the given block, if it exists. pub fn state_root(&self, block_number: u64) -> Result, RpcClientError> { Ok(tokio::task::block_in_place(move || { @@ -112,7 +112,7 @@ impl StateRef for RemoteState { mod tests { use std::str::FromStr; - use edr_eth::chain_spec::L1ChainSpec; + use edr_eth::spec::L1ChainSpec; use tokio::runtime; use super::*; diff --git a/crates/edr_evm/src/state/remote/cached.rs b/crates/edr_evm/src/state/remote/cached.rs index 308a7622a..b3cbced05 100644 --- a/crates/edr_evm/src/state/remote/cached.rs +++ b/crates/edr_evm/src/state/remote/cached.rs @@ -134,7 +134,7 @@ fn fetch_remote_account( mod tests { use std::{str::FromStr, sync::Arc}; - use edr_eth::chain_spec::L1ChainSpec; + use edr_eth::spec::L1ChainSpec; use edr_rpc_eth::client::EthRpcClient; use edr_test_utils::env::get_alchemy_url; use tokio::runtime; diff --git a/crates/edr_evm/src/test_utils.rs b/crates/edr_evm/src/test_utils.rs index 8ff8d6fec..e33ac2f31 100644 --- a/crates/edr_evm/src/test_utils.rs +++ b/crates/edr_evm/src/test_utils.rs @@ -3,11 +3,11 @@ use std::{fmt::Debug, num::NonZeroU64, sync::Arc}; use anyhow::anyhow; use edr_eth::{ block::{miner_reward, BlockOptions}, - chain_spec::L1ChainSpec, env::CfgEnv, log::FilterLog, receipt::Receipt as _, result::InvalidTransaction, + spec::L1ChainSpec, transaction::{TransactionValidation, TxKind}, withdrawal::Withdrawal, AccountInfo, Address, Bytes, HashMap, PreEip1898BlockSpec, SpecId, U256, @@ -16,8 +16,7 @@ use edr_rpc_eth::client::EthRpcClient; use crate::{ blockchain::{Blockchain as _, ForkedBlockchain}, - chain_spec::SyncChainSpec, - evm::handler::CfgEnvWithEvmWiring, + spec::SyncRuntimeSpec, state::{AccountTrie, IrregularState, StateError, TrieState}, transaction, Block, BlockBuilder, DebugContext, ExecutionResultWithContext, MemPool, MemPoolAddTransactionError, RandomHashGenerator, RemoteBlock, @@ -160,7 +159,7 @@ pub fn dummy_eip1559_transaction( /// block. pub async fn run_full_block< ChainSpecT: Debug - + SyncChainSpec< + + SyncRuntimeSpec< Block: Default, Hardfork: Debug, ExecutionReceipt: PartialEq, @@ -217,12 +216,11 @@ pub async fn run_full_block< cfg.chain_id = chain_id; cfg.disable_eip3607 = true; - let cfg = CfgEnvWithEvmWiring::::new(cfg, hardfork); - let parent = blockchain.last_block()?; let mut builder = BlockBuilder::new( cfg, + hardfork, &parent, BlockOptions { beneficiary: Some(replay_header.beneficiary), @@ -367,7 +365,7 @@ pub async fn run_full_block< /// Implements full block tests for the provided chain specs. /// ```no_run -/// use edr_eth::chain_spec::L1ChainSpec; +/// use edr_eth::spec::L1ChainSpec; /// use edr_evm::impl_full_block_tests; /// use edr_test_utils::env::get_alchemy_url; /// diff --git a/crates/edr_evm/src/trace.rs b/crates/edr_evm/src/trace.rs index 9cb1455e2..1dc240c81 100644 --- a/crates/edr_evm/src/trace.rs +++ b/crates/edr_evm/src/trace.rs @@ -1,7 +1,7 @@ use std::{cell::RefCell, fmt::Debug, rc::Rc, sync::Arc}; use derive_where::derive_where; -use edr_eth::{Address, Bytes, U256}; +use edr_eth::{result::EVMErrorWiring, Address, Bytes, U256}; use revm::{ handler::register::EvmHandler, interpreter::{ @@ -9,22 +9,23 @@ use revm::{ return_revert, CallInputs, CallOutcome, CallValue, CreateInputs, CreateOutcome, InstructionResult, Interpreter, SuccessOrHalt, }, - primitives::{Bytecode, EVMErrorForChain, ExecutionResult, Output}, + primitives::{Bytecode, ChainSpec, ExecutionResult, HaltReasonTrait, Output}, Context, Database, EvmContext, FrameOrResult, FrameResult, }; -use crate::{chain_spec::EvmWiring, debug::GetContextData}; +use crate::{debug::GetContextData, spec::EvmWiring}; /// Registers trace collector handles to the EVM handler. pub fn register_trace_collector_handles< - ChainSpecT: revm::EvmWiring, - DatabaseT: Database, - ContextT: GetContextData>, + EvmWiringT: revm::EvmWiring< + ExternalContext: GetContextData< + TraceCollector<::HaltReason>, + >, + Database: Database, + >, >( - handler: &mut EvmHandler<'_, ChainSpecT, ContextT, DatabaseT>, -) where - DatabaseT::Error: Debug, -{ + handler: &mut EvmHandler<'_, EvmWiringT>, +) { let table = &mut handler.instruction_table; // Update all instructions to call the instruction handler. @@ -39,9 +40,7 @@ pub fn register_trace_collector_handles< let create_input_stack_inner = create_input_stack.clone(); let old_handle = handler.execution.create.clone(); handler.execution.create = Arc::new( - move |ctx, - inputs| - -> Result> { + move |ctx, inputs| -> Result> { let tracer = ctx.external.get_context_data(); tracer.create(&ctx.evm, &inputs); @@ -55,9 +54,7 @@ pub fn register_trace_collector_handles< let call_input_stack_inner = call_input_stack.clone(); let old_handle = handler.execution.call.clone(); handler.execution.call = Arc::new( - move |ctx, - inputs| - -> Result> { + move |ctx, inputs| -> Result> { let tracer = ctx.external.get_context_data(); tracer.call(&mut ctx.evm, &inputs); @@ -71,10 +68,7 @@ pub fn register_trace_collector_handles< let call_input_stack_inner = call_input_stack.clone(); let old_handle = handler.execution.insert_call_outcome.clone(); handler.execution.insert_call_outcome = Arc::new( - move |ctx: &mut revm::Context, - frame, - shared_memory, - outcome| { + move |ctx: &mut revm::Context, frame, shared_memory, outcome| { let call_inputs = call_input_stack_inner.borrow_mut().pop().unwrap(); let tracer = ctx.external.get_context_data(); @@ -119,14 +113,17 @@ pub fn register_trace_collector_handles< } /// Outer closure that calls tracer for every instruction. -fn instruction_handler( - prev: &DynInstruction<'_, Context>, +fn instruction_handler( + prev: &DynInstruction<'_, Context>, interpreter: &mut Interpreter, - host: &mut Context, + host: &mut Context, ) where - ChainSpecT: revm::EvmWiring, - ContextT: GetContextData>, - DatabaseT: Database, + EvmWiringT: revm::EvmWiring< + Database: Database, + ExternalContext: GetContextData< + TraceCollector<::HaltReason>, + >, + >, { // SAFETY: as the PC was already incremented we need to subtract 1 to preserve // the old Inspector behavior. @@ -144,15 +141,14 @@ fn instruction_handler( } /// Stack tracing message -#[derive(Debug)] -#[derive_where(Clone; ChainSpecT::HaltReason)] -pub enum TraceMessage { +#[derive(Clone, Debug)] +pub enum TraceMessage { /// Event that occurs before a call or create message. Before(BeforeMessage), /// Event that occurs every step of a call or create message. Step(Step), /// Event that occurs after a call or create message. - After(AfterMessage), + After(AfterMessage), } /// Temporary before message type for handling traces @@ -179,25 +175,23 @@ pub struct BeforeMessage { } /// Event that occurs after a call or create message. -#[derive(Debug)] -#[derive_where(Clone; ChainSpecT::HaltReason)] -pub struct AfterMessage { +#[derive(Clone, Debug)] +pub struct AfterMessage { /// The execution result - pub execution_result: ExecutionResult, + pub execution_result: ExecutionResult, /// The newly created contract address if it's a create tx. `None` /// if there was an error creating the contract. pub contract_address: Option
, } /// A trace for an EVM call. -#[derive(Debug)] -#[derive_where(Clone; ChainSpecT::HaltReason)] +#[derive(Clone, Debug)] #[derive_where(Default)] -pub struct Trace { +pub struct Trace { // /// The individual steps of the call // pub steps: Vec, /// Messages - pub messages: Vec>, + pub messages: Vec>, /// The return value of the call pub return_value: Bytes, } @@ -253,14 +247,14 @@ impl Stack { } } -impl Trace { +impl Trace { /// Adds a before message pub fn add_before(&mut self, message: BeforeMessage) { self.messages.push(TraceMessage::Before(message)); } /// Adds a result message - pub fn add_after(&mut self, message: AfterMessage) { + pub fn add_after(&mut self, message: AfterMessage) { self.messages.push(TraceMessage::After(message)); } @@ -273,14 +267,14 @@ impl Trace { /// Object that gathers trace information during EVM execution and can be turned /// into a trace upon completion. #[derive(Debug)] -pub struct TraceCollector { - traces: Vec>, +pub struct TraceCollector { + traces: Vec>, pending_before: Option, is_new_trace: bool, verbose: bool, } -impl TraceCollector { +impl TraceCollector { /// Create a trace collector. If verbose is `true` full stack and memory /// will be recorded. pub fn new(verbose: bool) -> Self { @@ -293,16 +287,16 @@ impl TraceCollector { } /// Converts the [`TraceCollector`] into its [`Trace`]. - pub fn into_traces(self) -> Vec> { + pub fn into_traces(self) -> Vec> { self.traces } /// Returns the traces collected so far. - pub fn traces(&self) -> &[Trace] { + pub fn traces(&self) -> &[Trace] { &self.traces } - fn current_trace_mut(&mut self) -> &mut Trace { + fn current_trace_mut(&mut self) -> &mut Trace { self.traces.last_mut().expect("Trace must have been added") } @@ -312,13 +306,13 @@ impl TraceCollector { } } - fn call( + fn call< + EvmWiringT: EvmWiring, Database: Database>, + >( &mut self, - data: &mut EvmContext, + data: &mut EvmContext, inputs: &CallInputs, - ) where - DatabaseT::Error: Debug, - { + ) { if self.is_new_trace { self.is_new_trace = false; self.traces.push(Trace::default()); @@ -367,9 +361,9 @@ impl TraceCollector { }); } - fn call_end( + fn call_end>>( &mut self, - data: &EvmContext, + data: &EvmContext, _inputs: &CallInputs, outcome: &CallOutcome, ) { @@ -393,7 +387,7 @@ impl TraceCollector { ret }; - let execution_result = match SuccessOrHalt::::from(safe_ret) { + let execution_result = match SuccessOrHalt::from(safe_ret) { SuccessOrHalt::Success(reason) => ExecutionResult::Success { reason, gas_used: outcome.gas().spent(), @@ -421,9 +415,9 @@ impl TraceCollector { }); } - fn create( + fn create>>( &mut self, - data: &EvmContext, + data: &EvmContext, inputs: &CreateInputs, ) { if self.is_new_trace { @@ -446,14 +440,12 @@ impl TraceCollector { }); } - fn create_end( + fn create_end>>( &mut self, - data: &EvmContext, + data: &EvmContext, _inputs: &CreateInputs, outcome: &CreateOutcome, - ) where - ::Error: Debug, - { + ) { self.validate_before_message(); let ret = *outcome.instruction_result(); @@ -464,7 +456,7 @@ impl TraceCollector { ret }; - let execution_result = match SuccessOrHalt::::from(safe_ret) { + let execution_result = match SuccessOrHalt::from(safe_ret) { SuccessOrHalt::Success(reason) => ExecutionResult::Success { reason, gas_used: outcome.gas().spent(), @@ -492,10 +484,10 @@ impl TraceCollector { }); } - fn step( + fn step>>( &mut self, interp: &Interpreter, - data: &EvmContext, + data: &EvmContext, ) { // Skip the step let skip_step = self.pending_before.as_ref().map_or(false, |message| { @@ -525,9 +517,11 @@ impl TraceCollector { } } - fn call_transaction_end( + fn call_transaction_end< + EvmWiringT: EvmWiring>, + >( &mut self, - data: &EvmContext, + data: &EvmContext, inputs: &CallInputs, outcome: &CallOutcome, ) { @@ -535,23 +529,23 @@ impl TraceCollector { self.call_end(data, inputs, outcome); } - fn create_transaction_end( + fn create_transaction_end< + EvmWiringT: EvmWiring>, + >( &mut self, - data: &EvmContext, + data: &EvmContext, inputs: &CreateInputs, outcome: &CreateOutcome, - ) where - DatabaseT::Error: Debug, - { + ) { self.is_new_trace = true; self.create_end(data, inputs, outcome); } } -impl GetContextData> - for TraceCollector +impl GetContextData> + for TraceCollector { - fn get_context_data(&mut self) -> &mut TraceCollector { + fn get_context_data(&mut self) -> &mut TraceCollector { self } } diff --git a/crates/edr_evm/src/transaction.rs b/crates/edr_evm/src/transaction.rs index 492360b1e..e48108d40 100644 --- a/crates/edr_evm/src/transaction.rs +++ b/crates/edr_evm/src/transaction.rs @@ -7,22 +7,23 @@ use std::fmt::Debug; use derive_where::derive_where; // Re-export the transaction types from `edr_eth`. pub use edr_eth::transaction::*; -use edr_eth::{result::InvalidHeader, SpecId, U256}; +use edr_eth::{ + result::{EVMErrorForChain, InvalidHeader}, + SpecId, U256, +}; use revm::{ - db::DatabaseComponentError, - interpreter::gas::validate_initial_tx_gas, - primitives::{EVMError, EVMErrorForChain}, + db::DatabaseComponentError, interpreter::gas::validate_initial_tx_gas, primitives::EVMError, }; pub use self::detailed::*; -use crate::chain_spec::ChainSpec; +use crate::spec::RuntimeSpec; /// Invalid transaction error #[derive(thiserror::Error)] #[derive_where(Debug; ::ValidationError, BlockchainErrorT, StateErrorT)] pub enum TransactionError where - ChainSpecT: revm::primitives::EvmWiring, + ChainSpecT: revm::primitives::ChainSpec, { /// Blockchain errors #[error(transparent)] @@ -57,13 +58,13 @@ where } impl - From, ChainSpecT>> + From>> for TransactionError where - ChainSpecT: ChainSpec, + ChainSpecT: RuntimeSpec, { fn from( - error: EVMErrorForChain, ChainSpecT>, + error: EVMErrorForChain>, ) -> Self { match error { EVMError::Transaction(error) => ChainSpecT::cast_transaction_error(error), diff --git a/crates/edr_evm/src/transaction/detailed.rs b/crates/edr_evm/src/transaction/detailed.rs index b43a81efa..16a89d008 100644 --- a/crates/edr_evm/src/transaction/detailed.rs +++ b/crates/edr_evm/src/transaction/detailed.rs @@ -2,10 +2,10 @@ use std::sync::Arc; use edr_eth::{log::FilterLog, receipt::BlockReceipt}; -use crate::chain_spec::ChainSpec; +use crate::spec::RuntimeSpec; /// Wrapper struct for a transaction and its receipt. -pub struct DetailedTransaction<'transaction, ChainSpecT: ChainSpec> { +pub struct DetailedTransaction<'transaction, ChainSpecT: RuntimeSpec> { /// The transaction pub transaction: &'transaction ChainSpecT::Transaction, /// The transaction's receipt diff --git a/crates/edr_evm/tests/blockchain.rs b/crates/edr_evm/tests/blockchain.rs index 9cae4d902..5716f2ff9 100644 --- a/crates/edr_evm/tests/blockchain.rs +++ b/crates/edr_evm/tests/blockchain.rs @@ -4,11 +4,11 @@ use std::{collections::BTreeMap, sync::Arc}; use edr_eth::{ block::PartialHeader, - chain_spec::L1ChainSpec, eips::eip2718::TypedEnvelope, log::{ExecutionLog, FilterLog}, receipt::{self, ExecutionReceiptBuilder, Receipt as _, TransactionReceipt}, result::{ExecutionResult, Output, SuccessReason}, + spec::L1ChainSpec, transaction::ExecutableTransaction as _, Address, Bytes, HashSet, SpecId, B256, U256, }; diff --git a/crates/edr_evm/tests/issues.rs b/crates/edr_evm/tests/issues.rs index 33a156675..9ab415347 100644 --- a/crates/edr_evm/tests/issues.rs +++ b/crates/edr_evm/tests/issues.rs @@ -3,7 +3,7 @@ use std::{str::FromStr, sync::Arc}; use edr_defaults::CACHE_DIR; -use edr_eth::{chain_spec::L1ChainSpec, Address, HashMap, SpecId, U256}; +use edr_eth::{spec::L1ChainSpec, Address, HashMap, SpecId, U256}; use edr_evm::{ blockchain::ForkedBlockchain, precompile::{self, Precompiles}, diff --git a/crates/edr_evm/tests/transaction.rs b/crates/edr_evm/tests/transaction.rs index 2fe1bbe34..dff66272e 100644 --- a/crates/edr_evm/tests/transaction.rs +++ b/crates/edr_evm/tests/transaction.rs @@ -9,7 +9,7 @@ mod alchemy { #[tokio::test] async fn []() { use edr_eth::{ - chain_spec::L1ChainSpec, + spec::L1ChainSpec, transaction::{self, ExecutableTransaction as _}, PreEip1898BlockSpec, B256 diff --git a/crates/edr_generic/Cargo.toml b/crates/edr_generic/Cargo.toml index 95a64819c..1ea814d3e 100644 --- a/crates/edr_generic/Cargo.toml +++ b/crates/edr_generic/Cargo.toml @@ -12,13 +12,11 @@ edr_evm = { path = "../edr_evm" } edr_provider = { path = "../edr_provider" } edr_rpc_eth = { path = "../edr_rpc_eth" } log = { version = "0.4.17", default-features = false } -revm = { git = "https://github.com/Wodann/revm", rev = "a500675", version = "12.1", default-features = false, features = ["c-kzg", "dev", "serde"] } -revm-primitives = { git = "https://github.com/Wodann/revm", rev = "a500675", version = "7.1", default-features = false, features = ["c-kzg", "hashbrown"] } serde = { version = "1.0.209", default-features = false, features = ["derive"] } thiserror = { version = "1.0.37", default-features = false } [dev-dependencies] -anyhow = "1.0.75" +anyhow = "1.0.89" edr_defaults = { path = "../edr_defaults" } edr_evm = { path = "../edr_evm", features = ["test-utils"] } edr_rpc_eth = { path = "../edr_rpc_eth", features = ["test-utils"] } diff --git a/crates/edr_generic/src/lib.rs b/crates/edr_generic/src/lib.rs index 2f6a1207c..0a4368cfe 100644 --- a/crates/edr_generic/src/lib.rs +++ b/crates/edr_generic/src/lib.rs @@ -8,7 +8,7 @@ mod transaction; /// The chain specification for Ethereum Layer 1 that is a bit more lenient /// and allows for more flexibility in contrast to -/// [`L1ChainSpec`](edr_eth::chain_spec::L1ChainSpec). +/// [`L1ChainSpec`](edr_eth::spec::L1ChainSpec). /// /// Specifically: /// - it allows unknown transaction types (treats them as legacy diff --git a/crates/edr_generic/src/receipt/execution.rs b/crates/edr_generic/src/receipt/execution.rs index b77e6eacd..41f912c5c 100644 --- a/crates/edr_generic/src/receipt/execution.rs +++ b/crates/edr_generic/src/receipt/execution.rs @@ -1,23 +1,27 @@ use edr_eth::{ + db::StateRef, log::ExecutionLog, receipt::{ execution::{Eip658, Legacy}, Execution, ExecutionReceiptBuilder, }, + result::{ExecutionResult, HaltReason}, transaction::TransactionType, + SpecId, }; -use revm_primitives::{EvmWiring, SpecId}; -use crate::{eip2718::TypedEnvelope, GenericChainSpec}; +use crate::{eip2718::TypedEnvelope, transaction}; pub struct Builder; -impl ExecutionReceiptBuilder for Builder { +impl ExecutionReceiptBuilder + for Builder +{ type Receipt = TypedEnvelope>; - fn new_receipt_builder( + fn new_receipt_builder( _pre_execution_state: StateT, - _transaction: &::Transaction, + _transaction: &transaction::SignedWithFallbackToPostEip155, ) -> Result { Ok(Self) } @@ -26,7 +30,7 @@ impl ExecutionReceiptBuilder for Builder { self, header: &edr_eth::block::PartialHeader, transaction: &crate::transaction::SignedWithFallbackToPostEip155, - result: &revm_primitives::ExecutionResult, + result: &ExecutionResult, hardfork: SpecId, ) -> Self::Receipt { let logs = result.logs().to_vec(); diff --git a/crates/edr_generic/src/rpc/block.rs b/crates/edr_generic/src/rpc/block.rs index dde95492d..af9a53ad2 100644 --- a/crates/edr_generic/src/rpc/block.rs +++ b/crates/edr_generic/src/rpc/block.rs @@ -5,7 +5,7 @@ use edr_eth::{ withdrawal::Withdrawal, Address, Bloom, Bytes, B256, B64, U256, }; -use edr_evm::{chain_spec::ChainSpec, BlockAndTotalDifficulty, EthBlockData, EthRpcBlock}; +use edr_evm::{spec::RuntimeSpec, BlockAndTotalDifficulty, EthBlockData, EthRpcBlock}; use edr_rpc_eth::spec::GetBlockNumber; use serde::{Deserialize, Serialize}; @@ -116,7 +116,7 @@ impl EthRpcBlock for Block { /// Error that occurs when trying to convert the JSON-RPC `Block` type. #[derive(thiserror::Error)] #[derive_where(Debug; ChainSpecT::RpcTransactionConversionError)] -pub enum ConversionError { +pub enum ConversionError { /// Missing hash #[error("Missing hash")] MissingHash, @@ -190,7 +190,7 @@ where } } -impl +impl From> for crate::rpc::block::Block { fn from(value: BlockAndTotalDifficulty) -> Self { diff --git a/crates/edr_generic/src/spec.rs b/crates/edr_generic/src/spec.rs index 8bb739aed..25e707100 100644 --- a/crates/edr_generic/src/spec.rs +++ b/crates/edr_generic/src/spec.rs @@ -1,61 +1,43 @@ use edr_eth::{ - block::{Header, PartialHeader}, - chain_spec::{EthHeaderConstants, L1ChainSpec}, - eips::eip1559::{BaseFeeParams, ConstantBaseFeeParams}, - result::HaltReason, + db::Database, + eips::eip1559::BaseFeeParams, + env::BlockEnv, + result::{HaltReason, InvalidTransaction}, + spec::{ChainSpec, EthHeaderConstants, L1ChainSpec}, + transaction::TransactionValidation, SpecId, }; use edr_evm::{ - chain_spec::{BlockEnvConstructor, ChainSpec}, hardfork::Activations, + spec::{L1Wiring, RuntimeSpec}, transaction::TransactionError, }; use edr_provider::{time::TimeSinceEpoch, ProviderSpec, TransactionFailureReason}; -use revm_primitives::{BlockEnv, EvmWiring, InvalidTransaction, TransactionValidation}; use crate::GenericChainSpec; -impl EvmWiring for GenericChainSpec { - type Block = revm_primitives::BlockEnv; - - type Hardfork = revm_primitives::SpecId; +impl ChainSpec for GenericChainSpec { + type ChainContext = (); - type HaltReason = revm_primitives::HaltReason; + type Block = BlockEnv; - type Transaction = crate::transaction::SignedWithFallbackToPostEip155; -} + type Hardfork = SpecId; -impl revm::EvmWiring for GenericChainSpec { - type Context = (); + type HaltReason = HaltReason; - fn handler<'evm, EXT, DB>(hardfork: Self::Hardfork) -> revm::EvmHandler<'evm, Self, EXT, DB> - where - DB: revm::Database, - { - revm::EvmHandler::mainnet_with_spec(hardfork) - } + type Transaction = crate::transaction::SignedWithFallbackToPostEip155; } impl EthHeaderConstants for GenericChainSpec { - const BASE_FEE_PARAMS: BaseFeeParams = - BaseFeeParams::Constant(ConstantBaseFeeParams::ethereum()); + const BASE_FEE_PARAMS: BaseFeeParams = L1ChainSpec::BASE_FEE_PARAMS; - const MIN_ETHASH_DIFFICULTY: u64 = 131072; + const MIN_ETHASH_DIFFICULTY: u64 = L1ChainSpec::MIN_ETHASH_DIFFICULTY; } -impl BlockEnvConstructor for BlockEnv { - fn new_block_env(header: &Header, hardfork: SpecId) -> Self { - BlockEnvConstructor::::new_block_env(header, hardfork) - } -} +impl RuntimeSpec for GenericChainSpec { + type EvmWiring = + L1Wiring; -impl BlockEnvConstructor for BlockEnv { - fn new_block_env(header: &PartialHeader, hardfork: SpecId) -> Self { - BlockEnvConstructor::::new_block_env(header, hardfork) - } -} - -impl ChainSpec for GenericChainSpec { type ReceiptBuilder = crate::receipt::execution::Builder; type RpcBlockConversionError = crate::rpc::block::ConversionError; type RpcReceiptConversionError = crate::rpc::receipt::ConversionError; @@ -88,16 +70,7 @@ impl ProviderSpec for GenericChainSpec { type PooledTransaction = edr_eth::transaction::pooled::PooledTransaction; type TransactionRequest = crate::transaction::Request; - fn cast_halt_reason(reason: Self::HaltReason) -> TransactionFailureReason { - match reason { - HaltReason::CreateContractSizeLimit => { - TransactionFailureReason::CreateContractSizeLimit - } - HaltReason::OpcodeNotFound | HaltReason::InvalidFEOpcode => { - TransactionFailureReason::OpcodeNotFound - } - HaltReason::OutOfGas(error) => TransactionFailureReason::OutOfGas(error), - remainder => TransactionFailureReason::Inner(remainder), - } + fn cast_halt_reason(reason: Self::HaltReason) -> TransactionFailureReason { + >::cast_halt_reason(reason) } } diff --git a/crates/edr_generic/src/transaction/signed.rs b/crates/edr_generic/src/transaction/signed.rs index ac2fbff99..239100b3c 100644 --- a/crates/edr_generic/src/transaction/signed.rs +++ b/crates/edr_generic/src/transaction/signed.rs @@ -1,6 +1,9 @@ -use edr_eth::transaction::{self, ExecutableTransaction, TransactionMut, TransactionType}; -use revm_primitives::{ - AccessListItem, Address, AuthorizationList, Bytes, TransactionValidation, TxKind, B256, U256, +use edr_eth::{ + transaction::{ + self, AuthorizationList, ExecutableTransaction, Transaction, TransactionMut, + TransactionType, TransactionValidation, TxKind, + }, + AccessListItem, Address, Bytes, B256, U256, }; /// The type of transaction. @@ -93,7 +96,7 @@ impl TransactionValidation for SignedWithFallbackToPostEip155 { type ValidationError = ::ValidationError; } -impl revm_primitives::Transaction for SignedWithFallbackToPostEip155 { +impl Transaction for SignedWithFallbackToPostEip155 { fn caller(&self) -> &Address { self.0.caller() } diff --git a/crates/edr_napi/Cargo.toml b/crates/edr_napi/Cargo.toml index cae707b2a..0de8502f2 100644 --- a/crates/edr_napi/Cargo.toml +++ b/crates/edr_napi/Cargo.toml @@ -16,10 +16,9 @@ edr_optimism = { path = "../edr_optimism", optional = true } edr_provider = { path = "../edr_provider" } edr_rpc_client = { path = "../edr_rpc_client" } mimalloc = { version = "0.1.39", default-features = false, features = ["local_dynamic_tls"] } -# when napi is pinned, be sure to pin napi-derive to the same version # The `async` feature ensures that a tokio runtime is available -napi = { version = "2.16.0", default-features = false, features = ["async", "error_anyhow", "napi8", "serde-json"] } -napi-derive = "2.16.0" +napi = { version = "2.16.10", default-features = false, features = ["async", "error_anyhow", "napi8", "serde-json"] } +napi-derive = "2.16.12" rand = { version = "0.8.4", optional = true } serde = { version = "1.0.209", features = ["derive"] } serde_json = { version = "1.0.127" } diff --git a/crates/edr_napi/index.d.ts b/crates/edr_napi/index.d.ts index c97cb11c6..0c04549be 100644 --- a/crates/edr_napi/index.d.ts +++ b/crates/edr_napi/index.d.ts @@ -64,9 +64,9 @@ export interface CallOverrideResult { shouldRevert: boolean } export const GENERIC_CHAIN_TYPE: string -export function genericChainProviderFactory(): ProviderFactory +export declare function genericChainProviderFactory(): ProviderFactory export const L1_CHAIN_TYPE: string -export function l1ProviderFactory(): ProviderFactory +export declare function l1ProviderFactory(): ProviderFactory /** Identifier for the Ethereum spec. */ export const enum SpecId { /** Frontier */ @@ -347,7 +347,9 @@ export const enum ExceptionalHalt { /** Aud data is smaller then already present data size. */ EofAuxDataTooSmall = 15, /** EOF Subroutine stack overflow */ - EOFFunctionStackOverflow = 16 + EOFFunctionStackOverflow = 16, + /** Check for target address validity is only done inside subcall. */ + InvalidEXTCALLTarget = 17 } /** The result when the EVM terminates due to an exceptional halt. */ export interface HaltResult { diff --git a/crates/edr_napi/src/chains/l1.rs b/crates/edr_napi/src/chains/l1.rs index 61726ede6..a4e549f44 100644 --- a/crates/edr_napi/src/chains/l1.rs +++ b/crates/edr_napi/src/chains/l1.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use edr_eth::{chain_spec::L1ChainSpec, specification}; +use edr_eth::{spec::L1ChainSpec, specification}; use edr_napi_core::{ logger::Logger, provider::{self, ProviderBuilder, SyncProviderFactory}, diff --git a/crates/edr_napi/src/provider/response.rs b/crates/edr_napi/src/provider/response.rs index 058f97b44..8fe96c2f8 100644 --- a/crates/edr_napi/src/provider/response.rs +++ b/crates/edr_napi/src/provider/response.rs @@ -1,4 +1,4 @@ -use edr_generic::GenericChainSpec; +use edr_eth::result::HaltReason; use napi::Either; use napi_derive::napi; @@ -6,11 +6,11 @@ use crate::trace::RawTrace; #[napi] pub struct Response { - inner: edr_napi_core::spec::Response, + inner: edr_napi_core::spec::Response, } -impl From> for Response { - fn from(value: edr_napi_core::spec::Response) -> Self { +impl From> for Response { + fn from(value: edr_napi_core::spec::Response) -> Self { Self { inner: value } } } diff --git a/crates/edr_napi/src/result.rs b/crates/edr_napi/src/result.rs index 4d55fd764..d12a983d2 100644 --- a/crates/edr_napi/src/result.rs +++ b/crates/edr_napi/src/result.rs @@ -1,5 +1,5 @@ +use edr_eth::result::HaltReason; use edr_evm::trace::AfterMessage; -use edr_generic::GenericChainSpec; use napi::{ bindgen_prelude::{BigInt, Buffer, Either3}, Either, Env, JsBuffer, JsBufferValue, @@ -107,6 +107,8 @@ pub enum ExceptionalHalt { EofAuxDataTooSmall, /// EOF Subroutine stack overflow EOFFunctionStackOverflow, + /// Check for target address validity is only done inside subcall. + InvalidEXTCALLTarget, } impl From for ExceptionalHalt { @@ -137,6 +139,9 @@ impl From for ExceptionalHalt { edr_eth::result::HaltReason::EOFFunctionStackOverflow => { ExceptionalHalt::EOFFunctionStackOverflow } + edr_eth::result::HaltReason::InvalidEXTCALLTarget => { + ExceptionalHalt::InvalidEXTCALLTarget + } edr_eth::result::HaltReason::OverflowPayment | edr_eth::result::HaltReason::StateChangeDuringStaticCall | edr_eth::result::HaltReason::CallNotAllowedInsideStatic @@ -168,6 +173,7 @@ impl From for edr_eth::result::HaltReason { ExceptionalHalt::EofAuxDataOverflow => Self::EofAuxDataOverflow, ExceptionalHalt::EofAuxDataTooSmall => Self::EofAuxDataTooSmall, ExceptionalHalt::EOFFunctionStackOverflow => Self::EOFFunctionStackOverflow, + ExceptionalHalt::InvalidEXTCALLTarget => Self::InvalidEXTCALLTarget, } } } @@ -192,7 +198,7 @@ pub struct ExecutionResult { } impl ExecutionResult { - pub fn new(env: &Env, message: &AfterMessage) -> napi::Result { + pub fn new(env: &Env, message: &AfterMessage) -> napi::Result { let AfterMessage { execution_result, contract_address, diff --git a/crates/edr_napi/src/trace.rs b/crates/edr_napi/src/trace.rs index 35fe3e452..ca50e2d6f 100644 --- a/crates/edr_napi/src/trace.rs +++ b/crates/edr_napi/src/trace.rs @@ -1,7 +1,7 @@ use std::sync::Arc; +use edr_eth::result::HaltReason; use edr_evm::{interpreter::OpCode, trace::BeforeMessage}; -use edr_generic::GenericChainSpec; use napi::{ bindgen_prelude::{BigInt, Buffer, Either3}, Env, JsBuffer, JsBufferValue, @@ -153,11 +153,11 @@ pub struct TracingMessageResult { #[napi] #[derive(Clone)] pub struct RawTrace { - inner: Arc>, + inner: Arc>, } -impl From>> for RawTrace { - fn from(value: Arc>) -> Self { +impl From>> for RawTrace { + fn from(value: Arc>) -> Self { Self { inner: value } } } diff --git a/crates/edr_napi_core/Cargo.toml b/crates/edr_napi_core/Cargo.toml index 577559e86..c47516d30 100644 --- a/crates/edr_napi_core/Cargo.toml +++ b/crates/edr_napi_core/Cargo.toml @@ -13,7 +13,7 @@ edr_generic = { path = "../edr_generic" } edr_provider = { path = "../edr_provider" } edr_rpc_client = { path = "../edr_rpc_client" } itertools = { version = "0.12.0", default-features = false } -napi = { version = "2.16.0", default-features = false, features = ["async", "error_anyhow", "napi8", "serde-json"] } +napi = { version = "2.16.10", default-features = false, features = ["async", "error_anyhow", "napi8", "serde-json"] } serde = { version = "1.0.209", features = ["derive"] } serde_json = { version = "1.0.127" } thiserror = { version = "1.0.37", default-features = false } diff --git a/crates/edr_napi_core/src/logger.rs b/crates/edr_napi_core/src/logger.rs index 7978b2ce4..46b9cacf1 100644 --- a/crates/edr_napi_core/src/logger.rs +++ b/crates/edr_napi_core/src/logger.rs @@ -130,7 +130,7 @@ where &mut self, hardfork: ChainSpecT::Hardfork, transaction: &ChainSpecT::Transaction, - result: &CallResult, + result: &CallResult, ) -> Result<(), Box> { self.collector.log_call(hardfork, transaction, result)?; @@ -141,7 +141,7 @@ where &mut self, hardfork: ChainSpecT::Hardfork, transaction: &ChainSpecT::Transaction, - failure: &EstimateGasFailure, + failure: &EstimateGasFailure, ) -> Result<(), Box> { self.collector .log_estimate_gas(hardfork, transaction, failure)?; @@ -261,7 +261,7 @@ impl> LogCollector { &mut self, hardfork: ChainSpecT::Hardfork, transaction: &ChainSpecT::Transaction, - result: &CallResult, + result: &CallResult, ) -> Result<(), LoggerError> { let CallResult { console_log_inputs, @@ -284,12 +284,10 @@ impl> LogCollector { logger.log_console_log_messages(console_log_inputs)?; - if let Some(transaction_failure) = - TransactionFailure::::from_execution_result::( - execution_result, - None, - trace, - ) + if let Some(transaction_failure) = TransactionFailure::from_execution_result::< + ChainSpecT, + CurrentTime, + >(execution_result, None, trace) { logger.log_transaction_failure(&transaction_failure); } @@ -302,7 +300,7 @@ impl> LogCollector { &mut self, hardfork: ChainSpecT::Hardfork, transaction: &ChainSpecT::Transaction, - result: &EstimateGasFailure, + result: &EstimateGasFailure, ) -> Result<(), LoggerError> { let EstimateGasFailure { console_log_inputs, @@ -331,7 +329,10 @@ impl> LogCollector { }) } - fn log_transaction_failure(&mut self, failure: &edr_provider::TransactionFailure) { + fn log_transaction_failure( + &mut self, + failure: &edr_provider::TransactionFailure, + ) { let is_revert_error = matches!( failure.reason, edr_provider::TransactionFailureReason::Revert(_) @@ -640,8 +641,8 @@ impl> LogCollector { &mut self, hardfork: ChainSpecT::Hardfork, transaction: &ChainSpecT::Transaction, - result: &ExecutionResult, - trace: &Trace, + result: &ExecutionResult, + trace: &Trace, console_log_inputs: &[Bytes], should_highlight_hash: bool, ) -> Result<(), LoggerError> { @@ -673,11 +674,10 @@ impl> LogCollector { logger.log_console_log_messages(console_log_inputs)?; - let transaction_failure = - edr_provider::TransactionFailure::::from_execution_result::< - ChainSpecT, - CurrentTime, - >(result, Some(transaction_hash), trace); + let transaction_failure = edr_provider::TransactionFailure::from_execution_result::< + ChainSpecT, + CurrentTime, + >(result, Some(transaction_hash), trace); if let Some(transaction_failure) = transaction_failure { logger.log_transaction_failure(&transaction_failure); @@ -724,7 +724,7 @@ impl> LogCollector { fn log_contract_and_function_name( &mut self, hardfork: ChainSpecT::Hardfork, - trace: &Trace, + trace: &Trace, ) { if let Some(TraceMessage::Before(before_message)) = trace.messages.first() { if let Some(to) = before_message.to { @@ -1004,8 +1004,8 @@ impl> LogCollector { hardfork: ChainSpecT::Hardfork, block_result: &DebugMineBlockResult>, transaction: &ChainSpecT::Transaction, - transaction_result: &ExecutionResult, - trace: &Trace, + transaction_result: &ExecutionResult, + trace: &Trace, ) -> Result<(), LoggerError> { self.indented(|logger| { logger.log("Currently sent transaction:"); @@ -1051,8 +1051,8 @@ impl> LogCollector { hardfork: ChainSpecT::Hardfork, block_result: &DebugMineBlockResult>, transaction: &ChainSpecT::Transaction, - transaction_result: &ExecutionResult, - trace: &Trace, + transaction_result: &ExecutionResult, + trace: &Trace, ) -> Result<(), LoggerError> { self.indented(|logger| { logger.log_contract_and_function_name::(hardfork, trace); @@ -1079,11 +1079,12 @@ impl> LogCollector { logger.log_console_log_messages(&block_result.console_log_inputs)?; - let transaction_failure = - edr_provider::TransactionFailure::::from_execution_result::< - ChainSpecT, - CurrentTime, - >(transaction_result, Some(transaction_hash), trace); + let transaction_failure = edr_provider::TransactionFailure::from_execution_result::< + ChainSpecT, + CurrentTime, + >( + transaction_result, Some(transaction_hash), trace + ); if let Some(transaction_failure) = transaction_failure { logger.log_transaction_failure(&transaction_failure); diff --git a/crates/edr_napi_core/src/provider.rs b/crates/edr_napi_core/src/provider.rs index 495bf2a4a..22969e6c9 100644 --- a/crates/edr_napi_core/src/provider.rs +++ b/crates/edr_napi_core/src/provider.rs @@ -4,7 +4,7 @@ mod factory; use std::{str::FromStr as _, sync::Arc}; -use edr_generic::GenericChainSpec; +use edr_eth::result::HaltReason; use edr_provider::{InvalidRequestReason, SyncCallOverride}; use edr_rpc_client::jsonrpc; @@ -19,7 +19,7 @@ use crate::spec::{Response, SyncNapiSpec}; /// objects. pub trait SyncProvider: Send + Sync { /// Blocking method to handle a request. - fn handle_request(&self, request: String) -> napi::Result>; + fn handle_request(&self, request: String) -> napi::Result>; /// Set to `true` to make the traces returned with `eth_call`, /// `eth_estimateGas`, `eth_sendRawTransaction`, `eth_sendTransaction`, @@ -32,7 +32,7 @@ pub trait SyncProvider: Send + Sync { } impl SyncProvider for edr_provider::Provider { - fn handle_request(&self, request: String) -> napi::Result> { + fn handle_request(&self, request: String) -> napi::Result> { let request = match serde_json::from_str(&request) { Ok(request) => request, Err(error) => { diff --git a/crates/edr_napi_core/src/provider/config.rs b/crates/edr_napi_core/src/provider/config.rs index 3b332ff0d..a72298ae8 100644 --- a/crates/edr_napi_core/src/provider/config.rs +++ b/crates/edr_napi_core/src/provider/config.rs @@ -5,7 +5,7 @@ use edr_eth::{block::BlobGas, AccountInfo, Address, ChainId, HashMap, B256, U256 use edr_provider::{ hardfork::{Activations, ForkCondition}, hardhat_rpc_types::ForkConfig, - spec::ChainSpec, + spec::RuntimeSpec, AccountConfig, MiningConfig, }; use serde::{Deserialize, Serialize}; @@ -49,7 +49,7 @@ pub struct Config { impl From for edr_provider::ProviderConfig where - ChainSpecT: ChainSpec From<&'s str>>, + ChainSpecT: RuntimeSpec From<&'s str>>, { fn from(value: Config) -> Self { let cache_dir = PathBuf::from( diff --git a/crates/edr_napi_core/src/spec.rs b/crates/edr_napi_core/src/spec.rs index 1b1eb8cfb..a8adbf6a6 100644 --- a/crates/edr_napi_core/src/spec.rs +++ b/crates/edr_napi_core/src/spec.rs @@ -1,8 +1,8 @@ use std::sync::Arc; use edr_eth::{ - chain_spec::L1ChainSpec, - result::InvalidTransaction, + result::{HaltReason, InvalidTransaction}, + spec::{HaltReasonTrait, L1ChainSpec}, transaction::{IsEip155, IsEip4844, TransactionMut, TransactionType, TransactionValidation}, }; use edr_evm::trace::Trace; @@ -13,7 +13,7 @@ use napi::{Either, Status}; pub type ResponseData = Either; -pub struct Response { +pub struct Response { // N-API is known to be slow when marshalling `serde_json::Value`s, so we try to return a // `String`. If the object is too large to be represented as a `String`, we return a `Buffer` // instead. @@ -22,14 +22,14 @@ pub struct Response { /// transaction. /// /// Only present for L1 Ethereum chains. - pub solidity_trace: Option>>, + pub solidity_trace: Option>>, /// This may contain zero or more traces, depending on the (batch) request /// /// Always empty for non-L1 Ethereum chains. - pub traces: Vec>>, + pub traces: Vec>>, } -impl From for Response { +impl From for Response { fn from(value: String) -> Self { Response { solidity_trace: None, @@ -59,22 +59,50 @@ pub trait SyncNapiSpec: /// This is implemented as an associated function to avoid problems when /// implementing type conversions for third-party types. fn cast_response( - response: Result, ProviderError>, - ) -> napi::Result>; + response: Result, ProviderError>, + ) -> napi::Result>; } impl SyncNapiSpec for L1ChainSpec { const CHAIN_TYPE: &'static str = "L1"; fn cast_response( - response: Result, ProviderError>, - ) -> napi::Result> { + mut response: Result, ProviderError>, + ) -> napi::Result> { + // We can take the solidity trace as it won't be used for anything else + let solidity_trace: Option>> = + response.as_mut().err().and_then(|error| { + if let edr_provider::ProviderError::TransactionFailed(failure) = error { + if matches!( + failure.failure.reason, + edr_provider::TransactionFailureReason::OutOfGas(_) + ) { + None + } else { + Some(Arc::new(std::mem::take( + &mut failure.failure.solidity_trace, + ))) + } + } else { + None + } + }); + + // We can take the traces as they won't be used for anything else + let traces = match &mut response { + Ok(response) => std::mem::take(&mut response.traces), + Err(edr_provider::ProviderError::TransactionFailed(failure)) => { + std::mem::take(&mut failure.traces) + } + Err(_) => Vec::new(), + }; + let response = jsonrpc::ResponseData::from(response.map(|response| response.result)); marshal_response_data(response).map(|data| Response { - solidity_trace: None, + solidity_trace, data, - traces: Vec::new(), + traces: traces.into_iter().map(Arc::new).collect(), }) } } @@ -83,8 +111,8 @@ impl SyncNapiSpec for GenericChainSpec { const CHAIN_TYPE: &'static str = "generic"; fn cast_response( - mut response: Result, ProviderError>, - ) -> napi::Result> { + mut response: Result, ProviderError>, + ) -> napi::Result> { // We can take the solidity trace as it won't be used for anything else let solidity_trace = response.as_mut().err().and_then(|error| { if let edr_provider::ProviderError::TransactionFailed(failure) = error { diff --git a/crates/edr_napi_core/src/subscription.rs b/crates/edr_napi_core/src/subscription.rs index a695ec6f7..d8afe92c8 100644 --- a/crates/edr_napi_core/src/subscription.rs +++ b/crates/edr_napi_core/src/subscription.rs @@ -9,7 +9,7 @@ use napi::{ }; #[derive_where(Clone)] -pub struct Callback> { +pub struct Callback + 'static> { inner: ThreadsafeFunction, ErrorStrategy::Fatal>, } diff --git a/crates/edr_optimism/Cargo.toml b/crates/edr_optimism/Cargo.toml index 8462e34ec..3e5eb58eb 100644 --- a/crates/edr_optimism/Cargo.toml +++ b/crates/edr_optimism/Cargo.toml @@ -4,9 +4,9 @@ version = "0.3.5" edition = "2021" [dependencies] -alloy-eips = { version = "0.2", default-features = false } +alloy-eips = { version = "0.3", default-features = false } alloy-rlp = { version = "0.3", default-features = false, features = ["derive"] } -alloy-serde = { version = "0.2.0", default-features = false, features = ["std"] } +alloy-serde = { version = "0.3.5", default-features = false, features = ["std"] } edr_eth = { path = "../edr_eth", features = ["serde", "std"] } edr_evm = { path = "../edr_evm" } edr_generic = { path = "../edr_generic" } @@ -14,13 +14,14 @@ edr_napi_core = { path = "../edr_napi_core" } edr_provider = { path = "../edr_provider" } edr_rpc_eth = { path = "../edr_rpc_eth" } log = { version = "0.4.17", default-features = false } -revm = { git = "https://github.com/Wodann/revm", rev = "a500675", version = "12.1", default-features = false, features = ["c-kzg", "dev", "optimism", "serde", "std"] } +revm = { git = "https://github.com/Wodann/revm", rev = "f260074", version = "14.0", default-features = false, features = ["c-kzg", "dev", "serde", "std"] } +revm-optimism = { git = "https://github.com/Wodann/revm", rev = "f260074", version = "1.0", default-features = false, features = ["c-kzg", "dev", "serde", "std"] } serde = { version = "1.0.209", default-features = false, features = ["derive", "std"] } thiserror = { version = "1.0.37", default-features = false } tokio = { version = "1.21.2", default-features = false, features = ["macros", "rt-multi-thread", "sync"] } [dev-dependencies] -anyhow = "1.0.75" +anyhow = "1.0.89" edr_defaults = { path = "../edr_defaults" } edr_evm = { path = "../edr_evm", features = ["test-utils"] } edr_rpc_eth = { path = "../edr_rpc_eth", features = ["test-utils"] } diff --git a/crates/edr_optimism/src/hardfork.rs b/crates/edr_optimism/src/hardfork.rs index 8db816ce5..951fbe2d9 100644 --- a/crates/edr_optimism/src/hardfork.rs +++ b/crates/edr_optimism/src/hardfork.rs @@ -2,9 +2,8 @@ use std::sync::OnceLock; use edr_eth::HashMap; use edr_evm::hardfork::{Activations, ChainConfig, ForkCondition}; -use revm::optimism::OptimismSpecId; -use crate::OptimismChainSpec; +use crate::{OptimismChainSpec, OptimismSpecId}; const MAINNET_HARDFORKS: &[(ForkCondition, OptimismSpecId)] = &[ (ForkCondition::Block(0), OptimismSpecId::FRONTIER), diff --git a/crates/edr_optimism/src/lib.rs b/crates/edr_optimism/src/lib.rs index 904b98949..123001d14 100644 --- a/crates/edr_optimism/src/lib.rs +++ b/crates/edr_optimism/src/lib.rs @@ -19,3 +19,5 @@ pub use self::spec::OptimismChainSpec; /// Optimism transaction types pub mod transaction; + +pub use revm_optimism::OptimismSpecId; diff --git a/crates/edr_optimism/src/receipt/execution.rs b/crates/edr_optimism/src/receipt/execution.rs index ffd590efd..d242ff2c2 100644 --- a/crates/edr_optimism/src/receipt/execution.rs +++ b/crates/edr_optimism/src/receipt/execution.rs @@ -7,11 +7,15 @@ use edr_eth::{ transaction::TransactionType as _, Bloom, }; -use revm::{db::StateRef, optimism::OptimismSpecId, primitives::Transaction as _}; +use revm::{ + db::StateRef, + primitives::{ExecutionResult, Transaction as _}, +}; +use revm_optimism::{OptimismHaltReason, OptimismSpecId}; use self::deposit::Eip658OrDeposit; use super::Execution; -use crate::{eip2718::TypedEnvelope, transaction, OptimismChainSpec}; +use crate::{eip2718::TypedEnvelope, transaction}; /// Receipt for an Optimism deposit transaction with deposit nonce (since /// Regolith) and optionally deposit receipt version (since Canyon). @@ -106,7 +110,7 @@ pub struct Builder { deposit_nonce: u64, } -impl ExecutionReceiptBuilder for Builder { +impl ExecutionReceiptBuilder for Builder { type Receipt = TypedEnvelope>; fn new_receipt_builder( @@ -123,9 +127,9 @@ impl ExecutionReceiptBuilder for Builder { fn build_receipt( self, header: &edr_eth::block::PartialHeader, - transaction: &::Transaction, - result: &revm::primitives::ExecutionResult, - hardfork: ::Hardfork, + transaction: &transaction::Signed, + result: &ExecutionResult, + hardfork: OptimismSpecId, ) -> Self::Receipt { let logs = result.logs().to_vec(); let logs_bloom = edr_eth::log::logs_to_bloom(&logs); diff --git a/crates/edr_optimism/src/rpc.rs b/crates/edr_optimism/src/rpc.rs index 3e100dc6b..5f7c706cb 100644 --- a/crates/edr_optimism/src/rpc.rs +++ b/crates/edr_optimism/src/rpc.rs @@ -3,7 +3,7 @@ pub mod receipt; /// Types for Optimism RPC transaction. pub mod transaction; -use edr_eth::{env::SignedAuthorization, log::FilterLog, Address, Bloom, B256, U256}; +use edr_eth::{log::FilterLog, Address, Bloom, SignedAuthorization, B256, U256}; use serde::{Deserialize, Serialize}; /// Transaction receipt diff --git a/crates/edr_optimism/src/rpc/receipt.rs b/crates/edr_optimism/src/rpc/receipt.rs index c5e23af1a..7114cf56c 100644 --- a/crates/edr_optimism/src/rpc/receipt.rs +++ b/crates/edr_optimism/src/rpc/receipt.rs @@ -6,7 +6,7 @@ use edr_eth::{ transaction::TransactionType as _, }; use edr_rpc_eth::RpcTypeFrom; -use revm::optimism::OptimismSpecId; +use revm_optimism::OptimismSpecId; use super::BlockReceipt; use crate::{eip2718::TypedEnvelope, receipt, transaction}; diff --git a/crates/edr_optimism/src/rpc/transaction.rs b/crates/edr_optimism/src/rpc/transaction.rs index 33f9a9657..89bffcf21 100644 --- a/crates/edr_optimism/src/rpc/transaction.rs +++ b/crates/edr_optimism/src/rpc/transaction.rs @@ -8,7 +8,7 @@ use edr_evm::{ use edr_rpc_eth::{ RpcTypeFrom, TransactionConversionError as L1ConversionError, TransactionWithSignature, }; -use revm::optimism::{OptimismSpecId, OptimismTransaction}; +use revm_optimism::{OptimismSpecId, OptimismTransaction}; use super::Transaction; use crate::{transaction, OptimismChainSpec}; diff --git a/crates/edr_optimism/src/spec.rs b/crates/edr_optimism/src/spec.rs index 6c36283ad..608fe9f3b 100644 --- a/crates/edr_optimism/src/spec.rs +++ b/crates/edr_optimism/src/spec.rs @@ -1,29 +1,24 @@ +use std::marker::PhantomData; + use alloy_rlp::RlpEncodable; use edr_eth::{ - block::{self, BlobGas, PartialHeader}, - chain_spec::EthHeaderConstants, eips::eip1559::{BaseFeeParams, ConstantBaseFeeParams, ForkBaseFeeParams}, - env::{BlobExcessGasAndPrice, BlockEnv}, result::{HaltReason, InvalidTransaction}, - U256, + spec::EthHeaderConstants, }; use edr_evm::{ - chain_spec::{BlockEnvConstructor, ChainSpec}, + spec::RuntimeSpec, transaction::{TransactionError, TransactionValidation}, RemoteBlockConversionError, }; -use edr_generic::GenericChainSpec; use edr_napi_core::{ napi, spec::{marshal_response_data, Response, SyncNapiSpec}, }; use edr_provider::{time::TimeSinceEpoch, ProviderSpec, TransactionFailureReason}; use edr_rpc_eth::{jsonrpc, spec::RpcSpec}; -use revm::{ - handler::register::HandleRegisters, - optimism::{OptimismHaltReason, OptimismInvalidTransaction, OptimismSpecId}, - EvmHandler, -}; +use revm::{handler::register::HandleRegisters, primitives::ChainSpec, Database, EvmHandler}; +use revm_optimism::{OptimismHaltReason, OptimismInvalidTransaction, OptimismSpecId}; use serde::{de::DeserializeOwned, Serialize}; use crate::{eip2718::TypedEnvelope, hardfork, receipt, rpc, transaction}; @@ -41,75 +36,54 @@ impl RpcSpec for OptimismChainSpec { type RpcTransactionRequest = edr_rpc_eth::TransactionRequest; } -impl revm::primitives::EvmWiring for OptimismChainSpec { +impl revm::primitives::ChainSpec for OptimismChainSpec { + type ChainContext = revm_optimism::Context; type Block = edr_eth::env::BlockEnv; type Transaction = transaction::Signed; type Hardfork = OptimismSpecId; type HaltReason = OptimismHaltReason; } -impl revm::EvmWiring for OptimismChainSpec { - type Context = revm::optimism::Context; +/// EVM wiring for Optimism chains. +pub struct Wiring { + _phantom: PhantomData<(ChainSpecT, DatabaseT, ExternalContextT)>, +} - fn handler<'evm, EXT, DB>(hardfork: Self::Hardfork) -> EvmHandler<'evm, Self, EXT, DB> - where - DB: revm::Database, - { +impl edr_eth::spec::EvmWiring + for Wiring +where + DatabaseT: Database, + ChainSpecT: ChainSpec + revm_optimism::OptimismChainSpec, +{ + type ChainSpec = ChainSpecT; + type ExternalContext = ExternalContextT; + type Database = DatabaseT; +} + +impl revm::EvmWiring + for Wiring +where + ChainSpecT: revm_optimism::OptimismChainSpec, + DatabaseT: Database, +{ + fn handler<'evm>( + hardfork: ::Hardfork, + ) -> revm::EvmHandler<'evm, Self> { let mut handler = EvmHandler::mainnet_with_spec(hardfork); handler.append_handler_register(HandleRegisters::Plain( - revm::optimism::optimism_handle_register::, + revm_optimism::optimism_handle_register::< + Wiring, + >, )); handler } } -impl BlockEnvConstructor for revm::primitives::BlockEnv { - fn new_block_env(header: &PartialHeader, hardfork: OptimismSpecId) -> Self { - BlockEnv { - number: U256::from(header.number), - coinbase: header.beneficiary, - timestamp: U256::from(header.timestamp), - difficulty: header.difficulty, - basefee: header.base_fee.unwrap_or(U256::ZERO), - gas_limit: U256::from(header.gas_limit), - prevrandao: if hardfork >= OptimismSpecId::MERGE { - Some(header.mix_hash) - } else { - None - }, - blob_excess_gas_and_price: header - .blob_gas - .as_ref() - .map(|BlobGas { excess_gas, .. }| BlobExcessGasAndPrice::new(*excess_gas)), - } - } -} - -impl BlockEnvConstructor for revm::primitives::BlockEnv { - fn new_block_env(header: &block::Header, hardfork: OptimismSpecId) -> Self { - BlockEnv { - number: U256::from(header.number), - coinbase: header.beneficiary, - timestamp: U256::from(header.timestamp), - difficulty: header.difficulty, - basefee: header.base_fee_per_gas.unwrap_or(U256::ZERO), - gas_limit: U256::from(header.gas_limit), - prevrandao: if hardfork >= OptimismSpecId::MERGE { - Some(header.mix_hash) - } else { - None - }, - blob_excess_gas_and_price: header - .blob_gas - .as_ref() - .map(|BlobGas { excess_gas, .. }| BlobExcessGasAndPrice::new(*excess_gas)), - } - } -} +impl RuntimeSpec for OptimismChainSpec { + type EvmWiring = Wiring; -impl ChainSpec for OptimismChainSpec { type ReceiptBuilder = receipt::execution::Builder; type RpcBlockConversionError = RemoteBlockConversionError; type RpcReceiptConversionError = rpc::receipt::ConversionError; @@ -139,7 +113,7 @@ impl ChainSpec for OptimismChainSpec { } impl EthHeaderConstants for OptimismChainSpec { - const BASE_FEE_PARAMS: BaseFeeParams = + const BASE_FEE_PARAMS: BaseFeeParams = BaseFeeParams::Variable(ForkBaseFeeParams::new(&[ (OptimismSpecId::LONDON, ConstantBaseFeeParams::new(50, 6)), (OptimismSpecId::CANYON, ConstantBaseFeeParams::new(250, 6)), @@ -152,8 +126,11 @@ impl SyncNapiSpec for OptimismChainSpec { const CHAIN_TYPE: &'static str = "Optimism"; fn cast_response( - response: Result, edr_provider::ProviderError>, - ) -> napi::Result> { + response: Result< + edr_provider::ResponseWithTraces, + edr_provider::ProviderError, + >, + ) -> napi::Result> { let response = jsonrpc::ResponseData::from(response.map(|response| response.result)); marshal_response_data(response).map(|data| Response { @@ -168,7 +145,9 @@ impl ProviderSpec for OptimismChainSpec type PooledTransaction = transaction::Pooled; type TransactionRequest = transaction::Request; - fn cast_halt_reason(reason: OptimismHaltReason) -> TransactionFailureReason { + fn cast_halt_reason( + reason: OptimismHaltReason, + ) -> TransactionFailureReason { match reason { OptimismHaltReason::Base(reason) => match reason { HaltReason::CreateContractSizeLimit => { diff --git a/crates/edr_optimism/src/transaction/pooled.rs b/crates/edr_optimism/src/transaction/pooled.rs index 23eacc0c2..64ccbdd7c 100644 --- a/crates/edr_optimism/src/transaction/pooled.rs +++ b/crates/edr_optimism/src/transaction/pooled.rs @@ -1,9 +1,8 @@ pub use edr_eth::transaction::pooled::{Eip155, Eip1559, Eip2930, Eip4844, Legacy}; use edr_eth::{ - env::AuthorizationList, transaction::{ - signed::PreOrPostEip155, ExecutableTransaction, IsEip155, Transaction, TxKind, - INVALID_TX_TYPE_ERROR_MESSAGE, + signed::PreOrPostEip155, AuthorizationList, ExecutableTransaction, IsEip155, Transaction, + TxKind, INVALID_TX_TYPE_ERROR_MESSAGE, }, utils::enveloped, AccessListItem, Address, Blob, Bytes, B256, U256, diff --git a/crates/edr_optimism/src/transaction/signed.rs b/crates/edr_optimism/src/transaction/signed.rs index f7d982822..5a346047d 100644 --- a/crates/edr_optimism/src/transaction/signed.rs +++ b/crates/edr_optimism/src/transaction/signed.rs @@ -9,13 +9,13 @@ pub use edr_eth::transaction::signed::{Eip155, Eip1559, Eip2930, Eip4844, Legacy use edr_eth::{ signature::{Fakeable, Signature}, transaction::{ - ExecutableTransaction, HasAccessList, IsEip4844, IsLegacy, MaybeSignedTransaction, - Transaction, TransactionMut, TransactionType, TransactionValidation, TxKind, - INVALID_TX_TYPE_ERROR_MESSAGE, + AuthorizationList, ExecutableTransaction, HasAccessList, IsEip4844, IsLegacy, + MaybeSignedTransaction, Transaction, TransactionMut, TransactionType, + TransactionValidation, TxKind, INVALID_TX_TYPE_ERROR_MESSAGE, }, Address, Bytes, B256, U256, }; -use revm::optimism::{OptimismInvalidTransaction, OptimismTransaction}; +use revm_optimism::{OptimismInvalidTransaction, OptimismTransaction}; use super::Signed; @@ -417,7 +417,7 @@ impl Transaction for Signed { } } - fn authorization_list(&self) -> Option<&edr_eth::env::AuthorizationList> { + fn authorization_list(&self) -> Option<&AuthorizationList> { match self { Signed::PreEip155Legacy(tx) => tx.authorization_list(), Signed::PostEip155Legacy(tx) => tx.authorization_list(), diff --git a/crates/edr_optimism/src/transaction/signed/deposit.rs b/crates/edr_optimism/src/transaction/signed/deposit.rs index 0ffaf8287..28f1199b7 100644 --- a/crates/edr_optimism/src/transaction/signed/deposit.rs +++ b/crates/edr_optimism/src/transaction/signed/deposit.rs @@ -1,7 +1,6 @@ use alloy_rlp::Encodable; use edr_eth::{ - env::AuthorizationList, - transaction::{ExecutableTransaction, Transaction, TxKind}, + transaction::{AuthorizationList, ExecutableTransaction, Transaction, TxKind}, utils::enveloped, AccessListItem, Address, Bytes, B256, U256, }; diff --git a/crates/edr_provider/Cargo.toml b/crates/edr_provider/Cargo.toml index 1c472d134..a6a9ca5ff 100644 --- a/crates/edr_provider/Cargo.toml +++ b/crates/edr_provider/Cargo.toml @@ -4,14 +4,14 @@ version = "0.3.5" edition = "2021" [dependencies] -alloy-dyn-abi = { version = "0.7.6", features = ["eip712"] } -alloy-sol-types = { version = "0.5.1", default-features = false, features = ["std"] } -anyhow = { version = "1.0.75", optional = true } +alloy-dyn-abi = { version = "0.8.3", features = ["eip712"] } +alloy-sol-types = { version = "0.8.3", default-features = false, features = ["std"] } +anyhow = { version = "1.0.89", optional = true } auto_impl = { version = "1.2", default-features = false } derive-where = { version = "1.2.7", default-features = false } dyn-clone = { version = "1.0.13", default-features = false } edr_defaults = { version = "0.3.5", path = "../edr_defaults" } -edr_eth = { version = "0.3.5", path = "../edr_eth", features = ["rand"] } +edr_eth = { version = "0.3.5", path = "../edr_eth" } edr_evm = { version = "0.3.5", path = "../edr_evm", features = ["tracing"] } edr_rpc_eth = { version = "0.3.5", path = "../edr_rpc_eth" } indexmap = { version = "2.0.0", default-features = false, features = ["std"] } @@ -21,7 +21,7 @@ lazy_static = { version = "1.4.0", default-features = false } log = { version = "0.4.20", default-features = false } parking_lot = { version = "0.12.1", default-features = false } rand = { version = "0.8.5", default-features = false } -revm-precompile = { git = "https://github.com/Wodann/revm", rev = "a500675", version = "9.2", default-features = false, features = ["c-kzg", "secp256r1", "std"] } +revm-precompile = { git = "https://github.com/Wodann/revm", rev = "f260074", version = "11.0", default-features = false, features = ["c-kzg", "secp256r1", "std"] } rpds = { version = "1.1.0", default-features = false, features = ["std"] } serde = { version = "1.0.209", default-features = false, features = ["derive"] } serde_json = { version = "1.0.127" } @@ -32,7 +32,7 @@ tracing = { version = "0.1.37", features = ["attributes", "std"], optional = tru lru = "0.12.2" [dev-dependencies] -anyhow = "1.0.75" +anyhow = "1.0.89" edr_evm = { path = "../edr_evm", features = ["test-utils"] } edr_test_utils = { version = "0.3.5", path = "../edr_test_utils" } paste = { version = "1.0.14", default-features = false } diff --git a/crates/edr_provider/src/config.rs b/crates/edr_provider/src/config.rs index 29f173a26..d63b2c612 100644 --- a/crates/edr_provider/src/config.rs +++ b/crates/edr_provider/src/config.rs @@ -2,7 +2,7 @@ use std::{num::NonZeroU64, path::PathBuf, time::SystemTime}; use derive_where::derive_where; use edr_eth::{block::BlobGas, AccountInfo, Address, ChainId, HashMap, B256, U256}; -use edr_evm::{chain_spec::ChainSpec, hardfork, MineOrdering}; +use edr_evm::{hardfork, spec::RuntimeSpec, MineOrdering}; use rand::Rng; use serde::{de::DeserializeOwned, Deserialize, Serialize}; @@ -76,7 +76,7 @@ pub struct MiningConfig { deserialize = "ChainSpecT::Hardfork: DeserializeOwned", serialize = "ChainSpecT::Hardfork: Serialize" ))] -pub struct ProviderConfig { +pub struct ProviderConfig { pub allow_blocks_with_same_timestamp: bool, pub allow_unlimited_contract_size: bool, pub accounts: Vec, diff --git a/crates/edr_provider/src/console_log.rs b/crates/edr_provider/src/console_log.rs index ad1b08caa..3a0ef8300 100644 --- a/crates/edr_provider/src/console_log.rs +++ b/crates/edr_provider/src/console_log.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use edr_eth::{address, db::Database, result::EVMErrorForChain, Address, Bytes}; +use edr_eth::{address, result::EVMErrorWiring, Address, Bytes}; use edr_evm::{ evm::{handler::register::EvmHandler, FrameOrResult}, GetContextData, @@ -9,18 +9,13 @@ use edr_evm::{ const CONSOLE_ADDRESS: Address = address!("000000000000000000636F6e736F6c652e6c6f67"); /// Registers the `ConsoleLogCollector`'s handles. -pub fn register_console_log_handles< - ChainSpecT: edr_evm::chain_spec::EvmWiring, - DatabaseT: Database, - ContextT: GetContextData, ->( - handler: &mut EvmHandler<'_, ChainSpecT, ContextT, DatabaseT>, -) { +pub fn register_console_log_handles(handler: &mut EvmHandler<'_, EvmWiringT>) +where + EvmWiringT: edr_evm::spec::EvmWiring>, +{ let old_handle = handler.execution.call.clone(); handler.execution.call = Arc::new( - move |ctx, - inputs| - -> Result> { + move |ctx, inputs| -> Result> { if inputs.bytecode_address == CONSOLE_ADDRESS { let collector = ctx.external.get_context_data(); collector.record_console_log(inputs.input.clone()); @@ -51,8 +46,8 @@ impl ConsoleLogCollector { pub(crate) mod tests { use anyhow::Context; use edr_eth::{ - chain_spec::L1ChainSpec, hex, + spec::L1ChainSpec, transaction::{self, request::TransactionRequestAndSender, TxKind}, Bytes, U256, }; diff --git a/crates/edr_provider/src/data.rs b/crates/edr_provider/src/data.rs index d49ce7158..434b4bc00 100644 --- a/crates/edr_provider/src/data.rs +++ b/crates/edr_provider/src/data.rs @@ -27,6 +27,7 @@ use edr_eth::{ result::{ExecutionResult, InvalidTransaction}, reward_percentile::RewardPercentile, signature::{self, RecoveryMessage}, + spec::{ChainSpec, HaltReasonTrait}, state::{Account, EvmStorageSlot}, transaction::{ request::TransactionRequestAndSender, @@ -43,11 +44,9 @@ use edr_evm::{ Blockchain, BlockchainError, ForkedBlockchain, ForkedCreationError, GenesisBlockOptions, LocalBlockchain, LocalCreationError, SyncBlockchain, }, - chain_spec::{BlockEnvConstructor as _, ChainSpec, SyncChainSpec}, - debug_trace_transaction, - evm::handler::CfgEnvWithEvmWiring, - execution_result_to_debug_result, mempool, mine_block, mine_block_with_single_transaction, - register_eip_3155_and_raw_tracers_handles, + debug_trace_transaction, execution_result_to_debug_result, mempool, mine_block, + mine_block_with_single_transaction, register_eip_3155_and_raw_tracers_handles, + spec::{BlockEnvConstructor as _, RuntimeSpec, SyncRuntimeSpec}, state::{ AccountModifierFn, IrregularState, StateDiff, StateError, StateOverride, StateOverrides, SyncState, @@ -96,28 +95,32 @@ const DEFAULT_MAX_CACHED_STATES: usize = 100_000; /// The result of executing an `eth_call`. #[derive(Clone, Debug)] -pub struct CallResult { +pub struct CallResult { pub console_log_inputs: Vec, - pub execution_result: ExecutionResult, - pub trace: Trace, + pub execution_result: ExecutionResult, + pub trace: Trace, } #[derive(Clone)] -pub struct EstimateGasResult { +pub struct EstimateGasResult { pub estimation: u64, - pub traces: Vec>, + pub traces: Vec>, } -pub struct SendTransactionResult { +pub struct SendTransactionResult { pub transaction_hash: B256, pub mining_results: Vec>>, } -impl SendTransactionResult { +/// The result of executing a transaction. +pub type ExecutionResultAndTrace<'provider, ChainSpecT> = ( + &'provider ExecutionResult<::HaltReason>, + &'provider Trace<::HaltReason>, +); + +impl SendTransactionResult { /// Present if the transaction was auto-mined. - pub fn transaction_result_and_trace( - &self, - ) -> Option<(&ExecutionResult, &Trace)> { + pub fn transaction_result_and_trace(&self) -> Option> { self.mining_results.iter().find_map(|result| { izip!( result.block.transactions().iter(), @@ -135,8 +138,8 @@ impl SendTransactionResult { } } -impl From> - for (B256, Vec>) +impl From> + for (B256, Vec>) { fn from(value: SendTransactionResult) -> Self { let SendTransactionResult { @@ -156,7 +159,7 @@ impl From> #[derive(Debug, thiserror::Error)] pub enum CreationError where - ChainSpecT: ChainSpec, + ChainSpecT: RuntimeSpec, { /// A blockchain error #[error(transparent)] @@ -1216,11 +1219,7 @@ where } /// Creates an EVM configuration with the provided hardfork and chain id - fn create_evm_config( - &self, - hardfork: ChainSpecT::Hardfork, - chain_id: u64, - ) -> Result, ProviderError> { + fn create_evm_config(&self, chain_id: u64) -> CfgEnv { let mut cfg_env = CfgEnv::default(); cfg_env.chain_id = chain_id; cfg_env.limit_contract_code_size = if self.allow_unlimited_contract_size { @@ -1230,7 +1229,7 @@ where }; cfg_env.disable_eip3607 = true; - Ok(CfgEnvWithEvmWiring::::new(cfg_env, hardfork)) + cfg_env } /// Creates a configuration, taking into account the hardfork at the @@ -1238,7 +1237,7 @@ where fn create_evm_config_at_block_spec( &self, block_spec: &BlockSpec, - ) -> Result, ProviderError> { + ) -> Result<(CfgEnv, ChainSpecT::Hardfork), ProviderError> { let block_number = self.block_number_by_block_spec(block_spec)?; let spec_id = if let Some(block_number) = block_number { @@ -1253,7 +1252,8 @@ where self.blockchain.chain_id() }; - self.create_evm_config(spec_id, chain_id) + let cfg = self.create_evm_config(chain_id); + Ok((cfg, spec_id)) } fn current_state( @@ -1291,9 +1291,10 @@ where &mut self, mine_fn: impl FnOnce( &mut ProviderData, - &CfgEnvWithEvmWiring, + &CfgEnv, + ChainSpecT::Hardfork, BlockOptions, - &mut Debugger, + &mut Debugger, ) -> Result< MineBlockResultAndState, ProviderError, @@ -1351,9 +1352,10 @@ where &mut self, mine_fn: impl FnOnce( &mut ProviderData, - &CfgEnvWithEvmWiring, + &CfgEnv, + ChainSpecT::Hardfork, BlockOptions, - &mut Debugger, + &mut Debugger, ) -> Result< MineBlockResultAndState, ProviderError, @@ -1365,14 +1367,15 @@ where options.beneficiary = Some(options.beneficiary.unwrap_or(self.beneficiary)); options.gas_limit = Some(options.gas_limit.unwrap_or_else(|| self.block_gas_limit())); - let evm_config = - self.create_evm_config(self.blockchain.spec_id(), self.blockchain.chain_id())?; + let evm_config = self.create_evm_config(self.blockchain.chain_id()); + let hardfork = self.blockchain.spec_id(); - if options.mix_hash.is_none() && evm_config.spec_id.into() >= SpecId::MERGE { + let evm_spec_id = hardfork.into(); + if options.mix_hash.is_none() && evm_spec_id >= SpecId::MERGE { options.mix_hash = Some(self.prev_randao_generator.next_value()); } - if evm_config.spec_id.into() >= SpecId::CANCUN { + if evm_spec_id >= SpecId::CANCUN { options.parent_beacon_block_root = options .parent_beacon_block_root .or_else(|| Some(self.parent_beacon_block_root_generator.next_value())); @@ -1383,7 +1386,7 @@ where self.verbose_tracing, ); - let result = mine_fn(self, &evm_config, options, &mut debugger)?; + let result = mine_fn(self, &evm_config, hardfork, options, &mut debugger)?; let Debugger { console_logger, @@ -1695,8 +1698,8 @@ where transaction: ChainSpecT::Transaction, block_spec: &BlockSpec, trace_config: DebugTraceConfig, - ) -> Result, ProviderError> { - let cfg_env = self.create_evm_config_at_block_spec(block_spec)?; + ) -> Result, ProviderError> { + let (cfg_env, hardfork) = self.create_evm_config_at_block_spec(block_spec)?; let mut tracer = Eip3155AndRawTracers::new(trace_config, self.verbose_tracing); let precompiles = self.custom_precompiles.clone(); @@ -1707,7 +1710,8 @@ where header: block.header(), state, state_overrides: &StateOverrides::default(), - cfg_env: cfg_env.clone(), + cfg_env, + hardfork, transaction, precompiles: &precompiles, debug_context: Some(DebugContext { @@ -2102,8 +2106,8 @@ where transaction: ChainSpecT::Transaction, block_spec: &BlockSpec, state_overrides: &StateOverrides, - ) -> Result, ProviderError> { - let cfg_env = self.create_evm_config_at_block_spec(block_spec)?; + ) -> Result, ProviderError> { + let (cfg_env, hardfork) = self.create_evm_config_at_block_spec(block_spec)?; let mut debugger = Debugger::with_mocker( Mocker::new(self.call_override.clone()), @@ -2118,6 +2122,7 @@ where state, state_overrides, cfg_env, + hardfork, transaction, precompiles: &precompiles, debug_context: Some(DebugContext { @@ -2183,9 +2188,10 @@ where fn mine_block_with_mem_pool( &mut self, - config: &CfgEnvWithEvmWiring, + config: &CfgEnv, + hardfork: ChainSpecT::Hardfork, options: BlockOptions, - debugger: &mut Debugger, + debugger: &mut Debugger, ) -> Result, ProviderError> { let state_to_be_modified = (*self.current_state()?).clone(); let result = mine_block( @@ -2193,10 +2199,11 @@ where state_to_be_modified, &self.mem_pool, config, + hardfork, options, self.min_gas_price, self.initial_config.mining.mem_pool.order, - miner_reward(config.spec_id.into()).unwrap_or(U256::ZERO), + miner_reward(hardfork.into()).unwrap_or(U256::ZERO), Some(DebugContext { data: debugger, register_handles_fn: register_debugger_handles, @@ -2209,10 +2216,11 @@ where /// Mines a block with the provided transaction. fn mine_block_with_single_transaction( &mut self, - config: &CfgEnvWithEvmWiring, + config: &CfgEnv, + hardfork: ChainSpecT::Hardfork, options: BlockOptions, transaction: ChainSpecT::Transaction, - debugger: &mut Debugger, + debugger: &mut Debugger, ) -> Result, ProviderError> { let state_to_be_modified = (*self.current_state()?).clone(); let result = mine_block_with_single_transaction( @@ -2220,9 +2228,10 @@ where state_to_be_modified, transaction, config, + hardfork, options, self.min_gas_price, - miner_reward(config.spec_id.into()).unwrap_or(U256::ZERO), + miner_reward(hardfork.into()).unwrap_or(U256::ZERO), Some(DebugContext { data: debugger, register_handles_fn: register_debugger_handles, @@ -2262,9 +2271,10 @@ where self.notify_subscribers_about_pending_transaction(&transaction_hash); let result = self.mine_and_commit_block_impl( - move |provider, config, options, debugger| { + move |provider, config, hardfork, options, debugger| { provider.mine_block_with_single_transaction( config, + hardfork, options, transaction, debugger, @@ -2287,13 +2297,13 @@ where None }; - let transaction_hash = self.add_pending_transaction(transaction).map_err(|error| { - if let Some(snapshot_id) = snapshot_id { - self.revert_to_snapshot(snapshot_id); - } - - error - })?; + let transaction_hash = self + .add_pending_transaction(transaction) + .inspect_err(|_error| { + if let Some(snapshot_id) = snapshot_id { + self.revert_to_snapshot(snapshot_id); + } + })?; let mut mining_results = Vec::new(); snapshot_id @@ -2301,10 +2311,8 @@ where loop { let result = self .mine_and_commit_block(BlockOptions::default()) - .map_err(|error| { + .inspect_err(|_error| { self.revert_to_snapshot(snapshot_id); - - error })?; let mined_transaction = result.has_transaction(&transaction_hash); @@ -2319,10 +2327,8 @@ where while self.mem_pool.has_pending_transactions() { let result = self .mine_and_commit_block(BlockOptions::default()) - .map_err(|error| { + .inspect_err(|_error| { self.revert_to_snapshot(snapshot_id); - - error })?; mining_results.push(result); @@ -2359,7 +2365,7 @@ where &mut self, transaction_hash: &B256, trace_config: DebugTraceConfig, - ) -> Result, ProviderError> { + ) -> Result, ProviderError> { let block = self .blockchain .block_by_transaction_hash(transaction_hash)? @@ -2367,7 +2373,8 @@ where let header = block.header(); - let cfg_env = self.create_evm_config_at_block_spec(&BlockSpec::Number(header.number))?; + let (cfg_env, hardfork) = + self.create_evm_config_at_block_spec(&BlockSpec::Number(header.number))?; let transactions = block.transactions().to_vec(); @@ -2378,12 +2385,13 @@ where self.execute_in_block_context( prev_block_spec.as_ref(), |blockchain, _prev_block, state| { - let block_env = ChainSpecT::Block::new_block_env(header, cfg_env.spec_id); + let block_env = ChainSpecT::Block::new_block_env(header, hardfork.into()); debug_trace_transaction( blockchain, state.clone(), cfg_env, + hardfork, trace_config, block_env, transactions, @@ -2415,8 +2423,8 @@ where &mut self, transaction: ChainSpecT::Transaction, block_spec: &BlockSpec, - ) -> Result, ProviderError> { - let cfg_env = self.create_evm_config_at_block_spec(block_spec)?; + ) -> Result, ProviderError> { + let (cfg_env, hardfork) = self.create_evm_config_at_block_spec(block_spec)?; // Minimum gas cost that is required for transaction to be included in // a block let minimum_cost = transaction::initial_cost(&transaction, self.evm_spec_id()); @@ -2441,6 +2449,7 @@ where state, state_overrides: &state_overrides, cfg_env: cfg_env.clone(), + hardfork, transaction: transaction.clone(), precompiles: &precompiles, debug_context: Some(DebugContext { @@ -2496,6 +2505,7 @@ where state, state_overrides: &state_overrides, cfg_env: cfg_env.clone(), + hardfork, transaction: transaction.clone(), gas_limit: initial_estimation, precompiles: &precompiles, @@ -2519,6 +2529,7 @@ where state, state_overrides: &state_overrides, cfg_env: cfg_env.clone(), + hardfork, transaction, lower_bound: initial_estimation, upper_bound: header.gas_limit, @@ -2544,7 +2555,7 @@ impl StateId { } } -fn block_time_offset_seconds>( +fn block_time_offset_seconds>( config: &ProviderConfig, timer: &impl TimeSinceEpoch, ) -> Result> { @@ -2564,7 +2575,7 @@ fn block_time_offset_seconds>( }) } -struct BlockchainAndState { +struct BlockchainAndState { blockchain: Box, StateError>>, fork_metadata: Option, rpc_client: Option>>, @@ -2575,7 +2586,7 @@ struct BlockchainAndState { next_block_base_fee_per_gas: Option, } -fn create_blockchain_and_state>( +fn create_blockchain_and_state>( runtime: runtime::Handle, config: &ProviderConfig, timer: &impl TimeSinceEpoch, @@ -2773,7 +2784,7 @@ fn create_blockchain_and_state>( pub(crate) mod test_utils { use anyhow::anyhow; use edr_eth::{ - chain_spec::L1ChainSpec, + spec::L1ChainSpec, transaction::{self, TxKind}, }; @@ -2916,7 +2927,7 @@ pub(crate) mod test_utils { #[cfg(test)] mod tests { use anyhow::Context; - use edr_eth::{chain_spec::L1ChainSpec, hex, transaction::ExecutableTransaction as _}; + use edr_eth::{hex, spec::L1ChainSpec, transaction::ExecutableTransaction as _}; use edr_evm::MineOrdering; use serde_json::json; @@ -3883,6 +3894,7 @@ mod tests { #[cfg(feature = "test-remote")] mod alchemy { + use edr_eth::result::HaltReason; use edr_evm::impl_full_block_tests; use edr_test_utils::env::get_alchemy_url; @@ -3948,7 +3960,7 @@ mod tests { sol! { function Hello() public pure returns (string); } - fn assert_decoded_output(result: ExecutionResult) -> anyhow::Result<()> { + fn assert_decoded_output(result: ExecutionResult) -> anyhow::Result<()> { let output = result.into_output().expect("Call must have output"); let decoded = HelloCall::abi_decode_returns(output.as_ref(), false)?; @@ -3964,7 +3976,7 @@ mod tests { data: &mut ProviderData, block_spec: BlockSpec, request: CallRequest, - ) -> Result, ProviderError> { + ) -> Result, ProviderError> { let state_overrides = StateOverrides::default(); let transaction = diff --git a/crates/edr_provider/src/data/account.rs b/crates/edr_provider/src/data/account.rs index 2e11ac636..b4930687b 100644 --- a/crates/edr_provider/src/data/account.rs +++ b/crates/edr_provider/src/data/account.rs @@ -3,7 +3,7 @@ use edr_eth::{ state::{Account, AccountStatus}, AccountInfo, Address, HashMap, KECCAK_EMPTY, }; -use edr_evm::chain_spec::ChainSpec; +use edr_evm::spec::RuntimeSpec; use indexmap::IndexMap; use crate::{AccountConfig, ProviderConfig}; @@ -13,7 +13,7 @@ pub(super) struct InitialAccounts { pub genesis_accounts: HashMap, } -pub(super) fn create_accounts( +pub(super) fn create_accounts( config: &ProviderConfig, ) -> InitialAccounts { let mut local_accounts = IndexMap::default(); diff --git a/crates/edr_provider/src/data/call.rs b/crates/edr_provider/src/data/call.rs index fbf8b1474..9526dd1b1 100644 --- a/crates/edr_provider/src/data/call.rs +++ b/crates/edr_provider/src/data/call.rs @@ -2,30 +2,35 @@ use core::fmt::Debug; use edr_eth::{ block::Header, + env::CfgEnv, result::{ExecutionResult, InvalidTransaction}, transaction::TransactionValidation, Address, HashMap, Precompile, U256, }; use edr_evm::{ blockchain::{BlockchainError, SyncBlockchain}, - chain_spec::{BlockEnvConstructor as _, ChainSpec, SyncChainSpec}, - evm::handler::CfgEnvWithEvmWiring, guaranteed_dry_run, + spec::{BlockEnvConstructor as _, RuntimeSpec, SyncRuntimeSpec}, state::{StateError, StateOverrides, StateRefOverrider, SyncState}, DebugContext, }; use crate::ProviderError; -pub(super) struct RunCallArgs<'a, 'evm, ChainSpecT: ChainSpec, DebugDataT> -where +pub(super) struct RunCallArgs< + 'a, + 'evm, + ChainSpecT: RuntimeSpec>>, + DebugDataT, +> where 'a: 'evm, { pub blockchain: &'a dyn SyncBlockchain, StateError>, pub header: &'a Header, pub state: &'a dyn SyncState, pub state_overrides: &'a StateOverrides, - pub cfg_env: CfgEnvWithEvmWiring, + pub cfg_env: CfgEnv, + pub hardfork: ChainSpecT::Hardfork, pub transaction: ChainSpecT::Transaction, pub precompiles: &'a HashMap, // `DebugContext` cannot be simplified further @@ -44,10 +49,10 @@ where /// Execute a transaction as a call. Returns the gas used and the output. pub(super) fn run_call<'a, 'evm, ChainSpecT, DebugDataT>( args: RunCallArgs<'a, 'evm, ChainSpecT, DebugDataT>, -) -> Result, ProviderError> +) -> Result, ProviderError> where 'a: 'evm, - ChainSpecT: SyncChainSpec< + ChainSpecT: SyncRuntimeSpec< Block: Default, Hardfork: Debug, Transaction: Default + TransactionValidation>, @@ -59,6 +64,7 @@ where state, state_overrides, cfg_env, + hardfork, transaction, precompiles, debug_context, @@ -68,13 +74,15 @@ where let mut header = header.clone(); header.base_fee_per_gas = header.base_fee_per_gas.map(|_| U256::ZERO); - let block = ChainSpecT::Block::new_block_env(&header, cfg_env.spec_id); + let block = ChainSpecT::Block::new_block_env(&header, hardfork.into()); + + let state_overrider = StateRefOverrider::new(state_overrides, state); guaranteed_dry_run( blockchain, - state, - state_overrides, + state_overrider, cfg_env, + hardfork, transaction, block, precompiles, diff --git a/crates/edr_provider/src/data/gas.rs b/crates/edr_provider/src/data/gas.rs index 62a5d832b..37fe2234a 100644 --- a/crates/edr_provider/src/data/gas.rs +++ b/crates/edr_provider/src/data/gas.rs @@ -2,6 +2,7 @@ use core::{cmp, fmt::Debug}; use edr_eth::{ block::Header, + env::CfgEnv, result::{ExecutionResult, InvalidTransaction}, reward_percentile::RewardPercentile, transaction::{Transaction as _, TransactionMut, TransactionValidation}, @@ -9,8 +10,7 @@ use edr_eth::{ }; use edr_evm::{ blockchain::{BlockchainError, SyncBlockchain}, - chain_spec::{ChainSpec, SyncChainSpec}, - evm::handler::CfgEnvWithEvmWiring, + spec::{RuntimeSpec, SyncRuntimeSpec}, state::{StateError, StateOverrides, SyncState}, trace::{register_trace_collector_handles, TraceCollector}, DebugContext, SyncBlock, @@ -22,16 +22,17 @@ use crate::{ ProviderError, }; -pub(super) struct CheckGasLimitArgs<'a, ChainSpecT: SyncChainSpec> { +pub(super) struct CheckGasLimitArgs<'a, ChainSpecT: SyncRuntimeSpec> { pub blockchain: &'a dyn SyncBlockchain, StateError>, pub header: &'a Header, pub state: &'a dyn SyncState, pub state_overrides: &'a StateOverrides, - pub cfg_env: CfgEnvWithEvmWiring, + pub cfg_env: CfgEnv, + pub hardfork: ChainSpecT::Hardfork, pub transaction: ChainSpecT::Transaction, pub gas_limit: u64, pub precompiles: &'a HashMap, - pub trace_collector: &'a mut TraceCollector, + pub trace_collector: &'a mut TraceCollector, } /// Test if the transaction successfully executes with the given gas limit. @@ -41,7 +42,7 @@ pub(super) fn check_gas_limit( args: CheckGasLimitArgs<'_, ChainSpecT>, ) -> Result> where - ChainSpecT: SyncChainSpec< + ChainSpecT: SyncRuntimeSpec< Block: Default, Hardfork: Debug, Transaction: Default @@ -55,6 +56,7 @@ where state, state_overrides, cfg_env, + hardfork, mut transaction, gas_limit, precompiles, @@ -69,6 +71,7 @@ where state, state_overrides, cfg_env, + hardfork, transaction, precompiles, debug_context: Some(DebugContext { @@ -80,17 +83,18 @@ where Ok(matches!(result, ExecutionResult::Success { .. })) } -pub(super) struct BinarySearchEstimationArgs<'a, ChainSpecT: SyncChainSpec> { +pub(super) struct BinarySearchEstimationArgs<'a, ChainSpecT: SyncRuntimeSpec> { pub blockchain: &'a dyn SyncBlockchain, StateError>, pub header: &'a Header, pub state: &'a dyn SyncState, pub state_overrides: &'a StateOverrides, - pub cfg_env: CfgEnvWithEvmWiring, + pub cfg_env: CfgEnv, + pub hardfork: ChainSpecT::Hardfork, pub transaction: ChainSpecT::Transaction, pub lower_bound: u64, pub upper_bound: u64, pub precompiles: &'a HashMap, - pub trace_collector: &'a mut TraceCollector, + pub trace_collector: &'a mut TraceCollector, } /// Search for a tight upper bound on the gas limit that will allow the @@ -100,7 +104,7 @@ pub(super) fn binary_search_estimation( args: BinarySearchEstimationArgs<'_, ChainSpecT>, ) -> Result> where - ChainSpecT: SyncChainSpec< + ChainSpecT: SyncRuntimeSpec< Block: Default, Hardfork: Debug, Transaction: Default @@ -116,6 +120,7 @@ where state, state_overrides, cfg_env, + hardfork, transaction, mut lower_bound, mut upper_bound, @@ -140,6 +145,7 @@ where state, state_overrides, cfg_env: cfg_env.clone(), + hardfork, transaction: transaction.clone(), gas_limit: mid, precompiles, @@ -177,7 +183,7 @@ fn min_difference(lower_bound: u64) -> u64 { } /// Compute miner rewards for percentiles. -pub(super) fn compute_rewards>( +pub(super) fn compute_rewards>( block: &dyn SyncBlock>, reward_percentiles: &[RewardPercentile], ) -> Result, ProviderError> { diff --git a/crates/edr_provider/src/debug_mine.rs b/crates/edr_provider/src/debug_mine.rs index 1cfe61f4b..deb08a2f1 100644 --- a/crates/edr_provider/src/debug_mine.rs +++ b/crates/edr_provider/src/debug_mine.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use derive_where::derive_where; use edr_eth::{result::ExecutionResult, transaction::ExecutableTransaction, Bytes, B256}; use edr_evm::{ - chain_spec::ChainSpec, + spec::RuntimeSpec, state::{StateDiff, SyncState}, trace::Trace, LocalBlock, MineBlockResultAndState, SyncBlock, @@ -12,7 +12,7 @@ use edr_evm::{ /// The result of mining a block, including the state, in debug mode. This /// result needs to be inserted into the blockchain to be persistent. -pub struct DebugMineBlockResultAndState { +pub struct DebugMineBlockResultAndState { /// Mined block pub block: LocalBlock, /// State after mining the block @@ -20,19 +20,19 @@ pub struct DebugMineBlockResultAndState { /// State diff applied by block pub state_diff: StateDiff, /// Transaction results - pub transaction_results: Vec>, + pub transaction_results: Vec>, /// Transaction traces - pub transaction_traces: Vec>, + pub transaction_traces: Vec>, /// Encoded `console.log` call inputs pub console_log_inputs: Vec, } -impl DebugMineBlockResultAndState { +impl DebugMineBlockResultAndState { /// Constructs a new instance from a [`MineBlockResultAndState`], /// transaction traces, and decoded console log messages. pub fn new( result: MineBlockResultAndState, - transaction_traces: Vec>, + transaction_traces: Vec>, console_log_decoded_messages: Vec, ) -> Self { Self { @@ -50,18 +50,18 @@ impl DebugMineBlockResultAndState { +pub struct DebugMineBlockResult { /// Mined block pub block: Arc>, /// Transaction results - pub transaction_results: Vec>, + pub transaction_results: Vec>, /// Transaction traces - pub transaction_traces: Vec>, + pub transaction_traces: Vec>, /// Encoded `console.log` call inputs pub console_log_inputs: Vec, } -impl DebugMineBlockResult { +impl DebugMineBlockResult { /// Whether the block contains a transaction with the given hash. pub fn has_transaction(&self, transaction_hash: &B256) -> bool { self.block diff --git a/crates/edr_provider/src/debugger.rs b/crates/edr_provider/src/debugger.rs index c06fc157a..8a3cfa779 100644 --- a/crates/edr_provider/src/debugger.rs +++ b/crates/edr_provider/src/debugger.rs @@ -1,8 +1,12 @@ use core::fmt::Debug; -use edr_eth::db::Database; +use edr_eth::{ + db::Database, + spec::{ChainSpec, HaltReasonTrait}, +}; use edr_evm::{ evm::handler::register::EvmHandler, + spec::EvmWiring, trace::{register_trace_collector_handles, TraceCollector}, GetContextData, }; @@ -13,27 +17,29 @@ use crate::{ }; /// Registers debugger handles. -pub fn register_debugger_handles( - handler: &mut EvmHandler<'_, ChainSpecT, ContextT, DatabaseT>, -) where - DatabaseT: Database, - DatabaseT::Error: Debug, - ContextT: GetContextData - + GetContextData - + GetContextData>, +pub fn register_debugger_handles(handler: &mut EvmHandler<'_, EvmWiringT>) +where + EvmWiringT: EvmWiring< + ExternalContext: GetContextData + + GetContextData + + GetContextData< + TraceCollector<::HaltReason>, + >, + Database: Database, + >, { register_console_log_handles(handler); register_mocking_handles(handler); register_trace_collector_handles(handler); } -pub struct Debugger { +pub struct Debugger { pub console_logger: ConsoleLogCollector, pub mocker: Mocker, - pub trace_collector: TraceCollector, + pub trace_collector: TraceCollector, } -impl Debugger { +impl Debugger { /// Creates a new instance with the provided mocker. /// If verbose is true, full stack and memory will be recorded for each /// step. @@ -46,24 +52,22 @@ impl Debugger { } } -impl GetContextData - for Debugger -{ +impl GetContextData for Debugger { fn get_context_data(&mut self) -> &mut ConsoleLogCollector { &mut self.console_logger } } -impl GetContextData for Debugger { +impl GetContextData for Debugger { fn get_context_data(&mut self) -> &mut Mocker { &mut self.mocker } } -impl GetContextData> - for Debugger +impl GetContextData> + for Debugger { - fn get_context_data(&mut self) -> &mut TraceCollector { + fn get_context_data(&mut self) -> &mut TraceCollector { &mut self.trace_collector } } diff --git a/crates/edr_provider/src/error.rs b/crates/edr_provider/src/error.rs index 8d7fa25b4..4f86bc5d4 100644 --- a/crates/edr_provider/src/error.rs +++ b/crates/edr_provider/src/error.rs @@ -2,17 +2,16 @@ use core::fmt::Debug; use std::num::TryFromIntError; use alloy_sol_types::{ContractError, SolInterface}; -use derive_where::derive_where; use edr_eth::{ - chain_spec::{EvmWiring, L1ChainSpec}, filter::SubscriptionType, hex, result::{ExecutionResult, HaltReason, OutOfGasError}, + spec::HaltReasonTrait, Address, BlockSpec, BlockTag, Bytes, SpecId, B256, U256, }; use edr_evm::{ blockchain::BlockchainError, - chain_spec::ChainSpec, + spec::RuntimeSpec, state::{AccountOverrideConversionError, StateError}, trace::Trace, transaction::{self, TransactionError}, @@ -28,7 +27,7 @@ use crate::{ #[derive(Debug, thiserror::Error)] pub enum ProviderError where - ChainSpecT: ChainSpec, + ChainSpecT: RuntimeSpec, { /// Account override conversion error. #[error(transparent)] @@ -74,7 +73,7 @@ where Eip712Error(#[from] alloy_dyn_abi::Error), /// A transaction error occurred while estimating gas. #[error(transparent)] - EstimateGasTransactionFailure(#[from] EstimateGasFailure), + EstimateGasTransactionFailure(#[from] EstimateGasFailure), #[error("{0}")] InvalidArgument(String), /// Block number or hash doesn't exist in blockchain @@ -188,7 +187,7 @@ where /// `eth_sendTransaction` failed and /// [`crate::config::ProviderConfig::bail_on_call_failure`] was enabled #[error(transparent)] - TransactionFailed(#[from] TransactionFailureWithTraces), + TransactionFailed(#[from] TransactionFailureWithTraces), /// Failed to convert an integer type #[error("Could not convert the integer argument, due to: {0}")] TryFromIntError(#[from] TryFromIntError), @@ -222,7 +221,7 @@ where impl From> for jsonrpc::Error where - ChainSpecT: ChainSpec, + ChainSpecT: RuntimeSpec, { fn from(value: ProviderError) -> Self { const INVALID_INPUT: i16 = -32000; @@ -314,28 +313,25 @@ where } /// Failure that occurred while estimating gas. -#[derive(thiserror::Error)] -#[derive_where(Debug; ChainSpecT, ChainSpecT::HaltReason)] -pub struct EstimateGasFailure { +#[derive(Debug, thiserror::Error)] +pub struct EstimateGasFailure { pub console_log_inputs: Vec, - pub transaction_failure: TransactionFailureWithTraces, + pub transaction_failure: TransactionFailureWithTraces, } -impl std::fmt::Display for EstimateGasFailure { +impl std::fmt::Display for EstimateGasFailure { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.transaction_failure) } } -#[derive(thiserror::Error)] -#[derive_where(Clone; ChainSpecT::HaltReason)] -#[derive_where(Debug; ChainSpecT, ChainSpecT::HaltReason)] -pub struct TransactionFailureWithTraces { - pub failure: TransactionFailure, - pub traces: Vec>, +#[derive(Clone, Debug, thiserror::Error)] +pub struct TransactionFailureWithTraces { + pub failure: TransactionFailure, + pub traces: Vec>, } -impl std::fmt::Display for TransactionFailureWithTraces { +impl std::fmt::Display for TransactionFailureWithTraces { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.failure) } @@ -343,27 +339,25 @@ impl std::fmt::Display for TransactionFailureWithTraces { - pub reason: TransactionFailureReason, +#[derive(Clone, Debug, thiserror::Error, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct TransactionFailure { + pub reason: TransactionFailureReason, pub data: String, #[serde(skip)] - pub solidity_trace: Trace, + pub solidity_trace: Trace, pub transaction_hash: Option, } -impl TransactionFailure { +impl TransactionFailure { pub fn from_execution_result< - NewChainSpecT: ProviderSpec, + NewChainSpecT: ProviderSpec, TimerT: Clone + TimeSinceEpoch, >( - execution_result: &ExecutionResult, + execution_result: &ExecutionResult, transaction_hash: Option<&B256>, - solidity_trace: &Trace, - ) -> Option> { + solidity_trace: &Trace, + ) -> Option> { match execution_result { ExecutionResult::Success { .. } => None, ExecutionResult::Revert { output, .. } => Some(TransactionFailure::revert( @@ -378,13 +372,11 @@ impl TransactionFailure { )), } } -} -impl TransactionFailure { pub fn halt( - reason: TransactionFailureReason, + reason: TransactionFailureReason, tx_hash: Option, - solidity_trace: Trace, + solidity_trace: Trace, ) -> Self { Self { reason, @@ -397,7 +389,7 @@ impl TransactionFailure { pub fn revert( output: Bytes, transaction_hash: Option, - solidity_trace: Trace, + solidity_trace: Trace, ) -> Self { let data = format!("0x{}", hex::encode(output.as_ref())); Self { @@ -409,7 +401,7 @@ impl TransactionFailure { } } -impl std::fmt::Display for TransactionFailure { +impl std::fmt::Display for TransactionFailure { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match &self.reason { TransactionFailureReason::CreateContractSizeLimit => { @@ -431,18 +423,16 @@ impl std::fmt::Display for TransactionFailure } } -#[derive_where(Clone, Debug; ChainSpecT::HaltReason)] -#[derive(Serialize)] -#[serde(bound = "ChainSpecT::HaltReason: Serialize")] -pub enum TransactionFailureReason { +#[derive(Clone, Debug, Serialize)] +pub enum TransactionFailureReason { CreateContractSizeLimit, - Inner(ChainSpecT::HaltReason), + Inner(HaltReasonT), OpcodeNotFound, OutOfGas(OutOfGasError), Revert(Bytes), } -impl From for TransactionFailureReason { +impl From for TransactionFailureReason { fn from(value: HaltReason) -> Self { match value { HaltReason::CreateContractSizeLimit => { diff --git a/crates/edr_provider/src/interval.rs b/crates/edr_provider/src/interval.rs index 67ae93c1b..4fa3e5cd6 100644 --- a/crates/edr_provider/src/interval.rs +++ b/crates/edr_provider/src/interval.rs @@ -2,7 +2,7 @@ use core::fmt::Debug; use std::{marker::PhantomData, sync::Arc}; use edr_eth::{result::InvalidTransaction, transaction::TransactionValidation}; -use edr_evm::chain_spec::ChainSpec; +use edr_evm::spec::RuntimeSpec; use tokio::{ runtime, sync::{oneshot, Mutex}, @@ -15,7 +15,7 @@ use crate::{ }; /// Type for interval mining on a separate thread. -pub struct IntervalMiner, TimerT> { +pub struct IntervalMiner, TimerT> { inner: Option>, runtime: runtime::Handle, phantom: PhantomData, @@ -23,7 +23,7 @@ pub struct IntervalMiner, TimerT> { /// Inner type for interval mining on a separate thread, required for /// implementation of `Drop`. -struct Inner> { +struct Inner> { cancellation_sender: oneshot::Sender<()>, background_task: JoinHandle>>, } @@ -103,7 +103,7 @@ async fn interval_mining_loop< } } -impl, TimerT> Drop for IntervalMiner { +impl, TimerT> Drop for IntervalMiner { #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))] fn drop(&mut self) { if let Some(Inner { diff --git a/crates/edr_provider/src/lib.rs b/crates/edr_provider/src/lib.rs index e75850bd7..159ce3fea 100644 --- a/crates/edr_provider/src/lib.rs +++ b/crates/edr_provider/src/lib.rs @@ -24,10 +24,13 @@ pub mod time; use core::fmt::Debug; -use edr_eth::HashSet; +use edr_eth::{ + spec::{ChainSpec, HaltReasonTrait}, + HashSet, +}; // Re-export parts of `edr_evm` pub use edr_evm::hardfork; -use edr_evm::{chain_spec::ChainSpec, trace::Trace}; +use edr_evm::{spec::RuntimeSpec, trace::Trace}; use lazy_static::lazy_static; pub use self::{ @@ -57,15 +60,18 @@ lazy_static! { }; } +pub type ProviderResultWithTraces = + Result<(T, Vec::HaltReason>>), ProviderError>; + #[derive(Clone, Debug)] -pub struct ResponseWithTraces { +pub struct ResponseWithTraces { pub result: serde_json::Value, - pub traces: Vec>, + pub traces: Vec>, } -fn to_json>( +fn to_json>( value: T, -) -> Result, ProviderError> { +) -> Result, ProviderError> { let response = serde_json::to_value(value).map_err(ProviderError::Serialization)?; Ok(ResponseWithTraces { @@ -74,9 +80,9 @@ fn to_json>( }) } -fn to_json_with_trace>( - value: (T, Trace), -) -> Result, ProviderError> { +fn to_json_with_trace>( + value: (T, Trace), +) -> Result, ProviderError> { let response = serde_json::to_value(value.0).map_err(ProviderError::Serialization)?; Ok(ResponseWithTraces { @@ -85,9 +91,9 @@ fn to_json_with_trace>( - value: (T, Vec>), -) -> Result, ProviderError> { +fn to_json_with_traces>( + value: (T, Vec>), +) -> Result, ProviderError> { let response = serde_json::to_value(value.0).map_err(ProviderError::Serialization)?; Ok(ResponseWithTraces { diff --git a/crates/edr_provider/src/logger.rs b/crates/edr_provider/src/logger.rs index 29b8929b2..37f619eab 100644 --- a/crates/edr_provider/src/logger.rs +++ b/crates/edr_provider/src/logger.rs @@ -3,13 +3,13 @@ use std::marker::PhantomData; use derive_where::derive_where; use dyn_clone::DynClone; -use edr_evm::{blockchain::BlockchainError, chain_spec::ChainSpec}; +use edr_evm::{blockchain::BlockchainError, spec::RuntimeSpec}; use crate::{ data::CallResult, debug_mine::DebugMineBlockResult, error::EstimateGasFailure, ProviderError, }; -pub trait Logger> { +pub trait Logger> { type BlockchainError; /// Whether the logger is enabled. @@ -22,7 +22,7 @@ pub trait Logger> { &mut self, hardfork: ChainSpecT::Hardfork, transaction: &ChainSpecT::Transaction, - result: &CallResult, + result: &CallResult, ) -> Result<(), Box> { let _hardfork = hardfork; let _transaction = transaction; @@ -35,7 +35,7 @@ pub trait Logger> { &mut self, hardfork: ChainSpecT::Hardfork, transaction: &ChainSpecT::Transaction, - result: &EstimateGasFailure, + result: &EstimateGasFailure, ) -> Result<(), Box> { let _hardfork = hardfork; let _transaction = transaction; @@ -90,19 +90,19 @@ pub trait Logger> { ) -> Result<(), Box>; } -pub trait SyncLogger>: +pub trait SyncLogger>: Logger + DynClone + Send + Sync { } impl SyncLogger for T where - ChainSpecT: ChainSpec, + ChainSpecT: RuntimeSpec, T: Logger + DynClone + Send + Sync, { } -impl, BlockchainErrorT> Clone +impl, BlockchainErrorT> Clone for Box> { fn clone(&self) -> Self { @@ -112,11 +112,11 @@ impl, BlockchainErrorT> Clone /// A logger that does nothing. #[derive_where(Clone, Default)] -pub struct NoopLogger { +pub struct NoopLogger { _phantom: PhantomData, } -impl> Logger for NoopLogger { +impl> Logger for NoopLogger { type BlockchainError = BlockchainError; fn is_enabled(&self) -> bool { diff --git a/crates/edr_provider/src/mock.rs b/crates/edr_provider/src/mock.rs index 587c2dc69..b177ca824 100644 --- a/crates/edr_provider/src/mock.rs +++ b/crates/edr_provider/src/mock.rs @@ -1,10 +1,12 @@ +use core::fmt::Debug; use std::sync::Arc; use dyn_clone::DynClone; -use edr_eth::{db::Database, result::EVMErrorForChain, Address, Bytes}; +use edr_eth::{db::Database, result::EVMErrorWiring, Address, Bytes}; use edr_evm::{ evm::{handler::register::EvmHandler, FrameOrResult, FrameResult}, interpreter::{CallOutcome, Gas, InstructionResult, InterpreterResult}, + spec::EvmWiring, GetContextData, }; @@ -28,18 +30,14 @@ impl SyncCallOverride for F where dyn_clone::clone_trait_object!(SyncCallOverride); /// Registers the `Mocker`'s handles. -pub fn register_mocking_handles< - ChainSpecT: edr_evm::chain_spec::EvmWiring, - DatabaseT: Database, - ContextT: GetContextData, ->( - handler: &mut EvmHandler<'_, ChainSpecT, ContextT, DatabaseT>, -) { +pub fn register_mocking_handles(handler: &mut EvmHandler<'_, EvmWiringT>) +where + EvmWiringT: + EvmWiring, Database: Database>, +{ let old_handle = handler.execution.call.clone(); handler.execution.call = Arc::new( - move |ctx, - inputs| - -> Result> { + move |ctx, inputs| -> Result> { let mocker = ctx.external.get_context_data(); if let Some(CallOverrideResult { output, diff --git a/crates/edr_provider/src/pending.rs b/crates/edr_provider/src/pending.rs index b2a7f23ae..3a6b46fbf 100644 --- a/crates/edr_provider/src/pending.rs +++ b/crates/edr_provider/src/pending.rs @@ -4,7 +4,7 @@ use derive_where::derive_where; use edr_eth::{db::BlockHashRef, transaction::ExecutableTransaction as _, HashSet, B256, U256}; use edr_evm::{ blockchain::{Blockchain, BlockchainError, BlockchainMut, SyncBlockchain}, - chain_spec::SyncChainSpec, + spec::SyncRuntimeSpec, state::{StateDiff, StateError, StateOverride, SyncState}, BlockAndTotalDifficulty, BlockReceipt, LocalBlock, SyncBlock, }; @@ -20,14 +20,14 @@ use edr_evm::{ /// [`SyncBlockchain`] because we cannot upcast the trait at its usage site /// #[derive_where(Debug)] -pub(crate) struct BlockchainWithPending<'blockchain, ChainSpecT: SyncChainSpec> { +pub(crate) struct BlockchainWithPending<'blockchain, ChainSpecT: SyncRuntimeSpec> { blockchain: &'blockchain dyn SyncBlockchain, StateError>, pending_block: Arc>>, pending_state_diff: StateDiff, } -impl<'blockchain, ChainSpecT: SyncChainSpec> BlockchainWithPending<'blockchain, ChainSpecT> { +impl<'blockchain, ChainSpecT: SyncRuntimeSpec> BlockchainWithPending<'blockchain, ChainSpecT> { /// Constructs a new instance with the provided blockchain and pending /// block. pub fn new( @@ -47,7 +47,7 @@ impl<'blockchain, ChainSpecT: SyncChainSpec> BlockchainWithPending<'blockchain, } } -impl<'blockchain, ChainSpecT: SyncChainSpec> Blockchain +impl<'blockchain, ChainSpecT: SyncRuntimeSpec> Blockchain for BlockchainWithPending<'blockchain, ChainSpecT> { type BlockchainError = BlockchainError; @@ -204,7 +204,7 @@ impl<'blockchain, ChainSpecT: SyncChainSpec> Blockchain } } -impl<'blockchain, ChainSpecT: SyncChainSpec> BlockchainMut +impl<'blockchain, ChainSpecT: SyncRuntimeSpec> BlockchainMut for BlockchainWithPending<'blockchain, ChainSpecT> { type Error = BlockchainError; @@ -226,7 +226,7 @@ impl<'blockchain, ChainSpecT: SyncChainSpec> BlockchainMut } } -impl<'blockchain, ChainSpecT: SyncChainSpec> BlockHashRef +impl<'blockchain, ChainSpecT: SyncRuntimeSpec> BlockHashRef for BlockchainWithPending<'blockchain, ChainSpecT> { type Error = BlockchainError; diff --git a/crates/edr_provider/src/provider.rs b/crates/edr_provider/src/provider.rs index 53295cd57..8364aa977 100644 --- a/crates/edr_provider/src/provider.rs +++ b/crates/edr_provider/src/provider.rs @@ -164,7 +164,7 @@ impl< pub fn handle_request( &self, request: ProviderRequest, - ) -> Result, ProviderError> { + ) -> Result, ProviderError> { let mut data = task::block_in_place(|| self.runtime.block_on(self.data.lock())); let response = match request { @@ -180,7 +180,7 @@ impl< &self, data: &mut ProviderData, request: Vec>, - ) -> Result, ProviderError> { + ) -> Result, ProviderError> { let mut results = Vec::new(); let mut traces = Vec::new(); @@ -198,7 +198,7 @@ impl< &self, data: &mut ProviderData, request: MethodInvocation, - ) -> Result, ProviderError> { + ) -> Result, ProviderError> { let method_name = if data.logger_mut().is_enabled() { let method_name = request.method_name(); if PRIVATE_RPC_METHODS.contains(method_name) { diff --git a/crates/edr_provider/src/requests.rs b/crates/edr_provider/src/requests.rs index de27b4465..2a396546b 100644 --- a/crates/edr_provider/src/requests.rs +++ b/crates/edr_provider/src/requests.rs @@ -82,7 +82,7 @@ impl<'de, ChainSpecT: RpcSpec> Deserialize<'de> for ProviderRequest #[cfg(test)] mod tests { use anyhow::Context; - use edr_eth::chain_spec::L1ChainSpec; + use edr_eth::spec::L1ChainSpec; use super::*; diff --git a/crates/edr_provider/src/requests/debug.rs b/crates/edr_provider/src/requests/debug.rs index 624aa9893..d2a9475a4 100644 --- a/crates/edr_provider/src/requests/debug.rs +++ b/crates/edr_provider/src/requests/debug.rs @@ -1,5 +1,5 @@ use edr_eth::{result::InvalidTransaction, transaction::TransactionValidation, BlockSpec, B256}; -use edr_evm::{state::StateOverrides, trace::Trace, DebugTraceResult, DebugTraceResultWithTraces}; +use edr_evm::{state::StateOverrides, DebugTraceResult, DebugTraceResultWithTraces}; use serde::{Deserialize, Deserializer}; use crate::{ @@ -7,7 +7,7 @@ use crate::{ requests::eth::{resolve_block_spec_for_call_request, resolve_call_request}, spec::SyncProviderSpec, time::TimeSinceEpoch, - ProviderError, + ProviderError, ProviderResultWithTraces, }; pub fn handle_debug_trace_transaction< @@ -24,7 +24,7 @@ pub fn handle_debug_trace_transaction< data: &mut ProviderData, transaction_hash: B256, config: Option, -) -> Result<(DebugTraceResult, Vec>), ProviderError> { +) -> ProviderResultWithTraces { let DebugTraceResultWithTraces { result, traces } = data .debug_trace_transaction( &transaction_hash, @@ -45,7 +45,7 @@ pub fn handle_debug_trace_call( call_request: ChainSpecT::RpcCallRequest, block_spec: Option, config: Option, -) -> Result<(DebugTraceResult, Vec>), ProviderError> +) -> ProviderResultWithTraces where ChainSpecT: SyncProviderSpec< TimerT, diff --git a/crates/edr_provider/src/requests/eth/blocks.rs b/crates/edr_provider/src/requests/eth/blocks.rs index 207e9acc8..f5cc0c518 100644 --- a/crates/edr_provider/src/requests/eth/blocks.rs +++ b/crates/edr_provider/src/requests/eth/blocks.rs @@ -9,7 +9,7 @@ use edr_eth::{ use edr_evm::{ block::transaction::{BlockDataForTransaction, TransactionAndBlock}, blockchain::BlockchainError, - chain_spec::ChainSpec, + spec::RuntimeSpec, SyncBlock, }; use edr_rpc_eth::RpcTypeFrom as _; @@ -21,7 +21,7 @@ use crate::{ #[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)] #[serde(untagged)] -pub enum HashOrTransaction { +pub enum HashOrTransaction { Hash(B256), Transaction(ChainSpecT::RpcTransaction), } @@ -115,7 +115,7 @@ pub fn handle_get_block_transaction_count_by_block_number< /// The result returned by requesting a block by number. #[derive(Debug, Clone)] -struct BlockByNumberResult { +struct BlockByNumberResult { /// The block pub block: Arc>>, /// Whether the block is a pending block. @@ -172,7 +172,7 @@ fn block_by_number< } } -fn block_to_rpc_output>( +fn block_to_rpc_output>( hardfork: ChainSpecT::Hardfork, block: Arc>>, is_pending: bool, diff --git a/crates/edr_provider/src/requests/eth/call.rs b/crates/edr_provider/src/requests/eth/call.rs index e61b7889d..da1e252b5 100644 --- a/crates/edr_provider/src/requests/eth/call.rs +++ b/crates/edr_provider/src/requests/eth/call.rs @@ -29,7 +29,7 @@ pub fn handle_call_request< request: ChainSpecT::RpcCallRequest, block_spec: Option, state_overrides: Option, -) -> Result<(Bytes, Trace), ProviderError> { +) -> Result<(Bytes, Trace), ProviderError> { let block_spec = resolve_block_spec_for_call_request(block_spec); let state_overrides = @@ -44,11 +44,11 @@ pub fn handle_call_request< .map_err(ProviderError::Logger)?; if data.bail_on_call_failure() { - if let Some(failure) = TransactionFailure::::from_execution_result::< - ChainSpecT, - TimerT, - >(&result.execution_result, None, &result.trace) - { + if let Some(failure) = TransactionFailure::from_execution_result::( + &result.execution_result, + None, + &result.trace, + ) { return Err(ProviderError::TransactionFailed( crate::error::TransactionFailureWithTraces { failure, diff --git a/crates/edr_provider/src/requests/eth/config.rs b/crates/edr_provider/src/requests/eth/config.rs index 518ba20b1..1db4d11e9 100644 --- a/crates/edr_provider/src/requests/eth/config.rs +++ b/crates/edr_provider/src/requests/eth/config.rs @@ -1,7 +1,7 @@ use core::fmt::Debug; use edr_eth::{Address, U256, U64}; -use edr_evm::chain_spec::ChainSpec; +use edr_evm::spec::RuntimeSpec; use crate::{ data::ProviderData, @@ -33,23 +33,23 @@ pub fn handle_coinbase_request, TimerT: Clone + Ok(data.coinbase()) } -pub fn handle_max_priority_fee_per_gas>( +pub fn handle_max_priority_fee_per_gas>( ) -> Result> { // 1 gwei Ok(U256::from(1_000_000_000)) } -pub fn handle_mining>( +pub fn handle_mining>( ) -> Result> { Ok(false) } -pub fn handle_net_listening_request>( +pub fn handle_net_listening_request>( ) -> Result> { Ok(true) } -pub fn handle_net_peer_count_request>( +pub fn handle_net_peer_count_request>( ) -> Result> { Ok(U64::from(0)) } @@ -63,7 +63,7 @@ pub fn handle_net_version_request< Ok(data.network_id()) } -pub fn handle_syncing>( +pub fn handle_syncing>( ) -> Result> { Ok(false) } diff --git a/crates/edr_provider/src/requests/eth/evm.rs b/crates/edr_provider/src/requests/eth/evm.rs index 986d1d437..3f62a03e5 100644 --- a/crates/edr_provider/src/requests/eth/evm.rs +++ b/crates/edr_provider/src/requests/eth/evm.rs @@ -3,13 +3,12 @@ use std::num::NonZeroU64; use edr_eth::{ block::BlockOptions, result::InvalidTransaction, transaction::TransactionValidation, U64, }; -use edr_evm::trace::Trace; use crate::{ data::ProviderData, spec::{ProviderSpec, SyncProviderSpec}, time::TimeSinceEpoch, - ProviderError, Timestamp, + ProviderError, ProviderResultWithTraces, Timestamp, }; pub fn handle_increase_time_request< @@ -38,7 +37,7 @@ pub fn handle_mine_request< >( data: &mut ProviderData, timestamp: Option, -) -> Result<(String, Vec>), ProviderError> { +) -> ProviderResultWithTraces { let mine_block_result = data.mine_and_commit_block(BlockOptions { timestamp: timestamp.map(Into::into), ..BlockOptions::default() diff --git a/crates/edr_provider/src/requests/eth/gas.rs b/crates/edr_provider/src/requests/eth/gas.rs index 9f693c7a3..dcbee7333 100644 --- a/crates/edr_provider/src/requests/eth/gas.rs +++ b/crates/edr_provider/src/requests/eth/gas.rs @@ -5,14 +5,14 @@ use edr_eth::{ transaction::{signed::FakeSign as _, TransactionMut, TransactionValidation}, BlockSpec, SpecId, U256, U64, }; -use edr_evm::{state::StateOverrides, trace::Trace, transaction}; +use edr_evm::{state::StateOverrides, transaction}; use crate::{ data::ProviderData, requests::validation::validate_post_merge_block_tags, spec::{CallContext, FromRpcType as _, MaybeSender as _, SyncProviderSpec}, time::TimeSinceEpoch, - ProviderError, + ProviderError, ProviderResultWithTraces, }; pub fn handle_estimate_gas< @@ -30,7 +30,7 @@ pub fn handle_estimate_gas< data: &mut ProviderData, request: ChainSpecT::RpcCallRequest, block_spec: Option, -) -> Result<(U64, Vec>), ProviderError> { +) -> ProviderResultWithTraces { // Matching Hardhat behavior in defaulting to "pending" instead of "latest" for // estimate gas. let block_spec = block_spec.unwrap_or_else(BlockSpec::pending); diff --git a/crates/edr_provider/src/requests/eth/transactions.rs b/crates/edr_provider/src/requests/eth/transactions.rs index c75f2fde6..c343f6451 100644 --- a/crates/edr_provider/src/requests/eth/transactions.rs +++ b/crates/edr_provider/src/requests/eth/transactions.rs @@ -13,8 +13,7 @@ use edr_eth::{ use edr_evm::{ block::transaction::{BlockDataForTransaction, TransactionAndBlock}, blockchain::BlockchainError, - chain_spec::ChainSpec, - trace::Trace, + spec::RuntimeSpec, transaction, SyncBlock, }; use edr_rpc_eth::RpcTypeFrom as _; @@ -28,7 +27,7 @@ use crate::{ }, spec::{FromRpcType, Sender as _, SyncProviderSpec, TransactionContext}, time::TimeSinceEpoch, - ProviderError, TransactionFailure, + ProviderError, ProviderResultWithTraces, TransactionFailure, }; pub fn handle_get_transaction_by_block_hash_and_index< @@ -112,7 +111,7 @@ pub fn handle_pending_transactions< Ok(transactions) } -fn rpc_index_to_usize>( +fn rpc_index_to_usize>( index: &U256, ) -> Result> { index @@ -148,7 +147,7 @@ pub fn handle_get_transaction_receipt< Ok(receipt.map(|receipt| ChainSpecT::RpcReceipt::rpc_type_from(&receipt, data.hardfork()))) } -fn transaction_from_block( +fn transaction_from_block( block: Arc>>, transaction_index: usize, is_pending: bool, @@ -180,7 +179,7 @@ pub fn handle_send_transaction_request< >( data: &mut ProviderData, request: ChainSpecT::RpcTransactionRequest, -) -> Result<(B256, Vec>), ProviderError> { +) -> ProviderResultWithTraces { let sender = *request.sender(); let context = TransactionContext { data }; @@ -207,7 +206,7 @@ pub fn handle_send_raw_transaction_request< >( data: &mut ProviderData, raw_transaction: Bytes, -) -> Result<(B256, Vec>), ProviderError> { +) -> ProviderResultWithTraces { let mut raw_transaction: &[u8] = raw_transaction.as_ref(); let pooled_transaction = ChainSpecT::PooledTransaction::decode(&mut raw_transaction).map_err(|err| match err { @@ -241,7 +240,7 @@ fn send_raw_transaction_and_log< >( data: &mut ProviderData, signed_transaction: ChainSpecT::Transaction, -) -> Result<(B256, Vec>), ProviderError> { +) -> ProviderResultWithTraces { let result = data.send_transaction(signed_transaction.clone())?; let hardfork = data.hardfork(); @@ -254,7 +253,7 @@ fn send_raw_transaction_and_log< result .transaction_result_and_trace() .and_then(|(execution_result, trace)| { - TransactionFailure::::from_execution_result::( + TransactionFailure::from_execution_result::( execution_result, Some(&result.transaction_hash), trace, diff --git a/crates/edr_provider/src/requests/eth/web3.rs b/crates/edr_provider/src/requests/eth/web3.rs index d9018fb9e..f37958d69 100644 --- a/crates/edr_provider/src/requests/eth/web3.rs +++ b/crates/edr_provider/src/requests/eth/web3.rs @@ -1,7 +1,7 @@ use core::fmt::Debug; use edr_eth::{Bytes, B256}; -use edr_evm::chain_spec::ChainSpec; +use edr_evm::spec::RuntimeSpec; use sha3::{Digest, Keccak256}; use crate::ProviderError; @@ -14,12 +14,12 @@ pub fn client_version() -> String { ) } -pub fn handle_web3_client_version_request>( +pub fn handle_web3_client_version_request>( ) -> Result> { Ok(client_version()) } -pub fn handle_web3_sha3_request>( +pub fn handle_web3_sha3_request>( message: Bytes, ) -> Result> { let hash = Keccak256::digest(&message[..]); diff --git a/crates/edr_provider/src/requests/hardhat/miner.rs b/crates/edr_provider/src/requests/hardhat/miner.rs index e33430a1d..d5f3150c5 100644 --- a/crates/edr_provider/src/requests/hardhat/miner.rs +++ b/crates/edr_provider/src/requests/hardhat/miner.rs @@ -1,7 +1,9 @@ use edr_eth::{result::InvalidTransaction, transaction::TransactionValidation}; -use edr_evm::trace::Trace; -use crate::{data::ProviderData, spec::SyncProviderSpec, time::TimeSinceEpoch, ProviderError}; +use crate::{ + data::ProviderData, spec::SyncProviderSpec, time::TimeSinceEpoch, ProviderError, + ProviderResultWithTraces, +}; pub fn handle_interval_mine_request< ChainSpecT: SyncProviderSpec< @@ -33,7 +35,7 @@ pub fn handle_mine< data: &mut ProviderData, number_of_blocks: Option, interval: Option, -) -> Result<(bool, Vec>), ProviderError> { +) -> ProviderResultWithTraces { let number_of_blocks = number_of_blocks.unwrap_or(1); let interval = interval.unwrap_or(1); diff --git a/crates/edr_provider/src/requests/resolve.rs b/crates/edr_provider/src/requests/resolve.rs index 7689dbf47..6fb78604d 100644 --- a/crates/edr_provider/src/requests/resolve.rs +++ b/crates/edr_provider/src/requests/resolve.rs @@ -1,4 +1,4 @@ -use edr_eth::{chain_spec::L1ChainSpec, Bytes, SpecId, U256}; +use edr_eth::{spec::L1ChainSpec, Bytes, SpecId, U256}; use edr_evm::{blockchain::BlockchainError, transaction}; use edr_rpc_eth::{CallRequest, TransactionRequest}; diff --git a/crates/edr_provider/src/requests/serde.rs b/crates/edr_provider/src/requests/serde.rs index a9cd3eb3c..8f67dbbf3 100644 --- a/crates/edr_provider/src/requests/serde.rs +++ b/crates/edr_provider/src/requests/serde.rs @@ -6,7 +6,7 @@ use std::{ use alloy_dyn_abi::TypedData; use edr_eth::{Address, Bytes, U256, U64}; -use edr_evm::chain_spec::ChainSpec; +use edr_evm::spec::RuntimeSpec; use serde::{Deserialize, Deserializer, Serialize}; use crate::ProviderError; @@ -102,7 +102,7 @@ impl<'a> InvalidRequestReason<'a> { } /// Converts the invalid request reason into a provider error. - pub fn provider_error>( + pub fn provider_error>( &self, ) -> Option<(&str, ProviderError)> { match self { diff --git a/crates/edr_provider/src/requests/validation.rs b/crates/edr_provider/src/requests/validation.rs index 81bb054b2..4ffd42a9e 100644 --- a/crates/edr_provider/src/requests/validation.rs +++ b/crates/edr_provider/src/requests/validation.rs @@ -6,7 +6,7 @@ use edr_eth::{ MAX_INITCODE_SIZE, U256, }; use edr_evm::{ - chain_spec::ChainSpec, + spec::RuntimeSpec, transaction::{self, Transaction}, }; use edr_rpc_eth::{CallRequest, TransactionRequest}; @@ -171,7 +171,7 @@ You can use them by running Hardhat Network with 'hardfork' {minimum_hardfork:?} }) } -fn validate_transaction_spec>( +fn validate_transaction_spec>( spec_id: SpecId, value: &impl HardforkValidationData, ) -> Result<(), ProviderError> { @@ -242,7 +242,7 @@ fn validate_transaction_spec>( } /// Validates a `CallRequest` and `BlockSpec` against the provided hardfork. -pub fn validate_call_request>( +pub fn validate_call_request>( spec_id: SpecId, call_request: &CallRequest, block_spec: &BlockSpec, @@ -268,7 +268,7 @@ You can use them by running Hardhat Network with 'hardfork' {minimum_hardfork:?} }) } -pub(crate) fn validate_transaction_and_call_request>( +pub(crate) fn validate_transaction_and_call_request>( spec_id: SpecId, validation_data: &impl HardforkValidationData, ) -> Result<(), ProviderError> { @@ -286,7 +286,7 @@ You can use them by running Hardhat Network with 'hardfork' {minimum_hardfork:?} }) } -pub(crate) fn validate_eip3860_max_initcode_size>( +pub(crate) fn validate_eip3860_max_initcode_size>( spec_id: SpecId, allow_unlimited_contract_code_size: bool, to: Option<&Address>, @@ -337,7 +337,7 @@ impl<'a> From> for BlockSpec { } } -pub(crate) fn validate_post_merge_block_tags<'a, ChainSpecT: ChainSpec>( +pub(crate) fn validate_post_merge_block_tags<'a, ChainSpecT: RuntimeSpec>( hardfork: SpecId, block_spec: impl Into>, ) -> Result<(), ProviderError> { @@ -364,7 +364,7 @@ pub(crate) fn validate_post_merge_block_tags<'a, ChainSpecT: ChainSpec { +pub(crate) struct Snapshot { pub block_number: u64, pub block_number_to_state_id: HashTrieMapSync, pub block_time_offset_seconds: i64, diff --git a/crates/edr_provider/src/spec.rs b/crates/edr_provider/src/spec.rs index b550ef305..34a31f050 100644 --- a/crates/edr_provider/src/spec.rs +++ b/crates/edr_provider/src/spec.rs @@ -1,17 +1,17 @@ use core::fmt::Debug; -pub use edr_eth::chain_spec::EthHeaderConstants; +pub use edr_eth::spec::EthHeaderConstants; use edr_eth::{ - chain_spec::L1ChainSpec, result::HaltReason, rlp, + spec::L1ChainSpec, transaction::{ signed::{FakeSign, Sign}, Transaction, }, AccessListItem, Address, Blob, BlockSpec, B256, U256, }; -pub use edr_evm::chain_spec::{ChainSpec, SyncChainSpec}; +pub use edr_evm::spec::{RuntimeSpec, SyncRuntimeSpec}; use edr_evm::{ blockchain::BlockchainError, state::StateOverrides, transaction, BlockAndTotalDifficulty, }; @@ -20,7 +20,7 @@ use edr_rpc_eth::{CallRequest, TransactionRequest}; use crate::{data::ProviderData, time::TimeSinceEpoch, ProviderError, TransactionFailureReason}; pub trait ProviderSpec: - ChainSpec< + RuntimeSpec< Hardfork: Debug, RpcBlock: From>>, RpcCallRequest: MaybeSender, @@ -51,14 +51,14 @@ pub trait ProviderSpec: /// /// This is implemented as an associated function to avoid problems when /// implementing type conversions for third-party types. - fn cast_halt_reason(reason: Self::HaltReason) -> TransactionFailureReason; + fn cast_halt_reason(reason: Self::HaltReason) -> TransactionFailureReason; } impl ProviderSpec for L1ChainSpec { type PooledTransaction = transaction::pooled::PooledTransaction; type TransactionRequest = transaction::Request; - fn cast_halt_reason(reason: Self::HaltReason) -> TransactionFailureReason { + fn cast_halt_reason(reason: Self::HaltReason) -> TransactionFailureReason { match reason { HaltReason::CreateContractSizeLimit => { TransactionFailureReason::CreateContractSizeLimit @@ -135,11 +135,11 @@ pub trait FromRpcType: Sized { } pub trait SyncProviderSpec: - ProviderSpec + SyncChainSpec + ProviderSpec + SyncRuntimeSpec { } -impl + SyncChainSpec, TimerT: Clone + TimeSinceEpoch> +impl + SyncRuntimeSpec, TimerT: Clone + TimeSinceEpoch> SyncProviderSpec for ProviderSpecT { } diff --git a/crates/edr_provider/src/subscribe.rs b/crates/edr_provider/src/subscribe.rs index 2f9a320be..a892461ae 100644 --- a/crates/edr_provider/src/subscribe.rs +++ b/crates/edr_provider/src/subscribe.rs @@ -1,32 +1,32 @@ use derive_where::derive_where; use dyn_clone::DynClone; use edr_eth::{filter::LogOutput, B256, U256}; -use edr_evm::{blockchain::BlockchainError, chain_spec::ChainSpec, BlockAndTotalDifficulty}; +use edr_evm::{blockchain::BlockchainError, spec::RuntimeSpec, BlockAndTotalDifficulty}; /// Subscription event. #[derive_where(Clone, Debug)] -pub struct SubscriptionEvent { +pub struct SubscriptionEvent { pub filter_id: U256, pub result: SubscriptionEventData, } /// Subscription event data. #[derive_where(Clone, Debug)] -pub enum SubscriptionEventData { +pub enum SubscriptionEventData { Logs(Vec), NewHeads(BlockAndTotalDifficulty>), NewPendingTransactions(B256), } /// Supertrait for subscription callbacks. -pub trait SyncSubscriberCallback: +pub trait SyncSubscriberCallback: Fn(SubscriptionEvent) + DynClone + Send + Sync { } -impl SyncSubscriberCallback for F where +impl SyncSubscriberCallback for F where F: Fn(SubscriptionEvent) + DynClone + Send + Sync { } -dyn_clone::clone_trait_object!( SyncSubscriberCallback where ChainSpecT: ChainSpec); +dyn_clone::clone_trait_object!( SyncSubscriberCallback where ChainSpecT: RuntimeSpec); diff --git a/crates/edr_provider/src/test_utils.rs b/crates/edr_provider/src/test_utils.rs index 0c297280d..a80628068 100644 --- a/crates/edr_provider/src/test_utils.rs +++ b/crates/edr_provider/src/test_utils.rs @@ -1,16 +1,18 @@ use std::{num::NonZeroU64, time::SystemTime}; use edr_eth::{ - block::BlobGas, chain_spec::L1ChainSpec, result::InvalidTransaction, - signature::secret_key_from_str, transaction::TransactionValidation, trie::KECCAK_NULL_RLP, - Address, Bytes, HashMap, B256, U160, U256, + block::BlobGas, result::InvalidTransaction, signature::secret_key_from_str, spec::L1ChainSpec, + transaction::TransactionValidation, trie::KECCAK_NULL_RLP, Address, Bytes, HashMap, B256, U160, + U256, }; -use edr_evm::Block; +use edr_evm::{spec::RuntimeSpec, Block}; use edr_rpc_eth::TransactionRequest; -use time::TimeSinceEpoch; -use super::*; -use crate::{config::MiningConfig, requests::hardhat::rpc_types::ForkConfig}; +use crate::{ + config::MiningConfig, requests::hardhat::rpc_types::ForkConfig, time::TimeSinceEpoch, + AccountConfig, MethodInvocation, Provider, ProviderConfig, ProviderData, ProviderError, + ProviderRequest, SyncProviderSpec, +}; pub const TEST_SECRET_KEY: &str = "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"; @@ -22,7 +24,7 @@ pub const TEST_SECRET_KEY_SIGN_TYPED_DATA_V4: &str = pub const FORK_BLOCK_NUMBER: u64 = 18_725_000; /// Constructs a test config with a single account with 1 ether -pub fn create_test_config() -> ProviderConfig { +pub fn create_test_config() -> ProviderConfig { create_test_config_with_fork(None) } @@ -30,7 +32,7 @@ pub fn one_ether() -> U256 { U256::from(10).pow(U256::from(18)) } -pub fn create_test_config_with_fork( +pub fn create_test_config_with_fork( fork: Option, ) -> ProviderConfig { ProviderConfig { diff --git a/crates/edr_provider/tests/eip4844.rs b/crates/edr_provider/tests/eip4844.rs index 79b7b467f..47de3b293 100644 --- a/crates/edr_provider/tests/eip4844.rs +++ b/crates/edr_provider/tests/eip4844.rs @@ -4,9 +4,9 @@ use std::str::FromStr; use edr_defaults::SECRET_KEYS; use edr_eth::{ - chain_spec::L1ChainSpec, rlp::{self, Decodable}, signature::{secret_key_from_str, secret_key_to_address}, + spec::L1ChainSpec, transaction::{ self, pooled::PooledTransaction, ExecutableTransaction as _, Transaction as _, TransactionType as _, diff --git a/crates/edr_provider/tests/eth_max_priority_fee_per_gas.rs b/crates/edr_provider/tests/eth_max_priority_fee_per_gas.rs index 4f96abcba..e33a2648d 100644 --- a/crates/edr_provider/tests/eth_max_priority_fee_per_gas.rs +++ b/crates/edr_provider/tests/eth_max_priority_fee_per_gas.rs @@ -1,6 +1,6 @@ #![cfg(feature = "test-utils")] -use edr_eth::chain_spec::L1ChainSpec; +use edr_eth::spec::L1ChainSpec; use edr_provider::{ test_utils::create_test_config, time::CurrentTime, MethodInvocation, NoopLogger, Provider, ProviderRequest, diff --git a/crates/edr_provider/tests/eth_request_serialization.rs b/crates/edr_provider/tests/eth_request_serialization.rs index 6ef43c66d..74e0aae01 100644 --- a/crates/edr_provider/tests/eth_request_serialization.rs +++ b/crates/edr_provider/tests/eth_request_serialization.rs @@ -1,8 +1,8 @@ mod common; use edr_eth::{ - chain_spec::L1ChainSpec, filter::{LogFilterOptions, LogOutput, OneOrMore}, + spec::L1ChainSpec, Address, Blob, BlockSpec, BlockTag, Bytes, PreEip1898BlockSpec, B256, BYTES_PER_BLOB, U160, U256, }; diff --git a/crates/edr_provider/tests/hardhat_request_serialization.rs b/crates/edr_provider/tests/hardhat_request_serialization.rs index 844db204a..7a3d2a990 100644 --- a/crates/edr_provider/tests/hardhat_request_serialization.rs +++ b/crates/edr_provider/tests/hardhat_request_serialization.rs @@ -1,6 +1,6 @@ mod common; -use edr_eth::{chain_spec::L1ChainSpec, Address, Bytes, B256, U160, U256}; +use edr_eth::{spec::L1ChainSpec, Address, Bytes, B256, U160, U256}; use edr_provider::{ hardhat_rpc_types::{CompilerInput, CompilerOutput, ForkConfig, ResetProviderConfig}, MethodInvocation, diff --git a/crates/edr_provider/tests/issues/issue_324.rs b/crates/edr_provider/tests/issues/issue_324.rs index d1a8fa0de..6cd53da38 100644 --- a/crates/edr_provider/tests/issues/issue_324.rs +++ b/crates/edr_provider/tests/issues/issue_324.rs @@ -1,6 +1,6 @@ use std::str::FromStr; -use edr_eth::{chain_spec::L1ChainSpec, Address, Bytes, SpecId, U256}; +use edr_eth::{spec::L1ChainSpec, Address, Bytes, SpecId, U256}; use edr_provider::{ hardhat_rpc_types::ForkConfig, test_utils::create_test_config_with_fork, time::CurrentTime, MethodInvocation, NoopLogger, Provider, ProviderRequest, diff --git a/crates/edr_provider/tests/issues/issue_325.rs b/crates/edr_provider/tests/issues/issue_325.rs index 12fa28cc9..5ee153a20 100644 --- a/crates/edr_provider/tests/issues/issue_325.rs +++ b/crates/edr_provider/tests/issues/issue_325.rs @@ -1,5 +1,5 @@ use edr_eth::{ - chain_spec::L1ChainSpec, AccountInfo, Address, PreEip1898BlockSpec, SpecId, B256, KECCAK_EMPTY, + spec::L1ChainSpec, AccountInfo, Address, PreEip1898BlockSpec, SpecId, B256, KECCAK_EMPTY, }; use edr_provider::{ test_utils::{create_test_config_with_fork, one_ether}, diff --git a/crates/edr_provider/tests/issues/issue_326.rs b/crates/edr_provider/tests/issues/issue_326.rs index 770ec93fb..bdf73cb1f 100644 --- a/crates/edr_provider/tests/issues/issue_326.rs +++ b/crates/edr_provider/tests/issues/issue_326.rs @@ -1,6 +1,6 @@ use std::str::FromStr; -use edr_eth::{chain_spec::L1ChainSpec, AccountInfo, Address, SpecId, KECCAK_EMPTY, U256}; +use edr_eth::{spec::L1ChainSpec, AccountInfo, Address, SpecId, KECCAK_EMPTY, U256}; use edr_provider::{ test_utils::{create_test_config_with_fork, one_ether}, time::CurrentTime, diff --git a/crates/edr_provider/tests/issues/issue_346.rs b/crates/edr_provider/tests/issues/issue_346.rs index 72b07786a..ba49f3b8f 100644 --- a/crates/edr_provider/tests/issues/issue_346.rs +++ b/crates/edr_provider/tests/issues/issue_346.rs @@ -1,4 +1,4 @@ -use edr_eth::chain_spec::L1ChainSpec; +use edr_eth::spec::L1ChainSpec; use edr_provider::{test_utils::create_test_config, time::CurrentTime, NoopLogger, Provider}; use serde_json::json; use tokio::runtime; diff --git a/crates/edr_provider/tests/issues/issue_356.rs b/crates/edr_provider/tests/issues/issue_356.rs index e1e494d87..2c1a92250 100644 --- a/crates/edr_provider/tests/issues/issue_356.rs +++ b/crates/edr_provider/tests/issues/issue_356.rs @@ -1,7 +1,7 @@ use std::str::FromStr; use anyhow::Context; -use edr_eth::{chain_spec::L1ChainSpec, Address, Bytes, SpecId}; +use edr_eth::{spec::L1ChainSpec, Address, Bytes, SpecId}; use edr_provider::{ hardhat_rpc_types::ForkConfig, test_utils::create_test_config_with_fork, time::CurrentTime, MethodInvocation, NoopLogger, Provider, ProviderRequest, diff --git a/crates/edr_provider/tests/issues/issue_361.rs b/crates/edr_provider/tests/issues/issue_361.rs index 5ccf23e6e..1ebe45d21 100644 --- a/crates/edr_provider/tests/issues/issue_361.rs +++ b/crates/edr_provider/tests/issues/issue_361.rs @@ -1,5 +1,5 @@ use edr_eth::{ - chain_spec::L1ChainSpec, filter::LogFilterOptions, AccountInfo, Address, BlockSpec, SpecId, + filter::LogFilterOptions, spec::L1ChainSpec, AccountInfo, Address, BlockSpec, SpecId, KECCAK_EMPTY, }; use edr_provider::{ diff --git a/crates/edr_provider/tests/issues/issue_384.rs b/crates/edr_provider/tests/issues/issue_384.rs index bdb9f26ea..8c47eb323 100644 --- a/crates/edr_provider/tests/issues/issue_384.rs +++ b/crates/edr_provider/tests/issues/issue_384.rs @@ -1,4 +1,4 @@ -use edr_eth::chain_spec::L1ChainSpec; +use edr_eth::spec::L1ChainSpec; use edr_provider::{ hardhat_rpc_types::ForkConfig, test_utils::create_test_config_with_fork, time::CurrentTime, MethodInvocation, NoopLogger, Provider, ProviderRequest, diff --git a/crates/edr_provider/tests/issues/issue_407.rs b/crates/edr_provider/tests/issues/issue_407.rs index a16e9ebbf..25d3eb21d 100644 --- a/crates/edr_provider/tests/issues/issue_407.rs +++ b/crates/edr_provider/tests/issues/issue_407.rs @@ -1,4 +1,4 @@ -use edr_eth::chain_spec::L1ChainSpec; +use edr_eth::spec::L1ChainSpec; use edr_provider::{test_utils::create_test_config, time::CurrentTime, NoopLogger, Provider}; use serde_json::json; use tokio::runtime; diff --git a/crates/edr_provider/tests/issues/issue_503.rs b/crates/edr_provider/tests/issues/issue_503.rs index ed9774ec1..bfda34952 100644 --- a/crates/edr_provider/tests/issues/issue_503.rs +++ b/crates/edr_provider/tests/issues/issue_503.rs @@ -1,6 +1,6 @@ use std::str::FromStr as _; -use edr_eth::{chain_spec::L1ChainSpec, Address, SpecId, U256}; +use edr_eth::{spec::L1ChainSpec, Address, SpecId, U256}; use edr_provider::{ hardhat_rpc_types::ForkConfig, test_utils::create_test_config_with_fork, time::CurrentTime, MethodInvocation, NoopLogger, Provider, ProviderRequest, diff --git a/crates/edr_provider/tests/issues/issue_533.rs b/crates/edr_provider/tests/issues/issue_533.rs index 5ab443d06..cd6b8cc7c 100644 --- a/crates/edr_provider/tests/issues/issue_533.rs +++ b/crates/edr_provider/tests/issues/issue_533.rs @@ -1,6 +1,6 @@ use std::str::FromStr as _; -use edr_eth::{chain_spec::L1ChainSpec, B256}; +use edr_eth::{spec::L1ChainSpec, B256}; use edr_provider::{ hardhat_rpc_types::ForkConfig, test_utils::create_test_config_with_fork, time::CurrentTime, MethodInvocation, NoopLogger, Provider, ProviderRequest, diff --git a/crates/edr_provider/tests/rip7212.rs b/crates/edr_provider/tests/rip7212.rs index dc98a3583..eff1cf126 100644 --- a/crates/edr_provider/tests/rip7212.rs +++ b/crates/edr_provider/tests/rip7212.rs @@ -1,6 +1,6 @@ #![cfg(feature = "test-utils")] -use edr_eth::{bytes, chain_spec::L1ChainSpec, Bytes}; +use edr_eth::{bytes, spec::L1ChainSpec, Bytes}; use edr_provider::{ test_utils::create_test_config, time::CurrentTime, MethodInvocation, NoopLogger, Provider, ProviderRequest, diff --git a/crates/edr_provider/tests/timestamp.rs b/crates/edr_provider/tests/timestamp.rs index 43492d52e..fba9bc4cf 100644 --- a/crates/edr_provider/tests/timestamp.rs +++ b/crates/edr_provider/tests/timestamp.rs @@ -2,7 +2,7 @@ use std::sync::Arc; -use edr_eth::{chain_spec::L1ChainSpec, PreEip1898BlockSpec, B256}; +use edr_eth::{spec::L1ChainSpec, PreEip1898BlockSpec, B256}; use edr_provider::{ test_utils::create_test_config, time::{MockTime, TimeSinceEpoch}, diff --git a/crates/edr_rpc_client/Cargo.toml b/crates/edr_rpc_client/Cargo.toml index cd1debcda..9b4c092fe 100644 --- a/crates/edr_rpc_client/Cargo.toml +++ b/crates/edr_rpc_client/Cargo.toml @@ -4,7 +4,7 @@ version = "0.3.5" edition = "2021" [dependencies] -anyhow = { version = "1.0.75", default-features = false, features = ["std"] } +anyhow = { version = "1.0.89", default-features = false, features = ["std"] } edr_eth = { version = "0.3.5", path = "../edr_eth", features = ["serde"] } futures = { version = "0.3.28", default-features = false, features = ["std"] } hex = { version = "0.4.3", default-features = false, features = ["alloc"] } diff --git a/crates/edr_rpc_eth/Cargo.toml b/crates/edr_rpc_eth/Cargo.toml index 37761bb01..3bed84ac5 100644 --- a/crates/edr_rpc_eth/Cargo.toml +++ b/crates/edr_rpc_eth/Cargo.toml @@ -4,7 +4,8 @@ version = "0.3.5" edition = "2021" [dependencies] -alloy-serde = { version = "0.2.0", default-features = false, features = ["std"] } +alloy-eips = { version = "0.3", default-features = false } +alloy-serde = { version = "0.3.5", default-features = false, features = ["std"] } derive-where = { version = "1.2.7", default-features = false } edr_eth = { version = "0.3.5", path = "../edr_eth", features = ["serde"] } edr_rpc_client = { version = "0.3.5", path = "../edr_rpc_client" } @@ -17,7 +18,7 @@ tokio = { version = "1.21.2", default-features = false, features = ["macros"] } tracing = { version = "0.1.37", default-features = false, features = ["attributes", "std"], optional = true } [dev-dependencies] -anyhow = { version = "1.0.75", default-features = false, features = ["std"] } +anyhow = { version = "1.0.89", default-features = false, features = ["std"] } assert-json-diff = "2.0.2" edr_test_utils = { version = "0.3.5", path = "../edr_test_utils" } mockito = { version = "1.0.2", default-features = false } diff --git a/crates/edr_rpc_eth/src/client.rs b/crates/edr_rpc_eth/src/client.rs index ee1b61887..04ac58d66 100644 --- a/crates/edr_rpc_eth/src/client.rs +++ b/crates/edr_rpc_eth/src/client.rs @@ -26,7 +26,7 @@ const MAX_PARALLEL_REQUESTS: usize = 20; #[derive_where(Debug)] pub struct EthRpcClient { inner: RpcClient, - _phantom: std::marker::PhantomData, + phantom: std::marker::PhantomData, } impl EthRpcClient { @@ -42,7 +42,7 @@ impl EthRpcClient { let inner = RpcClient::new(url, cache_dir, extra_headers)?; Ok(Self { inner, - _phantom: std::marker::PhantomData, + phantom: std::marker::PhantomData, }) } @@ -322,7 +322,7 @@ impl EthRpcClient { mod tests { use std::{ops::Deref, str::FromStr}; - use edr_eth::chain_spec::L1ChainSpec; + use edr_eth::spec::L1ChainSpec; use reqwest::StatusCode; use tempfile::TempDir; diff --git a/crates/edr_rpc_eth/src/receipt.rs b/crates/edr_rpc_eth/src/receipt.rs index 673d7e2fa..e456fe37f 100644 --- a/crates/edr_rpc_eth/src/receipt.rs +++ b/crates/edr_rpc_eth/src/receipt.rs @@ -2,11 +2,10 @@ use std::marker::PhantomData; use edr_eth::{ eips::eip2718::TypedEnvelope, - env::SignedAuthorization, log::FilterLog, receipt::{self, Execution, Receipt as _, TransactionReceipt}, transaction::{self, TransactionType as _}, - Address, Bloom, SpecId, B256, U256, + Address, Bloom, SignedAuthorization, SpecId, B256, U256, }; use serde::{Deserialize, Serialize}; @@ -189,7 +188,7 @@ impl TryFrom for receipt::BlockReceipt: Receipt; diff --git a/crates/edr_rpc_eth/src/test_utils.rs b/crates/edr_rpc_eth/src/test_utils.rs index c74d4243c..8f3265cb4 100644 --- a/crates/edr_rpc_eth/src/test_utils.rs +++ b/crates/edr_rpc_eth/src/test_utils.rs @@ -1,6 +1,6 @@ #[macro_export] macro_rules! impl_execution_receipt_tests { - ($chain_spec:ident => { + ($chain_spec:ty => { $( $name:ident => $receipt:expr, )+ diff --git a/crates/edr_solidity/src/contracts_identifier/radix_tree.rs b/crates/edr_solidity/src/contracts_identifier/radix_tree.rs index 575e73d56..933d144f4 100644 --- a/crates/edr_solidity/src/contracts_identifier/radix_tree.rs +++ b/crates/edr_solidity/src/contracts_identifier/radix_tree.rs @@ -121,14 +121,14 @@ impl RadixNode { } } - /** - * Returns a tuple containing: - * - a boolean indicating if the word was matched exactly - * - the number of bytes matched - * - the node that matched the word - * If the word is not matched exactly, the node will be the one that - * matched the longest prefix. - */ + /// Returns a tuple containing: + /// + /// - a boolean indicating if the word was matched exactly + /// - the number of bytes matched + /// - the node that matched the word + /// + /// If the word is not matched exactly, the node will be the one that + /// matched the longest prefix. pub fn longest_match(&self, word: &[u8]) -> (bool, usize, &RadixNode) { let prefix_length = longest_prefix_length(word, &self.content); diff --git a/crates/tools/Cargo.toml b/crates/tools/Cargo.toml index 3c4ae501b..c76e86a8f 100644 --- a/crates/tools/Cargo.toml +++ b/crates/tools/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -anyhow = { version = "1.0.75" } +anyhow = { version = "1.0.89" } cfg-if = "1.0.0" clap = { version = "3.2.20", features = ["derive"] } derive-where = { version = "1.2.7", default-features = false } diff --git a/crates/tools/src/remote_block.rs b/crates/tools/src/remote_block.rs index 7641e8b7b..3b48e8247 100644 --- a/crates/tools/src/remote_block.rs +++ b/crates/tools/src/remote_block.rs @@ -2,12 +2,12 @@ use core::fmt::Debug; use clap::ValueEnum; use edr_eth::{ - chain_spec::L1ChainSpec, log::FilterLog, result::InvalidTransaction, + log::FilterLog, result::InvalidTransaction, spec::L1ChainSpec, transaction::TransactionValidation, }; use edr_evm::test_utils::run_full_block; use edr_optimism::OptimismChainSpec; -use edr_provider::spec::SyncChainSpec; +use edr_provider::spec::SyncRuntimeSpec; use edr_rpc_eth::client::EthRpcClient; #[derive(Clone, ValueEnum)] @@ -43,7 +43,7 @@ pub async fn replay_chain_specific_block( ) -> anyhow::Result<()> where ChainSpecT: Debug - + SyncChainSpec< + + SyncRuntimeSpec< Block: Default, Hardfork: Debug, ExecutionReceipt: PartialEq, diff --git a/crates/tools/src/scenario.rs b/crates/tools/src/scenario.rs index a408290f9..6eb11f7a9 100644 --- a/crates/tools/src/scenario.rs +++ b/crates/tools/src/scenario.rs @@ -8,8 +8,8 @@ use std::{ use anyhow::Context; use derive_where::derive_where; -use edr_eth::chain_spec::L1ChainSpec; -use edr_evm::{blockchain::BlockchainError, chain_spec::ChainSpec}; +use edr_eth::spec::L1ChainSpec; +use edr_evm::{blockchain::BlockchainError, spec::RuntimeSpec}; use edr_provider::{time::CurrentTime, Logger, ProviderError, ProviderRequest}; use edr_rpc_eth::jsonrpc; use flate2::bufread::GzDecoder; @@ -182,11 +182,11 @@ async fn load_json( } #[derive_where(Clone, Default)] -struct DisabledLogger { +struct DisabledLogger { _phantom: PhantomData, } -impl> Logger for DisabledLogger { +impl> Logger for DisabledLogger { type BlockchainError = BlockchainError; fn is_enabled(&self) -> bool { diff --git a/rust-toolchain b/rust-toolchain index 17420a571..d456f7459 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -1.79 +1.80