From 2aff1949a31245bf9c1d7bd75ab56329779e9daa Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Sat, 1 Jul 2023 00:20:54 +0200 Subject: [PATCH] feat: alloy migration --- Cargo.lock | 516 ++++++++++++++---- bins/revme/Cargo.toml | 7 +- bins/revme/src/cli_env.rs | 29 +- bins/revme/src/statetest/merkle_trie.rs | 97 ++-- .../src/statetest/models/deserializer.rs | 77 +-- bins/revme/src/statetest/models/mod.rs | 34 +- bins/revme/src/statetest/runner.rs | 111 ++-- crates/interpreter/Cargo.toml | 10 +- crates/interpreter/src/gas/calc.rs | 6 +- crates/interpreter/src/host.rs | 28 +- crates/interpreter/src/host/dummy_host.rs | 26 +- crates/interpreter/src/inner_models.rs | 30 +- crates/interpreter/src/instructions/host.rs | 14 +- .../interpreter/src/instructions/host_env.rs | 4 +- crates/interpreter/src/instructions/macros.rs | 25 +- crates/interpreter/src/instructions/system.rs | 8 +- .../interpreter/src/interpreter/contract.rs | 16 +- crates/interpreter/src/interpreter/memory.rs | 3 +- crates/interpreter/src/interpreter/stack.rs | 7 +- crates/precompile/Cargo.toml | 9 +- crates/precompile/src/blake2.rs | 2 +- crates/precompile/src/bn128.rs | 8 +- crates/precompile/src/hash.rs | 4 +- crates/precompile/src/identity.rs | 2 +- crates/precompile/src/lib.rs | 27 +- crates/precompile/src/modexp.rs | 4 +- crates/precompile/src/secp256k1.rs | 22 +- crates/primitives/CHANGELOG.md | 2 +- crates/primitives/Cargo.toml | 30 +- crates/primitives/src/bits.rs | 378 ------------- crates/primitives/src/bytecode.rs | 6 +- crates/primitives/src/constants.rs | 5 +- crates/primitives/src/db.rs | 22 +- crates/primitives/src/db/components.rs | 10 +- crates/primitives/src/db/components/state.rs | 20 +- crates/primitives/src/env.rs | 21 +- crates/primitives/src/lib.rs | 23 +- crates/primitives/src/log.rs | 8 +- crates/primitives/src/result.rs | 10 +- crates/primitives/src/state.rs | 9 +- crates/primitives/src/utilities.rs | 64 +-- crates/revm/CHANGELOG.md | 2 +- crates/revm/Cargo.toml | 6 +- crates/revm/benches/bench.rs | 39 +- crates/revm/src/db/emptydb.rs | 12 +- crates/revm/src/db/ethersdb.rs | 18 +- crates/revm/src/db/in_memory_db.rs | 41 +- crates/revm/src/db/states/bundle_state.rs | 16 +- crates/revm/src/db/states/cache.rs | 18 +- crates/revm/src/db/states/changes.rs | 10 +- crates/revm/src/db/states/state.rs | 22 +- crates/revm/src/db/states/transition_state.rs | 8 +- crates/revm/src/evm_impl.rs | 41 +- crates/revm/src/inspector.rs | 12 +- crates/revm/src/inspector/customprinter.rs | 34 +- crates/revm/src/inspector/gas.rs | 24 +- crates/revm/src/inspector/tracer_eip3155.rs | 13 +- crates/revm/src/journaled_state.rs | 82 +-- documentation/bins/revm-test.md | 1 - documentation/bins/revme.md | 1 - .../src/crates/interpreter/inner_models.md | 16 +- documentation/src/crates/precompile.md | 2 +- documentation/src/crates/primitives.md | 5 +- documentation/src/crates/primitives/bits.md | 10 +- .../src/crates/primitives/database.md | 2 +- documentation/src/crates/primitives/log.md | 2 +- documentation/src/crates/primitives/state.md | 2 +- documentation/src/crates/primitives/utils.md | 2 - documentation/src/crates/revm/evm_impl.md | 4 +- documentation/src/crates/revm/inspector.md | 12 +- documentation/src/examples.md | 18 +- examples/fork_ref_transact.rs | 18 +- 72 files changed, 968 insertions(+), 1259 deletions(-) delete mode 100644 crates/primitives/src/bits.rs delete mode 100644 documentation/bins/revm-test.md delete mode 100644 documentation/bins/revme.md diff --git a/Cargo.lock b/Cargo.lock index d8ae289871..069e94ea55 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,9 +41,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.2" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +checksum = "6748e8def348ed4d14996fa801f4122cd763fff530258cdc03f64b25f89d3a5a" dependencies = [ "memchr", ] @@ -54,6 +54,51 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +[[package]] +name = "alloy-primitives" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66f73f11dcfbf8bb763d88fb1d082fe7cca0a00d3227d9921bdbd52ce5e013e2" +dependencies = [ + "alloy-rlp", + "arbitrary", + "bytes", + "cfg-if", + "const-hex", + "derive_arbitrary", + "derive_more", + "hex-literal", + "itoa", + "proptest", + "proptest-derive", + "ruint", + "serde", + "tiny-keccak", +] + +[[package]] +name = "alloy-rlp" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f938f00332d63a5b0ac687bd6f46d03884638948921d9f8b50c59563d421ae25" +dependencies = [ + "alloy-rlp-derive", + "arrayvec", + "bytes", + "smol_str", +] + +[[package]] +name = "alloy-rlp-derive" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aa5bb468bc7c46e0c5074d418f575262ff79451242e5ac1380121ed4e23c4fd" +dependencies = [ + "proc-macro2 1.0.66", + "quote 1.0.32", + "syn 2.0.28", +] + [[package]] name = "android-tzdata" version = "0.1.1" @@ -83,9 +128,9 @@ checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" [[package]] name = "anyhow" -version = "1.0.72" +version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854" +checksum = "f768393e7fabd388fe8409b13faa4d93ab0fef35db1508438dfdb066918bcf38" [[package]] name = "arbitrary" @@ -96,6 +141,130 @@ dependencies = [ "derive_arbitrary", ] +[[package]] +name = "ark-ff" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b3235cc41ee7a12aaaf2c575a2ad7b46713a8a50bda2fc3b003a04845c05dd6" +dependencies = [ + "ark-ff-asm 0.3.0", + "ark-ff-macros 0.3.0", + "ark-serialize 0.3.0", + "ark-std 0.3.0", + "derivative", + "num-bigint", + "num-traits", + "paste", + "rustc_version 0.3.3", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm 0.4.2", + "ark-ff-macros 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", + "derivative", + "digest 0.10.7", + "itertools", + "num-bigint", + "num-traits", + "paste", + "rustc_version 0.4.0", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db02d390bf6643fb404d3d22d31aee1c4bc4459600aef9113833d17e786c6e44" +dependencies = [ + "quote 1.0.32", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote 1.0.32", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fd794a08ccb318058009eefdf15bcaaaaf6f8161eb3345f907222bac38b20" +dependencies = [ + "num-bigint", + "num-traits", + "quote 1.0.32", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2 1.0.66", + "quote 1.0.32", + "syn 1.0.109", +] + +[[package]] +name = "ark-serialize" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6c2b318ee6e10f8c2853e73a83adc0ccb88995aa978d8a3408d492ab2ee671" +dependencies = [ + "ark-std 0.3.0", + "digest 0.9.0", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-std 0.4.0", + "digest 0.10.7", + "num-bigint", +] + +[[package]] +name = "ark-std" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df2c09229cbc5a028b1d70e00fdb2acee28b1055dfb5ca73eea49c5a25c4e7c" +dependencies = [ + "num-traits", + "rand", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand", +] + [[package]] name = "arrayvec" version = "0.7.4" @@ -104,13 +273,13 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "async-trait" -version = "0.1.72" +version = "0.1.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6dde6e4ed435a4c1ee4e73592f5ba9da2151af10076cc04858746af9352d09" +checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2 1.0.66", "quote 1.0.32", - "syn 2.0.27", + "syn 2.0.28", ] [[package]] @@ -121,7 +290,7 @@ checksum = "b6d7b9decdf35d8908a7e3ef02f64c5e9b1695e230154c0e8de3969142d9b94c" dependencies = [ "futures", "pharos", - "rustc_version", + "rustc_version 0.4.0", ] [[package]] @@ -323,9 +492,12 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.0.79" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "305fe645edc1442a0fa8b6726ba61d422798d37a52e12eaecf4b022ebbb88f01" +dependencies = [ + "libc", +] [[package]] name = "cfg-if" @@ -397,18 +569,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.3.19" +version = "4.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd304a20bff958a57f04c4e96a2e7594cc4490a0e809cbd48bb6437edaa452d" +checksum = "c27cdf28c0f604ba3f512b0c9a409f8de8513e4816705deb0498b627e7c3a3fd" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.3.19" +version = "4.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01c6a3f08f1fe5662a35cfe393aec09c4df95f60ee93b7556505260f75eee9e1" +checksum = "08a9f1ab5e9f01a9b81f202e8562eb9a10de70abf9eaeac1be465c28b75aa4aa" dependencies = [ "anstyle", "clap_lex", @@ -489,11 +661,23 @@ dependencies = [ "windows-sys 0.45.0", ] +[[package]] +name = "const-hex" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "268f52aae268980d03dd9544c1ea591965b2735b038d6998d6e4ab37c8c24445" +dependencies = [ + "cfg-if", + "cpufeatures", + "hex", + "serde", +] + [[package]] name = "const-oid" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "795bc6e66a8e340f075fcf6227e417a2dc976b92b91f3cdc778bb858778b6747" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" [[package]] name = "convert_case" @@ -519,7 +703,7 @@ dependencies = [ "anes", "cast", "ciborium", - "clap 4.3.19", + "clap 4.3.21", "criterion-plot", "is-terminal", "itertools", @@ -634,14 +818,25 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "der" -version = "0.7.7" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7ed52955ce76b1554f509074bb357d3fb8ac9b51288a65a3fd480d1dfba946" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" dependencies = [ "const-oid", "zeroize", ] +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2 1.0.66", + "quote 1.0.32", + "syn 1.0.109", +] + [[package]] name = "derive_arbitrary" version = "1.3.1" @@ -650,7 +845,7 @@ checksum = "53e0efad4403bfc52dc201159c4b842a246a14b98c64b55dfd0f2d89729dfeb8" dependencies = [ "proc-macro2 1.0.66", "quote 1.0.32", - "syn 2.0.27", + "syn 2.0.28", ] [[package]] @@ -662,7 +857,7 @@ dependencies = [ "convert_case", "proc-macro2 1.0.66", "quote 1.0.32", - "rustc_version", + "rustc_version 0.4.0", "syn 1.0.109", ] @@ -767,7 +962,7 @@ checksum = "b893c4eb2dc092c811165f84dc7447fae16fb66521717968c34c509b39b1a5c5" dependencies = [ "proc-macro2 1.0.66", "quote 1.0.32", - "syn 2.0.27", + "syn 2.0.28", ] [[package]] @@ -778,9 +973,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" dependencies = [ "errno-dragonfly", "libc", @@ -974,6 +1169,17 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" +[[package]] +name = "fastrlp" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139834ddba373bbdd213dffe02c8d110508dcf1726c2be27e8d1f7d7e1856418" +dependencies = [ + "arrayvec", + "auto_impl", + "bytes", +] + [[package]] name = "ff" version = "0.13.0" @@ -1073,7 +1279,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2 1.0.66", "quote 1.0.32", - "syn 2.0.27", + "syn 2.0.28", ] [[package]] @@ -1319,9 +1525,9 @@ checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" @@ -1431,9 +1637,9 @@ dependencies = [ [[package]] name = "indicatif" -version = "0.17.5" +version = "0.17.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ff8cc23a7393a397ed1d7f56e6365cba772aba9f9912ab968b03043c395d057" +checksum = "0b297dc40733f23a0e52728a58fa9489a5b7638a324932de16b41adc3ef80730" dependencies = [ "console", "instant", @@ -1547,15 +1753,15 @@ checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" [[package]] name = "linux-raw-sys" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" +checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" [[package]] name = "log" -version = "0.4.19" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "memchr" @@ -1625,9 +1831,9 @@ dependencies = [ [[package]] name = "num-complex" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02e0d21255c828d6f128a1e41534206671e8c3ea0c62f32291e808dc82cff17d" +checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214" dependencies = [ "num-traits", ] @@ -1703,7 +1909,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2 1.0.66", "quote 1.0.32", - "syn 2.0.27", + "syn 2.0.28", ] [[package]] @@ -1790,6 +1996,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + [[package]] name = "pbkdf2" version = "0.11.0" @@ -1815,6 +2027,16 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +[[package]] +name = "pest" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1acb4a4365a13f749a93f1a094a7805e5cfa0955373a9de860d962eaa3a5fe5a" +dependencies = [ + "thiserror", + "ucd-trie", +] + [[package]] name = "pharos" version = "0.5.3" @@ -1822,27 +2044,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9567389417feee6ce15dd6527a8a1ecac205ef62c2932bcf3d9f6fc5b78b414" dependencies = [ "futures", - "rustc_version", + "rustc_version 0.4.0", ] [[package]] name = "pin-project" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "030ad2bc4db10a8944cb0d837f158bdfec4d4a4873ab701a95046770d11f8842" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2 1.0.66", "quote 1.0.32", - "syn 2.0.27", + "syn 2.0.28", ] [[package]] @@ -2121,9 +2343,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.9.1" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" +checksum = "81bc1d4caf89fac26a70747fe603c130093b53c773888797a6329091246d651a" dependencies = [ "aho-corasick", "memchr", @@ -2133,9 +2355,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.3" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310" +checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69" dependencies = [ "aho-corasick", "memchr", @@ -2199,7 +2421,6 @@ version = "3.3.0" dependencies = [ "anyhow", "auto_impl", - "bytes", "criterion", "ethers-contract", "ethers-core", @@ -2227,7 +2448,6 @@ dependencies = [ "proptest-derive", "revm-primitives", "serde", - "sha3", ] [[package]] @@ -2242,7 +2462,6 @@ dependencies = [ "ripemd", "secp256k1", "sha2 0.10.7", - "sha3", "substrate-bn", ] @@ -2250,6 +2469,8 @@ dependencies = [ name = "revm-primitives" version = "1.1.2" dependencies = [ + "alloy-primitives", + "alloy-rlp", "arbitrary", "auto_impl", "bitflags 2.4.0", @@ -2257,17 +2478,14 @@ dependencies = [ "bytes", "derive_more", "enumn", - "fixed-hash", "hashbrown 0.14.0", "hex", "hex-literal", "primitive-types", "proptest", "proptest-derive", - "rlp", "ruint", "serde", - "sha3", "to-binary", ] @@ -2275,20 +2493,17 @@ dependencies = [ name = "revme" version = "0.2.0" dependencies = [ - "bytes", + "alloy-rlp", "hash-db", "hashbrown 0.14.0", "hex", "hex-literal", "indicatif", "plain_hasher", - "primitive-types", "revm", - "rlp", "ruint", "serde", "serde_json", - "sha3", "structopt", "thiserror", "triehash", @@ -2353,17 +2568,26 @@ dependencies = [ [[package]] name = "ruint" -version = "1.9.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77e1574d439643c8962edf612a888e7cc5581bcdf36cb64e6bc88466b03b2daa" +checksum = "95294d6e3a6192f3aabf91c38f56505a625aa495533442744185a36d75a790c4" dependencies = [ + "alloy-rlp", "arbitrary", + "ark-ff 0.3.0", + "ark-ff 0.4.2", + "bytes", + "fastrlp", + "num-bigint", + "parity-scale-codec", "primitive-types", "proptest", + "rand", "rlp", "ruint-macro", "serde", - "thiserror", + "valuable", + "zeroize", ] [[package]] @@ -2384,20 +2608,29 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver 0.11.0", +] + [[package]] name = "rustc_version" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver", + "semver 1.0.18", ] [[package]] name = "rustix" -version = "0.38.4" +version = "0.38.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" +checksum = "19ed4fa021d81c8392ce04db050a3da9a60299050b7ae1cf482d862b54a7218f" dependencies = [ "bitflags 2.4.0", "errno", @@ -2408,13 +2641,13 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.5" +version = "0.21.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79ea77c539259495ce8ca47f53e66ae0330a8819f67e23ac96ca02f50e7b7d36" +checksum = "1d1feddffcfcc0b33f5c6ce9a29e341e4cd59c3f78e7ee45f4a40c038b1d6cbb" dependencies = [ "log", "ring", - "rustls-webpki 0.101.2", + "rustls-webpki 0.101.3", "sct", ] @@ -2439,9 +2672,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.101.2" +version = "0.101.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "513722fd73ad80a71f72b61009ea1b584bcfa1483ca93949c8f290298837fa59" +checksum = "261e9e0888cba427c3316e6322805653c9425240b6fd96cee7cb671ab70ab8d0" dependencies = [ "ring", "untrusted", @@ -2573,12 +2806,30 @@ dependencies = [ "cc", ] +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + [[package]] name = "semver" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] + [[package]] name = "send_wrapper" version = "0.4.0" @@ -2593,22 +2844,22 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.179" +version = "1.0.183" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a5bf42b8d227d4abf38a1ddb08602e229108a517cd4e5bb28f9c7eaafdce5c0" +checksum = "32ac8da02677876d532745a130fc9d8e6edfa81a269b107c5b00829b91d8eb3c" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.179" +version = "1.0.183" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "741e124f5485c7e60c03b043f79f320bff3527f4bbf12cf3831750dc46a0ec2c" +checksum = "aafe972d60b0b9bee71a91b92fee2d4fb3c9d7e8f6b179aa99f27203d99a4816" dependencies = [ "proc-macro2 1.0.66", "quote 1.0.32", - "syn 2.0.27", + "syn 2.0.28", ] [[package]] @@ -2699,6 +2950,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "smol_str" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74212e6bbe9a4352329b2f68ba3130c15a3f26fe88ff22dbdc6cdd58fa85e99c" +dependencies = [ + "serde", +] + [[package]] name = "socket2" version = "0.4.9" @@ -2782,15 +3042,15 @@ dependencies = [ [[package]] name = "strum_macros" -version = "0.25.1" +version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6069ca09d878a33f883cc06aaa9718ede171841d3832450354410b718b097232" +checksum = "ad8d03b598d3d0fff69bf533ee3ef19b8eeb342729596df84bcc7e1f96ec4059" dependencies = [ "heck 0.4.1", "proc-macro2 1.0.66", "quote 1.0.32", "rustversion", - "syn 2.0.27", + "syn 2.0.28", ] [[package]] @@ -2836,9 +3096,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.27" +version = "2.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0" +checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" dependencies = [ "proc-macro2 1.0.66", "quote 1.0.32", @@ -2853,9 +3113,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.7.0" +version = "3.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5486094ee78b2e5038a6382ed7645bc084dc2ec433426ca4c3cb61e2007b8998" +checksum = "dc02fddf48964c42031a0b3fe0428320ecf3a73c401040fc0096f97794310651" dependencies = [ "cfg-if", "fastrand", @@ -2875,22 +3135,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.44" +version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" +checksum = "dedd246497092a89beedfe2c9f176d44c1b672ea6090edc20544ade01fbb7ea0" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.44" +version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" +checksum = "7d7b1fadccbbc7e19ea64708629f9d8dccd007c260d66485f20a6d41bc1cf4b3" dependencies = [ "proc-macro2 1.0.66", "quote 1.0.32", - "syn 2.0.27", + "syn 2.0.28", ] [[package]] @@ -2961,7 +3221,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2 1.0.66", "quote 1.0.32", - "syn 2.0.27", + "syn 2.0.28", ] [[package]] @@ -3046,7 +3306,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2 1.0.66", "quote 1.0.32", - "syn 2.0.27", + "syn 2.0.28", ] [[package]] @@ -3111,6 +3371,12 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + [[package]] name = "uint" version = "0.9.5" @@ -3207,6 +3473,12 @@ dependencies = [ "serde", ] +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "vec_map" version = "0.8.2" @@ -3274,7 +3546,7 @@ dependencies = [ "once_cell", "proc-macro2 1.0.66", "quote 1.0.32", - "syn 2.0.27", + "syn 2.0.28", "wasm-bindgen-shared", ] @@ -3308,7 +3580,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2 1.0.66", "quote 1.0.32", - "syn 2.0.27", + "syn 2.0.28", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3403,7 +3675,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets 0.48.1", + "windows-targets 0.48.2", ] [[package]] @@ -3423,17 +3695,17 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.1" +version = "0.48.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" +checksum = "d1eeca1c172a285ee6c2c84c341ccea837e7c01b12fbb2d0fe3c9e550ce49ec8" dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", + "windows_aarch64_gnullvm 0.48.2", + "windows_aarch64_msvc 0.48.2", + "windows_i686_gnu 0.48.2", + "windows_i686_msvc 0.48.2", + "windows_x86_64_gnu 0.48.2", + "windows_x86_64_gnullvm 0.48.2", + "windows_x86_64_msvc 0.48.2", ] [[package]] @@ -3444,9 +3716,9 @@ checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.0" +version = "0.48.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +checksum = "b10d0c968ba7f6166195e13d593af609ec2e3d24f916f081690695cf5eaffb2f" [[package]] name = "windows_aarch64_msvc" @@ -3456,9 +3728,9 @@ checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_aarch64_msvc" -version = "0.48.0" +version = "0.48.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +checksum = "571d8d4e62f26d4932099a9efe89660e8bd5087775a2ab5cdd8b747b811f1058" [[package]] name = "windows_i686_gnu" @@ -3468,9 +3740,9 @@ checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_gnu" -version = "0.48.0" +version = "0.48.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "2229ad223e178db5fbbc8bd8d3835e51e566b8474bfca58d2e6150c48bb723cd" [[package]] name = "windows_i686_msvc" @@ -3480,9 +3752,9 @@ checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_i686_msvc" -version = "0.48.0" +version = "0.48.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +checksum = "600956e2d840c194eedfc5d18f8242bc2e17c7775b6684488af3a9fff6fe3287" [[package]] name = "windows_x86_64_gnu" @@ -3492,9 +3764,9 @@ checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnu" -version = "0.48.0" +version = "0.48.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +checksum = "ea99ff3f8b49fb7a8e0d305e5aec485bd068c2ba691b6e277d29eaeac945868a" [[package]] name = "windows_x86_64_gnullvm" @@ -3504,9 +3776,9 @@ checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" +version = "0.48.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +checksum = "8f1a05a1ece9a7a0d5a7ccf30ba2c33e3a61a30e042ffd247567d1de1d94120d" [[package]] name = "windows_x86_64_msvc" @@ -3516,15 +3788,15 @@ checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "windows_x86_64_msvc" -version = "0.48.0" +version = "0.48.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +checksum = "d419259aba16b663966e29e6d7c6ecfa0bb8425818bb96f6f1f3c3eb71a6e7b9" [[package]] name = "winnow" -version = "0.5.1" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b5872fa2e10bd067ae946f927e726d7d603eaeb6e02fa6a350e0722d2b8c11" +checksum = "5504cc7644f4b593cbc05c4a55bf9bd4e94b867c3c0bd440934174d50482427d" dependencies = [ "memchr", ] @@ -3549,7 +3821,7 @@ dependencies = [ "js-sys", "log", "pharos", - "rustc_version", + "rustc_version 0.4.0", "send_wrapper 0.6.0", "thiserror", "wasm-bindgen", @@ -3571,3 +3843,17 @@ name = "zeroize" version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2 1.0.66", + "quote 1.0.32", + "syn 2.0.28", +] diff --git a/bins/revme/Cargo.toml b/bins/revme/Cargo.toml index d8e55964ec..f5f25802aa 100644 --- a/bins/revme/Cargo.toml +++ b/bins/revme/Cargo.toml @@ -10,23 +10,20 @@ version = "0.2.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -bytes = "1.4" hash-db = "0.15" hashbrown = "0.14" hex = "0.4" indicatif = "0.17" plain_hasher = "0.2" -primitive-types = { version = "0.12", features = ["rlp", "serde"] } revm = { path = "../../crates/revm", version = "3.3.0", default-features = false, features = [ "ethersdb", "std", "serde", ] } -rlp = { version = "0.5", default-features = false } -ruint = { version = "1.8.0", features = ["rlp", "serde"] } +alloy-rlp = { version = "0.3", default-features = false, features = ["arrayvec"] } +ruint = { version = "1.9.0", features = ["rlp", "serde"] } serde = { version = "1.0", features = ["derive", "rc"] } serde_json = { version = "1.0", features = ["preserve_order"] } -sha3 = { version = "0.10", default-features = false } structopt = "0.3" thiserror = "1.0" triehash = "0.8" diff --git a/bins/revme/src/cli_env.rs b/bins/revme/src/cli_env.rs index dd48f11c8d..9ab82dc3d3 100644 --- a/bins/revme/src/cli_env.rs +++ b/bins/revme/src/cli_env.rs @@ -1,7 +1,4 @@ -use std::str::FromStr; - -use bytes::Bytes; -use revm::primitives::{Env, TransactTo, B160, U256}; +use revm::primitives::{Address, Bytes, Env, TransactTo, U256}; use structopt::StructOpt; #[derive(StructOpt, Clone, Debug)] @@ -63,8 +60,8 @@ pub struct CliEnvBlock { pub number: Option, /// Coinbase or miner or address that created and signed the block. /// Address where we are going to send gas spend - #[structopt(long = "env.block.coinbase", parse(try_from_str = parse_b160))] - pub coinbase: Option, + #[structopt(long = "env.block.coinbase")] + pub coinbase: Option
, #[structopt(long = "env.block.timestamp")] pub timestamp: Option, #[structopt(long = "env.block.difficulty")] @@ -77,32 +74,24 @@ pub struct CliEnvBlock { #[derive(StructOpt, Clone, Debug)] pub struct CliEnvTx { /// Caller or Author or tx signer - #[structopt(long = "env.tx.caller", parse(try_from_str = parse_b160))] - pub caller: Option, + #[structopt(long = "env.tx.caller")] + pub caller: Option
, #[structopt(long = "env.tx.gas_limit")] pub tx_gas_limit: Option, #[structopt(long = "env.tx.gas_price")] pub gas_price: Option, #[structopt(long = "env.tx.gas_priority_fee")] pub gas_priority_fee: Option, - #[structopt(long = "env.tx.to", parse(try_from_str = parse_b160))] - pub transact_to: Option, + #[structopt(long = "env.tx.to")] + pub transact_to: Option
, #[structopt(long = "env.tx.value")] pub value: Option, - #[structopt(long = "env.tx.data", parse(try_from_str = parse_hex))] + #[structopt(long = "env.tx.data")] pub data: Option, #[structopt(long = "env.tx.chain_id")] pub chain_id: Option, #[structopt(long = "env.tx.nonce")] pub nonce: Option, //#[structopt(long = "env.")] - //TODO pub access_list: Vec<(B160, Vec)>, -} - -fn parse_hex(src: &str) -> Result { - Ok(Bytes::from(hex::decode(src)?)) -} - -pub fn parse_b160(input: &str) -> Result::Err> { - B160::from_str(input) + //TODO pub access_list: Vec<(Address, Vec)>, } diff --git a/bins/revme/src/statetest/merkle_trie.rs b/bins/revme/src/statetest/merkle_trie.rs index b37ec4a2ee..cda0bfd2e1 100644 --- a/bins/revme/src/statetest/merkle_trie.rs +++ b/bins/revme/src/statetest/merkle_trie.rs @@ -1,79 +1,74 @@ -use bytes::Bytes; +use alloy_rlp::{RlpEncodable, RlpMaxEncodedLen}; use hash_db::Hasher; use plain_hasher::PlainHasher; -use primitive_types::{H160, H256}; use revm::{ db::PlainAccount, - primitives::{keccak256, Log, B160, B256, U256}, + primitives::{keccak256, Address, Log, B256, U256}, }; -use rlp::RlpStream; -use sha3::{Digest, Keccak256}; use triehash::sec_trie_root; -pub fn log_rlp_hash(logs: Vec) -> B256 { - //https://github.com/ethereum/go-ethereum/blob/356bbe343a30789e77bb38f25983c8f2f2bfbb47/cmd/evm/internal/t8ntool/execution.go#L255 - let mut stream = RlpStream::new(); - stream.begin_unbounded_list(); - for log in logs { - stream.begin_list(3); - stream.append(&log.address.0.as_ref()); - stream.begin_unbounded_list(); - for topic in log.topics { - stream.append(&topic.0.as_ref()); - } - stream.finalize_unbounded_list(); - stream.append(&log.data); - } - stream.finalize_unbounded_list(); - let out = stream.out().freeze(); - +pub fn log_rlp_hash(logs: &[Log]) -> B256 { + let mut out = Vec::with_capacity(alloy_rlp::list_length(logs)); + alloy_rlp::encode_list(logs, &mut out); keccak256(&out) } pub fn state_merkle_trie_root<'a>( - accounts: impl IntoIterator, + accounts: impl IntoIterator, ) -> B256 { - let vec = accounts - .into_iter() - .map(|(address, info)| { - let acc_root = trie_account_rlp(info); - (H160::from(address.0), acc_root) - }) - .collect(); + trie_root(accounts.into_iter().map(|(address, acc)| { + ( + address, + alloy_rlp::encode_fixed_size(&TrieAccount::new(acc)), + ) + })) +} - trie_root(vec) +#[derive(RlpEncodable, RlpMaxEncodedLen)] +struct TrieAccount { + nonce: u64, + balance: U256, + root_hash: B256, + code_hash: B256, } -/// Returns the RLP for this account. -pub fn trie_account_rlp(acc: &PlainAccount) -> Bytes { - let mut stream = RlpStream::new_list(4); - stream.append(&acc.info.nonce); - stream.append(&acc.info.balance); - stream.append(&{ - sec_trie_root::( - acc.storage - .iter() - .filter(|(_k, &v)| v != U256::ZERO) - .map(|(&k, v)| (H256::from(k.to_be_bytes()), rlp::encode(v))), - ) - }); - stream.append(&acc.info.code_hash.0.as_ref()); - stream.out().freeze() +impl TrieAccount { + #[inline(always)] + fn new(acc: &PlainAccount) -> Self { + Self { + nonce: acc.info.nonce, + balance: acc.info.balance, + root_hash: sec_trie_root::( + acc.storage + .iter() + .filter(|(_k, &v)| v != U256::ZERO) + .map(|(k, v)| (k.to_be_bytes::<32>(), alloy_rlp::encode_fixed_size(v))), + ), + code_hash: acc.info.code_hash, + } + } } -pub fn trie_root(acc_data: Vec<(H160, Bytes)>) -> B256 { - B256(sec_trie_root::(acc_data).0) +#[inline] +pub fn trie_root(input: I) -> B256 +where + I: IntoIterator, + A: AsRef<[u8]>, + B: AsRef<[u8]>, +{ + sec_trie_root::(input) } #[derive(Default, Debug, Clone, PartialEq, Eq)] pub struct KeccakHasher; impl Hasher for KeccakHasher { - type Out = H256; + type Out = B256; type StdHasher = PlainHasher; const LENGTH: usize = 32; + + #[inline] fn hash(x: &[u8]) -> Self::Out { - let out = Keccak256::digest(x); - H256::from_slice(out.as_slice()) + keccak256(x) } } diff --git a/bins/revme/src/statetest/models/deserializer.rs b/bins/revme/src/statetest/models/deserializer.rs index a10bae0bc3..a89c70a99c 100644 --- a/bins/revme/src/statetest/models/deserializer.rs +++ b/bins/revme/src/statetest/models/deserializer.rs @@ -1,11 +1,5 @@ -use std::str::FromStr; - -use bytes::Bytes; -use revm::primitives::{B160, U256}; -use serde::{ - de::{self, Error}, - Deserialize, -}; +use revm::primitives::Address; +use serde::{de, Deserialize}; pub fn deserialize_str_as_u64<'de, D>(deserializer: D) -> Result where @@ -13,71 +7,22 @@ where { let string = String::deserialize(deserializer)?; - let output = if let Some(stripped) = string.strip_prefix("0x") { - u64::from_str_radix(stripped, 16).unwrap() + if let Some(stripped) = string.strip_prefix("0x") { + u64::from_str_radix(stripped, 16) } else { - string.parse().unwrap() - }; - - Ok(output) -} - -pub fn deserialize_str_as_u256<'de, D>(deserializer: D) -> Result -where - D: de::Deserializer<'de>, -{ - let string = String::deserialize(deserializer)?; - let output = string.parse().unwrap(); - - Ok(output) -} - -pub fn deserialize_vec_as_vec_bytes<'de, D>(deserializer: D) -> Result, D::Error> -where - D: de::Deserializer<'de>, -{ - let strings: Vec = Vec::::deserialize(deserializer)?; - - let mut out = Vec::new(); - for string in strings { - out.push( - hex::decode(string.strip_prefix("0x").unwrap_or(&string)) - .map_err(D::Error::custom)? - .into(), - ) + string.parse() } - Ok(out) + .map_err(serde::de::Error::custom) } -pub fn deserialize_maybe_empty<'de, D>(deserializer: D) -> Result, D::Error> +pub fn deserialize_maybe_empty<'de, D>(deserializer: D) -> Result, D::Error> where D: de::Deserializer<'de>, { - let string: String = String::deserialize(deserializer)?; + let string = String::deserialize(deserializer)?; if string.is_empty() { - return Ok(None); + Ok(None) + } else { + string.parse().map_err(de::Error::custom).map(Some) } - Ok(Some(B160::from_str(&string).map_err(D::Error::custom)?)) -} - -pub fn deserialize_str_as_bytes<'de, D>(deserializer: D) -> Result -where - D: de::Deserializer<'de>, -{ - let s = String::deserialize(deserializer)?; - - Ok(hex::decode(s.strip_prefix("0x").unwrap_or(&s)) - .map_err(D::Error::custom)? - .into()) -} - -pub fn deserialize_opt_str_as_bytes<'de, D>(deserializer: D) -> Result, D::Error> -where - D: de::Deserializer<'de>, -{ - #[derive(Debug, Deserialize)] - struct WrappedValue(#[serde(deserialize_with = "deserialize_str_as_bytes")] Bytes); - - Option::::deserialize(deserializer) - .map(|opt_wrapped: Option| opt_wrapped.map(|wrapped: WrappedValue| wrapped.0)) } diff --git a/bins/revme/src/statetest/models/mod.rs b/bins/revme/src/statetest/models/mod.rs index 9b94cef315..a86a7e6b51 100644 --- a/bins/revme/src/statetest/models/mod.rs +++ b/bins/revme/src/statetest/models/mod.rs @@ -1,22 +1,20 @@ -use bytes::Bytes; -use revm::primitives::{HashMap, B160, B256, U256}; +use revm::primitives::{Address, Bytes, HashMap, B256, U256}; +use serde::Deserialize; use std::collections::BTreeMap; -mod deserializer; -mod spec; +mod deserializer; use deserializer::*; -use serde::Deserialize; - +mod spec; pub use self::spec::SpecName; #[derive(Debug, PartialEq, Eq, Deserialize)] -pub struct TestSuit(pub BTreeMap); +pub struct TestSuite(pub BTreeMap); #[derive(Debug, PartialEq, Eq, Deserialize)] pub struct TestUnit { pub env: Env, - pub pre: HashMap, + pub pre: HashMap, pub post: BTreeMap>, pub transaction: TransactionParts, } @@ -28,10 +26,10 @@ pub struct Test { pub hash: B256, /// Indexes pub indexes: TxPartIndices, - // logs + /// Logs pub logs: B256, + /// Transaction bytes #[serde(default)] - #[serde(deserialize_with = "deserialize_opt_str_as_bytes")] pub txbytes: Option, } @@ -47,7 +45,6 @@ pub struct TxPartIndices { #[serde(rename_all = "camelCase")] pub struct AccountInfo { pub balance: U256, - #[serde(deserialize_with = "deserialize_str_as_bytes")] pub code: Bytes, #[serde(deserialize_with = "deserialize_str_as_u64")] pub nonce: u64, @@ -57,14 +54,10 @@ pub struct AccountInfo { #[derive(Debug, PartialEq, Eq, Deserialize)] #[serde(rename_all = "camelCase")] pub struct Env { - pub current_coinbase: B160, - #[serde(default, deserialize_with = "deserialize_str_as_u256")] + pub current_coinbase: Address, pub current_difficulty: U256, - #[serde(deserialize_with = "deserialize_str_as_u256")] pub current_gas_limit: U256, - #[serde(deserialize_with = "deserialize_str_as_u256")] pub current_number: U256, - #[serde(deserialize_with = "deserialize_str_as_u256")] pub current_timestamp: U256, pub current_base_fee: Option, pub previous_hash: B256, @@ -73,7 +66,6 @@ pub struct Env { #[derive(Debug, PartialEq, Eq, Deserialize)] #[serde(rename_all = "camelCase")] pub struct TransactionParts { - #[serde(deserialize_with = "deserialize_vec_as_vec_bytes")] pub data: Vec, pub access_lists: Option>>, pub gas_limit: Vec, @@ -81,7 +73,7 @@ pub struct TransactionParts { pub nonce: U256, pub secret_key: Option, #[serde(deserialize_with = "deserialize_maybe_empty")] - pub to: Option, + pub to: Option
, pub value: Vec, pub max_fee_per_gas: Option, pub max_priority_fee_per_gas: Option, @@ -90,7 +82,7 @@ pub struct TransactionParts { #[derive(Debug, PartialEq, Eq, Deserialize, Clone)] #[serde(rename_all = "camelCase")] pub struct AccessListItem { - pub address: B160, + pub address: Address, pub storage_keys: Vec, } @@ -100,7 +92,7 @@ pub type AccessList = Vec; mod tests { use super::*; - use revm::primitives::B160; + use revm::primitives::Address; use serde_json::Error; #[test] @@ -123,7 +115,7 @@ mod tests { #[derive(Deserialize, Debug)] pub struct Test { - _item: B160, + _item: Address, } let out: Test = serde_json::from_str(json)?; diff --git a/bins/revme/src/statetest/runner.rs b/bins/revme/src/statetest/runner.rs index 45bc679d0c..f93bd41906 100644 --- a/bins/revme/src/statetest/runner.rs +++ b/bins/revme/src/statetest/runner.rs @@ -1,6 +1,5 @@ use std::io::stdout; use std::{ - ffi::OsStr, path::{Path, PathBuf}, sync::{atomic::AtomicBool, Arc, Mutex}, time::{Duration, Instant}, @@ -8,15 +7,16 @@ use std::{ use super::{ merkle_trie::{log_rlp_hash, state_merkle_trie_root}, - models::{SpecName, TestSuit}, + models::{SpecName, TestSuite}, }; -use hex_literal::hex; use indicatif::ProgressBar; use revm::inspectors::TracerEip3155; use revm::primitives::keccak256; use revm::{ interpreter::CreateScheme, - primitives::{Bytecode, Env, ExecutionResult, HashMap, SpecId, TransactTo, B160, B256, U256}, + primitives::{ + address, b256, Bytecode, Env, ExecutionResult, HashMap, SpecId, TransactTo, B256, U256, + }, }; use std::sync::atomic::Ordering; use thiserror::Error; @@ -31,7 +31,7 @@ pub enum TestError { got: B256, expect: B256, }, - #[error("Serde json error")] + #[error("Serde json error: {0}")] SerdeDeserialize(#[from] serde_json::Error), #[error("Internal system error")] SystemError, @@ -48,44 +48,44 @@ pub fn find_all_json_tests(path: &Path) -> Vec { .collect::>() } -pub fn execute_test_suit( +pub fn execute_test_suite( path: &Path, elapsed: &Arc>, trace: bool, ) -> Result<(), TestError> { + let name = path.file_name().unwrap().to_str().unwrap(); + // funky test with `bigint 0x00` value in json :) not possible to happen on mainnet and require custom json parser. // https://github.com/ethereum/tests/issues/971 - if path.file_name() == Some(OsStr::new("ValueOverflow.json")) { + if name == "ValueOverflow.json" { return Ok(()); } // precompiles having storage is not possible - if path.file_name() == Some(OsStr::new("RevertPrecompiledTouch_storage.json")) - || path.file_name() == Some(OsStr::new("RevertPrecompiledTouch.json")) - { + if name == "RevertPrecompiledTouch_storage.json" || name == "RevertPrecompiledTouch.json" { return Ok(()); } // txbyte is of type 02 and we dont parse tx bytes for this test to fail. - if path.file_name() == Some(OsStr::new("typeTwoBerlin.json")) { + if name == "typeTwoBerlin.json" { return Ok(()); } // Test checks if nonce overflows. We are handling this correctly but we are not parsing exception in testsuite // There are more nonce overflow tests that are in internal call/create, and those tests are passing and are enabled. - if path.file_name() == Some(OsStr::new("CreateTransactionHighNonce.json")) { + if name == "CreateTransactionHighNonce.json" { return Ok(()); } // Need to handle Test errors - if path.file_name() == Some(OsStr::new("transactionIntinsicBug.json")) { + if name == "transactionIntinsicBug.json" { return Ok(()); } // Test check if gas price overflows, we handle this correctly but does not match tests specific exception. - if path.file_name() == Some(OsStr::new("HighGasPrice.json")) - || path.file_name() == Some(OsStr::new("CREATE_HighNonce.json")) - || path.file_name() == Some(OsStr::new("CREATE_HighNonceMinus1.json")) + if name == "HighGasPrice.json" + || name == "CREATE_HighNonce.json" + || name == "CREATE_HighNonceMinus1.json" { return Ok(()); } @@ -93,20 +93,20 @@ pub fn execute_test_suit( // Skip test where basefee/accesslist/diffuculty is present but it shouldn't be supported in London/Berlin/TheMerge. // https://github.com/ethereum/tests/blob/5b7e1ab3ffaf026d99d20b17bb30f533a2c80c8b/GeneralStateTests/stExample/eip1559.json#L130 // It is expected to not execute these tests. - if path.file_name() == Some(OsStr::new("accessListExample.json")) - || path.file_name() == Some(OsStr::new("basefeeExample.json")) - || path.file_name() == Some(OsStr::new("eip1559.json")) - || path.file_name() == Some(OsStr::new("mergeTest.json")) + if name == "accessListExample.json" + || name == "basefeeExample.json" + || name == "eip1559.json" + || name == "mergeTest.json" { return Ok(()); } // These tests are passing, but they take a lot of time to execute so we are going to skip them. - if path.file_name() == Some(OsStr::new("loopExp.json")) - || path.file_name() == Some(OsStr::new("Call50000_sha256.json")) - || path.file_name() == Some(OsStr::new("static_Call50000_sha256.json")) - || path.file_name() == Some(OsStr::new("loopMul.json")) - || path.file_name() == Some(OsStr::new("CALLBlake2f_MaxRounds.json")) + if name == "loopExp.json" + || name == "Call50000_sha256.json" + || name == "static_Call50000_sha256.json" + || name == "loopMul.json" + || name == "CALLBlake2f_MaxRounds.json" { return Ok(()); } @@ -115,53 +115,41 @@ pub fn execute_test_suit( return Ok(()); } - let json_reader = std::fs::read(path).unwrap(); - let suit: TestSuit = serde_json::from_reader(&*json_reader)?; + let s = std::fs::read_to_string(path).unwrap(); + let suite: TestSuite = serde_json::from_str(&s)?; let map_caller_keys: HashMap<_, _> = [ ( - B256(hex!( - "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8" - )), - B160(hex!("a94f5374fce5edbc8e2a8697c15331677e6ebf0b")), + b256!("45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8"), + address!("a94f5374fce5edbc8e2a8697c15331677e6ebf0b"), ), ( - B256(hex!( - "c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4" - )), - B160(hex!("cd2a3d9f938e13cd947ec05abc7fe734df8dd826")), + b256!("c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4"), + address!("cd2a3d9f938e13cd947ec05abc7fe734df8dd826"), ), ( - B256(hex!( - "044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d" - )), - B160(hex!("82a978b3f5962a5b0957d9ee9eef472ee55b42f1")), + b256!("044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d"), + address!("82a978b3f5962a5b0957d9ee9eef472ee55b42f1"), ), ( - B256(hex!( - "6a7eeac5f12b409d42028f66b0b2132535ee158cfda439e3bfdd4558e8f4bf6c" - )), - B160(hex!("c9c5a15a403e41498b6f69f6f89dd9f5892d21f7")), + b256!("6a7eeac5f12b409d42028f66b0b2132535ee158cfda439e3bfdd4558e8f4bf6c"), + address!("c9c5a15a403e41498b6f69f6f89dd9f5892d21f7"), ), ( - B256(hex!( - "a95defe70ebea7804f9c3be42d20d24375e2a92b9d9666b832069c5f3cd423dd" - )), - B160(hex!("3fb1cd2cd96c6d5c0b5eb3322d807b34482481d4")), + b256!("a95defe70ebea7804f9c3be42d20d24375e2a92b9d9666b832069c5f3cd423dd"), + address!("3fb1cd2cd96c6d5c0b5eb3322d807b34482481d4"), ), ( - B256(hex!( - "fe13266ff57000135fb9aa854bbfe455d8da85b21f626307bf3263a0c2a8e7fe" - )), - B160(hex!("dcc5ba93a1ed7e045690d722f2bf460a51c61415")), + b256!("fe13266ff57000135fb9aa854bbfe455d8da85b21f626307bf3263a0c2a8e7fe"), + address!("dcc5ba93a1ed7e045690d722f2bf460a51c61415"), ), ] .into(); - for (name, unit) in suit.0.into_iter() { + for (name, unit) in suite.0 { // Create database and insert cache let mut cache_state = revm::CacheState::new(false); - for (address, info) in unit.pre.into_iter() { + for (address, info) in unit.pre { let acc_info = revm::primitives::AccountInfo { balance: info.balance, code_hash: keccak256(&info.code), // try with dummy hash. @@ -212,29 +200,26 @@ pub fn execute_test_suit( env.cfg.spec_id = spec_name.to_spec_id(); for (id, test) in tests.into_iter().enumerate() { - let gas_limit = *unit.transaction.gas_limit.get(test.indexes.gas).unwrap(); - let gas_limit = u64::try_from(gas_limit).unwrap_or(u64::MAX); - env.tx.gas_limit = gas_limit; + env.tx.gas_limit = unit.transaction.gas_limit[test.indexes.gas].saturating_to(); env.tx.data = unit .transaction .data .get(test.indexes.data) .unwrap() .clone(); - env.tx.value = *unit.transaction.value.get(test.indexes.value).unwrap(); + env.tx.value = unit.transaction.value[test.indexes.value]; let access_list = match unit.transaction.access_lists { Some(ref access_list) => access_list .get(test.indexes.data) - .cloned() - .flatten() + .and_then(Option::as_deref) .unwrap_or_default() - .into_iter() + .iter() .map(|item| { ( item.address, item.storage_keys - .into_iter() + .iter() .map(|key| U256::from_be_bytes(key.0)) .collect::>(), ) @@ -280,7 +265,7 @@ pub fn execute_test_suit( Ok(ExecutionResult::Success { logs, .. }) => logs.clone(), _ => Vec::new(), }; - let logs_root = log_rlp_hash(logs); + let logs_root = log_rlp_hash(&logs); if test.hash != state_root || test.logs != logs_root { println!( "Roots did not match:\nState root: wanted {:?}, got {state_root:?}\nLogs root: wanted {:?}, got {logs_root:?}", @@ -386,7 +371,7 @@ pub fn run( return Ok(()); } //println!("Test:{:?}\n",test_path); - if let Err(err) = execute_test_suit(&test_path, &elapsed, trace) { + if let Err(err) = execute_test_suite(&test_path, &elapsed, trace) { endjob.store(true, Ordering::SeqCst); println!("Test[{index}] named:\n{test_path:?} failed: {err}\n"); return Err(err); diff --git a/crates/interpreter/Cargo.toml b/crates/interpreter/Cargo.toml index a5c4fec52f..9efb7def19 100644 --- a/crates/interpreter/Cargo.toml +++ b/crates/interpreter/Cargo.toml @@ -10,15 +10,12 @@ version = "1.1.2" readme = "../../README.md" [dependencies] -revm-primitives = { path = "../primitives", version="1.1.2", default-features = false } +revm-primitives = { path = "../primitives", version = "1.1.2", default-features = false } #utility derive_more = "0.99" enumn = "0.1" -# sha3 keccak hasher -sha3 = { version = "0.10", default-features = false, features = [] } - # optional serde = { version = "1.0", features = ["derive", "rc"], optional = true } arbitrary = { version = "1.3", features = ["derive"], optional = true } @@ -48,10 +45,7 @@ optional_eip3607 = ["revm-primitives/optional_eip3607"] optional_gas_refund = ["revm-primitives/optional_gas_refund"] optional_no_base_fee = ["revm-primitives/optional_no_base_fee"] std = ["revm-primitives/std"] -serde = [ - "dep:serde", - "revm-primitives/serde", -] +serde = ["dep:serde", "revm-primitives/serde"] arbitrary = [ "std", "dep:arbitrary", diff --git a/crates/interpreter/src/gas/calc.rs b/crates/interpreter/src/gas/calc.rs index ae7d7c4b5f..715ed2d954 100644 --- a/crates/interpreter/src/gas/calc.rs +++ b/crates/interpreter/src/gas/calc.rs @@ -1,11 +1,11 @@ use super::constants::*; -use crate::alloc::vec::Vec; use crate::{ inner_models::SelfDestructResult, primitives::Spec, primitives::{SpecId::*, U256}, }; -use revm_primitives::{Bytes, B160}; +use alloc::vec::Vec; +use revm_primitives::{Address, Bytes}; #[allow(clippy::collapsible_else_if)] pub fn sstore_refund(original: U256, current: U256, new: U256) -> i64 { @@ -333,7 +333,7 @@ pub fn memory_gas(a: usize) -> u64 { pub fn initial_tx_gas( input: &Bytes, is_create: bool, - access_list: &[(B160, Vec)], + access_list: &[(Address, Vec)], ) -> u64 { let mut initial_gas = 0; let zero_data_len = input.iter().filter(|v| **v == 0).count() as u64; diff --git a/crates/interpreter/src/host.rs b/crates/interpreter/src/host.rs index 0d317af51f..c9d4ac779e 100644 --- a/crates/interpreter/src/host.rs +++ b/crates/interpreter/src/host.rs @@ -1,13 +1,13 @@ -mod dummy_host; - use crate::primitives::Bytecode; use crate::{ - primitives::{Bytes, Env, B160, B256, U256}, + primitives::{Address, Bytes, Env, B256, U256}, CallInputs, CreateInputs, Gas, InstructionResult, Interpreter, SelfDestructResult, }; pub use alloc::vec::Vec; pub use dummy_host::DummyHost; +mod dummy_host; + /// EVM context host. pub trait Host { fn step(&mut self, interpreter: &mut Interpreter) -> InstructionResult; @@ -20,38 +20,38 @@ pub trait Host { fn env(&mut self) -> &mut Env; /// load account. Returns (is_cold,is_new_account) - fn load_account(&mut self, address: B160) -> Option<(bool, bool)>; + fn load_account(&mut self, address: Address) -> Option<(bool, bool)>; /// Get environmental block hash. fn block_hash(&mut self, number: U256) -> Option; /// Get balance of address and if account is cold loaded. - fn balance(&mut self, address: B160) -> Option<(U256, bool)>; + fn balance(&mut self, address: Address) -> Option<(U256, bool)>; /// Get code of address and if account is cold loaded. - fn code(&mut self, address: B160) -> Option<(Bytecode, bool)>; + fn code(&mut self, address: Address) -> Option<(Bytecode, bool)>; /// Get code hash of address and if account is cold loaded. - fn code_hash(&mut self, address: B160) -> Option<(B256, bool)>; + fn code_hash(&mut self, address: Address) -> Option<(B256, bool)>; /// Get storage value of address at index and if account is cold loaded. - fn sload(&mut self, address: B160, index: U256) -> Option<(U256, bool)>; + fn sload(&mut self, address: Address, index: U256) -> Option<(U256, bool)>; /// Set storage value of account address at index. /// Returns (original, present, new, sis_cold) fn sstore( &mut self, - address: B160, + address: Address, index: U256, value: U256, ) -> Option<(U256, U256, U256, bool)>; /// Get the transient storage value of address at index. - fn tload(&mut self, address: B160, index: U256) -> U256; + fn tload(&mut self, address: Address, index: U256) -> U256; /// Set the transient storage value of address at index. - fn tstore(&mut self, address: B160, index: U256, value: U256); + fn tstore(&mut self, address: Address, index: U256, value: U256); /// Create a log owned by address with given topics and data. - fn log(&mut self, address: B160, topics: Vec, data: Bytes); + fn log(&mut self, address: Address, topics: Vec, data: Bytes); /// Mark an address to be deleted, with funds transferred to target. - fn selfdestruct(&mut self, address: B160, target: B160) -> Option; + fn selfdestruct(&mut self, address: Address, target: Address) -> Option; /// Invoke a create operation. fn create( &mut self, inputs: &mut CreateInputs, - ) -> (InstructionResult, Option, Gas, Bytes); + ) -> (InstructionResult, Option
, Gas, Bytes); /// Invoke a call operation. fn call(&mut self, input: &mut CallInputs) -> (InstructionResult, Gas, Bytes); } diff --git a/crates/interpreter/src/host/dummy_host.rs b/crates/interpreter/src/host/dummy_host.rs index 61241a13f5..4cb5e08286 100644 --- a/crates/interpreter/src/host/dummy_host.rs +++ b/crates/interpreter/src/host/dummy_host.rs @@ -1,6 +1,6 @@ use crate::primitives::{hash_map::Entry, Bytecode, Bytes, HashMap, U256}; use crate::{ - primitives::{Env, Log, B160, B256, KECCAK_EMPTY}, + primitives::{Address, Env, Log, B256, KECCAK_EMPTY}, CallInputs, CreateInputs, Gas, Host, InstructionResult, Interpreter, SelfDestructResult, }; use alloc::vec::Vec; @@ -44,27 +44,27 @@ impl Host for DummyHost { &mut self.env } - fn load_account(&mut self, _address: B160) -> Option<(bool, bool)> { + fn load_account(&mut self, _address: Address) -> Option<(bool, bool)> { Some((true, true)) } fn block_hash(&mut self, _number: U256) -> Option { - Some(B256::zero()) + Some(B256::ZERO) } - fn balance(&mut self, _address: B160) -> Option<(U256, bool)> { + fn balance(&mut self, _address: Address) -> Option<(U256, bool)> { Some((U256::ZERO, false)) } - fn code(&mut self, _address: B160) -> Option<(Bytecode, bool)> { + fn code(&mut self, _address: Address) -> Option<(Bytecode, bool)> { Some((Bytecode::default(), false)) } - fn code_hash(&mut self, __address: B160) -> Option<(B256, bool)> { + fn code_hash(&mut self, __address: Address) -> Option<(B256, bool)> { Some((KECCAK_EMPTY, false)) } - fn sload(&mut self, __address: B160, index: U256) -> Option<(U256, bool)> { + fn sload(&mut self, __address: Address, index: U256) -> Option<(U256, bool)> { match self.storage.entry(index) { Entry::Occupied(entry) => Some((*entry.get(), false)), Entry::Vacant(entry) => { @@ -76,7 +76,7 @@ impl Host for DummyHost { fn sstore( &mut self, - _address: B160, + _address: Address, index: U256, value: U256, ) -> Option<(U256, U256, U256, bool)> { @@ -91,18 +91,18 @@ impl Host for DummyHost { Some((U256::ZERO, present, value, is_cold)) } - fn tload(&mut self, _address: B160, index: U256) -> U256 { + fn tload(&mut self, _address: Address, index: U256) -> U256 { self.transient_storage .get(&index) .cloned() .unwrap_or_default() } - fn tstore(&mut self, _address: B160, index: U256, value: U256) { + fn tstore(&mut self, _address: Address, index: U256, value: U256) { self.transient_storage.insert(index, value); } - fn log(&mut self, address: B160, topics: Vec, data: Bytes) { + fn log(&mut self, address: Address, topics: Vec, data: Bytes) { self.log.push(Log { address, topics, @@ -110,14 +110,14 @@ impl Host for DummyHost { }) } - fn selfdestruct(&mut self, _address: B160, _target: B160) -> Option { + fn selfdestruct(&mut self, _address: Address, _target: Address) -> Option { panic!("Selfdestruct is not supported for this host") } fn create( &mut self, _inputs: &mut CreateInputs, - ) -> (InstructionResult, Option, Gas, Bytes) { + ) -> (InstructionResult, Option
, Gas, Bytes) { panic!("Create is not supported for this host") } diff --git a/crates/interpreter/src/inner_models.rs b/crates/interpreter/src/inner_models.rs index 5467876995..614ea567d0 100644 --- a/crates/interpreter/src/inner_models.rs +++ b/crates/interpreter/src/inner_models.rs @@ -1,18 +1,14 @@ pub use crate::primitives::CreateScheme; -use crate::primitives::{Bytes, B160, U256}; +use crate::primitives::{Address, Bytes, U256}; /// Inputs for a call. #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct CallInputs { /// The target of the call. - pub contract: B160, + pub contract: Address, /// The transfer, if any, in this call. pub transfer: Transfer, /// The call data of the call. - #[cfg_attr( - feature = "serde", - serde(with = "crate::primitives::utilities::serde_hex_bytes") - )] pub input: Bytes, /// The gas limit of the call. pub gas_limit: u64, @@ -24,13 +20,9 @@ pub struct CallInputs { #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct CreateInputs { - pub caller: B160, + pub caller: Address, pub scheme: CreateScheme, pub value: U256, - #[cfg_attr( - feature = "serde", - serde(with = "crate::primitives::utilities::serde_hex_bytes") - )] pub init_code: Bytes, pub gas_limit: u64, } @@ -54,11 +46,11 @@ pub enum CallScheme { #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct CallContext { /// Execution address. - pub address: B160, + pub address: Address, /// Caller of the EVM. - pub caller: B160, + pub caller: Address, /// The address the contract code was loaded from, if any. - pub code_address: B160, + pub code_address: Address, /// Apparent value of the EVM. pub apparent_value: U256, /// The scheme used for the call. @@ -68,9 +60,9 @@ pub struct CallContext { impl Default for CallContext { fn default() -> Self { CallContext { - address: B160::default(), - caller: B160::default(), - code_address: B160::default(), + address: Address::default(), + caller: Address::default(), + code_address: Address::default(), apparent_value: U256::default(), scheme: CallScheme::Call, } @@ -82,9 +74,9 @@ impl Default for CallContext { #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Transfer { /// Source address. - pub source: B160, + pub source: Address, /// Target address. - pub target: B160, + pub target: Address, /// Transfer value. pub value: U256, } diff --git a/crates/interpreter/src/instructions/host.rs b/crates/interpreter/src/instructions/host.rs index 57e34394b5..967d01c2a9 100644 --- a/crates/interpreter/src/instructions/host.rs +++ b/crates/interpreter/src/instructions/host.rs @@ -1,13 +1,13 @@ -use crate::primitives::{Bytes, Spec, SpecId::*, B160, B256, U256}; +use crate::primitives::{Address, Bytes, Spec, SpecId::*, B256, U256}; use crate::MAX_INITCODE_SIZE; use crate::{ - alloc::boxed::Box, - alloc::vec::Vec, gas::{self, COLD_ACCOUNT_ACCESS_COST, WARM_STORAGE_READ_COST}, interpreter::Interpreter, return_ok, return_revert, CallContext, CallInputs, CallScheme, CreateInputs, CreateScheme, Host, InstructionResult, Transfer, }; +use alloc::boxed::Box; +use alloc::vec::Vec; use core::cmp::min; pub fn balance(interpreter: &mut Interpreter, host: &mut dyn Host) { @@ -225,7 +225,7 @@ pub fn log(interpreter: &mut Interpreter, host: &mut dyn Host) { let mut topics = Vec::with_capacity(n); for _ in 0..(n) { // Safety: stack bounds already checked few lines above - topics.push(B256(unsafe { + topics.push(B256::new(unsafe { interpreter.stack.pop_unsafe().to_be_bytes() })); } @@ -345,14 +345,14 @@ pub fn create( match return_reason { return_ok!() => { - push_b256!(interpreter, address.unwrap_or_default().into()); + push_b256!(interpreter, address.unwrap_or_default().into_word()); if crate::USE_GAS { interpreter.gas.erase_cost(gas.remaining()); interpreter.gas.record_refund(gas.refunded()); } } return_revert!() => { - push_b256!(interpreter, B256::zero()); + push_b256!(interpreter, B256::ZERO); if crate::USE_GAS { interpreter.gas.erase_cost(gas.remaining()); } @@ -361,7 +361,7 @@ pub fn create( interpreter.instruction_result = InstructionResult::FatalExternalError; } _ => { - push_b256!(interpreter, B256::zero()); + push_b256!(interpreter, B256::ZERO); } } } diff --git a/crates/interpreter/src/instructions/host_env.rs b/crates/interpreter/src/instructions/host_env.rs index e3d7d5fc6a..8447135e23 100644 --- a/crates/interpreter/src/instructions/host_env.rs +++ b/crates/interpreter/src/instructions/host_env.rs @@ -11,7 +11,7 @@ pub fn chainid(interpreter: &mut Interpreter, host: &mut dyn Host) { pub fn coinbase(interpreter: &mut Interpreter, host: &mut dyn Host) { gas!(interpreter, gas::BASE); - push_b256!(interpreter, host.env().block.coinbase.into()); + push_b256!(interpreter, host.env().block.coinbase.into_word()); } pub fn timestamp(interpreter: &mut Interpreter, host: &mut dyn Host) { @@ -52,5 +52,5 @@ pub fn basefee(interpreter: &mut Interpreter, host: &mut dyn Host) { pub fn origin(interpreter: &mut Interpreter, host: &mut dyn Host) { gas!(interpreter, gas::BASE); - push_b256!(interpreter, host.env().tx.caller.into()); + push_b256!(interpreter, host.env().tx.caller.into_word()); } diff --git a/crates/interpreter/src/instructions/macros.rs b/crates/interpreter/src/instructions/macros.rs index 71b6d17f22..a0da29b7b3 100644 --- a/crates/interpreter/src/instructions/macros.rs +++ b/crates/interpreter/src/instructions/macros.rs @@ -82,35 +82,22 @@ macro_rules! memory_resize { } macro_rules! pop_address { - ( $interp:expr, $x1:ident) => { + ($interp:expr, $x1:ident) => { if $interp.stack.len() < 1 { $interp.instruction_result = InstructionResult::StackUnderflow; return; } // Safety: Length is checked above. - let $x1: B160 = B160( - unsafe { $interp.stack.pop_unsafe() }.to_be_bytes::<{ U256::BYTES }>()[12..] - .try_into() - .unwrap(), - ); + let $x1 = Address::from_word(B256::from(unsafe { $interp.stack.pop_unsafe() })); }; - ( $interp:expr, $x1:ident, $x2:ident) => { + ($interp:expr, $x1:ident, $x2:ident) => { if $interp.stack.len() < 2 { $interp.instruction_result = InstructionResult::StackUnderflow; return; } - let mut temp = H256::zero(); - - let $x1: B160 = B160( - unsafe { $interp.stack.pop_unsafe() }.to_be_bytes::<{ U256::BYTES }>()[12..] - .try_into() - .unwrap(), - ); - let $x2: B160 = B160( - unsafe { $interp.stack.pop_unsafe() }.to_be_bytes::<{ U256::BYTES }>()[12..] - .try_into() - .unwrap(), - ); + // Safety: Length is checked above. + let $x1 = Address::from_word(B256::from(unsafe { $interp.stack.pop_unsafe() })); + let $x2 = Address::from_word(B256::from(unsafe { $interp.stack.pop_unsafe() })); }; } diff --git a/crates/interpreter/src/instructions/system.rs b/crates/interpreter/src/instructions/system.rs index a40a6c6cf5..03ad16f344 100644 --- a/crates/interpreter/src/instructions/system.rs +++ b/crates/interpreter/src/instructions/system.rs @@ -23,12 +23,12 @@ pub fn calculate_keccak256(interpreter: &mut Interpreter, _host: &mut dyn Host) pub fn address(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::BASE); - push_b256!(interpreter, B256::from(interpreter.contract.address)); + push_b256!(interpreter, interpreter.contract.address.into_word()); } pub fn caller(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::BASE); - push_b256!(interpreter, B256::from(interpreter.contract.caller)); + push_b256!(interpreter, interpreter.contract.caller.into_word()); } pub fn codesize(interpreter: &mut Interpreter, _host: &mut dyn Host) { @@ -69,9 +69,9 @@ pub fn calldataload(interpreter: &mut Interpreter, _host: &mut dyn Host) { let have_bytes = min(interpreter.contract.input.len() - index, 32); let mut bytes = [0u8; 32]; bytes[..have_bytes].copy_from_slice(&interpreter.contract.input[index..index + have_bytes]); - B256(bytes) + B256::new(bytes) } else { - B256::zero() + B256::ZERO }; push_b256!(interpreter, load); diff --git a/crates/interpreter/src/interpreter/contract.rs b/crates/interpreter/src/interpreter/contract.rs index 434c1c7156..2fa7bb8e15 100644 --- a/crates/interpreter/src/interpreter/contract.rs +++ b/crates/interpreter/src/interpreter/contract.rs @@ -1,5 +1,5 @@ use super::analysis::{to_analysed, BytecodeLocked}; -use crate::primitives::{Bytecode, Bytes, B160, U256}; +use crate::primitives::{Address, Bytecode, Bytes, U256}; use crate::CallContext; use revm_primitives::{Env, TransactTo}; @@ -11,15 +11,21 @@ pub struct Contract { /// Note that current code is extended with push padding and STOP at end. pub bytecode: BytecodeLocked, /// Contract address - pub address: B160, + pub address: Address, /// Caller of the EVM. - pub caller: B160, + pub caller: Address, /// Value send to contract. pub value: U256, } impl Contract { - pub fn new(input: Bytes, bytecode: Bytecode, address: B160, caller: B160, value: U256) -> Self { + pub fn new( + input: Bytes, + bytecode: Bytecode, + address: Address, + caller: Address, + value: U256, + ) -> Self { let bytecode = to_analysed(bytecode).try_into().expect("it is analyzed"); Self { @@ -35,7 +41,7 @@ impl Contract { pub fn new_env(env: &Env, bytecode: Bytecode) -> Self { let contract_address = match env.tx.transact_to { TransactTo::Call(caller) => caller, - TransactTo::Create(..) => B160::zero(), + TransactTo::Create(..) => Address::ZERO, }; Self::new( env.tx.data.clone(), diff --git a/crates/interpreter/src/interpreter/memory.rs b/crates/interpreter/src/interpreter/memory.rs index d821ab679e..2a442b959f 100644 --- a/crates/interpreter/src/interpreter/memory.rs +++ b/crates/interpreter/src/interpreter/memory.rs @@ -1,4 +1,5 @@ -use crate::{alloc::vec::Vec, primitives::U256}; +use crate::primitives::U256; +use alloc::vec::Vec; use core::{ cmp::min, ops::{BitAnd, Not}, diff --git a/crates/interpreter/src/interpreter/stack.rs b/crates/interpreter/src/interpreter/stack.rs index 7b20e8e758..17584024e6 100644 --- a/crates/interpreter/src/interpreter/stack.rs +++ b/crates/interpreter/src/interpreter/stack.rs @@ -1,5 +1,8 @@ -use crate::primitives::{B256, U256}; -use crate::{alloc::vec::Vec, InstructionResult}; +use crate::{ + primitives::{B256, U256}, + InstructionResult, +}; +use alloc::vec::Vec; pub const STACK_LIMIT: usize = 1024; diff --git a/crates/precompile/Cargo.toml b/crates/precompile/Cargo.toml index c137bd2935..39825e8533 100644 --- a/crates/precompile/Cargo.toml +++ b/crates/precompile/Cargo.toml @@ -9,15 +9,17 @@ repository = "https://github.com/bluealloy/revm" version = "2.0.3" [dependencies] -revm-primitives = { path = "../primitives", version="1.1.2", default-features = false } +revm-primitives = { path = "../primitives", version = "1.1.2", default-features = false } bn = { package = "substrate-bn", version = "0.6", default-features = false } k256 = { version = "0.13", default-features = false, features = ["ecdsa"] } num = { version = "0.4.0", default-features = false, features = ["alloc"] } once_cell = "1.17" ripemd = { version = "0.1", default-features = false } -secp256k1 = { version = "0.27.0", default-features = false, features = ["alloc", "recovery"], optional = true } +secp256k1 = { version = "0.27.0", default-features = false, features = [ + "alloc", + "recovery", +], optional = true } sha2 = { version = "0.10.5", default-features = false } -sha3 = { version = "0.10.7", default-features = false } [dev-dependencies] hex = "0.4" @@ -28,4 +30,3 @@ default = ["secp256k1"] # Only problem that it has, it fails to build for wasm target on windows and mac as it is c lib. # If you dont require wasm on win/mac, i would recommend its usage. secp256k1 = ["dep:secp256k1"] - diff --git a/crates/precompile/src/blake2.rs b/crates/precompile/src/blake2.rs index 803c644549..80d78a9bf9 100644 --- a/crates/precompile/src/blake2.rs +++ b/crates/precompile/src/blake2.rs @@ -6,7 +6,7 @@ const F_ROUND: u64 = 1; const INPUT_LENGTH: usize = 213; pub const FUN: PrecompileAddress = PrecompileAddress( - crate::u64_to_b160(9), + crate::u64_to_address(9), Precompile::Standard(run as StandardPrecompileFn), ); diff --git a/crates/precompile/src/bn128.rs b/crates/precompile/src/bn128.rs index 4c1ac8c7b7..6247e01b33 100644 --- a/crates/precompile/src/bn128.rs +++ b/crates/precompile/src/bn128.rs @@ -1,9 +1,9 @@ -use crate::{primitives::U256, Error, Precompile, PrecompileAddress, PrecompileResult, B160}; +use crate::{primitives::U256, Address, Error, Precompile, PrecompileAddress, PrecompileResult}; use alloc::vec::Vec; pub mod add { use super::*; - const ADDRESS: B160 = crate::u64_to_b160(6); + const ADDRESS: Address = crate::u64_to_address(6); pub const ISTANBUL: PrecompileAddress = PrecompileAddress( ADDRESS, @@ -28,7 +28,7 @@ pub mod add { pub mod mul { use super::*; - const ADDRESS: B160 = crate::u64_to_b160(7); + const ADDRESS: Address = crate::u64_to_address(7); pub const ISTANBUL: PrecompileAddress = PrecompileAddress( ADDRESS, Precompile::Standard(|input: &[u8], gas_limit: u64| -> PrecompileResult { @@ -52,7 +52,7 @@ pub mod mul { pub mod pair { use super::*; - const ADDRESS: B160 = crate::u64_to_b160(8); + const ADDRESS: Address = crate::u64_to_address(8); const ISTANBUL_PAIR_PER_POINT: u64 = 34_000; const ISTANBUL_PAIR_BASE: u64 = 45_000; diff --git a/crates/precompile/src/hash.rs b/crates/precompile/src/hash.rs index b5b231d660..c750507f78 100644 --- a/crates/precompile/src/hash.rs +++ b/crates/precompile/src/hash.rs @@ -3,11 +3,11 @@ use crate::{Error, Precompile, PrecompileAddress, PrecompileResult, StandardPrec use sha2::*; pub const SHA256: PrecompileAddress = PrecompileAddress( - crate::u64_to_b160(2), + crate::u64_to_address(2), Precompile::Standard(sha256_run as StandardPrecompileFn), ); pub const RIPEMD160: PrecompileAddress = PrecompileAddress( - crate::u64_to_b160(3), + crate::u64_to_address(3), Precompile::Standard(ripemd160_run as StandardPrecompileFn), ); diff --git a/crates/precompile/src/identity.rs b/crates/precompile/src/identity.rs index 9dda458792..7f54931a17 100644 --- a/crates/precompile/src/identity.rs +++ b/crates/precompile/src/identity.rs @@ -2,7 +2,7 @@ use super::calc_linear_cost_u32; use crate::{Error, Precompile, PrecompileAddress, PrecompileResult, StandardPrecompileFn}; pub const FUN: PrecompileAddress = PrecompileAddress( - crate::u64_to_b160(4), + crate::u64_to_address(4), Precompile::Standard(identity_run as StandardPrecompileFn), ); diff --git a/crates/precompile/src/lib.rs b/crates/precompile/src/lib.rs index 888335ef13..2ee7157d7a 100644 --- a/crates/precompile/src/lib.rs +++ b/crates/precompile/src/lib.rs @@ -18,7 +18,7 @@ pub use primitives::{ #[doc(inline)] pub use revm_primitives as primitives; -pub type B160 = [u8; 20]; +pub type Address = [u8; 20]; pub type B256 = [u8; 32]; use alloc::vec::Vec; @@ -37,7 +37,7 @@ pub struct PrecompileOutput { #[derive(Debug, Default)] pub struct Log { - pub address: B160, + pub address: Address, pub topics: Vec, pub data: Bytes, } @@ -54,7 +54,7 @@ impl PrecompileOutput { #[derive(Clone, Debug)] pub struct Precompiles { - pub fun: HashMap, + pub fun: HashMap, } impl Default for Precompiles { @@ -78,9 +78,9 @@ impl fmt::Debug for Precompile { } } -pub struct PrecompileAddress(B160, Precompile); +pub struct PrecompileAddress(Address, Precompile); -impl From for (B160, Precompile) { +impl From for (Address, Precompile) { fn from(value: PrecompileAddress) -> Self { (value.0, value.1) } @@ -205,15 +205,15 @@ impl Precompiles { } } - pub fn addresses(&self) -> impl IntoIterator { + pub fn addresses(&self) -> impl IntoIterator { self.fun.keys() } - pub fn contains(&self, address: &B160) -> bool { + pub fn contains(&self, address: &Address) -> bool { self.fun.contains_key(address) } - pub fn get(&self, address: &B160) -> Option { + pub fn get(&self, address: &Address) -> Option { //return None; self.fun.get(address).cloned() } @@ -227,13 +227,14 @@ impl Precompiles { } } -/// const fn for making an address by concatenating the bytes from two given numbers, +/// Const function for making an address by concatenating the bytes from two given numbers. +/// /// Note that 32 + 128 = 160 = 20 bytes (the length of an address). This function is used /// as a convenience for specifying the addresses of the various precompiles. -const fn u64_to_b160(x: u64) -> B160 { - let x_bytes = x.to_be_bytes(); +#[inline] +const fn u64_to_address(x: u64) -> Address { + let x = x.to_be_bytes(); [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_bytes[0], x_bytes[1], x_bytes[2], x_bytes[3], - x_bytes[4], x_bytes[5], x_bytes[6], x_bytes[7], + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], ] } diff --git a/crates/precompile/src/modexp.rs b/crates/precompile/src/modexp.rs index 4344f5cce9..573f763a7d 100644 --- a/crates/precompile/src/modexp.rs +++ b/crates/precompile/src/modexp.rs @@ -9,12 +9,12 @@ use core::{ use num::{BigUint, One, Zero}; pub const BYZANTIUM: PrecompileAddress = PrecompileAddress( - crate::u64_to_b160(5), + crate::u64_to_address(5), Precompile::Standard(byzantium_run as StandardPrecompileFn), ); pub const BERLIN: PrecompileAddress = PrecompileAddress( - crate::u64_to_b160(5), + crate::u64_to_address(5), Precompile::Standard(berlin_run as StandardPrecompileFn), ); diff --git a/crates/precompile/src/secp256k1.rs b/crates/precompile/src/secp256k1.rs index 7bd44d09d6..beb7581404 100644 --- a/crates/precompile/src/secp256k1.rs +++ b/crates/precompile/src/secp256k1.rs @@ -1,17 +1,16 @@ use crate::{Error, Precompile, PrecompileAddress, PrecompileResult, StandardPrecompileFn}; pub const ECRECOVER: PrecompileAddress = PrecompileAddress( - crate::u64_to_b160(1), + crate::u64_to_address(1), Precompile::Standard(ec_recover_run as StandardPrecompileFn), ); #[cfg(not(feature = "secp256k1"))] #[allow(clippy::module_inception)] mod secp256k1 { - use k256::ecdsa::{Error, RecoveryId, Signature, VerifyingKey}; - use sha3::{Digest, Keccak256}; - use crate::B256; + use k256::ecdsa::{Error, RecoveryId, Signature, VerifyingKey}; + use revm_primitives::keccak256; pub fn ecrecover(sig: &[u8; 65], msg: &B256) -> Result { // parse signature @@ -22,15 +21,15 @@ mod secp256k1 { let recovered_key = VerifyingKey::recover_from_prehash(msg, &signature, recid)?; // hash it - let hash = Keccak256::digest( + let mut hash = keccak256( &recovered_key .to_encoded_point(/* compress = */ false) .as_bytes()[1..], - ); + ) + .0; // truncate to 20 bytes - let mut hash: B256 = hash[..].try_into().unwrap(); - hash.iter_mut().take(12).for_each(|i| *i = 0); + hash[..12].fill(0); Ok(hash) } } @@ -39,11 +38,11 @@ mod secp256k1 { #[allow(clippy::module_inception)] mod secp256k1 { use crate::B256; + use revm_primitives::keccak256; use secp256k1::{ ecdsa::{RecoverableSignature, RecoveryId}, Message, Secp256k1, }; - use sha3::{Digest, Keccak256}; pub fn ecrecover(sig: &[u8; 65], msg: &B256) -> Result { let sig = @@ -52,9 +51,8 @@ mod secp256k1 { let secp = Secp256k1::new(); let public = secp.recover_ecdsa(&Message::from_slice(&msg[..32])?, &sig)?; - let hash = Keccak256::digest(&public.serialize_uncompressed()[1..]); - let mut hash: B256 = hash[..].try_into().unwrap(); - hash.iter_mut().take(12).for_each(|i| *i = 0); + let mut hash = keccak256(&public.serialize_uncompressed()[1..]).0; + hash[..12].fill(0); Ok(hash) } } diff --git a/crates/primitives/CHANGELOG.md b/crates/primitives/CHANGELOG.md index b55f6b7f9a..95ae31f266 100644 --- a/crates/primitives/CHANGELOG.md +++ b/crates/primitives/CHANGELOG.md @@ -52,4 +52,4 @@ Changelog: # v1.0.0 date: 29.01.2023 -Interpreter was extracted from main revm crate at the revm v3.0.0 version. \ No newline at end of file +Interpreter was extracted from main revm crate at the revm v3.0.0 version. diff --git a/crates/primitives/Cargo.toml b/crates/primitives/Cargo.toml index 265d103102..928cd9d8e3 100644 --- a/crates/primitives/Cargo.toml +++ b/crates/primitives/Cargo.toml @@ -10,28 +10,22 @@ version = "1.1.2" readme = "../../README.md" [dependencies] +alloy-primitives = { version = "0.3", default-features = false, features = ["rlp"] } +alloy-rlp = { version = "0.3", default-features = false, features = ["derive"] } bytes = { version = "1.4", default-features = false } hashbrown = "0.14" primitive-types = { version = "0.12", default-features = false } -rlp = { version = "0.5", default-features = false } # used for create2 address calculation -ruint = { version = "1.8.0", features = ["primitive-types", "rlp"] } auto_impl = "1.1" bitvec = { version = "1", default-features = false, features = ["alloc"] } -bitflags = { version = "2.4.0", default-features = false} +bitflags = { version = "2.2.1", default-features = false } -# bits B256 B160 crate -fixed-hash = { version = "0.8", default-features = false, features = ["rustc-hex"] } - -#utility +# utility hex-literal = "0.4" hex = { version = "0.4", default-features = false } to-binary = "0.4" derive_more = "0.99" enumn = "0.1" -# sha3 keccak hasher -sha3 = { version = "0.10", default-features = false } - # optional serde = { version = "1.0", features = ["derive", "rc"], optional = true } arbitrary = { version = "1.3", features = ["derive"], optional = true } @@ -42,7 +36,7 @@ proptest-derive = { version = "0.3", optional = true } arbitrary = { version = "1.3", features = ["derive"] } proptest = "1.1" proptest-derive = "0.3" -ruint = { version = "1.8.0", features = ["primitive-types", "rlp", "proptest", "arbitrary"] } +ruint = { version = "1.9.0", features = ["primitive-types", "rlp", "proptest", "arbitrary"] } [features] default = ["std"] @@ -61,20 +55,26 @@ optional_block_gas_limit = [] optional_eip3607 = [] optional_gas_refund = [] optional_no_base_fee = [] -std = ["bytes/std", "rlp/std", "hex/std", "bitvec/std", "bitflags/std"] +std = [ + "alloy-primitives/std", + "alloy-rlp/std", + "bytes/std", + "hex/std", + "bitvec/std", + "bitflags/std", +] serde = [ "dep:serde", + "alloy-primitives/serde", "hex/serde", "hashbrown/serde", - "ruint/serde", "bytes/serde", "bitvec/serde", "bitflags/serde", ] arbitrary = [ "std", - "ruint/arbitrary", - "ruint/proptest", + "alloy-primitives/arbitrary", "dep:arbitrary", "dep:proptest", "dep:proptest-derive", diff --git a/crates/primitives/src/bits.rs b/crates/primitives/src/bits.rs deleted file mode 100644 index 45ac577d8c..0000000000 --- a/crates/primitives/src/bits.rs +++ /dev/null @@ -1,378 +0,0 @@ -#![allow(clippy::incorrect_clone_impl_on_copy_type)] - -use derive_more::{AsRef, Deref}; -use fixed_hash::{construct_fixed_hash, impl_fixed_hash_conversions}; - -#[cfg(any(test, feature = "arbitrary"))] -use arbitrary::Arbitrary; -#[cfg(any(test, feature = "arbitrary"))] -use proptest_derive::Arbitrary as PropTestArbitrary; - -construct_fixed_hash! { - /// revm 256 bits type. - #[cfg_attr(any(test, feature = "arbitrary"), derive(Arbitrary, PropTestArbitrary))] - #[derive(AsRef,Deref)] - pub struct B256(32); -} - -construct_fixed_hash! { - /// revm 160 bits type. - #[cfg_attr(any(test, feature = "arbitrary"), derive(Arbitrary, PropTestArbitrary))] - #[derive(AsRef,Deref)] - pub struct B160(20); -} - -impl From for B160 { - fn from(fr: u64) -> Self { - let x_bytes = fr.to_be_bytes(); - B160([ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x_bytes[0], x_bytes[1], x_bytes[2], x_bytes[3], - x_bytes[4], x_bytes[5], x_bytes[6], x_bytes[7], - ]) - } -} - -impl From for B160 { - fn from(fr: primitive_types::H160) -> Self { - B160(fr.0) - } -} - -impl From for B256 { - fn from(fr: primitive_types::H256) -> Self { - B256(fr.0) - } -} - -impl From for primitive_types::H160 { - fn from(fr: B160) -> Self { - primitive_types::H160(fr.0) - } -} - -impl From for primitive_types::H256 { - fn from(fr: B256) -> Self { - primitive_types::H256(fr.0) - } -} - -impl From for B256 { - fn from(fr: primitive_types::U256) -> Self { - let mut ret = B256::zero(); - fr.to_big_endian(ret.as_bytes_mut()); - ret - } -} - -impl From for primitive_types::U256 { - fn from(fr: B256) -> Self { - primitive_types::U256::from(fr.as_ref() as &[u8]) - } -} - -impl From for B256 { - fn from(fr: ruint::aliases::U256) -> Self { - B256(fr.to_be_bytes()) - } -} - -impl From for ruint::aliases::U256 { - fn from(fr: B256) -> Self { - ruint::aliases::U256::from_be_bytes(fr.0) - } -} - -impl_fixed_hash_conversions!(B256, B160); - -#[cfg(feature = "serde")] -impl serde::Serialize for B256 { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - let mut slice = [0u8; 2 + 2 * 32]; - serialize::serialize_raw(&mut slice, &self.0, serializer) - } -} -#[cfg(feature = "serde")] -impl<'de> serde::Deserialize<'de> for B256 { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - let mut bytes = [0u8; 32]; - serialize::deserialize_check_len(deserializer, serialize::ExpectedLen::Exact(&mut bytes))?; - Ok(B256(bytes)) - } -} -#[cfg(feature = "serde")] -impl serde::Serialize for B160 { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - let mut slice = [0u8; 2 + 2 * 20]; - serialize::serialize_raw(&mut slice, &self.0, serializer) - } -} - -#[cfg(feature = "serde")] -impl<'de> serde::Deserialize<'de> for B160 { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - let mut bytes = [0u8; 20]; - serialize::deserialize_check_len(deserializer, serialize::ExpectedLen::Exact(&mut bytes))?; - Ok(B160(bytes)) - } -} - -// code optained from: https://docs.rs/impl-serde/0.4.0/impl_serde/ -#[cfg(feature = "serde")] -mod serialize { - - use alloc::string::String; - use core::{fmt, result::Result}; - use serde::{de, Deserializer, Serializer}; - - static CHARS: &[u8] = b"0123456789abcdef"; - - fn to_hex_raw<'a>(v: &'a mut [u8], bytes: &[u8], skip_leading_zero: bool) -> &'a str { - assert!(v.len() > 1 + bytes.len() * 2); - - v[0] = b'0'; - v[1] = b'x'; - - let mut idx = 2; - let first_nibble = bytes[0] >> 4; - if first_nibble != 0 || !skip_leading_zero { - v[idx] = CHARS[first_nibble as usize]; - idx += 1; - } - v[idx] = CHARS[(bytes[0] & 0xf) as usize]; - idx += 1; - - for &byte in bytes.iter().skip(1) { - v[idx] = CHARS[(byte >> 4) as usize]; - v[idx + 1] = CHARS[(byte & 0xf) as usize]; - idx += 2; - } - - // SAFETY: all characters come either from CHARS or "0x", therefore valid UTF8 - unsafe { core::str::from_utf8_unchecked(&v[0..idx]) } - } - - /// Decoding bytes from hex string error. - #[derive(Debug, PartialEq, Eq)] - pub enum FromHexError { - /// Invalid (non-hex) character encountered. - InvalidHex { - /// The unexpected character. - character: char, - /// Index of that occurrence. - index: usize, - }, - } - - #[cfg(feature = "std")] - impl std::error::Error for FromHexError {} - - impl fmt::Display for FromHexError { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - match *self { - Self::InvalidHex { character, index } => { - write!(fmt, "invalid hex character: {character}, at {index}") - } - } - } - } - - /// Decode given 0x-prefix-stripped hex string into provided slice. - /// Used internally by `from_hex` and `deserialize_check_len`. - /// - /// The method will panic if `bytes` have incorrect length (make sure to allocate enough beforehand). - fn from_hex_raw(v: &str, bytes: &mut [u8], stripped: bool) -> Result { - let bytes_len = v.len(); - let mut modulus = bytes_len % 2; - let mut buf = 0; - let mut pos = 0; - for (index, byte) in v.bytes().enumerate() { - buf <<= 4; - - match byte { - b'A'..=b'F' => buf |= byte - b'A' + 10, - b'a'..=b'f' => buf |= byte - b'a' + 10, - b'0'..=b'9' => buf |= byte - b'0', - b' ' | b'\r' | b'\n' | b'\t' => { - buf >>= 4; - continue; - } - b => { - let character = char::from(b); - return Err(FromHexError::InvalidHex { - character, - index: index + if stripped { 2 } else { 0 }, - }); - } - } - - modulus += 1; - if modulus == 2 { - modulus = 0; - bytes[pos] = buf; - pos += 1; - } - } - - Ok(pos) - } - - /// Serializes a slice of bytes. - pub fn serialize_raw( - slice: &mut [u8], - bytes: &[u8], - serializer: S, - ) -> Result - where - S: Serializer, - { - if bytes.is_empty() { - serializer.serialize_str("0x") - } else { - serializer.serialize_str(to_hex_raw(slice, bytes, false)) - } - } - - /// Expected length of bytes vector. - #[derive(Debug, PartialEq, Eq)] - pub enum ExpectedLen<'a> { - /// Exact length in bytes. - Exact(&'a mut [u8]), - /// A bytes length between (min; slice.len()]. - #[allow(dead_code)] - Between(usize, &'a mut [u8]), - } - - impl<'a> fmt::Display for ExpectedLen<'a> { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - match *self { - ExpectedLen::Exact(ref v) => write!(fmt, "length of {}", v.len() * 2), - ExpectedLen::Between(min, ref v) => { - write!(fmt, "length between ({}; {}]", min * 2, v.len() * 2) - } - } - } - } - - /// Deserialize into vector of bytes with additional size check. - /// Returns number of bytes written. - pub fn deserialize_check_len<'a, 'de, D>( - deserializer: D, - len: ExpectedLen<'a>, - ) -> Result - where - D: Deserializer<'de>, - { - struct Visitor<'a> { - len: ExpectedLen<'a>, - } - - impl<'a, 'b> de::Visitor<'b> for Visitor<'a> { - type Value = usize; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - write!( - formatter, - "a (both 0x-prefixed or not) hex string with {}", - self.len - ) - } - - fn visit_str(self, v: &str) -> Result { - let (v, stripped) = v.strip_prefix("0x").map_or((v, false), |v| (v, true)); - - let len = v.len(); - let is_len_valid = match self.len { - ExpectedLen::Exact(ref slice) => len == 2 * slice.len(), - ExpectedLen::Between(min, ref slice) => len <= 2 * slice.len() && len > 2 * min, - }; - - if !is_len_valid { - return Err(E::invalid_length(v.len(), &self)); - } - - let bytes = match self.len { - ExpectedLen::Exact(slice) => slice, - ExpectedLen::Between(_, slice) => slice, - }; - - from_hex_raw(v, bytes, stripped).map_err(E::custom) - } - - fn visit_string(self, v: String) -> Result { - self.visit_str(&v) - } - } - - deserializer.deserialize_str(Visitor { len }) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn arbitrary() { - proptest::proptest!(|(_v1: B160, _v2: B256)| {}); - } - - #[test] - fn should_convert_from_primitive_types_h160() { - let h160 = primitive_types::H160::random(); - let b160: B160 = h160.into(); - let new_h160: primitive_types::H160 = b160.into(); - assert_eq!(h160, new_h160) - } - - #[test] - fn should_convert_to_primitive_types_h160() { - let b160 = B160::random(); - let h160: primitive_types::H160 = b160.into(); - let new_b160: B160 = h160.into(); - assert_eq!(b160, new_b160) - } - - #[test] - fn should_convert_from_primitive_types_h256() { - let h256 = primitive_types::H256::random(); - let b256: B256 = h256.into(); - let new_h256: primitive_types::H256 = b256.into(); - assert_eq!(h256, new_h256) - } - - #[test] - fn should_convert_to_primitive_types_h256() { - let b256 = B256::random(); - let h256: primitive_types::H256 = b256.into(); - let new_b256: B256 = h256.into(); - assert_eq!(b256, new_b256) - } - - #[test] - fn should_convert_to_primitive_types_h256_u256() { - let b256 = B256::random(); - let u256: primitive_types::U256 = b256.into(); - let new_b256: B256 = u256.into(); - assert_eq!(b256, new_b256) - } - - #[test] - fn should_convert_to_ruint_u256() { - let b256 = B256::random(); - let u256: ruint::aliases::U256 = b256.into(); - let new_b256: B256 = u256.into(); - assert_eq!(b256, new_b256) - } -} diff --git a/crates/primitives/src/bytecode.rs b/crates/primitives/src/bytecode.rs index 395c97cb8a..b67c3af271 100644 --- a/crates/primitives/src/bytecode.rs +++ b/crates/primitives/src/bytecode.rs @@ -1,8 +1,7 @@ -use crate::{keccak256, B256, KECCAK_EMPTY}; +use crate::{keccak256, Bytes, B256, KECCAK_EMPTY}; use alloc::{sync::Arc, vec::Vec}; use bitvec::prelude::{bitvec, Lsb0}; use bitvec::vec::BitVec; -use bytes::Bytes; use core::fmt::Debug; use to_binary::BinaryString; @@ -50,7 +49,6 @@ pub enum BytecodeState { #[derive(Clone, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Bytecode { - #[cfg_attr(feature = "serde", serde(with = "crate::utilities::serde_hex_bytes"))] pub bytecode: Bytes, pub state: BytecodeState, } @@ -58,7 +56,7 @@ pub struct Bytecode { impl Debug for Bytecode { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_struct("Bytecode") - .field("bytecode", &hex::encode(&self.bytecode[..])) + .field("bytecode", &self.bytecode) .field("state", &self.state) .finish() } diff --git a/crates/primitives/src/constants.rs b/crates/primitives/src/constants.rs index a715086c83..3ebaca6b9a 100644 --- a/crates/primitives/src/constants.rs +++ b/crates/primitives/src/constants.rs @@ -1,4 +1,4 @@ -use crate::B160; +use crate::Address; /// Interpreter stack limit pub const STACK_LIMIT: u64 = 1024; @@ -15,4 +15,5 @@ pub const MAX_CODE_SIZE: usize = 0x6000; pub const MAX_INITCODE_SIZE: usize = 2 * MAX_CODE_SIZE; /// Precompile 3 is special in few places -pub const PRECOMPILE3: B160 = B160([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3]); +pub const PRECOMPILE3: Address = + Address::new([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3]); diff --git a/crates/primitives/src/db.rs b/crates/primitives/src/db.rs index 5790fdbe4e..cda31bec78 100644 --- a/crates/primitives/src/db.rs +++ b/crates/primitives/src/db.rs @@ -3,7 +3,7 @@ pub mod components; use crate::AccountInfo; use crate::U256; use crate::{Account, Bytecode}; -use crate::{B160, B256}; +use crate::{Address, B256}; use auto_impl::auto_impl; use hashbrown::HashMap as Map; @@ -15,11 +15,11 @@ pub use components::{ pub trait Database { type Error; /// Get basic account information. - fn basic(&mut self, address: B160) -> Result, Self::Error>; + fn basic(&mut self, address: Address) -> Result, Self::Error>; /// Get account code by its hash fn code_by_hash(&mut self, code_hash: B256) -> Result; /// Get storage value of address at index. - fn storage(&mut self, address: B160, index: U256) -> Result; + fn storage(&mut self, address: Address, index: U256) -> Result; // History related fn block_hash(&mut self, number: U256) -> Result; @@ -33,20 +33,20 @@ impl From for WrapDatabaseRef { #[auto_impl(&mut, Box)] pub trait DatabaseCommit { - fn commit(&mut self, changes: Map); + fn commit(&mut self, changes: Map); } #[auto_impl(&, Box, Arc)] pub trait DatabaseRef { type Error; /// Whether account at address exists. - //fn exists(&self, address: B160) -> Option; + //fn exists(&self, address: Address) -> Option; /// Get basic account information. - fn basic(&self, address: B160) -> Result, Self::Error>; + fn basic(&self, address: Address) -> Result, Self::Error>; /// Get account code by its hash fn code_by_hash(&self, code_hash: B256) -> Result; /// Get storage value of address at index. - fn storage(&self, address: B160, index: U256) -> Result; + fn storage(&self, address: Address, index: U256) -> Result; // History related fn block_hash(&self, number: U256) -> Result; @@ -57,7 +57,7 @@ pub struct WrapDatabaseRef(pub T); impl Database for WrapDatabaseRef { type Error = T::Error; - fn basic(&mut self, address: B160) -> Result, Self::Error> { + fn basic(&mut self, address: Address) -> Result, Self::Error> { self.0.basic(address) } @@ -65,7 +65,7 @@ impl Database for WrapDatabaseRef { self.0.code_by_hash(code_hash) } - fn storage(&mut self, address: B160, index: U256) -> Result { + fn storage(&mut self, address: Address, index: U256) -> Result { self.0.storage(address, index) } @@ -87,7 +87,7 @@ impl<'a, Error> RefDBWrapper<'a, Error> { impl<'a, Error> Database for RefDBWrapper<'a, Error> { type Error = Error; /// Get basic account information. - fn basic(&mut self, address: B160) -> Result, Self::Error> { + fn basic(&mut self, address: Address) -> Result, Self::Error> { self.db.basic(address) } /// Get account code by its hash @@ -95,7 +95,7 @@ impl<'a, Error> Database for RefDBWrapper<'a, Error> { self.db.code_by_hash(code_hash) } /// Get storage value of address at index. - fn storage(&mut self, address: B160, index: U256) -> Result { + fn storage(&mut self, address: Address, index: U256) -> Result { self.db.storage(address, index) } diff --git a/crates/primitives/src/db/components.rs b/crates/primitives/src/db/components.rs index 7495c1fc50..d8e5d9d063 100644 --- a/crates/primitives/src/db/components.rs +++ b/crates/primitives/src/db/components.rs @@ -7,7 +7,7 @@ pub use state::{State, StateRef}; use crate::{ db::{Database, DatabaseRef}, - AccountInfo, Bytecode, B160, B256, U256, + AccountInfo, Address, Bytecode, B256, U256, }; #[derive(Debug)] @@ -25,7 +25,7 @@ pub enum DatabaseComponentError { impl Database for DatabaseComponents { type Error = DatabaseComponentError; - fn basic(&mut self, address: B160) -> Result, Self::Error> { + fn basic(&mut self, address: Address) -> Result, Self::Error> { self.state.basic(address).map_err(Self::Error::State) } @@ -35,7 +35,7 @@ impl Database for DatabaseComponents { .map_err(Self::Error::State) } - fn storage(&mut self, address: B160, index: U256) -> Result { + fn storage(&mut self, address: Address, index: U256) -> Result { self.state .storage(address, index) .map_err(Self::Error::State) @@ -51,7 +51,7 @@ impl Database for DatabaseComponents { impl DatabaseRef for DatabaseComponents { type Error = DatabaseComponentError; - fn basic(&self, address: B160) -> Result, Self::Error> { + fn basic(&self, address: Address) -> Result, Self::Error> { self.state.basic(address).map_err(Self::Error::State) } @@ -61,7 +61,7 @@ impl DatabaseRef for DatabaseComponents { .map_err(Self::Error::State) } - fn storage(&self, address: B160, index: U256) -> Result { + fn storage(&self, address: Address, index: U256) -> Result { self.state .storage(address, index) .map_err(Self::Error::State) diff --git a/crates/primitives/src/db/components/state.rs b/crates/primitives/src/db/components/state.rs index ce38ffb6c0..c59b4408d0 100644 --- a/crates/primitives/src/db/components/state.rs +++ b/crates/primitives/src/db/components/state.rs @@ -1,7 +1,7 @@ //! State database component from [`crate::db::Database`] //! it is used inside [crate::db::DatabaseComponents`] -use crate::{AccountInfo, Bytecode, B160, B256, U256}; +use crate::{AccountInfo, Address, Bytecode, B256, U256}; use alloc::sync::Arc; use auto_impl::auto_impl; use core::ops::Deref; @@ -11,11 +11,11 @@ pub trait State { type Error; /// Get basic account information. - fn basic(&mut self, address: B160) -> Result, Self::Error>; + fn basic(&mut self, address: Address) -> Result, Self::Error>; /// Get account code by its hash fn code_by_hash(&mut self, code_hash: B256) -> Result; /// Get storage value of address at index. - fn storage(&mut self, address: B160, index: U256) -> Result; + fn storage(&mut self, address: Address, index: U256) -> Result; } #[auto_impl(&, Box, Arc)] @@ -23,13 +23,13 @@ pub trait StateRef { type Error; /// Whether account at address exists. - //fn exists(&self, address: B160) -> Option; + //fn exists(&self, address: Address) -> Option; /// Get basic account information. - fn basic(&self, address: B160) -> Result, Self::Error>; + fn basic(&self, address: Address) -> Result, Self::Error>; /// Get account code by its hash fn code_by_hash(&self, code_hash: B256) -> Result; /// Get storage value of address at index. - fn storage(&self, address: B160, index: U256) -> Result; + fn storage(&self, address: Address, index: U256) -> Result; } impl State for &T @@ -38,7 +38,7 @@ where { type Error = ::Error; - fn basic(&mut self, address: B160) -> Result, Self::Error> { + fn basic(&mut self, address: Address) -> Result, Self::Error> { StateRef::basic(*self, address) } @@ -46,7 +46,7 @@ where StateRef::code_by_hash(*self, code_hash) } - fn storage(&mut self, address: B160, index: U256) -> Result { + fn storage(&mut self, address: Address, index: U256) -> Result { StateRef::storage(*self, address, index) } } @@ -57,7 +57,7 @@ where { type Error = ::Error; - fn basic(&mut self, address: B160) -> Result, Self::Error> { + fn basic(&mut self, address: Address) -> Result, Self::Error> { self.deref().basic(address) } @@ -65,7 +65,7 @@ where self.deref().code_by_hash(code_hash) } - fn storage(&mut self, address: B160, index: U256) -> Result { + fn storage(&mut self, address: Address, index: U256) -> Result { self.deref().storage(address, index) } } diff --git a/crates/primitives/src/env.rs b/crates/primitives/src/env.rs index 1e2306dcc9..83ce09cd9b 100644 --- a/crates/primitives/src/env.rs +++ b/crates/primitives/src/env.rs @@ -1,8 +1,8 @@ use crate::{ - alloc::vec::Vec, Account, EVMError, InvalidTransaction, Spec, SpecId, B160, B256, KECCAK_EMPTY, + Account, Address, Bytes, EVMError, InvalidTransaction, Spec, SpecId, B256, KECCAK_EMPTY, MAX_INITCODE_SIZE, U256, }; -use bytes::Bytes; +use alloc::vec::Vec; use core::cmp::{min, Ordering}; #[derive(Clone, Debug, Default)] @@ -18,7 +18,7 @@ pub struct BlockEnv { pub number: U256, /// Coinbase or miner or address that created and signed the block. /// Address where we are going to send gas spend - pub coinbase: B160, + pub coinbase: Address, pub timestamp: U256, /// Difficulty is removed and not used after Paris (aka TheMerge). Value is replaced with prevrandao. pub difficulty: U256, @@ -34,23 +34,22 @@ pub struct BlockEnv { #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct TxEnv { /// Caller or Author or tx signer - pub caller: B160, + pub caller: Address, pub gas_limit: u64, pub gas_price: U256, pub gas_priority_fee: Option, pub transact_to: TransactTo, pub value: U256, - #[cfg_attr(feature = "serde", serde(with = "crate::utilities::serde_hex_bytes"))] pub data: Bytes, pub chain_id: Option, pub nonce: Option, - pub access_list: Vec<(B160, Vec)>, + pub access_list: Vec<(Address, Vec)>, } #[derive(Clone, Debug)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum TransactTo { - Call(B160), + Call(Address), Create(CreateScheme), } @@ -209,10 +208,10 @@ impl Default for BlockEnv { BlockEnv { gas_limit: U256::MAX, number: U256::ZERO, - coinbase: B160::zero(), + coinbase: Address::ZERO, timestamp: U256::from(1), difficulty: U256::ZERO, - prevrandao: Some(B256::zero()), + prevrandao: Some(B256::ZERO), basefee: U256::ZERO, } } @@ -221,11 +220,11 @@ impl Default for BlockEnv { impl Default for TxEnv { fn default() -> TxEnv { TxEnv { - caller: B160::zero(), + caller: Address::ZERO, gas_limit: u64::MAX, gas_price: U256::ZERO, gas_priority_fee: None, - transact_to: TransactTo::Call(B160::zero()), //will do nothing + transact_to: TransactTo::Call(Address::ZERO), //will do nothing value: U256::ZERO, data: Bytes::new(), chain_id: None, diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index 6fe75693ef..6e269269cc 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -2,7 +2,6 @@ extern crate alloc; -pub mod bits; pub mod bytecode; pub mod constants; pub mod db; @@ -14,19 +13,13 @@ pub mod specification; pub mod state; pub mod utilities; -pub use bits::B160; -pub use bits::B256; -pub use bytes; -pub use bytes::Bytes; -pub use hex; -pub use hex_literal; +pub use alloy_primitives::{ + self, address, b256, bytes, fixed_bytes, hex, hex_literal, ruint, uint, Address, Bytes, + FixedBytes, B256, U256, +}; +pub use bitvec; pub use to_binary; -/// Address type is last 20 bytes of hash of ethereum account -pub type Address = B160; -/// Hash, in Ethereum usually keccak256. -pub type Hash = B256; -pub use bitvec; pub use bytecode::*; pub use constants::*; pub use env::*; @@ -34,9 +27,9 @@ pub use hashbrown::{hash_map, hash_set, HashMap, HashSet}; pub use log::Log; pub use precompile::*; pub use result::*; -pub use ruint; -pub use ruint::aliases::U256; -pub use ruint::uint; pub use specification::*; pub use state::*; pub use utilities::*; + +/// Hash, in Ethereum usually keccak256. +pub type Hash = B256; diff --git a/crates/primitives/src/log.rs b/crates/primitives/src/log.rs index 3c16ed035a..578f0b243f 100644 --- a/crates/primitives/src/log.rs +++ b/crates/primitives/src/log.rs @@ -1,11 +1,11 @@ -use crate::{bytes::Bytes, B160, B256}; +use crate::{Address, Bytes, B256}; use alloc::vec::Vec; +use alloy_rlp::{RlpDecodable, RlpEncodable}; -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, Default, PartialEq, Eq, RlpDecodable, RlpEncodable)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Log { - pub address: B160, + pub address: Address, pub topics: Vec, - #[cfg_attr(feature = "serde", serde(with = "crate::utilities::serde_hex_bytes"))] pub data: Bytes, } diff --git a/crates/primitives/src/result.rs b/crates/primitives/src/result.rs index d38604f979..f86687792d 100644 --- a/crates/primitives/src/result.rs +++ b/crates/primitives/src/result.rs @@ -1,8 +1,6 @@ -use crate::{Log, State, B160}; +use crate::{Address, Bytes, Log, State, U256}; use alloc::vec::Vec; -use bytes::Bytes; use core::fmt; -use ruint::aliases::U256; pub type EVMResult = core::result::Result>; @@ -94,12 +92,8 @@ impl ExecutionResult { #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum Output { - #[cfg_attr(feature = "serde", serde(with = "crate::utilities::serde_hex_bytes"))] Call(Bytes), - Create( - #[cfg_attr(feature = "serde", serde(with = "crate::utilities::serde_hex_bytes"))] Bytes, - Option, - ), + Create(Bytes, Option
), } impl Output { diff --git a/crates/primitives/src/state.rs b/crates/primitives/src/state.rs index 3b6e1e91a5..229ce7c6c8 100644 --- a/crates/primitives/src/state.rs +++ b/crates/primitives/src/state.rs @@ -1,4 +1,4 @@ -use crate::{Bytecode, B160, B256, KECCAK_EMPTY, U256}; +use crate::{Address, Bytecode, B256, KECCAK_EMPTY, U256}; use bitflags::bitflags; use hashbrown::HashMap; @@ -41,10 +41,11 @@ impl Default for AccountStatus { } } -pub type State = HashMap; +pub type State = HashMap; /// Structure used for EIP-1153 transient storage. -pub type TransientStorage = HashMap<(B160, U256), U256>; +pub type TransientStorage = HashMap<(Address, U256), U256>; + pub type Storage = HashMap; impl Account { @@ -207,7 +208,7 @@ impl AccountInfo { } pub fn is_empty(&self) -> bool { - let code_empty = self.code_hash == KECCAK_EMPTY || self.code_hash == B256::zero(); + let code_empty = self.code_hash == KECCAK_EMPTY || self.code_hash == B256::ZERO; self.balance == U256::ZERO && self.nonce == 0 && code_empty } diff --git a/crates/primitives/src/utilities.rs b/crates/primitives/src/utilities.rs index ff5d364c80..63885a1f84 100644 --- a/crates/primitives/src/utilities.rs +++ b/crates/primitives/src/utilities.rs @@ -1,61 +1,19 @@ -use crate::{B160, B256, U256}; -use hex_literal::hex; -use sha3::{Digest, Keccak256}; +use crate::{b256, Address, B256, U256}; -pub const KECCAK_EMPTY: B256 = B256(hex!( - "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" -)); +pub use alloy_primitives::keccak256; -#[inline(always)] -pub fn keccak256(input: &[u8]) -> B256 { - B256(Keccak256::digest(input)[..].try_into().unwrap()) -} +/// The Keccak-256 hash of the empty string `""`. +pub const KECCAK_EMPTY: B256 = + b256!("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"); /// Returns the address for the legacy `CREATE` scheme: [`CreateScheme::Create`] -pub fn create_address(caller: B160, nonce: u64) -> B160 { - let mut stream = rlp::RlpStream::new_list(2); - stream.append(&caller.0.as_ref()); - stream.append(&nonce); - let out = keccak256(&stream.out()); - B160(out[12..].try_into().unwrap()) +#[inline] +pub fn create_address(caller: Address, nonce: u64) -> Address { + caller.create(nonce) } /// Returns the address for the `CREATE2` scheme: [`CreateScheme::Create2`] -pub fn create2_address(caller: B160, code_hash: B256, salt: U256) -> B160 { - let mut hasher = Keccak256::new(); - hasher.update([0xff]); - hasher.update(&caller[..]); - hasher.update(salt.to_be_bytes::<{ U256::BYTES }>()); - hasher.update(&code_hash[..]); - - B160(hasher.finalize().as_slice()[12..].try_into().unwrap()) -} - -/// Serde functions to serde as [bytes::Bytes] hex string -#[cfg(feature = "serde")] -pub mod serde_hex_bytes { - use alloc::string::{String, ToString}; - use serde::{Deserialize, Deserializer, Serializer}; - - pub fn serialize(x: T, s: S) -> Result - where - S: Serializer, - T: AsRef<[u8]>, - { - s.serialize_str(&alloc::format!("0x{}", hex::encode(x.as_ref()))) - } - - pub fn deserialize<'de, D>(d: D) -> Result - where - D: Deserializer<'de>, - { - let value = String::deserialize(d)?; - if let Some(value) = value.strip_prefix("0x") { - hex::decode(value) - } else { - hex::decode(&value) - } - .map(Into::into) - .map_err(|e| serde::de::Error::custom(e.to_string())) - } +#[inline] +pub fn create2_address(caller: Address, code_hash: B256, salt: U256) -> Address { + caller.create2(salt.to_be_bytes::<32>(), code_hash) } diff --git a/crates/revm/CHANGELOG.md b/crates/revm/CHANGELOG.md index ea982f395f..cf9f1ec1f5 100644 --- a/crates/revm/CHANGELOG.md +++ b/crates/revm/CHANGELOG.md @@ -390,4 +390,4 @@ Published v0.2.0, first initial version of code. London supported and all eth st * subroutines: Feels okay but it needs more scrutiny just to be sure that all corner cases are covered. * Test that are failing (~20) are mostly related to EIP-158: State clearing. For EIP-158 I will time to do it properly. * There is probably benefit of replaing HashMap hasher with something simpler, but this is research for another time. -## Project structure: \ No newline at end of file +## Project structure: diff --git a/crates/revm/Cargo.toml b/crates/revm/Cargo.toml index 40c0f94752..4473ca53a3 100644 --- a/crates/revm/Cargo.toml +++ b/crates/revm/Cargo.toml @@ -22,10 +22,7 @@ serde = { version = "1.0", features = ["derive", "rc"], optional = true } serde_json = { version = "1.0", features = ["preserve_order"], optional = true } # ethersdb -tokio = { version = "1.31", features = [ - "rt-multi-thread", - "macros", -], optional = true } +tokio = { version = "1.31", features = ["rt-multi-thread", "macros"], optional = true } ethers-providers = { version = "2.0", optional = true } ethers-core = { version = "2.0", optional = true } futures = { version = "0.3.27", optional = true } @@ -37,7 +34,6 @@ rayon = { version = "1.7", optional = true } hex-literal = "0.4" ethers-contract = { version = "2.0.3", default-features = false } hex = "0.4.3" -bytes = "1.4.0" anyhow = "1.0.71" criterion = "0.5" diff --git a/crates/revm/benches/bench.rs b/crates/revm/benches/bench.rs index d51e174d0c..e52a65ee23 100644 --- a/crates/revm/benches/bench.rs +++ b/crates/revm/benches/bench.rs @@ -1,11 +1,10 @@ -use bytes::Bytes; use criterion::{ criterion_group, criterion_main, measurement::WallTime, BenchmarkGroup, Criterion, }; use revm::{ db::BenchmarkDB, interpreter::{analysis::to_analysed, BytecodeLocked, Contract, DummyHost, Interpreter}, - primitives::{BerlinSpec, Bytecode, BytecodeState, TransactTo, U256}, + primitives::{address, bytes, BerlinSpec, Bytecode, BytecodeState, Bytes, TransactTo, U256}, }; use std::time::Duration; @@ -14,16 +13,10 @@ type Evm = revm::EVM; fn analysis(c: &mut Criterion) { let mut evm = revm::new(); - evm.env.tx.caller = "0x1000000000000000000000000000000000000000" - .parse() - .unwrap(); - evm.env.tx.transact_to = TransactTo::Call( - "0x0000000000000000000000000000000000000000" - .parse() - .unwrap(), - ); - // evm.env.tx.data = Bytes::from(hex::decode("30627b7c").unwrap()); - evm.env.tx.data = Bytes::from(hex::decode("8035F0CE").unwrap()); + evm.env.tx.caller = address!("1000000000000000000000000000000000000000"); + evm.env.tx.transact_to = TransactTo::Call(address!("0000000000000000000000000000000000000000")); + // evm.env.tx.data = bytes!("30627b7c"); + evm.env.tx.data = bytes!("8035F0CE"); let contract_data: Bytes = hex::decode(ANALYSIS).unwrap().into(); @@ -52,15 +45,9 @@ fn snailtracer(c: &mut Criterion) { let mut evm = revm::new(); evm.database(BenchmarkDB::new_bytecode(bytecode(SNAILTRACER))); - evm.env.tx.caller = "0x1000000000000000000000000000000000000000" - .parse() - .unwrap(); - evm.env.tx.transact_to = TransactTo::Call( - "0x0000000000000000000000000000000000000000" - .parse() - .unwrap(), - ); - evm.env.tx.data = Bytes::from(hex::decode("30627b7c").unwrap()); + evm.env.tx.caller = address!("1000000000000000000000000000000000000000"); + evm.env.tx.transact_to = TransactTo::Call(address!("0000000000000000000000000000000000000000")); + evm.env.tx.data = bytes!("30627b7c"); let mut g = c.benchmark_group("snailtracer"); g.noise_threshold(0.03) @@ -76,14 +63,8 @@ fn transfer(c: &mut Criterion) { let mut evm = revm::new(); evm.database(BenchmarkDB::new_bytecode(Bytecode::new())); - evm.env.tx.caller = "0x0000000000000000000000000000000000000001" - .parse() - .unwrap(); - evm.env.tx.transact_to = TransactTo::Call( - "0x0000000000000000000000000000000000000000" - .parse() - .unwrap(), - ); + evm.env.tx.caller = address!("0000000000000000000000000000000000000001"); + evm.env.tx.transact_to = TransactTo::Call(address!("0000000000000000000000000000000000000000")); evm.env.tx.value = U256::from(10); let mut g = c.benchmark_group("transfer"); diff --git a/crates/revm/src/db/emptydb.rs b/crates/revm/src/db/emptydb.rs index 65bc67cab3..7af17e2868 100644 --- a/crates/revm/src/db/emptydb.rs +++ b/crates/revm/src/db/emptydb.rs @@ -1,7 +1,7 @@ use core::{convert::Infallible, marker::PhantomData}; use revm_interpreter::primitives::{ db::{Database, DatabaseRef}, - keccak256, AccountInfo, Bytecode, B160, B256, U256, + keccak256, AccountInfo, Address, Bytecode, B256, U256, }; pub type EmptyDB = EmptyDBTyped; @@ -41,7 +41,7 @@ impl EmptyDBTyped { impl Database for EmptyDBTyped { type Error = T; - fn basic(&mut self, address: B160) -> Result, Self::Error> { + fn basic(&mut self, address: Address) -> Result, Self::Error> { ::basic(self, address) } @@ -49,7 +49,7 @@ impl Database for EmptyDBTyped { ::code_by_hash(self, code_hash) } - fn storage(&mut self, address: B160, index: U256) -> Result { + fn storage(&mut self, address: Address, index: U256) -> Result { ::storage(self, address, index) } @@ -61,7 +61,7 @@ impl Database for EmptyDBTyped { impl DatabaseRef for EmptyDBTyped { type Error = T; /// Get basic account information. - fn basic(&self, _address: B160) -> Result, Self::Error> { + fn basic(&self, _address: Address) -> Result, Self::Error> { Ok(None) } /// Get account code by its hash @@ -69,12 +69,12 @@ impl DatabaseRef for EmptyDBTyped { Ok(Bytecode::new()) } /// Get storage value of address at index. - fn storage(&self, _address: B160, _index: U256) -> Result { + fn storage(&self, _address: Address, _index: U256) -> Result { Ok(U256::default()) } // History related fn block_hash(&self, number: U256) -> Result { - Ok(keccak256(&number.to_be_bytes::<{ U256::BYTES }>())) + Ok(keccak256(number.to_be_bytes::<{ U256::BYTES }>())) } } diff --git a/crates/revm/src/db/ethersdb.rs b/crates/revm/src/db/ethersdb.rs index 2de1307df7..1ea50d1bbc 100644 --- a/crates/revm/src/db/ethersdb.rs +++ b/crates/revm/src/db/ethersdb.rs @@ -1,4 +1,4 @@ -use crate::primitives::{AccountInfo, Bytecode, B160, B256, KECCAK_EMPTY, U256}; +use crate::primitives::{AccountInfo, Address, Bytecode, B256, KECCAK_EMPTY, U256}; use crate::Database; use ethers_core::types::{BlockId, H160 as eH160, H256, U64 as eU64}; use ethers_providers::Middleware; @@ -58,8 +58,8 @@ where { type Error = (); - fn basic(&mut self, address: B160) -> Result, Self::Error> { - let add = eH160::from(address.0); + fn basic(&mut self, address: Address) -> Result, Self::Error> { + let add = eH160::from(address.0 .0); let f = async { let nonce = self.client.get_transaction_count(add, self.block_number); @@ -69,10 +69,8 @@ where }; let (nonce, balance, code) = self.block_on(f); // panic on not getting data? - let bytecode = Bytecode::new_raw( - code.unwrap_or_else(|e| panic!("ethers get code error: {e:?}")) - .0, - ); + let bytecode = code.unwrap_or_else(|e| panic!("ethers get code error: {e:?}")); + let bytecode = Bytecode::new_raw(bytecode.0.into()); let code_hash = bytecode.hash_slow(); Ok(Some(AccountInfo::new( U256::from_limbs( @@ -93,8 +91,8 @@ where // not needed because we already load code with basic info } - fn storage(&mut self, address: B160, index: U256) -> Result { - let add = eH160::from(address.0); + fn storage(&mut self, address: Address, index: U256) -> Result { + let add = eH160::from(address.0 .0); let index = H256::from(index.to_be_bytes()); let f = async { let storage = self @@ -120,7 +118,7 @@ where .ok() .flatten() }; - Ok(B256(self.block_on(f).unwrap().hash.unwrap().0)) + Ok(B256::new(self.block_on(f).unwrap().hash.unwrap().0)) } } diff --git a/crates/revm/src/db/in_memory_db.rs b/crates/revm/src/db/in_memory_db.rs index bf13978278..aaa1a19cbb 100644 --- a/crates/revm/src/db/in_memory_db.rs +++ b/crates/revm/src/db/in_memory_db.rs @@ -1,6 +1,7 @@ use super::{DatabaseCommit, DatabaseRef, EmptyDB}; use crate::primitives::{ - hash_map::Entry, Account, AccountInfo, Bytecode, HashMap, Log, B160, B256, KECCAK_EMPTY, U256, + hash_map::Entry, Account, AccountInfo, Address, Bytecode, HashMap, Log, B256, KECCAK_EMPTY, + U256, }; use crate::Database; use alloc::vec::Vec; @@ -28,7 +29,7 @@ impl Default for InMemoryDB { pub struct CacheDB { /// Account info where None means it is not existing. Not existing state is needed for Pre TANGERINE forks. /// `code` is always `None`, and bytecode can be found in `contracts`. - pub accounts: HashMap, + pub accounts: HashMap, /// Tracks all contracts by their code hash. pub contracts: HashMap, /// All logs that were committed via [DatabaseCommit::commit]. @@ -45,7 +46,7 @@ impl CacheDB { pub fn new(db: ExtDB) -> Self { let mut contracts = HashMap::new(); contracts.insert(KECCAK_EMPTY, Bytecode::new()); - contracts.insert(B256::zero(), Bytecode::new()); + contracts.insert(B256::ZERO, Bytecode::new()); Self { accounts: HashMap::new(), contracts, @@ -69,13 +70,13 @@ impl CacheDB { .or_insert_with(|| code.clone()); } } - if account.code_hash == B256::zero() { + if account.code_hash == B256::ZERO { account.code_hash = KECCAK_EMPTY; } } /// Insert account info but not override storage - pub fn insert_account_info(&mut self, address: B160, mut info: AccountInfo) { + pub fn insert_account_info(&mut self, address: Address, mut info: AccountInfo) { self.insert_contract(&mut info); self.accounts.entry(address).or_default().info = info; } @@ -83,7 +84,7 @@ impl CacheDB { /// Returns the account for the given address. /// /// If the account was not found in the cache, it will be loaded from the underlying database. - pub fn load_account(&mut self, address: B160) -> Result<&mut DbAccount, ExtDB::Error> { + pub fn load_account(&mut self, address: Address) -> Result<&mut DbAccount, ExtDB::Error> { let db = &self.db; match self.accounts.entry(address) { Entry::Occupied(entry) => Ok(entry.into_mut()), @@ -101,7 +102,7 @@ impl CacheDB { /// insert account storage without overriding account info pub fn insert_account_storage( &mut self, - address: B160, + address: Address, slot: U256, value: U256, ) -> Result<(), ExtDB::Error> { @@ -113,7 +114,7 @@ impl CacheDB { /// replace account storage without overriding account info pub fn replace_account_storage( &mut self, - address: B160, + address: Address, storage: HashMap, ) -> Result<(), ExtDB::Error> { let account = self.load_account(address)?; @@ -124,7 +125,7 @@ impl CacheDB { } impl DatabaseCommit for CacheDB { - fn commit(&mut self, changes: HashMap) { + fn commit(&mut self, changes: HashMap) { for (address, mut account) in changes { if !account.is_touched() { continue; @@ -164,7 +165,7 @@ impl DatabaseCommit for CacheDB { impl Database for CacheDB { type Error = ExtDB::Error; - fn basic(&mut self, address: B160) -> Result, Self::Error> { + fn basic(&mut self, address: Address) -> Result, Self::Error> { let basic = match self.accounts.entry(address) { Entry::Occupied(entry) => entry.into_mut(), Entry::Vacant(entry) => entry.insert( @@ -193,7 +194,7 @@ impl Database for CacheDB { /// Get the value in an account's storage slot. /// /// It is assumed that account is already loaded. - fn storage(&mut self, address: B160, index: U256) -> Result { + fn storage(&mut self, address: Address, index: U256) -> Result { match self.accounts.entry(address) { Entry::Occupied(mut acc_entry) => { let acc_entry = acc_entry.get_mut(); @@ -245,7 +246,7 @@ impl Database for CacheDB { impl DatabaseRef for CacheDB { type Error = ExtDB::Error; - fn basic(&self, address: B160) -> Result, Self::Error> { + fn basic(&self, address: Address) -> Result, Self::Error> { match self.accounts.get(&address) { Some(acc) => Ok(acc.info()), None => self.db.basic(address), @@ -259,7 +260,7 @@ impl DatabaseRef for CacheDB { } } - fn storage(&self, address: B160, index: U256) -> Result { + fn storage(&self, address: Address, index: U256) -> Result { match self.accounts.get(&address) { Some(acc_entry) => match acc_entry.storage.get(&index) { Some(entry) => Ok(*entry), @@ -373,8 +374,8 @@ impl BenchmarkDB { impl Database for BenchmarkDB { type Error = Infallible; /// Get basic account information. - fn basic(&mut self, address: B160) -> Result, Self::Error> { - if address == B160::zero() { + fn basic(&mut self, address: Address) -> Result, Self::Error> { + if address == Address::ZERO { return Ok(Some(AccountInfo { nonce: 1, balance: U256::from(10000000), @@ -382,7 +383,7 @@ impl Database for BenchmarkDB { code_hash: self.1, })); } - if address == B160::from(1) { + if address == Address::with_last_byte(1) { return Ok(Some(AccountInfo { nonce: 0, balance: U256::from(10000000), @@ -399,7 +400,7 @@ impl Database for BenchmarkDB { } /// Get storage value of address at index. - fn storage(&mut self, _address: B160, _index: U256) -> Result { + fn storage(&mut self, _address: Address, _index: U256) -> Result { Ok(U256::default()) } @@ -412,11 +413,11 @@ impl Database for BenchmarkDB { #[cfg(test)] mod tests { use super::{CacheDB, EmptyDB}; - use crate::primitives::{db::Database, AccountInfo, U256}; + use crate::primitives::{db::Database, AccountInfo, Address, U256}; #[test] pub fn test_insert_account_storage() { - let account = 42.into(); + let account = Address::with_last_byte(42); let nonce = 42; let mut init_state = CacheDB::new(EmptyDB::default()); init_state.insert_account_info( @@ -437,7 +438,7 @@ mod tests { #[test] pub fn test_replace_account_storage() { - let account = 42.into(); + let account = Address::with_last_byte(42); let nonce = 42; let mut init_state = CacheDB::new(EmptyDB::default()); init_state.insert_account_info( diff --git a/crates/revm/src/db/states/bundle_state.rs b/crates/revm/src/db/states/bundle_state.rs index 19d2d26367..b505e51b38 100644 --- a/crates/revm/src/db/states/bundle_state.rs +++ b/crates/revm/src/db/states/bundle_state.rs @@ -5,7 +5,7 @@ use super::{ use rayon::slice::ParallelSliceMut; use revm_interpreter::primitives::{ hash_map::{self, Entry}, - AccountInfo, Bytecode, HashMap, StorageSlot, B160, B256, U256, + AccountInfo, Address, Bytecode, HashMap, StorageSlot, B256, U256, }; /// Bundle state contain only values that got changed @@ -18,14 +18,14 @@ use revm_interpreter::primitives::{ #[derive(Clone, Debug, PartialEq, Eq)] pub struct BundleState { /// Account state. - pub state: HashMap, + pub state: HashMap, /// All created contracts in this block. pub contracts: HashMap, /// Changes to revert. /// /// Note: Inside vector is *not* sorted by address. /// But it is unique by address. - pub reverts: Vec>, + pub reverts: Vec>, } impl Default for BundleState { @@ -40,7 +40,7 @@ impl Default for BundleState { impl BundleState { /// Return reference to the state. - pub fn state(&self) -> &HashMap { + pub fn state(&self) -> &HashMap { &self.state } @@ -58,7 +58,7 @@ impl BundleState { pub fn new( state: impl IntoIterator< Item = ( - B160, + Address, Option, Option, HashMap, @@ -67,7 +67,7 @@ impl BundleState { reverts: impl IntoIterator< Item = impl IntoIterator< Item = ( - B160, + Address, Option>, impl IntoIterator, ), @@ -135,7 +135,7 @@ impl BundleState { } /// Get account from state - pub fn account(&self, addres: &B160) -> Option<&BundleAccount> { + pub fn account(&self, addres: &Address) -> Option<&BundleAccount> { self.state.get(addres) } @@ -356,7 +356,7 @@ mod tests { #[test] fn transition_all_states() { // dummy data - let address = B160([0x01; 20]); + let address = Address::new([0x01; 20]); let acc1 = AccountInfo { balance: U256::from(10), nonce: 1, diff --git a/crates/revm/src/db/states/cache.rs b/crates/revm/src/db/states/cache.rs index 4d0a215cbe..5108b60495 100644 --- a/crates/revm/src/db/states/cache.rs +++ b/crates/revm/src/db/states/cache.rs @@ -1,7 +1,10 @@ use super::{ plain_account::PlainStorage, transition_account::TransitionAccount, CacheAccount, PlainAccount, }; -use revm_interpreter::primitives::{AccountInfo, Bytecode, HashMap, State as EVMState, B160, B256}; +use revm_interpreter::primitives::{ + AccountInfo, Address, Bytecode, HashMap, State as EVMState, B256, +}; + /// Cache state contains both modified and original values. /// /// Cache state is main state that revm uses to access state. @@ -11,7 +14,7 @@ use revm_interpreter::primitives::{AccountInfo, Bytecode, HashMap, State as EVMS #[derive(Debug, Clone)] pub struct CacheState { /// Block state account with account state - pub accounts: HashMap, + pub accounts: HashMap, /// created contracts /// TODO add bytecode counter for number of bytecodes added/removed. pub contracts: HashMap, @@ -41,8 +44,9 @@ impl CacheState { } /// Helper function that returns all accounts. + /// /// Used inside tests to generate merkle tree. - pub fn trie_account(&self) -> impl IntoIterator { + pub fn trie_account(&self) -> impl IntoIterator { self.accounts.iter().filter_map(|(address, account)| { account .account @@ -52,13 +56,13 @@ impl CacheState { } /// Insert not existing account. - pub fn insert_not_existing(&mut self, address: B160) { + pub fn insert_not_existing(&mut self, address: Address) { self.accounts .insert(address, CacheAccount::new_loaded_not_existing()); } /// Insert Loaded (Or LoadedEmptyEip161 if account is empty) account. - pub fn insert_account(&mut self, address: B160, info: AccountInfo) { + pub fn insert_account(&mut self, address: Address, info: AccountInfo) { let account = if !info.is_empty() { CacheAccount::new_loaded(info, HashMap::default()) } else { @@ -70,7 +74,7 @@ impl CacheState { /// Similar to `insert_account` but with storage. pub fn insert_account_with_storage( &mut self, - address: B160, + address: Address, info: AccountInfo, storage: PlainStorage, ) { @@ -84,7 +88,7 @@ impl CacheState { /// Apply output of revm execution and create TransactionAccount /// that is used to build BundleState. - pub fn apply_evm_state(&mut self, evm_state: EVMState) -> Vec<(B160, TransitionAccount)> { + pub fn apply_evm_state(&mut self, evm_state: EVMState) -> Vec<(Address, TransitionAccount)> { let mut transitions = Vec::with_capacity(evm_state.len()); for (address, account) in evm_state { if !account.is_touched() { diff --git a/crates/revm/src/db/states/changes.rs b/crates/revm/src/db/states/changes.rs index aa90dc9a1d..ed9bc71b8e 100644 --- a/crates/revm/src/db/states/changes.rs +++ b/crates/revm/src/db/states/changes.rs @@ -1,4 +1,4 @@ -use revm_interpreter::primitives::{AccountInfo, Bytecode, B160, B256, U256}; +use revm_interpreter::primitives::{AccountInfo, Address, Bytecode, B256, U256}; /// Sorted accounts/storages/contracts for inclusion into database. /// Structure is made so it is easier to apply dirrectly to database @@ -6,7 +6,7 @@ use revm_interpreter::primitives::{AccountInfo, Bytecode, B160, B256, U256}; #[derive(Clone, Debug, Default)] pub struct StateChangeset { /// Vector of account presorted by address, with removed contracts bytecode - pub accounts: Vec<(B160, Option)>, + pub accounts: Vec<(Address, Option)>, /// Vector of storage presorted by address /// First bool is indicatior if storage needs to be dropped. pub storage: StorageChangeset, @@ -15,14 +15,14 @@ pub struct StateChangeset { } /// Storage changeset -pub type StorageChangeset = Vec<(B160, (bool, Vec<(U256, U256)>))>; +pub type StorageChangeset = Vec<(Address, (bool, Vec<(U256, U256)>))>; #[derive(Clone, Debug, Default)] pub struct StateReverts { /// Vector of account presorted by anddress, with removed cotracts bytecode /// /// Note: AccountInfo None means that account needs to be removed. - pub accounts: Vec)>>, + pub accounts: Vec)>>, /// Vector of storage presorted by address /// U256::ZERO means that storage needs to be removed. pub storage: StorageRevert, @@ -39,4 +39,4 @@ impl StateReverts { } /// Storage reverts -pub type StorageRevert = Vec)>>; +pub type StorageRevert = Vec)>>; diff --git a/crates/revm/src/db/states/state.rs b/crates/revm/src/db/states/state.rs index e6066e1630..b6607eede1 100644 --- a/crates/revm/src/db/states/state.rs +++ b/crates/revm/src/db/states/state.rs @@ -4,7 +4,7 @@ use super::{ use crate::TransitionAccount; use revm_interpreter::primitives::{ db::{Database, DatabaseCommit}, - hash_map, Account, AccountInfo, Bytecode, HashMap, B160, B256, U256, + hash_map, Account, AccountInfo, Address, Bytecode, HashMap, B256, U256, }; /// State of blockchain. @@ -47,7 +47,7 @@ impl<'a, DBError> State<'a, DBError> { /// Update will create transitions for all accounts that are updated. pub fn increment_balances( &mut self, - balances: impl IntoIterator, + balances: impl IntoIterator, ) -> Result<(), DBError> { // make transition and update cache state let mut transitions = Vec::new(); @@ -67,7 +67,7 @@ impl<'a, DBError> State<'a, DBError> { /// It is used for DAO hardfork state change to move values from given accounts. pub fn drain_balances( &mut self, - addresses: impl IntoIterator, + addresses: impl IntoIterator, ) -> Result, DBError> { // make transition and update cache state let mut transitions = Vec::new(); @@ -90,17 +90,17 @@ impl<'a, DBError> State<'a, DBError> { self.cache.set_state_clear_flag(has_state_clear); } - pub fn insert_not_existing(&mut self, address: B160) { + pub fn insert_not_existing(&mut self, address: Address) { self.cache.insert_not_existing(address) } - pub fn insert_account(&mut self, address: B160, info: AccountInfo) { + pub fn insert_account(&mut self, address: Address, info: AccountInfo) { self.cache.insert_account(address, info) } pub fn insert_account_with_storage( &mut self, - address: B160, + address: Address, info: AccountInfo, storage: PlainStorage, ) { @@ -109,7 +109,7 @@ impl<'a, DBError> State<'a, DBError> { } /// Apply evm transitions to transition state. - fn apply_transition(&mut self, transitions: Vec<(B160, TransitionAccount)>) { + fn apply_transition(&mut self, transitions: Vec<(Address, TransitionAccount)>) { // add transition to transition state. if let Some(s) = self.transition_state.as_mut() { s.add_transitions(transitions) @@ -135,7 +135,7 @@ impl<'a, DBError> State<'a, DBError> { } } - pub fn load_cache_account(&mut self, address: B160) -> Result<&mut CacheAccount, DBError> { + pub fn load_cache_account(&mut self, address: Address) -> Result<&mut CacheAccount, DBError> { match self.cache.accounts.entry(address) { hash_map::Entry::Vacant(entry) => { let info = self.database.basic(address)?; @@ -164,7 +164,7 @@ impl<'a, DBError> State<'a, DBError> { impl<'a, DBError> Database for State<'a, DBError> { type Error = DBError; - fn basic(&mut self, address: B160) -> Result, Self::Error> { + fn basic(&mut self, address: Address) -> Result, Self::Error> { self.load_cache_account(address).map(|a| a.account_info()) } @@ -183,7 +183,7 @@ impl<'a, DBError> Database for State<'a, DBError> { res } - fn storage(&mut self, address: B160, index: U256) -> Result { + fn storage(&mut self, address: Address, index: U256) -> Result { // Account is guaranteed to be loaded. if let Some(account) = self.cache.accounts.get_mut(&address) { // account will always be some, but if it is not, U256::ZERO will be returned. @@ -219,7 +219,7 @@ impl<'a, DBError> Database for State<'a, DBError> { } impl<'a, DBError> DatabaseCommit for State<'a, DBError> { - fn commit(&mut self, evm_state: HashMap) { + fn commit(&mut self, evm_state: HashMap) { let transitions = self.cache.apply_evm_state(evm_state); self.apply_transition(transitions); } diff --git a/crates/revm/src/db/states/transition_state.rs b/crates/revm/src/db/states/transition_state.rs index b6a5ce9235..cc635b0693 100644 --- a/crates/revm/src/db/states/transition_state.rs +++ b/crates/revm/src/db/states/transition_state.rs @@ -1,10 +1,10 @@ use super::TransitionAccount; -use revm_interpreter::primitives::{hash_map::Entry, HashMap, B160}; +use revm_interpreter::primitives::{hash_map::Entry, Address, HashMap}; #[derive(Clone, Debug)] pub struct TransitionState { /// Block state account with account state - pub transitions: HashMap, + pub transitions: HashMap, } impl Default for TransitionState { @@ -18,7 +18,7 @@ impl Default for TransitionState { impl TransitionState { /// Create new transition state with one transition. - pub fn single(address: B160, transition: TransitionAccount) -> Self { + pub fn single(address: Address, transition: TransitionAccount) -> Self { let mut transitions = HashMap::new(); transitions.insert(address, transition); TransitionState { transitions } @@ -29,7 +29,7 @@ impl TransitionState { core::mem::take(self) } - pub fn add_transitions(&mut self, transitions: Vec<(B160, TransitionAccount)>) { + pub fn add_transitions(&mut self, transitions: Vec<(Address, TransitionAccount)>) { for (address, account) in transitions { match self.transitions.entry(address) { Entry::Occupied(entry) => { diff --git a/crates/revm/src/evm_impl.rs b/crates/revm/src/evm_impl.rs index 97c8e71a7d..b5720943f6 100644 --- a/crates/revm/src/evm_impl.rs +++ b/crates/revm/src/evm_impl.rs @@ -5,11 +5,11 @@ use crate::interpreter::{ }; use crate::journaled_state::{is_precompile, JournalCheckpoint}; use crate::primitives::{ - create2_address, create_address, keccak256, Account, AnalysisKind, Bytecode, Bytes, EVMError, - EVMResult, Env, ExecutionResult, HashMap, InvalidTransaction, Log, Output, ResultAndState, - Spec, + create2_address, create_address, keccak256, Account, Address, AnalysisKind, Bytecode, Bytes, + EVMError, EVMResult, Env, ExecutionResult, HashMap, InvalidTransaction, Log, Output, + ResultAndState, Spec, SpecId::{self, *}, - TransactTo, B160, B256, U256, + TransactTo, B256, U256, }; use crate::{db::Database, journaled_state::JournaledState, precompile, Inspector}; use alloc::boxed::Box; @@ -35,14 +35,14 @@ pub struct EVMImpl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> { struct PreparedCreate { gas: Gas, - created_address: B160, + created_address: Address, checkpoint: JournalCheckpoint, contract: Box, } struct CreateResult { result: InstructionResult, - created_address: Option, + created_address: Option
, gas: Gas, return_value: Bytes, } @@ -248,7 +248,10 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> EVMImpl<'a, GSPEC, DB, } } - fn finalize(&mut self, gas: &Gas) -> (HashMap, Vec, u64, u64) { + fn finalize( + &mut self, + gas: &Gas, + ) -> (HashMap, Vec, u64, u64) { let caller = self.data.env.tx.caller; let coinbase = self.data.env.block.coinbase; let (gas_used, gas_refunded) = if crate::USE_GAS { @@ -716,7 +719,7 @@ impl<'a, GSPEC: Spec, DB: Database + 'a, const INSPECT: bool> Host .ok() } - fn load_account(&mut self, address: B160) -> Option<(bool, bool)> { + fn load_account(&mut self, address: Address) -> Option<(bool, bool)> { self.data .journaled_state .load_account_exist(address, self.data.db) @@ -724,7 +727,7 @@ impl<'a, GSPEC: Spec, DB: Database + 'a, const INSPECT: bool> Host .ok() } - fn balance(&mut self, address: B160) -> Option<(U256, bool)> { + fn balance(&mut self, address: Address) -> Option<(U256, bool)> { let db = &mut self.data.db; let journal = &mut self.data.journaled_state; let error = &mut self.data.error; @@ -735,7 +738,7 @@ impl<'a, GSPEC: Spec, DB: Database + 'a, const INSPECT: bool> Host .map(|(acc, is_cold)| (acc.info.balance, is_cold)) } - fn code(&mut self, address: B160) -> Option<(Bytecode, bool)> { + fn code(&mut self, address: Address) -> Option<(Bytecode, bool)> { let journal = &mut self.data.journaled_state; let db = &mut self.data.db; let error = &mut self.data.error; @@ -748,7 +751,7 @@ impl<'a, GSPEC: Spec, DB: Database + 'a, const INSPECT: bool> Host } /// Get code hash of address. - fn code_hash(&mut self, address: B160) -> Option<(B256, bool)> { + fn code_hash(&mut self, address: Address) -> Option<(B256, bool)> { let journal = &mut self.data.journaled_state; let db = &mut self.data.db; let error = &mut self.data.error; @@ -758,13 +761,13 @@ impl<'a, GSPEC: Spec, DB: Database + 'a, const INSPECT: bool> Host .map_err(|e| *error = Some(e)) .ok()?; if acc.is_empty() { - return Some((B256::zero(), is_cold)); + return Some((B256::ZERO, is_cold)); } Some((acc.info.code_hash, is_cold)) } - fn sload(&mut self, address: B160, index: U256) -> Option<(U256, bool)> { + fn sload(&mut self, address: Address, index: U256) -> Option<(U256, bool)> { // account is always hot. reference on that statement https://eips.ethereum.org/EIPS/eip-2929 see `Note 2:` self.data .journaled_state @@ -775,7 +778,7 @@ impl<'a, GSPEC: Spec, DB: Database + 'a, const INSPECT: bool> Host fn sstore( &mut self, - address: B160, + address: Address, index: U256, value: U256, ) -> Option<(U256, U256, U256, bool)> { @@ -786,15 +789,15 @@ impl<'a, GSPEC: Spec, DB: Database + 'a, const INSPECT: bool> Host .ok() } - fn tload(&mut self, address: B160, index: U256) -> U256 { + fn tload(&mut self, address: Address, index: U256) -> U256 { self.data.journaled_state.tload(address, index) } - fn tstore(&mut self, address: B160, index: U256, value: U256) { + fn tstore(&mut self, address: Address, index: U256, value: U256) { self.data.journaled_state.tstore(address, index, value) } - fn log(&mut self, address: B160, topics: Vec, data: Bytes) { + fn log(&mut self, address: Address, topics: Vec, data: Bytes) { if INSPECT { self.inspector.log(&mut self.data, &address, &topics, &data); } @@ -806,7 +809,7 @@ impl<'a, GSPEC: Spec, DB: Database + 'a, const INSPECT: bool> Host self.data.journaled_state.log(log); } - fn selfdestruct(&mut self, address: B160, target: B160) -> Option { + fn selfdestruct(&mut self, address: Address, target: Address) -> Option { if INSPECT { self.inspector.selfdestruct(address, target); } @@ -820,7 +823,7 @@ impl<'a, GSPEC: Spec, DB: Database + 'a, const INSPECT: bool> Host fn create( &mut self, inputs: &mut CreateInputs, - ) -> (InstructionResult, Option, Gas, Bytes) { + ) -> (InstructionResult, Option
, Gas, Bytes) { // Call inspector if INSPECT { let (ret, address, gas, out) = self.inspector.create(&mut self.data, inputs); diff --git a/crates/revm/src/inspector.rs b/crates/revm/src/inspector.rs index 586cf0b836..085197088d 100644 --- a/crates/revm/src/inspector.rs +++ b/crates/revm/src/inspector.rs @@ -1,6 +1,6 @@ use crate::evm_impl::EVMData; use crate::interpreter::{CallInputs, CreateInputs, Gas, InstructionResult, Interpreter}; -use crate::primitives::{db::Database, Bytes, B160, B256}; +use crate::primitives::{db::Database, Address, Bytes, B256}; use auto_impl::auto_impl; @@ -55,7 +55,7 @@ pub trait Inspector { fn log( &mut self, _evm_data: &mut EVMData<'_, DB>, - _address: &B160, + _address: &Address, _topics: &[B256], _data: &Bytes, ) { @@ -106,7 +106,7 @@ pub trait Inspector { &mut self, _data: &mut EVMData<'_, DB>, _inputs: &mut CreateInputs, - ) -> (InstructionResult, Option, Gas, Bytes) { + ) -> (InstructionResult, Option
, Gas, Bytes) { ( InstructionResult::Continue, None, @@ -124,13 +124,13 @@ pub trait Inspector { _data: &mut EVMData<'_, DB>, _inputs: &CreateInputs, ret: InstructionResult, - address: Option, + address: Option
, remaining_gas: Gas, out: Bytes, - ) -> (InstructionResult, Option, Gas, Bytes) { + ) -> (InstructionResult, Option
, Gas, Bytes) { (ret, address, remaining_gas, out) } /// Called when a contract has been self-destructed with funds transferred to target. - fn selfdestruct(&mut self, _contract: B160, _target: B160) {} + fn selfdestruct(&mut self, _contract: Address, _target: Address) {} } diff --git a/crates/revm/src/inspector/customprinter.rs b/crates/revm/src/inspector/customprinter.rs index 0d028fecf7..e893c6d411 100644 --- a/crates/revm/src/inspector/customprinter.rs +++ b/crates/revm/src/inspector/customprinter.rs @@ -2,7 +2,7 @@ //! It is a great tool if some debugging is needed. //! use crate::interpreter::{opcode, CallInputs, CreateInputs, Gas, InstructionResult, Interpreter}; -use crate::primitives::{hex, Bytes, B160}; +use crate::primitives::{Address, Bytes}; use crate::{inspectors::GasInspector, Database, EVMData, Inspector}; #[derive(Clone, Default)] pub struct CustomPrintTracer { @@ -74,10 +74,10 @@ impl Inspector for CustomPrintTracer { data: &mut EVMData<'_, DB>, inputs: &CreateInputs, ret: InstructionResult, - address: Option, + address: Option
, remaining_gas: Gas, out: Bytes, - ) -> (InstructionResult, Option, Gas, Bytes) { + ) -> (InstructionResult, Option
, Gas, Bytes) { self.gas_inspector .create_end(data, inputs, ret, address, remaining_gas, out.clone()); (ret, address, remaining_gas, out) @@ -103,19 +103,15 @@ impl Inspector for CustomPrintTracer { &mut self, _data: &mut EVMData<'_, DB>, inputs: &mut CreateInputs, - ) -> (InstructionResult, Option, Gas, Bytes) { + ) -> (InstructionResult, Option
, Gas, Bytes) { println!( "CREATE CALL: caller:{:?}, scheme:{:?}, value:{:?}, init_code:{:?}, gas:{:?}", - inputs.caller, - inputs.scheme, - inputs.value, - hex::encode(&inputs.init_code), - inputs.gas_limit + inputs.caller, inputs.scheme, inputs.value, inputs.init_code, inputs.gas_limit ); (InstructionResult::Continue, None, Gas::new(0), Bytes::new()) } - fn selfdestruct(&mut self, contract: B160, target: B160) { + fn selfdestruct(&mut self, contract: Address, target: Address) { println!("SELFDESTRUCT on {contract:?} refund target: {target:?}"); } } @@ -126,27 +122,25 @@ mod test { #[cfg(not(feature = "no_gas_measuring"))] #[test] fn gas_calculation_underflow() { - use crate::primitives::hex_literal; + use crate::primitives::{address, bytes}; + // https://github.com/bluealloy/revm/issues/277 // checks this use case let mut evm = crate::new(); let mut database = crate::InMemoryDB::default(); - let code: crate::primitives::Bytes = hex_literal::hex!("5b597fb075978b6c412c64d169d56d839a8fe01b3f4607ed603b2c78917ce8be1430fe6101e8527ffe64706ecad72a2f5c97a95e006e279dc57081902029ce96af7edae5de116fec610208527f9fc1ef09d4dd80683858ae3ea18869fe789ddc365d8d9d800e26c9872bac5e5b6102285260276102485360d461024953601661024a53600e61024b53607d61024c53600961024d53600b61024e5360b761024f5360596102505360796102515360a061025253607261025353603a6102545360fb61025553601261025653602861025753600761025853606f61025953601761025a53606161025b53606061025c5360a661025d53602b61025e53608961025f53607a61026053606461026153608c6102625360806102635360d56102645360826102655360ae61026653607f6101e8610146610220677a814b184591c555735fdcca53617f4d2b9134b29090c87d01058e27e962047654f259595947443b1b816b65cdb6277f4b59c10a36f4e7b8658f5a5e6f5561").to_vec().into(); + let code = bytes!("5b597fb075978b6c412c64d169d56d839a8fe01b3f4607ed603b2c78917ce8be1430fe6101e8527ffe64706ecad72a2f5c97a95e006e279dc57081902029ce96af7edae5de116fec610208527f9fc1ef09d4dd80683858ae3ea18869fe789ddc365d8d9d800e26c9872bac5e5b6102285260276102485360d461024953601661024a53600e61024b53607d61024c53600961024d53600b61024e5360b761024f5360596102505360796102515360a061025253607261025353603a6102545360fb61025553601261025653602861025753600761025853606f61025953601761025a53606161025b53606061025c5360a661025d53602b61025e53608961025f53607a61026053606461026153608c6102625360806102635360d56102645360826102655360ae61026653607f6101e8610146610220677a814b184591c555735fdcca53617f4d2b9134b29090c87d01058e27e962047654f259595947443b1b816b65cdb6277f4b59c10a36f4e7b8658f5a5e6f5561"); let acc_info = crate::primitives::AccountInfo { balance: "0x100c5d668240db8e00".parse().unwrap(), code_hash: crate::primitives::keccak256(&code), code: Some(crate::primitives::Bytecode::new_raw(code.clone())), - nonce: "1".parse().unwrap(), + nonce: 1, }; - let callee = hex_literal::hex!("5fdcca53617f4d2b9134b29090c87d01058e27e9"); - database.insert_account_info(crate::primitives::B160(callee), acc_info); + let callee = address!("5fdcca53617f4d2b9134b29090c87d01058e27e9"); + database.insert_account_info(callee, acc_info); evm.database(database); - evm.env.tx.caller = crate::primitives::B160(hex_literal::hex!( - "5fdcca53617f4d2b9134b29090c87d01058e27e0" - )); - evm.env.tx.transact_to = - crate::primitives::TransactTo::Call(crate::primitives::B160(callee)); + evm.env.tx.caller = address!("5fdcca53617f4d2b9134b29090c87d01058e27e0"); + evm.env.tx.transact_to = crate::primitives::TransactTo::Call(callee); evm.env.tx.data = crate::primitives::Bytes::new(); evm.env.tx.value = crate::primitives::U256::ZERO; let _ = evm.inspect_commit(super::CustomPrintTracer::default()); diff --git a/crates/revm/src/inspector/gas.rs b/crates/revm/src/inspector/gas.rs index 28ccf87f28..3700ab355c 100644 --- a/crates/revm/src/inspector/gas.rs +++ b/crates/revm/src/inspector/gas.rs @@ -1,7 +1,7 @@ //! GasIspector. Helper Inspector to calculate gas for others. -//! + use crate::interpreter::{CallInputs, CreateInputs, Gas, InstructionResult}; -use crate::primitives::{db::Database, Bytes, B160}; +use crate::primitives::{db::Database, Address, Bytes}; use crate::{evm_impl::EVMData, Inspector}; #[allow(dead_code)] @@ -83,10 +83,10 @@ impl Inspector for GasInspector { _data: &mut EVMData<'_, DB>, _inputs: &CreateInputs, ret: InstructionResult, - address: Option, + address: Option
, remaining_gas: Gas, out: Bytes, - ) -> (InstructionResult, Option, Gas, Bytes) { + ) -> (InstructionResult, Option
, Gas, Bytes) { (ret, address, remaining_gas, out) } } @@ -97,9 +97,7 @@ mod tests { use crate::interpreter::{ opcode, CallInputs, CreateInputs, Gas, InstructionResult, Interpreter, OpCode, }; - use crate::primitives::{ - hex_literal::hex, Bytecode, Bytes, ResultAndState, TransactTo, B160, B256, - }; + use crate::primitives::{address, Address, Bytecode, Bytes, ResultAndState, TransactTo, B256}; use crate::{inspectors::GasInspector, Database, EVMData, Inspector}; #[derive(Default, Debug)] @@ -132,7 +130,7 @@ mod tests { fn log( &mut self, evm_data: &mut EVMData<'_, DB>, - address: &B160, + address: &Address, topics: &[B256], data: &Bytes, ) { @@ -182,7 +180,7 @@ mod tests { &mut self, data: &mut EVMData<'_, DB>, call: &mut CreateInputs, - ) -> (InstructionResult, Option, Gas, Bytes) { + ) -> (InstructionResult, Option
, Gas, Bytes) { self.gas_inspector.create(data, call); ( @@ -198,10 +196,10 @@ mod tests { data: &mut EVMData<'_, DB>, inputs: &CreateInputs, status: InstructionResult, - address: Option, + address: Option
, gas: Gas, retdata: Bytes, - ) -> (InstructionResult, Option, Gas, Bytes) { + ) -> (InstructionResult, Option
, Gas, Bytes) { self.gas_inspector .create_end(data, inputs, status, address, gas, retdata.clone()); (status, address, gas, retdata) @@ -229,9 +227,9 @@ mod tests { let mut evm = crate::new(); evm.database(BenchmarkDB::new_bytecode(bytecode.clone())); - evm.env.tx.caller = B160(hex!("1000000000000000000000000000000000000000")); + evm.env.tx.caller = address!("1000000000000000000000000000000000000000"); evm.env.tx.transact_to = - TransactTo::Call(B160(hex!("0000000000000000000000000000000000000000"))); + TransactTo::Call(address!("0000000000000000000000000000000000000000")); evm.env.tx.gas_limit = 21100; let mut inspector = StackInspector::default(); diff --git a/crates/revm/src/inspector/tracer_eip3155.rs b/crates/revm/src/inspector/tracer_eip3155.rs index 45fd8094a2..0a6d93748b 100644 --- a/crates/revm/src/inspector/tracer_eip3155.rs +++ b/crates/revm/src/inspector/tracer_eip3155.rs @@ -2,7 +2,7 @@ use crate::inspectors::GasInspector; use crate::interpreter::{CallInputs, CreateInputs, Gas, InstructionResult}; -use crate::primitives::{db::Database, hex, Bytes, B160}; +use crate::primitives::{db::Database, hex, Address, Bytes}; use crate::{evm_impl::EVMData, Inspector}; use revm_interpreter::primitives::U256; use revm_interpreter::{opcode, Interpreter, Memory, Stack}; @@ -125,7 +125,7 @@ impl Inspector for TracerEip3155 { &mut self, data: &mut EVMData<'_, DB>, _inputs: &mut CreateInputs, - ) -> (InstructionResult, Option, Gas, Bytes) { + ) -> (InstructionResult, Option
, Gas, Bytes) { self.print_log_line(data.journaled_state.depth()); ( InstructionResult::Continue, @@ -140,10 +140,10 @@ impl Inspector for TracerEip3155 { data: &mut EVMData<'_, DB>, inputs: &CreateInputs, ret: InstructionResult, - address: Option, + address: Option
, remaining_gas: Gas, out: Bytes, - ) -> (InstructionResult, Option, Gas, Bytes) { + ) -> (InstructionResult, Option
, Gas, Bytes) { self.gas_inspector .create_end(data, inputs, ret, address, remaining_gas, out.clone()); self.skip = true; @@ -177,9 +177,8 @@ impl TracerEip3155 { } fn short_hex(b: U256) -> String { - let s = hex::encode(b.to_be_bytes_vec()) - .trim_start_matches('0') - .to_string(); + let s = hex::encode(b.to_be_bytes::<32>()); + let s = s.trim_start_matches('0'); if s.is_empty() { "0x0".to_string() } else { diff --git a/crates/revm/src/journaled_state.rs b/crates/revm/src/journaled_state.rs index 3848ed6cc5..d9c0f2e190 100644 --- a/crates/revm/src/journaled_state.rs +++ b/crates/revm/src/journaled_state.rs @@ -1,7 +1,7 @@ use crate::interpreter::{inner_models::SelfDestructResult, InstructionResult}; use crate::primitives::{ - db::Database, hash_map::Entry, Account, Bytecode, HashMap, Log, Spec, SpecId::*, State, - StorageSlot, TransientStorage, B160, KECCAK_EMPTY, PRECOMPILE3, U256, + db::Database, hash_map::Entry, Account, Address, Bytecode, HashMap, Log, Spec, SpecId::*, + State, StorageSlot, TransientStorage, KECCAK_EMPTY, PRECOMPILE3, U256, }; use alloc::vec::Vec; use core::mem; @@ -34,13 +34,13 @@ pub enum JournalEntry { /// Used to mark account that is hot inside EVM in regards to EIP-2929 AccessList. /// Action: We will add Account to state. /// Revert: we will remove account from state. - AccountLoaded { address: B160 }, + AccountLoaded { address: Address }, /// Mark account to be destroyed and journal balance to be reverted /// Action: Mark account and transfer the balance /// Revert: Unmark the account and transfer balance back AccountDestroyed { - address: B160, - target: B160, + address: Address, + target: Address, was_destroyed: bool, // if account had already been destroyed before this journal entry had_balance: U256, }, @@ -48,27 +48,31 @@ pub enum JournalEntry { /// Only when account is called (to execute contract or transfer balance) only then account is made touched. /// Action: Mark account touched /// Revert: Unmark account touched - AccountTouched { address: B160 }, + AccountTouched { address: Address }, /// Transfer balance between two accounts /// Action: Transfer balance /// Revert: Transfer balance back - BalanceTransfer { from: B160, to: B160, balance: U256 }, + BalanceTransfer { + from: Address, + to: Address, + balance: U256, + }, /// Increment nonce /// Action: Increment nonce by one /// Revert: Decrement nonce by one NonceChange { - address: B160, //geth has nonce value, + address: Address, //geth has nonce value, }, /// Create account: /// Actions: Mark account as created /// Revert: Unmart account as created and reset nonce to zero. - AccountCreated { address: B160 }, + AccountCreated { address: Address }, /// It is used to track both storage change and hot load of storage slot. For hot load in regard /// to EIP-2929 AccessList had_value will be None /// Action: Storage change or hot load /// Revert: Revert to previous value or remove slot from storage StorageChange { - address: B160, + address: Address, key: U256, had_value: Option, //if none, storage slot was cold loaded from db and needs to be removed }, @@ -76,14 +80,14 @@ pub enum JournalEntry { /// Action: Transient storage changed. /// Revert: Revert to previous value. TransientStorageChange { - address: B160, + address: Address, key: U256, had_value: U256, }, /// Code changed /// Action: Account code changed /// Revert: Revert to previous bytecode. - CodeChange { address: B160 }, + CodeChange { address: Address }, } /// SubRoutine checkpoint that will help us to go back from this @@ -129,13 +133,13 @@ impl JournaledState { /// Mark account as touched as only touched accounts will be added to state. /// This is expecially important for state clear where touched empty accounts needs to /// be removed from state. - pub fn touch(&mut self, address: &B160) { + pub fn touch(&mut self, address: &Address) { if let Some(account) = self.state.get_mut(address) { Self::touch_account(self.journal.last_mut().unwrap(), address, account); } } - fn touch_account(journal: &mut Vec, address: &B160, account: &mut Account) { + fn touch_account(journal: &mut Vec, address: &Address, account: &mut Account) { if !account.is_touched() { journal.push(JournalEntry::AccountTouched { address: *address }); account.mark_touch(); @@ -153,7 +157,7 @@ impl JournaledState { } /// Use it with load_account function. - pub fn account(&self, address: B160) -> &Account { + pub fn account(&self, address: Address) -> &Account { self.state.get(&address).unwrap() // Always assume that acc is already loaded } @@ -163,7 +167,7 @@ impl JournaledState { /// use it only if you know that acc is hot /// Assume account is hot - pub fn set_code(&mut self, address: B160, code: Bytecode) { + pub fn set_code(&mut self, address: Address, code: Bytecode) { let account = self.state.get_mut(&address).unwrap(); Self::touch_account(self.journal.last_mut().unwrap(), &address, account); @@ -176,7 +180,7 @@ impl JournaledState { account.info.code = Some(code); } - pub fn inc_nonce(&mut self, address: B160) -> Option { + pub fn inc_nonce(&mut self, address: Address) -> Option { let account = self.state.get_mut(&address).unwrap(); // Check if nonce is going to overflow. if account.info.nonce == u64::MAX { @@ -195,8 +199,8 @@ impl JournaledState { pub fn transfer( &mut self, - from: &B160, - to: &B160, + from: &Address, + to: &Address, balance: U256, db: &mut DB, ) -> Result<(), InstructionResult> { @@ -251,8 +255,8 @@ impl JournaledState { /// caller is already loaded inside evm. This is already done inside `create_inner` pub fn create_account_checkpoint( &mut self, - caller: B160, - address: B160, + caller: Address, + address: Address, balance: U256, ) -> Result { // Enter subroutine @@ -318,7 +322,7 @@ impl JournaledState { #[inline(always)] pub fn check_account_collision( - address: B160, + address: Address, account: &Account, num_of_precompiles: usize, ) -> bool { @@ -471,8 +475,8 @@ impl JournaledState { /// transfer balance from address to target. Check if target exist/is_cold pub fn selfdestruct( &mut self, - address: B160, - target: B160, + address: Address, + target: Address, db: &mut DB, ) -> Result { let (is_cold, target_exists) = self.load_account_exist(target, db)?; @@ -512,7 +516,7 @@ impl JournaledState { pub fn initial_account_and_code_load( &mut self, - address: B160, + address: Address, db: &mut DB, ) -> Result<&mut Account, DB::Error> { let account = self.initial_account_load(address, &[], db)?; @@ -531,7 +535,7 @@ impl JournaledState { /// Initial load of account. This load will not be tracked inside journal pub fn initial_account_load( &mut self, - address: B160, + address: Address, slots: &[U256], db: &mut DB, ) -> Result<&mut Account, DB::Error> { @@ -557,7 +561,7 @@ impl JournaledState { /// load account into memory. return if it is cold or hot accessed pub fn load_account( &mut self, - address: B160, + address: Address, db: &mut DB, ) -> Result<(&mut Account, bool), DB::Error> { Ok(match self.state.entry(address) { @@ -586,7 +590,7 @@ impl JournaledState { // first is is_cold second bool is exists. pub fn load_account_exist( &mut self, - address: B160, + address: Address, db: &mut DB, ) -> Result<(bool, bool), DB::Error> { let is_before_spurious_dragon = self.is_before_spurious_dragon; @@ -604,7 +608,7 @@ impl JournaledState { pub fn load_code( &mut self, - address: B160, + address: Address, db: &mut DB, ) -> Result<(&mut Account, bool), DB::Error> { let (acc, is_cold) = self.load_account(address, db)?; @@ -623,7 +627,7 @@ impl JournaledState { // account is already present and loaded. pub fn sload( &mut self, - address: B160, + address: Address, key: U256, db: &mut DB, ) -> Result<(U256, bool), DB::Error> { @@ -661,7 +665,7 @@ impl JournaledState { /// returns (original,present,new) slot pub fn sstore( &mut self, - address: B160, + address: Address, key: U256, new: U256, db: &mut DB, @@ -694,7 +698,7 @@ impl JournaledState { /// Read transient storage tied to the account. /// /// EIP-1153: Transient storage opcodes - pub fn tload(&mut self, address: B160, key: U256) -> U256 { + pub fn tload(&mut self, address: Address, key: U256) -> U256 { self.transient_storage .get(&(address, key)) .cloned() @@ -707,7 +711,7 @@ impl JournaledState { /// so that old state can be reverted if that action is needed. /// /// EIP-1153: Transient storage opcodes - pub fn tstore(&mut self, address: B160, key: U256, new: U256) { + pub fn tstore(&mut self, address: Address, key: U256, new: U256) { let had_value = if new == U256::ZERO { // if new values is zero, remove entry from transient storage. // if previous values was some insert it inside journal. @@ -751,7 +755,7 @@ impl JournaledState { /// Check if address is precompile by having assumption /// that precompiles are in range of 1 to N. #[inline(always)] -pub fn is_precompile(address: B160, num_of_precompiles: usize) -> bool { +pub fn is_precompile(address: Address, num_of_precompiles: usize) -> bool { if !address[..18].iter().all(|i| *i == 0) { return false; } @@ -767,7 +771,7 @@ mod test { fn test_is_precompile() { assert!( !is_precompile( - B160([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), + Address::new([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 3 ), "Zero is not precompile" @@ -775,7 +779,7 @@ mod test { assert!( !is_precompile( - B160([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9]), + Address::new([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9]), 3 ), "0x100..0 is not precompile" @@ -783,7 +787,7 @@ mod test { assert!( !is_precompile( - B160([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4]), + Address::new([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4]), 3 ), "0x000..4 is not precompile" @@ -791,7 +795,7 @@ mod test { assert!( is_precompile( - B160([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]), + Address::new([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]), 3 ), "0x00..01 is precompile" @@ -799,7 +803,7 @@ mod test { assert!( is_precompile( - B160([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3]), + Address::new([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3]), 3 ), "0x000..3 is precompile" diff --git a/documentation/bins/revm-test.md b/documentation/bins/revm-test.md deleted file mode 100644 index 2757b53d14..0000000000 --- a/documentation/bins/revm-test.md +++ /dev/null @@ -1 +0,0 @@ -# revm-test diff --git a/documentation/bins/revme.md b/documentation/bins/revme.md deleted file mode 100644 index 15bca4c3fd..0000000000 --- a/documentation/bins/revme.md +++ /dev/null @@ -1 +0,0 @@ -# revme diff --git a/documentation/src/crates/interpreter/inner_models.md b/documentation/src/crates/interpreter/inner_models.md index 7a1c0f353f..bf4763b86c 100644 --- a/documentation/src/crates/interpreter/inner_models.md +++ b/documentation/src/crates/interpreter/inner_models.md @@ -8,7 +8,7 @@ The `CallInputs` struct is used to encapsulate the inputs to a smart contract ca ```rust pub struct CallInputs { - pub contract: B160, + pub contract: Address, pub transfer: Transfer, pub input: Bytes, pub gas_limit: u64, @@ -25,7 +25,7 @@ The `CreateInputs` struct encapsulates the inputs for creating a new smart contr ```rust pub struct CreateInputs { - pub caller: B160, + pub caller: Address, pub scheme: CreateScheme, pub value: U256, pub init_code: Bytes, @@ -56,9 +56,9 @@ The `CallContext` struct encapsulates the context of a smart contract call. ```rust pub struct CallContext { - pub address: B160, - pub caller: B160, - pub code_address: B160, + pub address: Address, + pub caller: Address, + pub code_address: Address, pub apparent_value: U256, pub scheme: CallScheme, } @@ -72,8 +72,8 @@ The `Transfer` struct represents a value transfer between two accounts. ```rust pub struct Transfer { - pub source: B160, - pub target: B160, + pub source: Address, + pub target: Address, pub value: U256, } ``` @@ -91,4 +91,4 @@ pub struct SelfDestructResult { } ``` -In summary, the `inner_models.rs` module provides several crucial data structures that facilitate the representation and handling of various EVM operations and their associated data within this Rust EVM implementation. \ No newline at end of file +In summary, the `inner_models.rs` module provides several crucial data structures that facilitate the representation and handling of various EVM operations and their associated data within this Rust EVM implementation. diff --git a/documentation/src/crates/precompile.md b/documentation/src/crates/precompile.md index ff0932d3b1..185fcdf380 100644 --- a/documentation/src/crates/precompile.md +++ b/documentation/src/crates/precompile.md @@ -13,7 +13,7 @@ Modules: Types and Constants: -- `B160`: A type alias for an array of 20 bytes. This is typically used to represent Ethereum addresses. +- `Address`: A type alias for an array of 20 bytes. This is typically used to represent Ethereum addresses. - `B256`: A type alias for an array of 32 bytes, typically used to represent 256-bit hashes or integer values in Ethereum. - `PrecompileOutput`: Represents the output of a precompiled contract execution, including the gas cost, output data, and any logs generated. - `Log`: Represents an Ethereum log, with an address, a list of topics, and associated data. diff --git a/documentation/src/crates/primitives.md b/documentation/src/crates/primitives.md index 6a66639b77..027d4a6bd6 100644 --- a/documentation/src/crates/primitives.md +++ b/documentation/src/crates/primitives.md @@ -4,7 +4,7 @@ This crate is a core component of the Revm system. It is designed to provide def Modules: -- [bits](./primitives/bits.md): This module provides types for handling specific sizes of byte arrays (B160 and B256). +- [bits](./primitives/bits.md): This module provides types for handling specific sizes of byte arrays (Address and B256). - [bytecode](./primitives/bytecode.md): This module provides functionality related to EVM bytecode. - [constants](./primitives/constants.md): This module contains constant values used throughout the EVM implementation. - [db](./primitives/database.md): This module contains data structures and functions related to the EVM's database implementation. @@ -28,12 +28,11 @@ External Crates: Type Aliases: -- Address: An alias for B160, representing a 20-byte Ethereum address. - Hash: An alias for B256, typically used to represent 256-bit hashes or integer values in Ethereum. Re-exported Types: -- B160: A type representing a 160-bit (or 20-byte) array, typically used for Ethereum addresses. +- Address: A type representing a 160-bit (or 20-byte) array, typically used for Ethereum addresses. - B256: A type representing a 256-bit (or 32-byte) array, typically used for Ethereum hashes or integers. - Bytes: A type representing a sequence of bytes. - U256: A 256-bit unsigned integer type from the ruint crate. diff --git a/documentation/src/crates/primitives/bits.md b/documentation/src/crates/primitives/bits.md index fb4ca94f41..8d562b19b3 100644 --- a/documentation/src/crates/primitives/bits.md +++ b/documentation/src/crates/primitives/bits.md @@ -1,15 +1,17 @@ # bits -This module houses the definitions for fixed-size bit arrays, `B160` and `B256`, showcasing its role in managing bits-related operations, to represent 256-bit and 160-bit fixed-size hashes respectively. These are defined using the `construct_fixed_hash!` macro from the `fixed_hash` crate. +> NOTE: This module's types have been replaced by [`alloy_primitives`](https://github.com/alloy-rs/core)'s `Address` and `FixedBytes`. + +This module houses the definitions for fixed-size bit arrays, `Address` and `B256`, showcasing its role in managing bits-related operations, to represent 256-bit and 160-bit fixed-size hashes respectively. These are defined using the `construct_fixed_hash!` macro from the `fixed_hash` crate. The `AsRef` and `Deref` traits from `derive_more` crate are derived for both of these structures, providing convenient methods for converting these types to and from references of their underlying data. The `Arbitrary` trait from the `arbitrary` crate and the `PropTestArbitrary` trait from `proptest_derive` crate are derived conditionally when either testing or the "arbitrary" feature is enabled. These traits are used for property testing, a form of testing where random inputs are generated and used to validate certain properties of your code. -The code also provides conversions between `B256`, `B160` and various other types such as `u64`, `primitive_types::H256`, `primitive_types::H160`, `primitive_types::U256`, and `ruint::aliases::U256`. The `impl` From blocks specify how to convert from one type to another. +The code also provides conversions between `B256`, `Address` and various other types such as `u64`, `primitive_types::H256`, `primitive_types::H160`, `primitive_types::U256`, and `ruint::aliases::U256`. The `impl` From blocks specify how to convert from one type to another. -`impl_fixed_hash_conversions!` macro is used to define conversions between `B256` and `B160` types. +`impl_fixed_hash_conversions!` macro is used to define conversions between `B256` and `Address` types. -If the "serde" feature is enabled, the Serialize and Deserialize traits from the serde crate are implemented for `B256` and `B160` using a custom serialization method that outputs/reads these types as hexadecimal strings. This includes a custom serialization/deserialization module for handling hexadecimal data. +If the "serde" feature is enabled, the Serialize and Deserialize traits from the serde crate are implemented for `B256` and `Address` using a custom serialization method that outputs/reads these types as hexadecimal strings. This includes a custom serialization/deserialization module for handling hexadecimal data. This module (serialize) provides functionality to serialize a slice of bytes to a hexadecimal string, and deserialize a hexadecimal string to a byte vector with size checks. It handles both "0x" prefixed and non-prefixed hexadecimal strings. It also provides functions to convert raw bytes to hexadecimal strings and vice versa, handling potential errors related to non-hexadecimal characters. The module also defines the `ExpectedLen` enum which is used to specify the expected length of the byte vectors during deserialization. diff --git a/documentation/src/crates/primitives/database.md b/documentation/src/crates/primitives/database.md index 65003c7e47..f4e4db471b 100644 --- a/documentation/src/crates/primitives/database.md +++ b/documentation/src/crates/primitives/database.md @@ -5,7 +5,7 @@ The module defines three primary traits (`Database`, `DatabaseCommit`, and `Data The `Database` trait defines an interface for mutable interaction with the database. It has a generic associated type `Error` to handle different kinds of errors that might occur during these interactions. It provides methods to retrieve basic account information (`basic`), retrieve account code by its hash (`code_by_hash`), retrieve the storage value of an address at a certain index (`storage`), and retrieve the block hash for a certain block number (`block_hash`). -The `DatabaseCommit` trait defines a single `commit` method for committing changes to the database. The changes are a map between Ethereum-like addresses (type `B160`) and accounts. +The `DatabaseCommit` trait defines a single `commit` method for committing changes to the database. The changes are a map between Ethereum-like addresses (type `Address`) and accounts. The `DatabaseRef` trait is similar to the `Database` trait but is designed for read-only or immutable interactions. It has the same `Error` associated type and the same set of methods as `Database`, but these methods take `&self` instead of `&mut self`, indicating that they do not mutate the database. diff --git a/documentation/src/crates/primitives/log.md b/documentation/src/crates/primitives/log.md index d01ed568ad..1c1dc9cc8b 100644 --- a/documentation/src/crates/primitives/log.md +++ b/documentation/src/crates/primitives/log.md @@ -2,7 +2,7 @@ This piece of Rust code defines a structure called Log which represents an Ethereum log entry. These logs are integral parts of the Ethereum network and are typically produced by smart contracts during execution. Each Log has three components: -- `address`: This field represents the address of the log originator, typically the smart contract that generated the log. The `B160` data type signifies a 160-bit Ethereum address. +- `address`: This field represents the address of the log originator, typically the smart contract that generated the log. The `Address` data type signifies a 160-bit Ethereum address. - `topics`: This field is a vector of `B256` type. In Ethereum, logs can have multiple '`topics`'. These are events that can be used to categorize and filter logs. The `B256` type denotes a 256-bit hash, which corresponds to the size of a topic in Ethereum. diff --git a/documentation/src/crates/primitives/state.md b/documentation/src/crates/primitives/state.md index 084e6ef723..0bbdafe0f9 100644 --- a/documentation/src/crates/primitives/state.md +++ b/documentation/src/crates/primitives/state.md @@ -10,6 +10,6 @@ The `AccountStatus` is a set of bitflags, representing the state of the account. The `StorageSlot` struct represents a storage slot in the Ethereum Virtual Machine. It holds an `original_value` and a `present_value` and includes methods for creating a new slot and checking if the slot's value has been modified. -Two `HashMap` type aliases are created: `State` and `Storage`. `State` maps from a `B160` address to an `Account` and `Storage` maps from a `U256` key to a `StorageSlot`. +Two `HashMap` type aliases are created: `State` and `Storage`. `State` maps from a `Address` address to an `Account` and `Storage` maps from a `U256` key to a `StorageSlot`. The module includes a series of methods implemented for `Account` to manipulate and query the account's status. These include methods like `mark_selfdestruct`, `unmark_selfdestruct`, `is_selfdestructed`, `mark_touch`, `unmark_touch`, `is_touched`, `mark_created`, `is_newly_created`, `is_empty`, and `new_not_existing`. diff --git a/documentation/src/crates/primitives/utils.md b/documentation/src/crates/primitives/utils.md index 00a364ca3c..283bff3426 100644 --- a/documentation/src/crates/primitives/utils.md +++ b/documentation/src/crates/primitives/utils.md @@ -9,5 +9,3 @@ The `keccak256` function takes a byte slice input and returns its Keccak-256 has `create_address` function implements the address calculation for the Ethereum `CREATE` operation. It takes as parameters the address of the caller (`caller`) and a nonce (`nonce`). The function serializes these inputs using Recursive Length Prefix (RLP) encoding, calculates the Keccak-256 hash of the result, and returns the last 20 bytes of this hash as the created address. `create2_address` function implements the address calculation for the Ethereum `CREATE2` operation. It takes as parameters the address of the caller (`caller`), a hash of the initializing code (`code_hash`), and a "salt" value (`salt`). The function hashes these inputs together in a specific way, as per the Ethereum `CREATE2` rules, and returns the last 20 bytes of the result as the created address. - -The `serde_hex_bytes` module includes helper functions for serialization and deserialization of hexadecimal strings representing byte arrays. These functions will be used if the "serde" feature flag is enabled. serialize `function` converts a byte array into a hexadecimal string, while `deserialize` function does the reverse, converting a hexadecimal string back into a byte array. diff --git a/documentation/src/crates/revm/evm_impl.md b/documentation/src/crates/revm/evm_impl.md index d782811efb..616ca6a5f0 100644 --- a/documentation/src/crates/revm/evm_impl.md +++ b/documentation/src/crates/revm/evm_impl.md @@ -28,7 +28,7 @@ This creates a contract with a specific bytecode and a gas price, then runs the This function handles the execution of precompiled contracts. These are a special set of contracts that are part of the Ethereum protocol and implemented in native code for efficiency. - `gas`: A `Gas` instance representing the amount of gas available for execution. -- `contract`: The address of the precompiled contract in the form of a `B160` instance. +- `contract`: The address of the precompiled contract in the form of a `Address` instance. - `input_data`: The input data for the contract as a `Bytes` instance. The function returns a tuple containing the result of the contract execution, the remaining gas, and any output data as a `Bytes` instance. @@ -37,7 +37,7 @@ For example ```rust let gas = Gas::new(1000000); -let contract = B160::zero(); +let contract = Address::ZERO; let input_data = Bytes::from("input data"); let (exit_reason, gas, output) = evm.call_precompile(gas, contract, input_data); ``` diff --git a/documentation/src/crates/revm/inspector.md b/documentation/src/crates/revm/inspector.md index c220761d7a..966d91da09 100644 --- a/documentation/src/crates/revm/inspector.md +++ b/documentation/src/crates/revm/inspector.md @@ -30,7 +30,7 @@ pub trait Inspector { fn log( &mut self, _evm_data: &mut EVMData<'_, DB>, - _address: &B160, + _address: &Address, _topics: &[B256], _data: &Bytes, ); @@ -57,17 +57,17 @@ pub trait Inspector { &mut self, _data: &mut EVMData<'_, DB>, _inputs: &mut CreateInputs, - ) -> (InstructionResult, Option, Gas, Bytes); + ) -> (InstructionResult, Option
, Gas, Bytes); fn create_end( &mut self, _data: &mut EVMData<'_, DB>, _inputs: &CreateInputs, ret: InstructionResult, - address: Option, + address: Option
, remaining_gas: Gas, out: Bytes, - ) -> (InstructionResult, Option, Gas, Bytes); - fn selfdestruct(&mut self, _contract: B160, _target: B160); + ) -> (InstructionResult, Option
, Gas, Bytes); + fn selfdestruct(&mut self, _contract: Address, _target: Address); } ``` @@ -93,7 +93,7 @@ To use an inspector, you need to implement the `Inspector` trait. For each metho For example, if you wanted to log all `SELFDESTRUCT` operations, you could implement the selfdestruct method to write a log entry every time a contract initiates a `selfdestruct` operation. ```rust -fn selfdestruct(&mut self, contract: B160, target: B160) { +fn selfdestruct(&mut self, contract: Address, target: Address) { println!("Contract {} self destructed, funds sent to {}", contract, target); } ``` diff --git a/documentation/src/examples.md b/documentation/src/examples.md index 0784c91051..42d6ed23a5 100644 --- a/documentation/src/examples.md +++ b/documentation/src/examples.md @@ -18,20 +18,18 @@ Finally, the code prints out the result of the `getReserves()` call from that po This code is a demonstration of how one can interact with a smart contract's storage, generate call data, initialize an EVM, and execute a transaction to a contract function using Rust and `revm`. ```rust -use anyhow::{Ok, Result}; -use bytes::Bytes; use ethers_contract::BaseContract; use ethers_core::abi::parse_abi; use ethers_providers::{Http, Provider}; use revm::{ db::{CacheDB, EmptyDB, EthersDB}, - primitives::{ExecutionResult, Output, TransactTo, B160, U256 as rU256}, + primitives::{address, ExecutionResult, Output, TransactTo, U256}, Database, EVM, }; -use std::{str::FromStr, sync::Arc}; +use std::sync::Arc; #[tokio::main] -async fn main() -> Result<()> { +async fn main() -> anyhow::Result<()> { // create ethers client and wrap it in Arc let client = Provider::::try_from( "https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27", @@ -51,10 +49,10 @@ async fn main() -> Result<()> { // =========================================================== // // choose slot of storage that you would like to transact with - let slot = rU256::from(8); + let slot = U256::from(8); // ETH/USDT pair on Uniswap V2 - let pool_address = B160::from_str("0x0d4a11d5EEaaC28EC3F61d100daF4d40471f1852")?; + let pool_address = address!("0d4a11d5EEaaC28EC3F61d100daF4d40471f1852"); // generate abi for the calldata from the human readable interface let abi = BaseContract::from( @@ -94,13 +92,13 @@ async fn main() -> Result<()> { // fill in missing bits of env struc // change that to whatever caller you want to be - evm.env.tx.caller = B160::from_str("0x0000000000000000000000000000000000000000")?; + evm.env.tx.caller = address!("0000000000000000000000000000000000000000"); // account you want to transact with evm.env.tx.transact_to = TransactTo::Call(pool_address); // calldata formed via abigen - evm.env.tx.data = Bytes::from(hex::decode(hex::encode(&encoded))?); + evm.env.tx.data = encoded.0.into(); // transaction value in wei - evm.env.tx.value = rU256::try_from(0)?; + evm.env.tx.value = U256::ZERO; // execute transaction without writing to the DB let ref_tx = evm.transact_ref().unwrap(); diff --git a/examples/fork_ref_transact.rs b/examples/fork_ref_transact.rs index 3eae558b19..7ef4174897 100644 --- a/examples/fork_ref_transact.rs +++ b/examples/fork_ref_transact.rs @@ -1,17 +1,15 @@ -use anyhow::{Ok, Result}; -use bytes::Bytes; use ethers_contract::BaseContract; use ethers_core::abi::parse_abi; use ethers_providers::{Http, Provider}; use revm::{ db::{CacheDB, EmptyDB, EthersDB}, - primitives::{ExecutionResult, Output, TransactTo, B160, U256 as rU256}, + primitives::{address, ExecutionResult, Output, TransactTo, U256}, Database, EVM, }; -use std::{str::FromStr, sync::Arc}; +use std::sync::Arc; #[tokio::main] -async fn main() -> Result<()> { +async fn main() -> anyhow::Result<()> { // create ethers client and wrap it in Arc let client = Provider::::try_from( "https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27", @@ -31,10 +29,10 @@ async fn main() -> Result<()> { // =========================================================== // // choose slot of storage that you would like to transact with - let slot = rU256::from(8); + let slot = U256::from(8); // ETH/USDT pair on Uniswap V2 - let pool_address = B160::from_str("0x0d4a11d5EEaaC28EC3F61d100daF4d40471f1852")?; + let pool_address = address!("0d4a11d5EEaaC28EC3F61d100daF4d40471f1852"); // generate abi for the calldata from the human readable interface let abi = BaseContract::from( @@ -74,13 +72,13 @@ async fn main() -> Result<()> { // fill in missing bits of env struc // change that to whatever caller you want to be - evm.env.tx.caller = B160::from_str("0x0000000000000000000000000000000000000000")?; + evm.env.tx.caller = address!("0000000000000000000000000000000000000000"); // account you want to transact with evm.env.tx.transact_to = TransactTo::Call(pool_address); // calldata formed via abigen - evm.env.tx.data = Bytes::from(hex::decode(hex::encode(&encoded))?); + evm.env.tx.data = encoded.0.into(); // transaction value in wei - evm.env.tx.value = rU256::try_from(0)?; + evm.env.tx.value = U256::ZERO; // execute transaction without writing to the DB let ref_tx = evm.transact_ref().unwrap();