diff --git a/Cargo.lock b/Cargo.lock index 44afd1f09c..a9363f2eb4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -54,12 +54,29 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +[[package]] +name = "alloy-rlp" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f938f00332d63a5b0ac687bd6f46d03884638948921d9f8b50c59563d421ae25" +dependencies = [ + "arrayvec", + "bytes", + "smol_str", +] + [[package]] name = "android-tzdata" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" +[[package]] +name = "anes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + [[package]] name = "ansi_term" version = "0.12.1" @@ -69,6 +86,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "anstyle" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" + [[package]] name = "anyhow" version = "1.0.72" @@ -84,6 +107,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" @@ -109,7 +256,7 @@ checksum = "b6d7b9decdf35d8908a7e3ef02f64c5e9b1695e230154c0e8de3969142d9b94c" dependencies = [ "futures", "pharos", - "rustc_version", + "rustc_version 0.4.0", ] [[package]] @@ -303,6 +450,12 @@ dependencies = [ "serde", ] +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + [[package]] name = "cc" version = "1.0.79" @@ -325,6 +478,33 @@ dependencies = [ "num-traits", ] +[[package]] +name = "ciborium" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656" + +[[package]] +name = "ciborium-ll" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b" +dependencies = [ + "ciborium-io", + "half", +] + [[package]] name = "cipher" version = "0.4.4" @@ -350,6 +530,31 @@ dependencies = [ "vec_map", ] +[[package]] +name = "clap" +version = "4.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fd304a20bff958a57f04c4e96a2e7594cc4490a0e809cbd48bb6437edaa452d" +dependencies = [ + "clap_builder", +] + +[[package]] +name = "clap_builder" +version = "4.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01c6a3f08f1fe5662a35cfe393aec09c4df95f60ee93b7556505260f75eee9e1" +dependencies = [ + "anstyle", + "clap_lex", +] + +[[package]] +name = "clap_lex" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" + [[package]] name = "coins-bip32" version = "0.8.3" @@ -440,6 +645,85 @@ dependencies = [ "libc", ] +[[package]] +name = "criterion" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f" +dependencies = [ + "anes", + "cast", + "ciborium", + "clap 4.3.19", + "criterion-plot", + "is-terminal", + "itertools", + "num-traits", + "once_cell", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" +dependencies = [ + "cast", + "itertools", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +dependencies = [ + "cfg-if", +] + [[package]] name = "crunchy" version = "0.2.2" @@ -493,6 +777,17 @@ dependencies = [ "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" @@ -513,7 +808,7 @@ dependencies = [ "convert_case", "proc-macro2 1.0.66", "quote 1.0.32", - "rustc_version", + "rustc_version 0.4.0", "syn 1.0.109", ] @@ -629,9 +924,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", @@ -825,6 +1120,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" @@ -1048,6 +1354,12 @@ dependencies = [ "tracing", ] +[[package]] +name = "half" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" + [[package]] name = "hash-db" version = "0.15.2" @@ -1311,6 +1623,26 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" +[[package]] +name = "is-terminal" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +dependencies = [ + "hermit-abi 0.3.2", + "rustix", + "windows-sys 0.48.0", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.9" @@ -1389,10 +1721,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] -name = "microbench" -version = "0.5.0" +name = "memoffset" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4c44e40aee4e6fd2f4257bb91e5948ce79285aeb949129448889cf2fbf6da0b" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +dependencies = [ + "autocfg", +] [[package]] name = "mime" @@ -1549,6 +1884,12 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +[[package]] +name = "oorandom" +version = "11.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" + [[package]] name = "opaque-debug" version = "0.3.0" @@ -1606,6 +1947,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" @@ -1631,6 +1978,16 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +[[package]] +name = "pest" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d2d1d55045829d65aad9d389139882ad623b33b904e7c9f1b10c5b8927298e5" +dependencies = [ + "thiserror", + "ucd-trie", +] + [[package]] name = "pharos" version = "0.5.3" @@ -1638,7 +1995,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9567389417feee6ce15dd6527a8a1ecac205ef62c2932bcf3d9f6fc5b78b414" dependencies = [ "futures", - "rustc_version", + "rustc_version 0.4.0", ] [[package]] @@ -1692,6 +2049,34 @@ dependencies = [ "crunchy", ] +[[package]] +name = "plotters" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" + +[[package]] +name = "plotters-svg" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" +dependencies = [ + "plotters-backend", +] + [[package]] name = "portable-atomic" version = "1.4.2" @@ -1876,6 +2261,28 @@ dependencies = [ "rand_core", ] +[[package]] +name = "rayon" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "num_cpus", +] + [[package]] name = "redox_syscall" version = "0.3.5" @@ -1899,9 +2306,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310" +checksum = "b7b6d6190b7594385f61bd3911cd1be99dfddcfc365a4160cc2ab5bff4aed294" dependencies = [ "aho-corasick", "memchr", @@ -1966,6 +2373,7 @@ dependencies = [ "anyhow", "auto_impl", "bytes", + "criterion", "ethers-contract", "ethers-core", "ethers-providers", @@ -1984,8 +2392,6 @@ name = "revm-interpreter" version = "1.1.2" dependencies = [ "arbitrary", - "derive_more", - "enumn", "proptest", "proptest-derive", "revm-primitives", @@ -2033,16 +2439,6 @@ dependencies = [ "sha3", ] -[[package]] -name = "revm-test" -version = "0.1.0" -dependencies = [ - "bytes", - "hex", - "microbench", - "revm", -] - [[package]] name = "revme" version = "0.2.0" @@ -2125,17 +2521,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]] @@ -2156,13 +2561,22 @@ 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]] @@ -2285,6 +2699,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "scrypt" version = "0.10.0" @@ -2339,12 +2759,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" @@ -2359,18 +2797,18 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.177" +version = "1.0.178" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63ba2516aa6bf82e0b19ca8b50019d52df58455d3cf9bdaf6315225fdd0c560a" +checksum = "60363bdd39a7be0266a520dab25fdc9241d2f987b08a01e01f0ec6d06a981348" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.177" +version = "1.0.178" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "401797fe7833d72109fedec6bfcbe67c0eed9b99772f26eb8afd261f0abc6fd3" +checksum = "f28482318d6641454cb273da158647922d1be6b5a2fcc6165cd89ebdd7ed576b" dependencies = [ "proc-macro2 1.0.66", "quote 1.0.32", @@ -2465,6 +2903,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" @@ -2509,7 +2956,7 @@ version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" dependencies = [ - "clap", + "clap 2.34.0", "lazy_static", "structopt-derive", ] @@ -2658,6 +3105,16 @@ dependencies = [ "crunchy", ] +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -2849,6 +3306,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" @@ -2945,6 +3408,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" @@ -3260,9 +3729,9 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "winnow" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b5872fa2e10bd067ae946f927e726d7d603eaeb6e02fa6a350e0722d2b8c11" +checksum = "8bd122eb777186e60c3fdf765a58ac76e41c582f1f535fbf3314434c6b58f3f7" dependencies = [ "memchr", ] @@ -3287,7 +3756,7 @@ dependencies = [ "js-sys", "log", "pharos", - "rustc_version", + "rustc_version 0.4.0", "send_wrapper 0.6.0", "thiserror", "wasm-bindgen", @@ -3309,3 +3778,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.27", +] diff --git a/Cargo.toml b/Cargo.toml index f1a0440fc0..3a418746f3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,10 +1,7 @@ [workspace] resolver = "2" -members = [ - "bins/*", - "crates/*", -] +members = ["bins/*", "crates/*"] default-members = ["crates/revm"] [profile.release] diff --git a/bins/revm-test/Cargo.toml b/bins/revm-test/Cargo.toml deleted file mode 100644 index 661ce1a654..0000000000 --- a/bins/revm-test/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -name = "revm-test" -version = "0.1.0" -edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -bytes = "1.4" -hex = "0.4" -revm = { path = "../../crates/revm", version = "3.3.0" } -microbench = "0.5" - -[[bin]] -name = "analysis" - -[[bin]] -name = "snailtracer" - -[[bin]] -name = "transfer" \ No newline at end of file diff --git a/bins/revm-test/src/bin/analysis.rs b/bins/revm-test/src/bin/analysis.rs deleted file mode 100644 index 3dc05de196..0000000000 --- a/bins/revm-test/src/bin/analysis.rs +++ /dev/null @@ -1,61 +0,0 @@ -use std::time::Instant; - -use bytes::Bytes; -use revm::{ - db::BenchmarkDB, - interpreter::analysis::to_analysed, - primitives::{Bytecode, TransactTo}, -}; -extern crate alloc; - -fn main() { - let contract_data : Bytes = hex::decode( "6060604052341561000f57600080fd5b604051610dd1380380610dd18339810160405280805190602001909190805182019190602001805190602001909190805182019190505083600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508360008190555082600390805190602001906100a79291906100e3565b5081600460006101000a81548160ff021916908360ff16021790555080600590805190602001906100d99291906100e3565b5050505050610188565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061012457805160ff1916838001178555610152565b82800160010185558215610152579182015b82811115610151578251825591602001919060010190610136565b5b50905061015f9190610163565b5090565b61018591905b80821115610181576000816000905550600101610169565b5090565b90565b610c3a806101976000396000f3006060604052600436106100af576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100b4578063095ea7b31461014257806318160ddd1461019c57806323b872dd146101c557806327e235e31461023e578063313ce5671461028b5780635c658165146102ba57806370a082311461032657806395d89b4114610373578063a9059cbb14610401578063dd62ed3e1461045b575b600080fd5b34156100bf57600080fd5b6100c76104c7565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101075780820151818401526020810190506100ec565b50505050905090810190601f1680156101345780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561014d57600080fd5b610182600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610565565b604051808215151515815260200191505060405180910390f35b34156101a757600080fd5b6101af610657565b6040518082815260200191505060405180910390f35b34156101d057600080fd5b610224600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061065d565b604051808215151515815260200191505060405180910390f35b341561024957600080fd5b610275600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506108f7565b6040518082815260200191505060405180910390f35b341561029657600080fd5b61029e61090f565b604051808260ff1660ff16815260200191505060405180910390f35b34156102c557600080fd5b610310600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610922565b6040518082815260200191505060405180910390f35b341561033157600080fd5b61035d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610947565b6040518082815260200191505060405180910390f35b341561037e57600080fd5b610386610990565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156103c65780820151818401526020810190506103ab565b50505050905090810190601f1680156103f35780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561040c57600080fd5b610441600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610a2e565b604051808215151515815260200191505060405180910390f35b341561046657600080fd5b6104b1600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610b87565b6040518082815260200191505060405180910390f35b60038054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561055d5780601f106105325761010080835404028352916020019161055d565b820191906000526020600020905b81548152906001019060200180831161054057829003601f168201915b505050505081565b600081600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60005481565b600080600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905082600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015801561072e5750828110155b151561073957600080fd5b82600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555082600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8110156108865782600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a360019150509392505050565b60016020528060005260406000206000915090505481565b600460009054906101000a900460ff1681565b6002602052816000526040600020602052806000526040600020600091509150505481565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60058054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610a265780601f106109fb57610100808354040283529160200191610a26565b820191906000526020600020905b815481529060010190602001808311610a0957829003601f168201915b505050505081565b600081600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610a7e57600080fd5b81600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a36001905092915050565b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050929150505600a165627a7a72305820df254047bc8f2904ad3e966b6db116d703bebd40efadadb5e738c836ffc8f58a0029" ).unwrap().into(); - - // BenchmarkDB is dummy state that implements Database trait. - let mut evm = revm::new(); - - // execution globals block hash/gas_limit/coinbase/timestamp.. - 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()); - - let bytecode_raw = Bytecode::new_raw(contract_data.clone()); - let bytecode_checked = Bytecode::new_raw(contract_data.clone()).to_checked(); - let bytecode_analysed = to_analysed(Bytecode::new_raw(contract_data)); - - evm.database(BenchmarkDB::new_bytecode(bytecode_raw)); - - // just to spead up processor. - for _ in 0..10000 { - let _ = evm.transact().unwrap(); - } - - let timer = Instant::now(); - for _ in 0..30000 { - let _ = evm.transact().unwrap(); - } - println!("Raw elapsed time: {:?}", timer.elapsed()); - - evm.database(BenchmarkDB::new_bytecode(bytecode_checked)); - - let timer = Instant::now(); - for _ in 0..30000 { - let _ = evm.transact().unwrap(); - } - println!("Checked elapsed time: {:?}", timer.elapsed()); - - evm.database(BenchmarkDB::new_bytecode(bytecode_analysed)); - - let timer = Instant::now(); - for _ in 0..30000 { - let _ = evm.transact().unwrap(); - } - println!("Analysed elapsed time: {:?}", timer.elapsed()); -} diff --git a/bins/revm-test/src/bin/snailtracer.rs b/bins/revm-test/src/bin/snailtracer.rs deleted file mode 100644 index 53ae3fdac8..0000000000 --- a/bins/revm-test/src/bin/snailtracer.rs +++ /dev/null @@ -1,61 +0,0 @@ -use std::time::Duration; - -use bytes::Bytes; -use revm::{ - db::BenchmarkDB, - interpreter::{analysis::to_analysed, BytecodeLocked, Contract, DummyHost, Interpreter}, - primitives::{BerlinSpec, Bytecode, TransactTo}, -}; -extern crate alloc; - -pub fn simple_example() { - let contract_data : Bytes = hex::decode("608060405234801561001057600080fd5b506004361061004c5760003560e01c806330627b7c1461005157806375ac892a14610085578063784f13661461011d578063c294360114610146575b600080fd5b610059610163565b604080516001600160f81b03199485168152928416602084015292168183015290519081900360600190f35b6100a86004803603604081101561009b57600080fd5b50803590602001356102d1565b6040805160208082528351818301528351919283929083019185019080838360005b838110156100e25781810151838201526020016100ca565b50505050905090810190601f16801561010f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6100596004803603606081101561013357600080fd5b508035906020810135906040013561055b565b6100a86004803603602081101561015c57600080fd5b5035610590565b6000806000610176610400610300610834565b60405180606001604052806001546000546207d5dc028161019357fe5b058152600060208083018290526040928301919091528251600b81905583820151600c81905593830151600d819055835160608082018652928152808401959095528484015282519081018352600654815260075491810191909152600854918101919091526102259161021c916102139161020e91612ef7565b612f64565b6207d5dc612feb565b620f424061301e565b8051600e556020810151600f55604001516010556102416142dd565b61025a816102556102006101806008613064565b613212565b90506102708161025561014561021c6008613064565b905061028481610255610258806008613064565b905061029a8161025561020a61020c6008613064565b90506102a781600461301e565b90506102b1613250565b8051602082015160409092015160f891821b9692821b9550901b92509050565b606060005b6000548112156104c95760006102ed828686613064565b90506002816000015160f81b90808054603f811680603e811461032a576002830184556001831661031c578192505b600160028404019350610342565b600084815260209081902060ff198516905560419094555b505050600190038154600116156103685790600052602060002090602091828204019190065b909190919091601f036101000a81548160ff02191690600160f81b840402179055506002816020015160f81b90808054603f811680603e81146103c557600283018455600183166103b7578192505b6001600284040193506103dd565b600084815260209081902060ff198516905560419094555b505050600190038154600116156104035790600052602060002090602091828204019190065b909190919091601f036101000a81548160ff02191690600160f81b840402179055506002816040015160f81b90808054603f811680603e81146104605760028301845560018316610452578192505b600160028404019350610478565b600084815260209081902060ff198516905560419094555b5050506001900381546001161561049e5790600052602060002090602091828204019190065b815460ff601f929092036101000a9182021916600160f81b90930402919091179055506001016102d6565b506002805460408051602060018416156101000260001901909316849004601f8101849004840282018401909252818152929183018282801561054d5780601f106105225761010080835404028352916020019161054d565b820191906000526020600020905b81548152906001019060200180831161053057829003601f168201915b505050505090505b92915050565b60008060008061056c878787613064565b8051602082015160409092015160f891821b9a92821b9950901b9650945050505050565b600154606090600019015b600081126107a35760005b6000548112156107995760006105bd828487613064565b90506002816000015160f81b90808054603f811680603e81146105fa57600283018455600183166105ec578192505b600160028404019350610612565b600084815260209081902060ff198516905560419094555b505050600190038154600116156106385790600052602060002090602091828204019190065b909190919091601f036101000a81548160ff02191690600160f81b840402179055506002816020015160f81b90808054603f811680603e81146106955760028301845560018316610687578192505b6001600284040193506106ad565b600084815260209081902060ff198516905560419094555b505050600190038154600116156106d35790600052602060002090602091828204019190065b909190919091601f036101000a81548160ff02191690600160f81b840402179055506002816040015160f81b90808054603f811680603e81146107305760028301845560018316610722578192505b600160028404019350610748565b600084815260209081902060ff198516905560419094555b5050506001900381546001161561076e5790600052602060002090602091828204019190065b815460ff601f929092036101000a9182021916600160f81b90930402919091179055506001016105a6565b506000190161059b565b506002805460408051602060018416156101000260001901909316849004601f810184900484028201840190925281815292918301828280156108275780601f106107fc57610100808354040283529160200191610827565b820191906000526020600020905b81548152906001019060200180831161080a57829003601f168201915b505050505090505b919050565b8160008190555080600181905550604051806080016040528060405180606001604052806302faf08081526020016303197500815260200163119e7f8081525081526020016108a460405180606001604052806000815260200161a673198152602001620f423f19815250612f64565b815260006020808301829052604092830182905283518051600355808201516004558301516005558381015180516006559081015160075582015160085582820151600955606092830151600a805460ff1916911515919091179055815192830190915260015490548291906207d5dc028161091c57fe5b058152600060208083018290526040928301919091528251600b81905583820151600c81905593830151600d819055835160608082018652928152808401959095528484015282519081018352600654815260075491810191909152600854918101919091526109979161021c916102139161020e91612ef7565b8051600e55602080820151600f55604091820151601055815160a08101835264174876e8008152825160608082018552641748862a40825263026e8f00828501526304dd1e008286015282840191825284518082018652600080825281860181905281870181905284870191825286518084018852620b71b081526203d09081880181905281890152928501928352608085018181526011805460018082018355919093528651600b9093027f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c688101938455955180517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c69880155808901517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6a8801558901517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6b870155925180517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6c870155808801517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6d8701558801517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6e860155925180517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6f860155958601517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c7085015594909501517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c71830155517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c72909101805492949192909160ff1990911690836002811115610c1057fe5b0217905550505060116040518060a0016040528064174876e8008152602001604051806060016040528064174290493f19815260200163026e8f0081526020016304dd1e008152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806203d09081526020016203d0908152602001620b71b0815250815260200160006002811115610cb657fe5b905281546001818101845560009384526020938490208351600b90930201918255838301518051838301558085015160028085019190915560409182015160038501558185015180516004860155808701516005860155820151600685015560608501518051600786015595860151600885015594015160098301556080830151600a83018054949593949193909260ff1990921691908490811115610d5857fe5b0217905550505060116040518060a0016040528064174876e800815260200160405180606001604052806302faf080815260200163026e8f00815260200164174876e800815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620b71b08152602001620b71b08152602001620b71b0815250815260200160006002811115610dfd57fe5b905281546001818101845560009384526020938490208351600b90930201918255838301518051838301558085015160028085019190915560409182015160038501558185015180516004860155808701516005860155820151600685015560608501518051600786015595860151600885015594015160098301556080830151600a83018054949593949193909260ff1990921691908490811115610e9f57fe5b0217905550505060116040518060a0016040528064174876e800815260200160405180606001604052806302faf080815260200163026e8f00815260200164173e54e97f1981525081526020016040518060600160405280600081526020016000815260200160008152508152602001604051806060016040528060008152602001600081526020016000815250815260200160006002811115610f3f57fe5b905281546001818101845560009384526020938490208351600b90930201918255838301518051838301558085015160028085019190915560409182015160038501558185015180516004860155808701516005860155820151600685015560608501518051600786015595860151600885015594015160098301556080830151600a83018054949593949193909260ff1990921691908490811115610fe157fe5b0217905550505060116040518060a0016040528064174876e800815260200160405180606001604052806302faf080815260200164174876e80081526020016304dd1e00815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620b71b08152602001620b71b08152602001620b71b081525081526020016000600281111561108657fe5b905281546001818101845560009384526020938490208351600b90930201918255838301518051838301558085015160028085019190915560409182015160038501558185015180516004860155808701516005860155820151600685015560608501518051600786015595860151600885015594015160098301556080830151600a83018054949593949193909260ff199092169190849081111561112857fe5b0217905550505060116040518060a0016040528064174876e800815260200160405180606001604052806302faf080815260200164174399c9ff1981526020016304dd1e00815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620b71b08152602001620b71b08152602001620b71b08152508152602001600060028111156111ce57fe5b905281546001818101845560009384526020938490208351600b90930201918255838301518051838301558085015160028085019190915560409182015160038501558185015180516004860155808701516005860155820151600685015560608501518051600786015595860151600885015594015160098301556080830151600a83018054949593949193909260ff199092169190849081111561127057fe5b0217905550505060116040518060a0016040528062fbc5208152602001604051806060016040528063019bfcc0815260200162fbc52081526020016302cd29c0815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e5881525081526020016001600281111561131157fe5b905281546001818101845560009384526020938490208351600b90930201918255838301518051838301558085015160028085019190915560409182015160038501558185015180516004860155808701516005860155820151600685015560608501518051600786015595860151600885015594015160098301556080830151600a83018054949593949193909260ff19909216919084908111156113b357fe5b0217905550505060116040518060a001604052806323c34600815260200160405180606001604052806302faf080815260200163289c455081526020016304dd1e008152508152602001604051806060016040528062b71b00815260200162b71b00815260200162b71b00815250815260200160405180606001604052806000815260200160008152602001600081525081526020016000600281111561145657fe5b905281546001818101845560009384526020938490208351600b90930201918255838301518051838301558085015160028085019190915560409182015160038501558185015180516004860155808701516005860155820151600685015560608501518051600786015595860151600885015594015160098301556080830151600a83018054949593949193909260ff19909216919084908111156114f857fe5b0217905550505060126040518060e00160405280604051806060016040528063035e1f208152602001630188c2e081526020016304a62f8081525081526020016040518060600160405280630459e4408152602001630188c2e081526020016305a1f4a081525081526020016040518060600160405280630459e44081526020016302f34f6081526020016304a62f808152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e5881525081526020016001600281111561160c57fe5b905281546001818101845560009384526020938490208351805160139094029091019283558085015183830155604090810151600280850191909155858501518051600386015580870151600486015582015160058501558185015180516006860155808701516007860155820151600885015560608501518051600986015580870151600a860155820151600b85015560808501518051600c86015580870151600d860155820151600e85015560a08501518051600f860155958601516010850155940151601183015560c0830151601283018054949593949193909260ff19909216919084908111156116fd57fe5b0217905550505060126040518060e00160405280604051806060016040528063035e1f20815260200163016a8c8081526020016304a62f8081525081526020016040518060600160405280630459e4408152602001600081526020016304a62f8081525081526020016040518060600160405280630459e440815260200163016a8c8081526020016305a1f4a08152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e5881525081526020016001600281111561180e57fe5b905281546001818101845560009384526020938490208351805160139094029091019283558085015183830155604090810151600280850191909155858501518051600386015580870151600486015582015160058501558185015180516006860155808701516007860155820151600885015560608501518051600986015580870151600a860155820151600b85015560808501518051600c86015580870151600d860155820151600e85015560a08501518051600f860155958601516010850155940151601183015560c0830151601283018054949593949193909260ff19909216919084908111156118ff57fe5b0217905550505060126040518060e001604052806040518060600160405280630555a9608152602001630188c2e081526020016304a62f8081525081526020016040518060600160405280630459e44081526020016302f34f6081526020016304a62f8081525081526020016040518060600160405280630459e4408152602001630188c2e081526020016305a1f4a08152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e58815250815260200160016002811115611a1357fe5b905281546001818101845560009384526020938490208351805160139094029091019283558085015183830155604090810151600280850191909155858501518051600386015580870151600486015582015160058501558185015180516006860155808701516007860155820151600885015560608501518051600986015580870151600a860155820151600b85015560808501518051600c86015580870151600d860155820151600e85015560a08501518051600f860155958601516010850155940151601183015560c0830151601283018054949593949193909260ff1990921691908490811115611b0457fe5b0217905550505060126040518060e001604052806040518060600160405280630555a960815260200163016a8c8081526020016304a62f8081525081526020016040518060600160405280630459e440815260200163016a8c8081526020016305a1f4a081525081526020016040518060600160405280630459e4408152602001600081526020016304a62f808152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e58815250815260200160016002811115611c1557fe5b905281546001818101845560009384526020938490208351805160139094029091019283558085015183830155604090810151600280850191909155858501518051600386015580870151600486015582015160058501558185015180516006860155808701516007860155820151600885015560608501518051600986015580870151600a860155820151600b85015560808501518051600c86015580870151600d860155820151600e85015560a08501518051600f860155958601516010850155940151601183015560c0830151601283018054949593949193909260ff1990921691908490811115611d0657fe5b0217905550505060126040518060e00160405280604051806060016040528063035e1f208152602001630188c2e081526020016304a62f8081525081526020016040518060600160405280630459e44081526020016302f34f6081526020016304a62f8081525081526020016040518060600160405280630459e4408152602001630188c2e081526020016303aa6a608152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e58815250815260200160016002811115611e1a57fe5b905281546001818101845560009384526020938490208351805160139094029091019283558085015183830155604090810151600280850191909155858501518051600386015580870151600486015582015160058501558185015180516006860155808701516007860155820151600885015560608501518051600986015580870151600a860155820151600b85015560808501518051600c86015580870151600d860155820151600e85015560a08501518051600f860155958601516010850155940151601183015560c0830151601283018054949593949193909260ff1990921691908490811115611f0b57fe5b0217905550505060126040518060e00160405280604051806060016040528063035e1f20815260200163016a8c8081526020016304a62f8081525081526020016040518060600160405280630459e440815260200163016a8c8081526020016303aa6a6081525081526020016040518060600160405280630459e4408152602001600081526020016304a62f808152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e5881525081526020016001600281111561201c57fe5b905281546001818101845560009384526020938490208351805160139094029091019283558085015183830155604090810151600280850191909155858501518051600386015580870151600486015582015160058501558185015180516006860155808701516007860155820151600885015560608501518051600986015580870151600a860155820151600b85015560808501518051600c86015580870151600d860155820151600e85015560a08501518051600f860155958601516010850155940151601183015560c0830151601283018054949593949193909260ff199092169190849081111561210d57fe5b0217905550505060126040518060e001604052806040518060600160405280630555a9608152602001630188c2e081526020016304a62f8081525081526020016040518060600160405280630459e4408152602001630188c2e081526020016303aa6a6081525081526020016040518060600160405280630459e44081526020016302f34f6081526020016304a62f808152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e5881525081526020016001600281111561222157fe5b905281546001818101845560009384526020938490208351805160139094029091019283558085015183830155604090810151600280850191909155858501518051600386015580870151600486015582015160058501558185015180516006860155808701516007860155820151600885015560608501518051600986015580870151600a860155820151600b85015560808501518051600c86015580870151600d860155820151600e85015560a08501518051600f860155958601516010850155940151601183015560c0830151601283018054949593949193909260ff199092169190849081111561231257fe5b0217905550505060126040518060e001604052806040518060600160405280630555a960815260200163016a8c8081526020016304a62f8081525081526020016040518060600160405280630459e4408152602001600081526020016304a62f8081525081526020016040518060600160405280630459e440815260200163016a8c8081526020016303aa6a608152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e5881525081526020016001600281111561242357fe5b905281546001818101845560009384526020938490208351805160139094029091019283558085015183830155604090810151600280850191909155858501518051600386015580870151600486015582015160058501558185015180516006860155808701516007860155820151600885015560608501518051600986015580870151600a860155820151600b85015560808501518051600c86015580870151600d860155820151600e85015560a08501518051600f860155958601516010850155940151601183015560c0830151601283018054949593949193909260ff199092169190849081111561251457fe5b0217905550505060126040518060e00160405280604051806060016040528063035e1f208152602001630188c2e081526020016304a62f8081525081526020016040518060600160405280630459e4408152602001630188c2e081526020016303aa6a6081525081526020016040518060600160405280630555a9608152602001630188c2e081526020016304a62f808152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e5881525081526020016001600281111561262857fe5b905281546001818101845560009384526020938490208351805160139094029091019283558085015183830155604090810151600280850191909155858501518051600386015580870151600486015582015160058501558185015180516006860155808701516007860155820151600885015560608501518051600986015580870151600a860155820151600b85015560808501518051600c86015580870151600d860155820151600e85015560a08501518051600f860155958601516010850155940151601183015560c0830151601283018054949593949193909260ff199092169190849081111561271957fe5b0217905550505060126040518060e00160405280604051806060016040528063035e1f208152602001630188c2e081526020016304a62f8081525081526020016040518060600160405280630555a9608152602001630188c2e081526020016304a62f8081525081526020016040518060600160405280630459e4408152602001630188c2e081526020016305a1f4a08152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e5881525081526020016001600281111561282d57fe5b905281546001818101845560009384526020938490208351805160139094029091019283558085015183830155604090810151600280850191909155858501518051600386015580870151600486015582015160058501558185015180516006860155808701516007860155820151600885015560608501518051600986015580870151600a860155820151600b85015560808501518051600c86015580870151600d860155820151600e85015560a08501518051600f860155958601516010850155940151601183015560c0830151601283018054949593949193909260ff199092169190849081111561291e57fe5b0217905550505060126040518060e00160405280604051806060016040528063035e1f20815260200163016a8c8081526020016304a62f8081525081526020016040518060600160405280630555a960815260200163016a8c8081526020016304a62f8081525081526020016040518060600160405280630459e440815260200163016a8c8081526020016303aa6a608152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e58815250815260200160016002811115612a3257fe5b905281546001818101845560009384526020938490208351805160139094029091019283558085015183830155604090810151600280850191909155858501518051600386015580870151600486015582015160058501558185015180516006860155808701516007860155820151600885015560608501518051600986015580870151600a860155820151600b85015560808501518051600c86015580870151600d860155820151600e85015560a08501518051600f860155958601516010850155940151601183015560c0830151601283018054949593949193909260ff1990921691908490811115612b2357fe5b0217905550505060126040518060e00160405280604051806060016040528063035e1f20815260200163016a8c8081526020016304a62f8081525081526020016040518060600160405280630459e440815260200163016a8c8081526020016305a1f4a081525081526020016040518060600160405280630555a960815260200163016a8c8081526020016304a62f808152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e58815250815260200160016002811115612c3757fe5b905281546001818101845560009384526020938490208351805160139094029091019283558085015183830155604090810151600280850191909155858501518051600386015580870151600486015582015160058501558185015180516006860155808701516007860155820151600885015560608501518051600986015580870151600a860155820151600b85015560808501518051600c86015580870151600d860155820151600e85015560a08501518051600f860155958601516010850155940151601183015560c0830151601283018054949593949193909260ff1990921691908490811115612d2857fe5b0217905550505060005b601254811015612ef257600060128281548110612d4b57fe5b600091825260209182902060408051610140810182526013909302909101805460e08401908152600182015461010085015260028083015461012086015290845282516060818101855260038401548252600484015482880152600584015482860152858701919091528351808201855260068401548152600784015481880152600884015481860152858501528351808201855260098401548152600a84015481880152600b840154818601528186015283518082018552600c8401548152600d84015481880152600e84015481860152608086015283519081018452600f830154815260108301549581019590955260118201549285019290925260a0830193909352601283015491929160c084019160ff90911690811115612e6c57fe5b6002811115612e7757fe5b815250509050612eac61020e612e95836020015184600001516132cd565b612ea7846040015185600001516132cd565b612ef7565b60128381548110612eb957fe5b60009182526020918290208351600960139093029091019182015590820151600a820155604090910151600b9091015550600101612d32565b505050565b612eff6142dd565b604051806060016040528083602001518560400151028460400151866020015102038152602001836040015185600001510284600001518660400151020381526020018360000151856020015102846020015186600001510203815250905092915050565b612f6c6142dd565b604082015160208301518351600092612f9292918002918002919091019080020161330c565b90506040518060600160405280828560000151620f42400281612fb157fe5b058152602001828560200151620f42400281612fc957fe5b058152602001828560400151620f42400281612fe157fe5b0590529392505050565b612ff36142dd565b5060408051606081018252835183028152602080850151840290820152928101519091029082015290565b6130266142dd565b60405180606001604052808385600001518161303e57fe5b0581526020018385602001518161305157fe5b05815260200183856040015181612fe157fe5b61306c6142dd565b6000546013805463ffffffff1916918502860163ffffffff169190911790556130936142dd565b905060005b828112156131f157600061317261314c61021c613115600b60405180606001604052908160008201548152602001600182015481526020016002820154815250506207a1206000546207a1206130ec613343565b63ffffffff16816130f957fe5b0663ffffffff168d620f424002018161310e57fe5b0503612feb565b60408051606081018252600e548152600f5460208201526010549181019190915260015461025591906207a12090816130ec613343565b604080516060810182526006548152600754602082015260085491810191909152613212565b6040805160e081019091526003546080820190815260045460a083015260055460c083015291925060009181906131ae9061025586608c612feb565b81526020016131bc84612f64565b815260006020820181905260409091015290506131e5846102556131df8461336c565b8861301e565b93505050600101613098565b5061320861021c61320183613753565b60ff612feb565b90505b9392505050565b61321a6142dd565b50604080516060810182528251845101815260208084015181860151019082015291810151928101519092019181019190915290565b60008080556001819055613266906002906142fe565b60006003819055600481905560058190556006819055600781905560088190556009819055600a805460ff19169055600b819055600c819055600d819055600e819055600f81905560108190556132bf90601190614345565b6132cb60126000614366565b565b6132d56142dd565b5060408051606081018252825184510381526020808401518186015103908201528282015184830151039181019190915292915050565b80600260018201055b8181121561333d5780915060028182858161332c57fe5b05018161333557fe5b059050613315565b50919050565b6013805463ffffffff19811663ffffffff9182166341c64e6d0261303901821617918290551690565b6133746142dd565b600a826040015113156133a657604051806060016040528060008152602001600081526020016000815250905061082f565b60008060006133b48561379f565b91945092509050826133e857604051806060016040528060008152602001600081526020016000815250935050505061082f565b6133f0614387565b6133f86143c7565b6134006142dd565b6134086142dd565b600086600181111561341657fe5b1415613505576011858154811061342957fe5b60009182526020918290206040805160a081018252600b90930290910180548352815160608082018452600183015482526002808401548388015260038401548386015285870192909252835180820185526004840154815260058401548188015260068401548186015285850152835180820185526007840154815260088401549681019690965260098301549386019390935291830193909352600a830154919291608084019160ff909116908111156134e157fe5b60028111156134ec57fe5b8152505093508360600151915083604001519050613653565b6012858154811061351257fe5b600091825260209182902060408051610140810182526013909302909101805460e08401908152600182015461010085015260028083015461012086015290845282516060818101855260038401548252600484015482880152600584015482860152858701919091528351808201855260068401548152600784015481880152600884015481860152858501528351808201855260098401548152600a84015481880152600b840154818601528186015283518082018552600c8401548152600d84015481880152600e84015481860152608086015283519081018452600f830154815260108301549581019590955260118201549285019290925260a0830193909352601283015491929160c084019160ff9091169081111561363357fe5b600281111561363e57fe5b8152505092508260a001519150826080015190505b6040820151600190811215613669575060408201515b808360200151131561367c575060208201515b808360400151131561368f575060408201515b60408a01805160010190819052600512156136f75780620f42406136b1613343565b63ffffffff16816136be57fe5b0663ffffffff1612156136e8576136e16136db84620f4240612feb565b8261301e565b92506136f7565b50965061082f95505050505050565b6136ff6142dd565b600088600181111561370d57fe5b14156137255761371e8b878b613a57565b9050613733565b6137308b868b613aec565b90505b6137448361025561021c8785613baa565b9b9a5050505050505050505050565b61375b6142dd565b60405180606001604052806137738460000151613be8565b81526020016137858460200151613be8565b81526020016137978460400151613be8565b905292915050565b60008080808080805b6011548110156138c2576000613890601183815481106137c457fe5b60009182526020918290206040805160a081018252600b90930290910180548352815160608082018452600183015482526002808401548388015260038401548386015285870192909252835180820185526004840154815260058401548188015260068401548186015285850152835180820185526007840154815260088401549681019690965260098301549386019390935291830193909352600a830154919291608084019160ff9091169081111561387c57fe5b600281111561388757fe5b9052508a613c13565b90506000811380156138a957508415806138a957508481125b156138b957809450600093508192505b506001016137a8565b5060005b601254811015613a49576000613a17601283815481106138e257fe5b600091825260209182902060408051610140810182526013909302909101805460e08401908152600182015461010085015260028083015461012086015290845282516060818101855260038401548252600484015482880152600584015482860152858701919091528351808201855260068401548152600784015481880152600884015481860152858501528351808201855260098401548152600a84015481880152600b840154818601528186015283518082018552600c8401548152600d84015481880152600e84015481860152608086015283519081018452600f830154815260108301549581019590955260118201549285019290925260a0830193909352601283015491929160c084019160ff90911690811115613a0357fe5b6002811115613a0e57fe5b9052508a613cbb565b9050600081138015613a305750841580613a3057508481125b15613a4057809450600193508192505b506001016138c6565b509196909550909350915050565b613a5f6142dd565b6000613a7a856000015161025561021c886020015187612feb565b90506000613a8f61020e8387602001516132cd565b9050600085608001516002811115613aa357fe5b1415613ae1576000613ab9828860200151613e0c565b12613acd57613aca81600019612feb565b90505b613ad8868383613e31565b9250505061320b565b613ad8868383613fc1565b613af46142dd565b6000613b0f856000015161025561021c886020015187612feb565b6060860151909150620a2c2a9015613b2757506216e3605b6000620f4240613b3f87606001518960200151613e0c565b81613b4657fe5b05905060008112613b55576000035b64e8d4a5100081800281038380020281900590036000811215613b8c57613b8188858960600151613fc1565b94505050505061320b565b613b9e88858960600151868686614039565b98975050505050505050565b613bb26142dd565b50604080516060810182528251845102815260208084015181860151029082015291810151928101519092029181019190915290565b600080821215613bfa5750600061082f565b620f4240821315613c0f5750620f424061082f565b5090565b600080613c28846020015184600001516132cd565b90506000620f4240613c3e838660200151613e0c565b81613c4557fe5b865191900591506000908002613c5b8480613e0c565b838402030190506000811215613c775760009350505050610555565b613c808161330c565b90506103e88183031315613c9957900391506105559050565b6103e88183011315613caf570191506105559050565b50600095945050505050565b600080613cd0846020015185600001516132cd565b90506000613ce6856040015186600001516132cd565b90506000613cf8856020015183612ef7565b90506000620f4240613d0a8584613e0c565b81613d1157fe5b0590506103e71981138015613d2757506103e881125b15613d39576000945050505050610555565b85518751600091613d49916132cd565b9050600082613d588386613e0c565b81613d5f57fe5b0590506000811280613d735750620f424081135b15613d875760009650505050505050610555565b6000613d938388612ef7565b9050600084613da68b6020015184613e0c565b81613dad57fe5b0590506000811280613dc35750620f4240818401135b15613dd957600098505050505050505050610555565b600085613de68985613e0c565b81613ded57fe5b0590506103e88112156137445760009950505050505050505050610555565b6040808201519083015160208084015190850151845186510291020191020192915050565b613e396142dd565b6000620f424080613e48613343565b63ffffffff1681613e5557fe5b0663ffffffff16625fdfb00281613e6857fe5b0590506000620f4240613e79613343565b63ffffffff1681613e8657fe5b0663ffffffff1690506000613e9a8261330c565b6103e8029050613ea86142dd565b620186a0613eb98760000151614216565b1315613ee657604051806060016040528060008152602001620f4240815260200160008152509050613f09565b6040518060600160405280620f4240815260200160008152602001600081525090505b613f1661020e8288612ef7565b90506000613f2761020e8884612ef7565b9050613f7f61020e613f64613f5285620f424088613f448c61422e565b0281613f4c57fe5b05612feb565b61025585620f424089613f448d61424e565b6102558a613f7689620f42400361330c565b6103e802612feb565b9150613fb460405180608001604052808a81526020018481526020018b6040015181526020018b60600151151581525061336c565b9998505050505050505050565b613fc96142dd565b6000613ffb61020e8660200151613ff686620f4240613fec898c60200151613e0c565b60020281613f4c57fe5b6132cd565b90506140306040518060800160405280868152602001838152602001876040015181526020018760600151151581525061336c565b95945050505050565b6140416142dd565b60608701516000199015614053575060015b600061408961020e61021c61406c8c602001518a612feb565b613ff68b6140798a61330c565b620f42408c8e0205018802612feb565b60608a0151909150620f42408601906140ba57620f42406140aa838a613e0c565b816140b157fe5b05620f42400390505b60408a0151619c406c0c9f2c9cd04674edea40000000620ea6008480028502850285020205019060021261415e5761412a61411f60405180608001604052808d81526020018681526020018e6040015181526020018e6060015115151581525061336c565b82620f424003612feb565b92506141448361025561413e8e8e8e613fc1565b84612feb565b925061415383620f424061301e565b94505050505061420c565b600281056203d09001620f4240614173613343565b63ffffffff168161418057fe5b0663ffffffff1612156141b2576141536141a461419e8d8d8d613fc1565b83612feb565b600283056203d0900161301e565b6142056141f76141ec60405180608001604052808e81526020018781526020018f6040015181526020018f6060015115151581525061336c565b83620f424003612feb565b60028305620b71b00361301e565b9450505050505b9695505050505050565b60008082131561422757508061082f565b5060000390565b60008061423a8361424e565b905061320b81820264e8d4a510000361330c565b60005b600082121561426757625fdfb082019150614251565b5b625fdfb0821261427f57625fdfb082039150614268565b6001828160025b818313156142d457818385028161429957fe5b0585019450620f4240808788860202816142af57fe5b05816142b757fe5b600095909503940592506001810181029190910290600201614286565b50505050919050565b60405180606001604052806000815260200160008152602001600081525090565b50805460018160011615610100020316600290046000825580601f106143245750614342565b601f0160209004906000526020600020908101906143429190614401565b50565b50805460008255600b02906000526020600020908101906143429190614416565b50805460008255601302906000526020600020908101906143429190614475565b6040518060a00160405280600081526020016143a16142dd565b81526020016143ae6142dd565b81526020016143bb6142dd565b81526020016000905290565b6040518060e001604052806143da6142dd565b81526020016143e76142dd565b81526020016143f46142dd565b81526020016143a16142dd565b5b80821115613c0f5760008155600101614402565b5b80821115613c0f57600080825560018201819055600282018190556003820181905560048201819055600582018190556006820181905560078201819055600882018190556009820155600a8101805460ff19169055600b01614417565b5b80821115613c0f576000808255600182018190556002820181905560038201819055600482018190556005820181905560068201819055600782018190556008820181905560098201819055600a8201819055600b8201819055600c8201819055600d8201819055600e8201819055600f820181905560108201819055601182015560128101805460ff1916905560130161447656fea2646970667358221220037024f5647853879c58fbcc61ac3616455f6f731cc6e84f91eb5a3b4e06c00464736f6c63430007060033").unwrap().into(); - - // BenchmarkDB is dummy state that implements Database trait. - let mut evm = revm::new(); - let bytecode = to_analysed(Bytecode::new_raw(contract_data)); - evm.database(BenchmarkDB::new_bytecode(bytecode.clone())); - - // execution globals block hash/gas_limit/coinbase/timestamp.. - 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()); - - // Microbenchmark - let bench_options = microbench::Options::default().time(Duration::from_secs(2)); - - let env = evm.env.clone(); - microbench::bench( - &bench_options, - "Snailtracer Host+Interpreter benchmark", - || { - let _ = evm.transact().unwrap(); - }, - ); - - // revm interpreter - let contract = Contract { - input: evm.env.tx.data, - bytecode: BytecodeLocked::try_from(bytecode).unwrap(), - ..Default::default() - }; - - let mut host = DummyHost::new(env); - microbench::bench(&bench_options, "Snailtracer Interpreter benchmark", || { - let mut interpreter = Interpreter::new(Box::new(contract.clone()), u64::MAX, false); - interpreter.run::<_, BerlinSpec>(&mut host); - host.clear() - }); -} - -fn main() { - println!("Running snailtracer bench!"); - simple_example(); - println!("end!"); -} diff --git a/bins/revm-test/src/bin/transfer.rs b/bins/revm-test/src/bin/transfer.rs deleted file mode 100644 index ff74d442c4..0000000000 --- a/bins/revm-test/src/bin/transfer.rs +++ /dev/null @@ -1,39 +0,0 @@ -use revm::{ - db::BenchmarkDB, - primitives::{Bytecode, TransactTo, U256}, -}; -use std::time::{Duration, Instant}; -extern crate alloc; - -fn main() { - // BenchmarkDB is dummy state that implements Database trait. - let mut evm = revm::new(); - - // execution globals block hash/gas_limit/coinbase/timestamp.. - evm.env.tx.caller = "0x0000000000000000000000000000000000000001" - .parse() - .unwrap(); - evm.env.tx.value = U256::from(10); - evm.env.tx.transact_to = TransactTo::Call( - "0x0000000000000000000000000000000000000000" - .parse() - .unwrap(), - ); - //evm.env.tx.data = Bytes::from(hex::decode("30627b7c").unwrap()); - - evm.database(BenchmarkDB::new_bytecode(Bytecode::new())); - - // Microbenchmark - let bench_options = microbench::Options::default().time(Duration::from_secs(1)); - - microbench::bench(&bench_options, "Simple value transfer", || { - let _ = evm.transact().unwrap(); - }); - - let time = Instant::now(); - for _ in 0..10000 { - let _ = evm.transact().unwrap(); - } - let elapsed = time.elapsed(); - println!("10k runs in {:?}", elapsed.as_nanos() / 10_000); -} diff --git a/bins/revme/Cargo.toml b/bins/revme/Cargo.toml index d8e55964ec..deeb9bcd4a 100644 --- a/bins/revme/Cargo.toml +++ b/bins/revme/Cargo.toml @@ -23,7 +23,7 @@ revm = { path = "../../crates/revm", version = "3.3.0", default-features = false "serde", ] } rlp = { version = "0.5", default-features = false } -ruint = { version = "1.8.0", features = ["rlp", "serde"] } +ruint = { version = "1.10.1", 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 } diff --git a/bins/revme/src/statetest/runner.rs b/bins/revme/src/statetest/runner.rs index c7506f5fc6..4b471290bd 100644 --- a/bins/revme/src/statetest/runner.rs +++ b/bins/revme/src/statetest/runner.rs @@ -110,7 +110,7 @@ pub fn execute_test_suit( let json_reader = std::fs::read(path).unwrap(); let suit: TestSuit = serde_json::from_reader(&*json_reader)?; - let map_caller_keys: HashMap<_, _> = vec![ + let map_caller_keys: HashMap<_, _> = [ ( B256(hex!( "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8" diff --git a/crates/interpreter/Cargo.toml b/crates/interpreter/Cargo.toml index a5c4fec52f..0c8a21e17c 100644 --- a/crates/interpreter/Cargo.toml +++ b/crates/interpreter/Cargo.toml @@ -10,14 +10,10 @@ version = "1.1.2" readme = "../../README.md" [dependencies] -revm-primitives = { path = "../primitives", version="1.1.2", default-features = false } - -#utility -derive_more = "0.99" -enumn = "0.1" +revm-primitives = { path = "../primitives", version = "1.1.2", default-features = false } # sha3 keccak hasher -sha3 = { version = "0.10", default-features = false, features = [] } +sha3 = { version = "0.10", default-features = false } # optional serde = { version = "1.0", features = ["derive", "rc"], optional = true } @@ -27,7 +23,7 @@ proptest-derive = { version = "0.3", optional = true } [dev-dependencies] arbitrary = { version = "1.3", features = ["derive"] } -proptest = { version = "1.1" } +proptest = "1.1" proptest-derive = "0.3" [features] @@ -48,10 +44,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..b966651f76 100644 --- a/crates/interpreter/src/gas/calc.rs +++ b/crates/interpreter/src/gas/calc.rs @@ -1,11 +1,7 @@ use super::constants::*; -use crate::alloc::vec::Vec; -use crate::{ - inner_models::SelfDestructResult, - primitives::Spec, - primitives::{SpecId::*, U256}, -}; -use revm_primitives::{Bytes, B160}; +use crate::inner_models::SelfDestructResult; +use crate::primitives::{Bytes, Spec, SpecId::*, B160, U256}; +use alloc::vec::Vec; #[allow(clippy::collapsible_else_if)] pub fn sstore_refund(original: U256, current: U256, new: U256) -> i64 { @@ -57,6 +53,7 @@ pub fn sstore_refund(original: U256, current: U256, new: U256) -> i6 } } +#[inline] pub fn create2_cost(len: usize) -> Option { let base = CREATE; // ceil(len / 32.0) @@ -68,6 +65,7 @@ pub fn create2_cost(len: usize) -> Option { Some(gas) } +#[inline] fn log2floor(value: U256) -> u64 { assert!(value != U256::ZERO); let mut l: u64 = 256; @@ -87,15 +85,17 @@ fn log2floor(value: U256) -> u64 { l } +#[inline] pub fn exp_cost(power: U256) -> Option { if power == U256::ZERO { Some(EXP) } else { + // EIP-160: EXP cost increase let gas_byte = U256::from(if SPEC::enabled(SPURIOUS_DRAGON) { - 50 + 50u64 } else { 10 - }); // EIP-160: EXP cost increase + }); let gas = U256::from(EXP) .checked_add(gas_byte.checked_mul(U256::from(log2floor(power) / 8 + 1))?)?; @@ -103,12 +103,14 @@ pub fn exp_cost(power: U256) -> Option { } } +#[inline] pub fn verylowcopy_cost(len: u64) -> Option { let wordd = len / 32; let wordr = len % 32; VERYLOW.checked_add(COPY.checked_mul(if wordr == 0 { wordd } else { wordd + 1 })?) } +#[inline] pub fn extcodecopy_cost(len: u64, is_cold: bool) -> Option { let wordd = len / 32; let wordr = len % 32; @@ -153,14 +155,18 @@ pub fn keccak256_cost(len: u64) -> Option { } /// EIP-3860: Limit and meter initcode -/// apply extra gas cost of 2 for every 32-byte chunk of initcode -/// Can't overflow as initcode length is assumed to be checked +/// +/// Apply extra gas cost of 2 for every 32-byte chunk of initcode. +/// +/// This cannot overflow as the initcode length is assumed to be checked. +#[inline] pub fn initcode_cost(len: u64) -> u64 { let wordd = len / 32; let wordr = len % 32; INITCODE_WORD_COST * if wordr == 0 { wordd } else { wordd + 1 } } +#[inline] pub fn sload_cost(is_cold: bool) -> u64 { if SPEC::enabled(BERLIN) { if is_cold { @@ -239,14 +245,15 @@ pub fn selfdestruct_cost(res: SelfDestructResult) -> u64 { !res.target_exists }; + // EIP-150: Gas cost changes for IO-heavy operations let selfdestruct_gas_topup = if SPEC::enabled(TANGERINE) && should_charge_topup { - //EIP-150: Gas cost changes for IO-heavy operations 25000 } else { 0 }; - let selfdestruct_gas = if SPEC::enabled(TANGERINE) { 5000 } else { 0 }; //EIP-150: Gas cost changes for IO-heavy operations + // EIP-150: Gas cost changes for IO-heavy operations + let selfdestruct_gas = if SPEC::enabled(TANGERINE) { 5000 } else { 0 }; let mut gas = selfdestruct_gas + selfdestruct_gas_topup; if SPEC::enabled(BERLIN) && res.is_cold { @@ -282,6 +289,7 @@ pub fn call_cost( + new_cost::(is_call_or_staticcall, is_new, transfers_value) } +#[inline] pub fn hot_cold_cost(is_cold: bool, regular_value: u64) -> u64 { if SPEC::enabled(BERLIN) { if is_cold { @@ -294,6 +302,7 @@ pub fn hot_cold_cost(is_cold: bool, regular_value: u64) -> u64 { } } +#[inline] fn xfer_cost(is_call_or_callcode: bool, transfers_value: bool) -> u64 { if is_call_or_callcode && transfers_value { CALLVALUE @@ -302,6 +311,7 @@ fn xfer_cost(is_call_or_callcode: bool, transfers_value: bool) -> u64 { } } +#[inline] fn new_cost(is_call_or_staticcall: bool, is_new: bool, transfers_value: bool) -> u64 { if is_call_or_staticcall { // EIP-161: State trie clearing (invariant-preserving alternative) @@ -321,6 +331,7 @@ fn new_cost(is_call_or_staticcall: bool, is_new: bool, transfers_val } } +#[inline] pub fn memory_gas(a: usize) -> u64 { let a = a as u64; MEMORY diff --git a/crates/interpreter/src/gas.rs b/crates/interpreter/src/gas/mod.rs similarity index 52% rename from crates/interpreter/src/gas.rs rename to crates/interpreter/src/gas/mod.rs index 1f1846ab8a..0a723a04a9 100644 --- a/crates/interpreter/src/gas.rs +++ b/crates/interpreter/src/gas/mod.rs @@ -4,21 +4,25 @@ pub mod constants; pub use calc::*; pub use constants::*; -#[derive(Clone, Copy, Debug)] +/// Represents the state of gas during execution. +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] pub struct Gas { - /// Gas Limit + /// The initial gas limit. limit: u64, - /// used+memory gas. + /// The total used gas. all_used_gas: u64, - /// Used gas without memory + /// Used gas without memory expansion. used: u64, - /// Used gas for memory expansion + /// Used gas for memory expansion. memory: u64, - /// Refunded gas. This gas is used only at the end of execution. + /// Refunded gas. This is used only at the end of execution. refunded: i64, } + impl Gas { - pub fn new(limit: u64) -> Self { + /// Creates a new `Gas` struct with the given gas limit. + #[inline] + pub const fn new(limit: u64) -> Self { Self { limit, used: 0, @@ -28,36 +32,55 @@ impl Gas { } } - pub fn limit(&self) -> u64 { + /// Returns the gas limit. + #[inline] + pub const fn limit(&self) -> u64 { self.limit } - pub fn memory(&self) -> u64 { + /// Returns the amount of gas that was used. + #[inline] + pub const fn memory(&self) -> u64 { self.memory } - pub fn refunded(&self) -> i64 { + /// Returns the amount of gas that was refunded. + #[inline] + pub const fn refunded(&self) -> i64 { self.refunded } - pub fn spend(&self) -> u64 { + /// Returns all the gas used in the execution. + #[inline] + pub const fn spend(&self) -> u64 { self.all_used_gas } - pub fn remaining(&self) -> u64 { + /// Returns the amount of gas remaining. + #[inline] + pub const fn remaining(&self) -> u64 { self.limit - self.all_used_gas } + /// Erases a gas cost from the totals. + #[inline] pub fn erase_cost(&mut self, returned: u64) { self.used -= returned; self.all_used_gas -= returned; } + /// Records a refund value. + /// + /// `refund` can be negative but `self.refunded` should always be positive. + #[inline] pub fn record_refund(&mut self, refund: i64) { self.refunded += refund; } - /// Record an explicit cost. + /// Records an explicit cost. + /// + /// This function is called on every instruction in the interpreter if the feature + /// `no_gas_measuring` is not enabled. #[inline(always)] pub fn record_cost(&mut self, cost: u64) -> bool { let (all_used_gas, overflow) = self.all_used_gas.overflowing_add(cost); @@ -71,6 +94,7 @@ impl Gas { } /// used in memory_resize! macro to record gas used for memory expansion. + #[inline] pub fn record_memory(&mut self, gas_memory: u64) -> bool { if gas_memory > self.memory { let (all_used_gas, overflow) = self.used.overflowing_add(gas_memory); @@ -83,9 +107,10 @@ impl Gas { true } - /// used in gas_refund! macro to record refund value. - /// Refund can be negative but self.refunded is always positive. + #[inline] + #[deprecated = "Use `record_refund` instead"] + #[doc(hidden)] pub fn gas_refund(&mut self, refund: i64) { - self.refunded += refund; + self.record_refund(refund); } } diff --git a/crates/interpreter/src/host/dummy_host.rs b/crates/interpreter/src/host/dummy.rs similarity index 90% rename from crates/interpreter/src/host/dummy_host.rs rename to crates/interpreter/src/host/dummy.rs index 61241a13f5..c2df6b2f65 100644 --- a/crates/interpreter/src/host/dummy_host.rs +++ b/crates/interpreter/src/host/dummy.rs @@ -13,6 +13,8 @@ pub struct DummyHost { } impl DummyHost { + /// Create a new dummy host with the given [`Env`]. + #[inline] pub fn new(env: Env) -> Self { Self { env, @@ -21,6 +23,9 @@ impl DummyHost { log: Vec::new(), } } + + /// Clears the storage and logs of the dummy host. + #[inline] pub fn clear(&mut self) { self.storage.clear(); self.log.clear(); @@ -28,10 +33,12 @@ impl DummyHost { } impl Host for DummyHost { + #[inline] fn step(&mut self, _interp: &mut Interpreter) -> InstructionResult { InstructionResult::Continue } + #[inline] fn step_end( &mut self, _interp: &mut Interpreter, @@ -40,30 +47,37 @@ impl Host for DummyHost { InstructionResult::Continue } + #[inline] fn env(&mut self) -> &mut Env { &mut self.env } + #[inline] fn load_account(&mut self, _address: B160) -> Option<(bool, bool)> { Some((true, true)) } + #[inline] fn block_hash(&mut self, _number: U256) -> Option { Some(B256::zero()) } + #[inline] fn balance(&mut self, _address: B160) -> Option<(U256, bool)> { Some((U256::ZERO, false)) } + #[inline] fn code(&mut self, _address: B160) -> Option<(Bytecode, bool)> { Some((Bytecode::default(), false)) } + #[inline] fn code_hash(&mut self, __address: B160) -> Option<(B256, bool)> { Some((KECCAK_EMPTY, false)) } + #[inline] fn sload(&mut self, __address: B160, index: U256) -> Option<(U256, bool)> { match self.storage.entry(index) { Entry::Occupied(entry) => Some((*entry.get(), false)), @@ -74,6 +88,7 @@ impl Host for DummyHost { } } + #[inline] fn sstore( &mut self, _address: B160, @@ -91,6 +106,7 @@ impl Host for DummyHost { Some((U256::ZERO, present, value, is_cold)) } + #[inline] fn tload(&mut self, _address: B160, index: U256) -> U256 { self.transient_storage .get(&index) @@ -98,10 +114,12 @@ impl Host for DummyHost { .unwrap_or_default() } + #[inline] fn tstore(&mut self, _address: B160, index: U256, value: U256) { self.transient_storage.insert(index, value); } + #[inline] fn log(&mut self, address: B160, topics: Vec, data: Bytes) { self.log.push(Log { address, @@ -110,10 +128,12 @@ impl Host for DummyHost { }) } + #[inline] fn selfdestruct(&mut self, _address: B160, _target: B160) -> Option { panic!("Selfdestruct is not supported for this host") } + #[inline] fn create( &mut self, _inputs: &mut CreateInputs, @@ -121,6 +141,7 @@ impl Host for DummyHost { panic!("Create is not supported for this host") } + #[inline] fn call(&mut self, _input: &mut CallInputs) -> (InstructionResult, Gas, Bytes) { panic!("Call is not supported for this host") } diff --git a/crates/interpreter/src/host.rs b/crates/interpreter/src/host/mod.rs similarity index 96% rename from crates/interpreter/src/host.rs rename to crates/interpreter/src/host/mod.rs index 0d317af51f..894562eee3 100644 --- a/crates/interpreter/src/host.rs +++ b/crates/interpreter/src/host/mod.rs @@ -1,12 +1,12 @@ -mod dummy_host; +mod dummy; use crate::primitives::Bytecode; use crate::{ primitives::{Bytes, Env, B160, B256, U256}, CallInputs, CreateInputs, Gas, InstructionResult, Interpreter, SelfDestructResult, }; -pub use alloc::vec::Vec; -pub use dummy_host::DummyHost; +use alloc::vec::Vec; +pub use dummy::DummyHost; /// EVM context host. pub trait Host { diff --git a/crates/interpreter/src/instruction_result.rs b/crates/interpreter/src/instruction_result.rs index b7997f5430..fe7da8fa33 100644 --- a/crates/interpreter/src/instruction_result.rs +++ b/crates/interpreter/src/instruction_result.rs @@ -1,4 +1,4 @@ -use revm_primitives::{Eval, Halt}; +use crate::primitives::{Eval, Halt}; #[repr(u8)] #[derive(Debug, Copy, Clone, PartialEq, Eq)] @@ -46,7 +46,21 @@ pub enum InstructionResult { } impl InstructionResult { - pub fn is_error(&self) -> bool { + /// Returns whether the result is a success. + #[inline] + pub fn is_ok(self) -> bool { + matches!(self, crate::return_ok!()) + } + + /// Returns whether the result is a revert. + #[inline] + pub fn is_revert(self) -> bool { + matches!(self, crate::return_revert!()) + } + + /// Returns whether the result is an error. + #[inline] + pub fn is_error(self) -> bool { matches!( self, Self::OutOfGas @@ -87,11 +101,13 @@ pub enum SuccessOrHalt { impl SuccessOrHalt { /// Returns true if the transaction returned successfully without halts. - pub fn is_success(&self) -> bool { + #[inline] + pub fn is_success(self) -> bool { matches!(self, SuccessOrHalt::Success(_)) } /// Returns the [Eval] value if this a successful result + #[inline] pub fn to_success(self) -> Option { match self { SuccessOrHalt::Success(eval) => Some(eval), @@ -100,16 +116,19 @@ impl SuccessOrHalt { } /// Returns true if the transaction reverted. - pub fn is_revert(&self) -> bool { + #[inline] + pub fn is_revert(self) -> bool { matches!(self, SuccessOrHalt::Revert) } /// Returns true if the EVM has experienced an exceptional halt - pub fn is_halt(&self) -> bool { + #[inline] + pub fn is_halt(self) -> bool { matches!(self, SuccessOrHalt::Halt(_)) } /// Returns the [Halt] value the EVM has experienced an exceptional halt + #[inline] pub fn to_halt(self) -> Option { match self { SuccessOrHalt::Halt(halt) => Some(halt), diff --git a/crates/interpreter/src/instructions.rs b/crates/interpreter/src/instructions.rs deleted file mode 100644 index 035d478185..0000000000 --- a/crates/interpreter/src/instructions.rs +++ /dev/null @@ -1,183 +0,0 @@ -#[macro_use] -mod macros; -mod arithmetic; -mod bitwise; -mod control; -mod host; -mod host_env; -mod i256; -mod memory; -pub mod opcode; -mod stack; -mod system; - -use crate::{interpreter::Interpreter, primitives::Spec, Host}; -pub use opcode::{OpCode, OPCODE_JUMPMAP}; - -pub use crate::{return_ok, return_revert, InstructionResult}; -pub fn return_stop(interpreter: &mut Interpreter, _host: &mut dyn Host) { - interpreter.instruction_result = InstructionResult::Stop; -} -pub fn return_invalid(interpreter: &mut Interpreter, _host: &mut dyn Host) { - interpreter.instruction_result = InstructionResult::InvalidFEOpcode; -} - -pub fn return_not_found(interpreter: &mut Interpreter, _host: &mut dyn Host) { - interpreter.instruction_result = InstructionResult::OpcodeNotFound; -} - -#[inline(always)] -pub fn eval(opcode: u8, interp: &mut Interpreter, host: &mut H) { - match opcode { - opcode::STOP => return_stop(interp, host), - opcode::ADD => arithmetic::wrapped_add(interp, host), - opcode::MUL => arithmetic::wrapping_mul(interp, host), - opcode::SUB => arithmetic::wrapping_sub(interp, host), - opcode::DIV => arithmetic::div(interp, host), - opcode::SDIV => arithmetic::sdiv(interp, host), - opcode::MOD => arithmetic::rem(interp, host), - opcode::SMOD => arithmetic::smod(interp, host), - opcode::ADDMOD => arithmetic::addmod(interp, host), - opcode::MULMOD => arithmetic::mulmod(interp, host), - opcode::EXP => arithmetic::eval_exp::(interp, host), - opcode::SIGNEXTEND => arithmetic::signextend(interp, host), - opcode::LT => bitwise::lt(interp, host), - opcode::GT => bitwise::gt(interp, host), - opcode::SLT => bitwise::slt(interp, host), - opcode::SGT => bitwise::sgt(interp, host), - opcode::EQ => bitwise::eq(interp, host), - opcode::ISZERO => bitwise::iszero(interp, host), - opcode::AND => bitwise::bitand(interp, host), - opcode::OR => bitwise::bitor(interp, host), - opcode::XOR => bitwise::bitxor(interp, host), - opcode::NOT => bitwise::not(interp, host), - opcode::BYTE => bitwise::byte(interp, host), - opcode::SHL => bitwise::shl::(interp, host), - opcode::SHR => bitwise::shr::(interp, host), - opcode::SAR => bitwise::sar::(interp, host), - opcode::KECCAK256 => system::calculate_keccak256(interp, host), - opcode::ADDRESS => system::address(interp, host), - opcode::BALANCE => host::balance::(interp, host), - opcode::SELFBALANCE => host::selfbalance::(interp, host), - opcode::CODESIZE => system::codesize(interp, host), - opcode::CODECOPY => system::codecopy(interp, host), - opcode::CALLDATALOAD => system::calldataload(interp, host), - opcode::CALLDATASIZE => system::calldatasize(interp, host), - opcode::CALLDATACOPY => system::calldatacopy(interp, host), - opcode::POP => stack::pop(interp, host), - opcode::MLOAD => memory::mload(interp, host), - opcode::MSTORE => memory::mstore(interp, host), - opcode::MSTORE8 => memory::mstore8(interp, host), - opcode::JUMP => control::jump(interp, host), - opcode::JUMPI => control::jumpi(interp, host), - opcode::PC => control::pc(interp, host), - opcode::MSIZE => memory::msize(interp, host), - opcode::JUMPDEST => control::jumpdest(interp, host), - opcode::PUSH0 => stack::push0::(interp, host), - opcode::PUSH1 => stack::push::<1>(interp, host), - opcode::PUSH2 => stack::push::<2>(interp, host), - opcode::PUSH3 => stack::push::<3>(interp, host), - opcode::PUSH4 => stack::push::<4>(interp, host), - opcode::PUSH5 => stack::push::<5>(interp, host), - opcode::PUSH6 => stack::push::<6>(interp, host), - opcode::PUSH7 => stack::push::<7>(interp, host), - opcode::PUSH8 => stack::push::<8>(interp, host), - opcode::PUSH9 => stack::push::<9>(interp, host), - opcode::PUSH10 => stack::push::<10>(interp, host), - opcode::PUSH11 => stack::push::<11>(interp, host), - opcode::PUSH12 => stack::push::<12>(interp, host), - opcode::PUSH13 => stack::push::<13>(interp, host), - opcode::PUSH14 => stack::push::<14>(interp, host), - opcode::PUSH15 => stack::push::<15>(interp, host), - opcode::PUSH16 => stack::push::<16>(interp, host), - opcode::PUSH17 => stack::push::<17>(interp, host), - opcode::PUSH18 => stack::push::<18>(interp, host), - opcode::PUSH19 => stack::push::<19>(interp, host), - opcode::PUSH20 => stack::push::<20>(interp, host), - opcode::PUSH21 => stack::push::<21>(interp, host), - opcode::PUSH22 => stack::push::<22>(interp, host), - opcode::PUSH23 => stack::push::<23>(interp, host), - opcode::PUSH24 => stack::push::<24>(interp, host), - opcode::PUSH25 => stack::push::<25>(interp, host), - opcode::PUSH26 => stack::push::<26>(interp, host), - opcode::PUSH27 => stack::push::<27>(interp, host), - opcode::PUSH28 => stack::push::<28>(interp, host), - opcode::PUSH29 => stack::push::<29>(interp, host), - opcode::PUSH30 => stack::push::<30>(interp, host), - opcode::PUSH31 => stack::push::<31>(interp, host), - opcode::PUSH32 => stack::push::<32>(interp, host), - opcode::DUP1 => stack::dup::<1>(interp, host), - opcode::DUP2 => stack::dup::<2>(interp, host), - opcode::DUP3 => stack::dup::<3>(interp, host), - opcode::DUP4 => stack::dup::<4>(interp, host), - opcode::DUP5 => stack::dup::<5>(interp, host), - opcode::DUP6 => stack::dup::<6>(interp, host), - opcode::DUP7 => stack::dup::<7>(interp, host), - opcode::DUP8 => stack::dup::<8>(interp, host), - opcode::DUP9 => stack::dup::<9>(interp, host), - opcode::DUP10 => stack::dup::<10>(interp, host), - opcode::DUP11 => stack::dup::<11>(interp, host), - opcode::DUP12 => stack::dup::<12>(interp, host), - opcode::DUP13 => stack::dup::<13>(interp, host), - opcode::DUP14 => stack::dup::<14>(interp, host), - opcode::DUP15 => stack::dup::<15>(interp, host), - opcode::DUP16 => stack::dup::<16>(interp, host), - - opcode::SWAP1 => stack::swap::<1>(interp, host), - opcode::SWAP2 => stack::swap::<2>(interp, host), - opcode::SWAP3 => stack::swap::<3>(interp, host), - opcode::SWAP4 => stack::swap::<4>(interp, host), - opcode::SWAP5 => stack::swap::<5>(interp, host), - opcode::SWAP6 => stack::swap::<6>(interp, host), - opcode::SWAP7 => stack::swap::<7>(interp, host), - opcode::SWAP8 => stack::swap::<8>(interp, host), - opcode::SWAP9 => stack::swap::<9>(interp, host), - opcode::SWAP10 => stack::swap::<10>(interp, host), - opcode::SWAP11 => stack::swap::<11>(interp, host), - opcode::SWAP12 => stack::swap::<12>(interp, host), - opcode::SWAP13 => stack::swap::<13>(interp, host), - opcode::SWAP14 => stack::swap::<14>(interp, host), - opcode::SWAP15 => stack::swap::<15>(interp, host), - opcode::SWAP16 => stack::swap::<16>(interp, host), - - opcode::RETURN => control::ret(interp, host), - opcode::REVERT => control::revert::(interp, host), - opcode::INVALID => return_invalid(interp, host), - opcode::BASEFEE => host_env::basefee::(interp, host), - opcode::ORIGIN => host_env::origin(interp, host), - opcode::CALLER => system::caller(interp, host), - opcode::CALLVALUE => system::callvalue(interp, host), - opcode::GASPRICE => host_env::gasprice(interp, host), - opcode::EXTCODESIZE => host::extcodesize::(interp, host), - opcode::EXTCODEHASH => host::extcodehash::(interp, host), - opcode::EXTCODECOPY => host::extcodecopy::(interp, host), - opcode::RETURNDATASIZE => system::returndatasize::(interp, host), - opcode::RETURNDATACOPY => system::returndatacopy::(interp, host), - opcode::BLOCKHASH => host::blockhash(interp, host), - opcode::COINBASE => host_env::coinbase(interp, host), - opcode::TIMESTAMP => host_env::timestamp(interp, host), - opcode::NUMBER => host_env::number(interp, host), - opcode::DIFFICULTY => host_env::difficulty::(interp, host), - opcode::GASLIMIT => host_env::gaslimit(interp, host), - opcode::SLOAD => host::sload::(interp, host), - opcode::SSTORE => host::sstore::(interp, host), - opcode::TSTORE => host::tstore::(interp, host), - opcode::TLOAD => host::tload::(interp, host), - opcode::GAS => system::gas(interp, host), - opcode::LOG0 => host::log::<0>(interp, host), - opcode::LOG1 => host::log::<1>(interp, host), - opcode::LOG2 => host::log::<2>(interp, host), - opcode::LOG3 => host::log::<3>(interp, host), - opcode::LOG4 => host::log::<4>(interp, host), - opcode::SELFDESTRUCT => host::selfdestruct::(interp, host), - opcode::CREATE => host::create::(interp, host), //check - opcode::CREATE2 => host::create::(interp, host), //check - opcode::CALL => host::call::(interp, host), //check - opcode::CALLCODE => host::call_code::(interp, host), //check - opcode::DELEGATECALL => host::delegate_call::(interp, host), //check - opcode::STATICCALL => host::static_call::(interp, host), //check - opcode::CHAINID => host_env::chainid::(interp, host), - opcode::MCOPY => memory::mcopy::(interp, host), - _ => return_not_found(interp, host), - } -} diff --git a/crates/interpreter/src/instructions/arithmetic.rs b/crates/interpreter/src/instructions/arithmetic.rs index 188716c5e3..a93e1f902b 100644 --- a/crates/interpreter/src/instructions/arithmetic.rs +++ b/crates/interpreter/src/instructions/arithmetic.rs @@ -1,67 +1,67 @@ use super::i256::{i256_div, i256_mod}; -use crate::{ - gas, - primitives::{Spec, U256}, - Host, InstructionResult, Interpreter, -}; +use super::prelude::*; -pub fn wrapped_add(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn wrapped_add(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); *op2 = op1.wrapping_add(*op2); } -pub fn wrapping_mul(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn wrapping_mul(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::LOW); pop_top!(interpreter, op1, op2); *op2 = op1.wrapping_mul(*op2); } -pub fn wrapping_sub(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn wrapping_sub(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); *op2 = op1.wrapping_sub(*op2); } -pub fn div(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn div(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::LOW); pop_top!(interpreter, op1, op2); - *op2 = op1.checked_div(*op2).unwrap_or_default() + if *op2 != U256::ZERO { + *op2 = op1.wrapping_div(*op2); + } } -pub fn sdiv(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn sdiv(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::LOW); pop_top!(interpreter, op1, op2); *op2 = i256_div(op1, *op2); } -pub fn rem(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn rem(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::LOW); pop_top!(interpreter, op1, op2); - *op2 = op1.checked_rem(*op2).unwrap_or_default() + if *op2 != U256::ZERO { + *op2 = op1.wrapping_rem(*op2); + } } -pub fn smod(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn smod(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::LOW); pop_top!(interpreter, op1, op2); if *op2 != U256::ZERO { *op2 = i256_mod(op1, *op2) - }; + } } -pub fn addmod(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn addmod(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::MID); pop_top!(interpreter, op1, op2, op3); *op3 = op1.add_mod(op2, *op3) } -pub fn mulmod(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn mulmod(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::MID); pop_top!(interpreter, op1, op2, op3); *op3 = op1.mul_mod(op2, *op3) } -pub fn eval_exp(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn exp(interpreter: &mut Interpreter, _host: &mut dyn Host) { pop_top!(interpreter, op1, op2); gas_or_fail!(interpreter, gas::exp_cost::(*op2)); *op2 = op1.pow(*op2); @@ -82,7 +82,7 @@ pub fn eval_exp(interpreter: &mut Interpreter, _host: &mut dyn Host) /// `y | !mask` where `|` is the bitwise `OR` and `!` is bitwise negation. Similarly, if /// `b == 0` then the yellow paper says the output should start with all zeros, then end with /// bits from `b`; this is equal to `y & mask` where `&` is bitwise `AND`. -pub fn signextend(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn signextend(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::LOW); pop_top!(interpreter, op1, op2); if op1 < U256::from(32) { diff --git a/crates/interpreter/src/instructions/bitwise.rs b/crates/interpreter/src/instructions/bitwise.rs index cb390bce47..c3d82582c7 100644 --- a/crates/interpreter/src/instructions/bitwise.rs +++ b/crates/interpreter/src/instructions/bitwise.rs @@ -1,127 +1,98 @@ use super::i256::{i256_cmp, i256_sign, two_compl, Sign}; -use crate::{ - gas, - primitives::SpecId::CONSTANTINOPLE, - primitives::{Spec, U256}, - Host, InstructionResult, Interpreter, -}; -use core::cmp::Ordering; -use core::ops::{BitAnd, BitOr, BitXor}; - -pub fn lt(interpreter: &mut Interpreter, _host: &mut dyn Host) { +use super::prelude::*; + +pub(super) fn lt(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); - *op2 = if op1.lt(op2) { - U256::from(1) - } else { - U256::ZERO - }; + *op2 = U256::from(op1 < *op2); } -pub fn gt(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn gt(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); - *op2 = if op1.gt(op2) { - U256::from(1) - } else { - U256::ZERO - }; + *op2 = U256::from(op1 > *op2); } -pub fn slt(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn slt(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); - *op2 = if i256_cmp(op1, *op2) == Ordering::Less { - U256::from(1) - } else { - U256::ZERO - } + *op2 = U256::from(i256_cmp(op1, *op2) == Ordering::Less); } -pub fn sgt(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn sgt(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); - *op2 = if i256_cmp(op1, *op2) == Ordering::Greater { - U256::from(1) - } else { - U256::ZERO - }; + *op2 = U256::from(i256_cmp(op1, *op2) == Ordering::Greater); } -pub fn eq(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn eq(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); - *op2 = if op1.eq(op2) { - U256::from(1) - } else { - U256::ZERO - }; + *op2 = U256::from(op1 == *op2); } -pub fn iszero(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn iszero(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1); - *op1 = if *op1 == U256::ZERO { - U256::from(1) - } else { - U256::ZERO - }; + *op1 = U256::from(*op1 == U256::ZERO); } -pub fn bitand(interpreter: &mut Interpreter, _host: &mut dyn Host) { + +pub(super) fn bitand(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); - *op2 = op1.bitand(*op2); + *op2 = op1 & *op2; } -pub fn bitor(interpreter: &mut Interpreter, _host: &mut dyn Host) { + +pub(super) fn bitor(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); - *op2 = op1.bitor(*op2); + *op2 = op1 | *op2; } -pub fn bitxor(interpreter: &mut Interpreter, _host: &mut dyn Host) { + +pub(super) fn bitxor(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); - *op2 = op1.bitxor(*op2); + *op2 = op1 ^ *op2; } -pub fn not(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn not(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1); *op1 = !*op1; } -pub fn byte(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn byte(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); - let mut ret = U256::ZERO; let o1 = as_usize_saturated!(op1); - if o1 < 32 { - let o2 = &*op2; - ret = (o2 << (8 * o1)) >> (8 * 31); - } - - *op2 = ret; + *op2 = if o1 < 32 { + // `31 - o1` because `byte` returns LE, while we want BE + U256::from(op2.byte(31 - o1)) + } else { + U256::ZERO + }; } -pub fn shl(interpreter: &mut Interpreter, _host: &mut dyn Host) { - // EIP-145: Bitwise shifting instructions in EVM - check!(interpreter, SPEC::enabled(CONSTANTINOPLE)); +// EIP-145: Bitwise shifting instructions in EVM +pub(super) fn shl(interpreter: &mut Interpreter, _host: &mut dyn Host) { + check!(interpreter, CONSTANTINOPLE); gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); *op2 <<= as_usize_saturated!(op1); } -pub fn shr(interpreter: &mut Interpreter, _host: &mut dyn Host) { - // EIP-145: Bitwise shifting instructions in EVM - check!(interpreter, SPEC::enabled(CONSTANTINOPLE)); +// EIP-145: Bitwise shifting instructions in EVM +pub(super) fn shr(interpreter: &mut Interpreter, _host: &mut dyn Host) { + check!(interpreter, CONSTANTINOPLE); gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); *op2 >>= as_usize_saturated!(op1); } -pub fn sar(interpreter: &mut Interpreter, _host: &mut dyn Host) { - // EIP-145: Bitwise shifting instructions in EVM - check!(interpreter, SPEC::enabled(CONSTANTINOPLE)); +// EIP-145: Bitwise shifting instructions in EVM +pub(super) fn sar(interpreter: &mut Interpreter, _host: &mut dyn Host) { + check!(interpreter, CONSTANTINOPLE); gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); @@ -132,19 +103,14 @@ pub fn sar(interpreter: &mut Interpreter, _host: &mut dyn Host) { // value is 0 or >=1, pushing 0 Sign::Plus | Sign::Zero => U256::ZERO, // value is <0, pushing -1 - Sign::Minus => two_compl(U256::from(1)), + Sign::Minus => U256::MAX, } } else { + const ONE: U256 = U256::from_limbs([1, 0, 0, 0]); let shift = usize::try_from(op1).unwrap(); - match value_sign { - Sign::Plus | Sign::Zero => *op2 >> shift, - Sign::Minus => { - let shifted = ((op2.overflowing_sub(U256::from(1)).0) >> shift) - .overflowing_add(U256::from(1)) - .0; - two_compl(shifted) - } + Sign::Plus | Sign::Zero => op2.wrapping_shr(shift), + Sign::Minus => two_compl(op2.wrapping_sub(ONE).wrapping_shr(shift).wrapping_add(ONE)), } }; } diff --git a/crates/interpreter/src/instructions/control.rs b/crates/interpreter/src/instructions/control.rs index ccb532f6c5..ba59bdd100 100644 --- a/crates/interpreter/src/instructions/control.rs +++ b/crates/interpreter/src/instructions/control.rs @@ -1,9 +1,6 @@ -use crate::{ - gas, interpreter::Interpreter, primitives::Spec, primitives::SpecId::*, primitives::U256, Host, - InstructionResult, -}; +use super::prelude::*; -pub fn jump(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn jump(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::MID); pop!(interpreter, dest); let dest = as_usize_or_fail!(interpreter, dest, InstructionResult::InvalidJump); @@ -17,7 +14,7 @@ pub fn jump(interpreter: &mut Interpreter, _host: &mut dyn Host) { } } -pub fn jumpi(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn jumpi(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::HIGH); pop!(interpreter, dest, value); if value != U256::ZERO { @@ -33,41 +30,54 @@ pub fn jumpi(interpreter: &mut Interpreter, _host: &mut dyn Host) { } } -pub fn jumpdest(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn jumpdest(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::JUMPDEST); } -pub fn pc(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn pc(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::BASE); + // - 1 because we have already advanced the instruction pointer in `Interpreter::step` push!(interpreter, U256::from(interpreter.program_counter() - 1)); } -pub fn ret(interpreter: &mut Interpreter, _host: &mut dyn Host) { - // zero gas cost gas!(interp,gas::ZERO); - pop!(interpreter, start, len); - let len = as_usize_or_fail!(interpreter, len, InstructionResult::InvalidOperandOOG); - if len == 0 { - interpreter.return_range = usize::MAX..usize::MAX; - } else { - let offset = as_usize_or_fail!(interpreter, start, InstructionResult::InvalidOperandOOG); - memory_resize!(interpreter, offset, len); - interpreter.return_range = offset..(offset + len); - } +macro_rules! return_setup { + ($interpreter:expr) => { + pop!($interpreter, offset, len); + let len = as_usize_or_fail!($interpreter, len); + // important: offset must be ignored if len is zero + if len != 0 { + let offset = as_usize_or_fail!($interpreter, offset); + memory_resize!($interpreter, offset, len); + $interpreter.return_offset = offset; + } + $interpreter.return_len = len; + }; +} + +pub(super) fn ret(interpreter: &mut Interpreter, _host: &mut dyn Host) { + // zero gas cost + // gas!(interpreter, gas::ZERO); + return_setup!(interpreter); interpreter.instruction_result = InstructionResult::Return; } -pub fn revert(interpreter: &mut Interpreter, _host: &mut dyn Host) { - // zero gas cost gas!(interp,gas::ZERO); - // EIP-140: REVERT instruction - check!(interpreter, SPEC::enabled(BYZANTIUM)); - pop!(interpreter, start, len); - let len = as_usize_or_fail!(interpreter, len, InstructionResult::InvalidOperandOOG); - if len == 0 { - interpreter.return_range = usize::MAX..usize::MAX; - } else { - let offset = as_usize_or_fail!(interpreter, start, InstructionResult::InvalidOperandOOG); - memory_resize!(interpreter, offset, len); - interpreter.return_range = offset..(offset + len); - } +// EIP-140: REVERT instruction +pub(super) fn revert(interpreter: &mut Interpreter, _host: &mut dyn Host) { + // zero gas cost + // gas!(interpreter, gas::ZERO); + check!(interpreter, BYZANTIUM); + return_setup!(interpreter); interpreter.instruction_result = InstructionResult::Revert; } + +pub(super) fn stop(interpreter: &mut Interpreter, _host: &mut dyn Host) { + interpreter.instruction_result = InstructionResult::Stop; +} + +pub(super) fn invalid(interpreter: &mut Interpreter, _host: &mut dyn Host) { + interpreter.instruction_result = InstructionResult::InvalidFEOpcode; +} + +pub(super) fn not_found(interpreter: &mut Interpreter, _host: &mut dyn Host) { + interpreter.instruction_result = InstructionResult::OpcodeNotFound; +} diff --git a/crates/interpreter/src/instructions/host.rs b/crates/interpreter/src/instructions/host.rs index bb0158ef82..4872e65f96 100644 --- a/crates/interpreter/src/instructions/host.rs +++ b/crates/interpreter/src/instructions/host.rs @@ -1,4 +1,4 @@ -use crate::primitives::{Bytes, Spec, SpecId::*, B160, B256, U256}; +use super::prelude::*; use crate::MAX_INITCODE_SIZE; use crate::{ alloc::boxed::Box, @@ -10,14 +10,12 @@ use crate::{ }; use core::cmp::min; -pub fn balance(interpreter: &mut Interpreter, host: &mut dyn Host) { +pub(super) fn balance(interpreter: &mut Interpreter, host: &mut dyn Host) { pop_address!(interpreter, address); - let ret = host.balance(address); - if ret.is_none() { + let Some((balance, is_cold)) = host.balance(address) else { interpreter.instruction_result = InstructionResult::FatalExternalError; return; - } - let (balance, is_cold) = ret.unwrap(); + }; gas!( interpreter, if SPEC::enabled(ISTANBUL) { @@ -32,27 +30,23 @@ pub fn balance(interpreter: &mut Interpreter, host: &mut dyn Host) { push!(interpreter, balance); } -pub fn selfbalance(interpreter: &mut Interpreter, host: &mut dyn Host) { - // EIP-1884: Repricing for trie-size-dependent opcodes - check!(interpreter, SPEC::enabled(ISTANBUL)); +// EIP-1884: Repricing for trie-size-dependent opcodes +pub(super) fn selfbalance(interpreter: &mut Interpreter, host: &mut dyn Host) { + check!(interpreter, ISTANBUL); gas!(interpreter, gas::LOW); - let ret = host.balance(interpreter.contract.address); - if ret.is_none() { + let Some((balance, _)) = host.balance(interpreter.contract.address) else { interpreter.instruction_result = InstructionResult::FatalExternalError; return; - } - let (balance, _) = ret.unwrap(); + }; push!(interpreter, balance); } -pub fn extcodesize(interpreter: &mut Interpreter, host: &mut dyn Host) { +pub(super) fn extcodesize(interpreter: &mut Interpreter, host: &mut dyn Host) { pop_address!(interpreter, address); - let ret = host.code(address); - if ret.is_none() { + let Some((code, is_cold)) = host.code(address) else { interpreter.instruction_result = InstructionResult::FatalExternalError; return; - } - let (code, is_cold) = ret.unwrap(); + }; if SPEC::enabled(BERLIN) { gas!( interpreter, @@ -71,15 +65,14 @@ pub fn extcodesize(interpreter: &mut Interpreter, host: &mut dyn Hos push!(interpreter, U256::from(code.len())); } -pub fn extcodehash(interpreter: &mut Interpreter, host: &mut dyn Host) { - check!(interpreter, SPEC::enabled(CONSTANTINOPLE)); // EIP-1052: EXTCODEHASH opcode +// EIP-1052: EXTCODEHASH opcode +pub(super) fn extcodehash(interpreter: &mut Interpreter, host: &mut dyn Host) { + check!(interpreter, CONSTANTINOPLE); pop_address!(interpreter, address); - let ret = host.code_hash(address); - if ret.is_none() { + let Some((code_hash, is_cold)) = host.code_hash(address) else { interpreter.instruction_result = InstructionResult::FatalExternalError; return; - } - let (code_hash, is_cold) = ret.unwrap(); + }; if SPEC::enabled(BERLIN) { gas!( interpreter, @@ -97,18 +90,16 @@ pub fn extcodehash(interpreter: &mut Interpreter, host: &mut dyn Hos push_b256!(interpreter, code_hash); } -pub fn extcodecopy(interpreter: &mut Interpreter, host: &mut dyn Host) { +pub(super) fn extcodecopy(interpreter: &mut Interpreter, host: &mut dyn Host) { pop_address!(interpreter, address); pop!(interpreter, memory_offset, code_offset, len_u256); - let ret = host.code(address); - if ret.is_none() { + let Some((code, is_cold)) = host.code(address) else { interpreter.instruction_result = InstructionResult::FatalExternalError; return; - } - let (code, is_cold) = ret.unwrap(); + }; - let len = as_usize_or_fail!(interpreter, len_u256, InstructionResult::InvalidOperandOOG); + let len = as_usize_or_fail!(interpreter, len_u256); gas_or_fail!( interpreter, gas::extcodecopy_cost::(len as u64, is_cold) @@ -116,11 +107,7 @@ pub fn extcodecopy(interpreter: &mut Interpreter, host: &mut dyn Hos if len == 0 { return; } - let memory_offset = as_usize_or_fail!( - interpreter, - memory_offset, - InstructionResult::InvalidOperandOOG - ); + let memory_offset = as_usize_or_fail!(interpreter, memory_offset); let code_offset = min(as_usize_saturated!(code_offset), code.len()); memory_resize!(interpreter, memory_offset, len); @@ -130,7 +117,7 @@ pub fn extcodecopy(interpreter: &mut Interpreter, host: &mut dyn Hos .set_data(memory_offset, code_offset, len, code.bytes()); } -pub fn blockhash(interpreter: &mut Interpreter, host: &mut dyn Host) { +pub(super) fn blockhash(interpreter: &mut Interpreter, host: &mut dyn Host) { gas!(interpreter, gas::BLOCKHASH); pop_top!(interpreter, number); @@ -138,41 +125,38 @@ pub fn blockhash(interpreter: &mut Interpreter, host: &mut dyn Host) { let diff = as_usize_saturated!(diff); // blockhash should push zero if number is same as current block number. if diff <= 256 && diff != 0 { - let ret = host.block_hash(*number); - if ret.is_none() { + let Some(hash) = host.block_hash(*number) else { interpreter.instruction_result = InstructionResult::FatalExternalError; return; - } - *number = U256::from_be_bytes(*ret.unwrap()); + }; + *number = U256::from_be_bytes(hash.0); return; } } *number = U256::ZERO; } -pub fn sload(interpreter: &mut Interpreter, host: &mut dyn Host) { +pub(super) fn sload(interpreter: &mut Interpreter, host: &mut dyn Host) { pop!(interpreter, index); - let ret = host.sload(interpreter.contract.address, index); - if ret.is_none() { + let Some((value, is_cold)) = host.sload(interpreter.contract.address, index) else { interpreter.instruction_result = InstructionResult::FatalExternalError; return; - } - let (value, is_cold) = ret.unwrap(); + }; gas!(interpreter, gas::sload_cost::(is_cold)); push!(interpreter, value); } -pub fn sstore(interpreter: &mut Interpreter, host: &mut dyn Host) { +pub(super) fn sstore(interpreter: &mut Interpreter, host: &mut dyn Host) { check_staticcall!(interpreter); pop!(interpreter, index, value); - let ret = host.sstore(interpreter.contract.address, index, value); - if ret.is_none() { + let Some((original, old, new, is_cold)) = + host.sstore(interpreter.contract.address, index, value) + else { interpreter.instruction_result = InstructionResult::FatalExternalError; return; - } - let (original, old, new, is_cold) = ret.unwrap(); + }; gas_or_fail!(interpreter, { let remaining_gas = interpreter.gas.remaining(); gas::sstore_cost::(original, old, new, remaining_gas, is_cold) @@ -180,10 +164,10 @@ pub fn sstore(interpreter: &mut Interpreter, host: &mut dyn Host) { refund!(interpreter, gas::sstore_refund::(original, old, new)); } +// EIP-1153: Transient storage opcodes /// Store value to transient storage -pub fn tstore(interpreter: &mut Interpreter, host: &mut H) { - // EIP-1153: Transient storage opcodes - check!(interpreter, SPEC::enabled(CANCUN)); +pub(super) fn tstore(interpreter: &mut Interpreter, host: &mut dyn Host) { + check!(interpreter, CANCUN); check_staticcall!(interpreter); gas!(interpreter, gas::WARM_STORAGE_READ_COST); @@ -192,10 +176,10 @@ pub fn tstore(interpreter: &mut Interpreter, host: &mut H) host.tstore(interpreter.contract.address, index, value); } +// EIP-1153: Transient storage opcodes /// Load value from transient storage -pub fn tload(interpreter: &mut Interpreter, host: &mut H) { - // EIP-1153: Transient storage opcodes - check!(interpreter, SPEC::enabled(CANCUN)); +pub(super) fn tload(interpreter: &mut Interpreter, host: &mut dyn Host) { + check!(interpreter, CANCUN); gas!(interpreter, gas::WARM_STORAGE_READ_COST); pop_top!(interpreter, index); @@ -203,46 +187,43 @@ pub fn tload(interpreter: &mut Interpreter, host: &mut H) { *index = host.tload(interpreter.contract.address, *index); } -pub fn log(interpreter: &mut Interpreter, host: &mut dyn Host) { +pub(super) fn log(interpreter: &mut Interpreter, host: &mut dyn Host) { check_staticcall!(interpreter); pop!(interpreter, offset, len); - let len = as_usize_or_fail!(interpreter, len, InstructionResult::InvalidOperandOOG); - gas_or_fail!(interpreter, gas::log_cost(N, len as u64)); + let len = as_usize_or_fail!(interpreter, len); + gas_or_fail!(interpreter, gas::log_cost(N as u8, len as u64)); let data = if len == 0 { Bytes::new() } else { - let offset = as_usize_or_fail!(interpreter, offset, InstructionResult::InvalidOperandOOG); + let offset = as_usize_or_fail!(interpreter, offset); memory_resize!(interpreter, offset, len); Bytes::copy_from_slice(interpreter.memory.get_slice(offset, len)) }; - let n = N as usize; - if interpreter.stack.len() < n { + + if interpreter.stack.len() < N { interpreter.instruction_result = InstructionResult::StackUnderflow; return; } - let mut topics = Vec::with_capacity(n); - for _ in 0..(n) { + let mut topics = Vec::with_capacity(N); + for _ in 0..N { // Safety: stack bounds already checked few lines above - topics.push(B256(unsafe { - interpreter.stack.pop_unsafe().to_be_bytes() - })); + let topic = unsafe { interpreter.stack.pop_unsafe() }; + topics.push(B256(topic.to_be_bytes())); } host.log(interpreter.contract.address, topics, data); } -pub fn selfdestruct(interpreter: &mut Interpreter, host: &mut dyn Host) { +pub(super) fn selfdestruct(interpreter: &mut Interpreter, host: &mut dyn Host) { check_staticcall!(interpreter); pop_address!(interpreter, target); - let res = host.selfdestruct(interpreter.contract.address, target); - if res.is_none() { + let Some(res) = host.selfdestruct(interpreter.contract.address, target) else { interpreter.instruction_result = InstructionResult::FatalExternalError; return; - } - let res = res.unwrap(); + }; // EIP-3529: Reduction in refunds if !SPEC::enabled(LONDON) && !res.previously_destroyed { @@ -253,29 +234,25 @@ pub fn selfdestruct(interpreter: &mut Interpreter, host: &mut dyn Ho interpreter.instruction_result = InstructionResult::SelfDestruct; } -pub fn prepare_create_inputs( +pub(super) fn prepare_create_inputs( interpreter: &mut Interpreter, create_inputs: &mut Option>, ) { check_staticcall!(interpreter); + + // EIP-1014: Skinny CREATE2 if IS_CREATE2 { - // EIP-1014: Skinny CREATE2 - check!(interpreter, SPEC::enabled(PETERSBURG)); + check!(interpreter, PETERSBURG); } interpreter.return_data_buffer = Bytes::new(); pop!(interpreter, value, code_offset, len); - let len = as_usize_or_fail!(interpreter, len, InstructionResult::InvalidOperandOOG); + let len = as_usize_or_fail!(interpreter, len); let code = if len == 0 { Bytes::new() } else { - let code_offset = as_usize_or_fail!( - interpreter, - code_offset, - InstructionResult::InvalidOperandOOG - ); // EIP-3860: Limit and meter initcode if SPEC::enabled(SHANGHAI) { if len > MAX_INITCODE_SIZE { @@ -284,6 +261,8 @@ pub fn prepare_create_inputs( } gas!(interpreter, gas::initcode_cost(len as u64)); } + + let code_offset = as_usize_or_fail!(interpreter, code_offset); memory_resize!(interpreter, code_offset, len); Bytes::copy_from_slice(interpreter.memory.get_slice(code_offset, len)) }; @@ -315,12 +294,12 @@ pub fn prepare_create_inputs( })); } -pub fn create( +pub(super) fn create( interpreter: &mut Interpreter, host: &mut dyn Host, ) { let mut create_input: Option> = None; - prepare_create_inputs::(interpreter, &mut create_input); + prepare_create_inputs::(interpreter, &mut create_input); let Some(mut create_input) = create_input else { return; @@ -337,14 +316,14 @@ pub fn create( match return_reason { return_ok!() => { - push_b256!(interpreter, address.unwrap_or_default().into()); + push_b256!(interpreter, address.map_or(B256::zero(), Into::into)); if crate::USE_GAS { interpreter.gas.erase_cost(gas.remaining()); interpreter.gas.record_refund(gas.refunded()); } } return_revert!() => { - push_b256!(interpreter, B256::zero()); + push!(interpreter, U256::ZERO); if crate::USE_GAS { interpreter.gas.erase_cost(gas.remaining()); } @@ -352,26 +331,24 @@ pub fn create( InstructionResult::FatalExternalError => { interpreter.instruction_result = InstructionResult::FatalExternalError; } - _ => { - push_b256!(interpreter, B256::zero()); - } + _ => push!(interpreter, U256::ZERO), } } -pub fn call(interpreter: &mut Interpreter, host: &mut dyn Host) { - call_inner::(interpreter, CallScheme::Call, host); +pub(super) fn call(interpreter: &mut Interpreter, host: &mut dyn Host) { + call_inner::(CallScheme::Call, interpreter, host); } -pub fn call_code(interpreter: &mut Interpreter, host: &mut dyn Host) { - call_inner::(interpreter, CallScheme::CallCode, host); +pub(super) fn call_code(interpreter: &mut Interpreter, host: &mut dyn Host) { + call_inner::(CallScheme::CallCode, interpreter, host); } -pub fn delegate_call(interpreter: &mut Interpreter, host: &mut dyn Host) { - call_inner::(interpreter, CallScheme::DelegateCall, host); +pub(super) fn delegate_call(interpreter: &mut Interpreter, host: &mut dyn Host) { + call_inner::(CallScheme::DelegateCall, interpreter, host); } -pub fn static_call(interpreter: &mut Interpreter, host: &mut dyn Host) { - call_inner::(interpreter, CallScheme::StaticCall, host); +pub(super) fn static_call(interpreter: &mut Interpreter, host: &mut dyn Host) { + call_inner::(CallScheme::StaticCall, interpreter, host); } fn prepare_call_inputs( @@ -404,23 +381,18 @@ fn prepare_call_inputs( pop!(interpreter, in_offset, in_len, out_offset, out_len); - let in_len = as_usize_or_fail!(interpreter, in_len, InstructionResult::InvalidOperandOOG); + let in_len = as_usize_or_fail!(interpreter, in_len); let input = if in_len != 0 { - let in_offset = - as_usize_or_fail!(interpreter, in_offset, InstructionResult::InvalidOperandOOG); + let in_offset = as_usize_or_fail!(interpreter, in_offset); memory_resize!(interpreter, in_offset, in_len); Bytes::copy_from_slice(interpreter.memory.get_slice(in_offset, in_len)) } else { Bytes::new() }; - *result_len = as_usize_or_fail!(interpreter, out_len, InstructionResult::InvalidOperandOOG); + *result_len = as_usize_or_fail!(interpreter, out_len); *result_offset = if *result_len != 0 { - let out_offset = as_usize_or_fail!( - interpreter, - out_offset, - InstructionResult::InvalidOperandOOG - ); + let out_offset = as_usize_or_fail!(interpreter, out_offset); memory_resize!(interpreter, out_offset, *result_len); out_offset } else { @@ -473,12 +445,10 @@ fn prepare_call_inputs( }; // load account and calculate gas cost. - let res = host.load_account(to); - if res.is_none() { + let Some((is_cold, exist)) = host.load_account(to) else { interpreter.instruction_result = InstructionResult::FatalExternalError; return; - } - let (is_cold, exist) = res.unwrap(); + }; let is_new = !exist; gas!( @@ -492,9 +462,9 @@ fn prepare_call_inputs( ) ); + // EIP-150: Gas cost changes for IO-heavy operations // take l64 part of gas_limit let mut gas_limit = if SPEC::enabled(TANGERINE) { - //EIP-150: Gas cost changes for IO-heavy operations let gas = interpreter.gas().remaining(); min(gas - gas / 64, local_gas_limit) } else { @@ -519,14 +489,16 @@ fn prepare_call_inputs( })); } -pub fn call_inner( - interpreter: &mut Interpreter, +pub(super) fn call_inner( scheme: CallScheme, + interpreter: &mut Interpreter, host: &mut dyn Host, ) { match scheme { - CallScheme::DelegateCall => check!(interpreter, SPEC::enabled(HOMESTEAD)), // EIP-7: DELEGATECALL - CallScheme::StaticCall => check!(interpreter, SPEC::enabled(BYZANTIUM)), // EIP-214: New opcode STATICCALL + // EIP-7: DELEGATECALL + CallScheme::DelegateCall => check!(interpreter, HOMESTEAD), + // EIP-214: New opcode STATICCALL + CallScheme::StaticCall => check!(interpreter, BYZANTIUM), _ => (), } interpreter.return_data_buffer = Bytes::new(); diff --git a/crates/interpreter/src/instructions/host_env.rs b/crates/interpreter/src/instructions/host_env.rs index e3d7d5fc6a..2c884dbc0b 100644 --- a/crates/interpreter/src/instructions/host_env.rs +++ b/crates/interpreter/src/instructions/host_env.rs @@ -1,30 +1,28 @@ -use crate::{ - gas, interpreter::Interpreter, primitives::Spec, primitives::SpecId::*, Host, InstructionResult, -}; +use super::prelude::*; -pub fn chainid(interpreter: &mut Interpreter, host: &mut dyn Host) { - // EIP-1344: ChainID opcode - check!(interpreter, SPEC::enabled(ISTANBUL)); +// EIP-1344: ChainID opcode +pub(super) fn chainid(interpreter: &mut Interpreter, host: &mut dyn Host) { + check!(interpreter, ISTANBUL); gas!(interpreter, gas::BASE); push!(interpreter, host.env().cfg.chain_id); } -pub fn coinbase(interpreter: &mut Interpreter, host: &mut dyn Host) { +pub(super) fn coinbase(interpreter: &mut Interpreter, host: &mut dyn Host) { gas!(interpreter, gas::BASE); push_b256!(interpreter, host.env().block.coinbase.into()); } -pub fn timestamp(interpreter: &mut Interpreter, host: &mut dyn Host) { +pub(super) fn timestamp(interpreter: &mut Interpreter, host: &mut dyn Host) { gas!(interpreter, gas::BASE); push!(interpreter, host.env().block.timestamp); } -pub fn number(interpreter: &mut Interpreter, host: &mut dyn Host) { +pub(super) fn number(interpreter: &mut Interpreter, host: &mut dyn Host) { gas!(interpreter, gas::BASE); push!(interpreter, host.env().block.number); } -pub fn difficulty(interpreter: &mut Interpreter, host: &mut H) { +pub(super) fn difficulty(interpreter: &mut Interpreter, host: &mut dyn Host) { gas!(interpreter, gas::BASE); if SPEC::enabled(MERGE) { push_b256!(interpreter, host.env().block.prevrandao.unwrap()); @@ -33,24 +31,24 @@ pub fn difficulty(interpreter: &mut Interpreter, host: &mut } } -pub fn gaslimit(interpreter: &mut Interpreter, host: &mut dyn Host) { +pub(super) fn gaslimit(interpreter: &mut Interpreter, host: &mut dyn Host) { gas!(interpreter, gas::BASE); push!(interpreter, host.env().block.gas_limit); } -pub fn gasprice(interpreter: &mut Interpreter, host: &mut dyn Host) { +pub(super) fn gasprice(interpreter: &mut Interpreter, host: &mut dyn Host) { gas!(interpreter, gas::BASE); push!(interpreter, host.env().effective_gas_price()); } -pub fn basefee(interpreter: &mut Interpreter, host: &mut dyn Host) { +// EIP-3198: BASEFEE opcode +pub(super) fn basefee(interpreter: &mut Interpreter, host: &mut dyn Host) { + check!(interpreter, LONDON); gas!(interpreter, gas::BASE); - // EIP-3198: BASEFEE opcode - check!(interpreter, SPEC::enabled(LONDON)); push!(interpreter, host.env().block.basefee); } -pub fn origin(interpreter: &mut Interpreter, host: &mut dyn Host) { +pub(super) fn origin(interpreter: &mut Interpreter, host: &mut dyn Host) { gas!(interpreter, gas::BASE); push_b256!(interpreter, host.env().tx.caller.into()); } diff --git a/crates/interpreter/src/instructions/i256.rs b/crates/interpreter/src/instructions/i256.rs index 6189fe93bf..02f9343c84 100644 --- a/crates/interpreter/src/instructions/i256.rs +++ b/crates/interpreter/src/instructions/i256.rs @@ -1,28 +1,24 @@ -use crate::primitives::U256; +use super::prelude::*; use core::cmp::Ordering; -#[cfg(test)] -use proptest_derive::Arbitrary as PropTestArbitrary; - -#[cfg(any(test, feature = "arbitrary"))] -use arbitrary::Arbitrary; - -#[cfg_attr(test, derive(PropTestArbitrary))] -#[cfg_attr(any(test, feature = "arbitrary"), derive(Arbitrary))] #[derive(Copy, Clone, Eq, PartialEq, Debug)] -pub enum Sign { +#[cfg_attr( + any(test, feature = "arbitrary"), + derive(arbitrary::Arbitrary, proptest_derive::Arbitrary) +)] +pub(super) enum Sign { Plus, Minus, Zero, } -pub const _SIGN_BIT_MASK: U256 = U256::from_limbs([ +pub(super) const _SIGN_BIT_MASK: U256 = U256::from_limbs([ 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFFF, ]); -pub const MIN_NEGATIVE_VALUE: U256 = U256::from_limbs([ +pub(super) const MIN_NEGATIVE_VALUE: U256 = U256::from_limbs([ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, @@ -31,13 +27,15 @@ pub const MIN_NEGATIVE_VALUE: U256 = U256::from_limbs([ const FLIPH_BITMASK_U64: u64 = 0x7FFFFFFFFFFFFFFF; -#[cfg_attr(test, derive(PropTestArbitrary))] -#[cfg_attr(any(test, feature = "arbitrary"), derive(Arbitrary))] #[derive(Copy, Clone, Eq, PartialEq, Debug)] -pub struct I256(pub Sign, pub U256); +#[cfg_attr( + any(test, feature = "arbitrary"), + derive(arbitrary::Arbitrary, proptest_derive::Arbitrary) +)] +pub(super) struct I256(pub(super) Sign, pub(super) U256); #[inline(always)] -pub fn i256_sign(val: &mut U256) -> Sign { +pub(super) fn i256_sign(val: &mut U256) -> Sign { if !val.bit(U256::BITS - 1) { if *val == U256::ZERO { Sign::Zero @@ -60,16 +58,16 @@ fn u256_remove_sign(val: &mut U256) { } #[inline(always)] -pub fn two_compl_mut(op: &mut U256) { +pub(super) fn two_compl_mut(op: &mut U256) { *op = two_compl(*op); } -pub fn two_compl(op: U256) -> U256 { +pub(super) fn two_compl(op: U256) -> U256 { op.wrapping_neg() } #[inline(always)] -pub fn i256_cmp(mut first: U256, mut second: U256) -> Ordering { +pub(super) fn i256_cmp(mut first: U256, mut second: U256) -> Ordering { let first_sign = i256_sign::(&mut first); let second_sign = i256_sign::(&mut second); match (first_sign, second_sign) { @@ -86,7 +84,7 @@ pub fn i256_cmp(mut first: U256, mut second: U256) -> Ordering { } #[inline(always)] -pub fn i256_div(mut first: U256, mut second: U256) -> U256 { +pub(super) fn i256_div(mut first: U256, mut second: U256) -> U256 { let second_sign = i256_sign::(&mut second); if second_sign == Sign::Zero { return U256::ZERO; @@ -120,7 +118,7 @@ pub fn i256_div(mut first: U256, mut second: U256) -> U256 { } #[inline(always)] -pub fn i256_mod(mut first: U256, mut second: U256) -> U256 { +pub(super) fn i256_mod(mut first: U256, mut second: U256) -> U256 { let first_sign = i256_sign::(&mut first); if first_sign == Sign::Zero { return U256::ZERO; diff --git a/crates/interpreter/src/instructions/macros.rs b/crates/interpreter/src/instructions/macros.rs index 71b6d17f22..a8f3ed5000 100644 --- a/crates/interpreter/src/instructions/macros.rs +++ b/crates/interpreter/src/instructions/macros.rs @@ -1,5 +1,3 @@ -pub use crate::InstructionResult; - macro_rules! check_staticcall { ($interp:expr) => { if $interp.is_static { @@ -10,8 +8,9 @@ macro_rules! check_staticcall { } macro_rules! check { - ($interp:expr, $expresion:expr) => { - if !$expresion { + ($interp:expr, $min:ident) => { + // TODO: Force const-eval on the condition with a `const {}` block once they are stable + if !::enabled($crate::primitives::SpecId::$min) { $interp.instruction_result = InstructionResult::NotActivated; return; } @@ -21,7 +20,7 @@ macro_rules! check { macro_rules! gas { ($interp:expr, $gas:expr) => { if crate::USE_GAS { - if !$interp.gas.record_cost(($gas)) { + if !$interp.gas.record_cost($gas) { $interp.instruction_result = InstructionResult::OutOfGas; return; } @@ -30,19 +29,19 @@ macro_rules! gas { } macro_rules! refund { - ($interp:expr, $gas:expr) => {{ + ($interp:expr, $gas:expr) => { if crate::USE_GAS { - $interp.gas.gas_refund($gas); + $interp.gas.record_refund($gas); } - }}; + }; } macro_rules! gas_or_fail { ($interp:expr, $gas:expr) => { if crate::USE_GAS { match $gas { - Some(gas_used) => gas!($interp, gas_used), - None => { + Some(gas_used) if $interp.gas.record_cost(gas_used) => {} + _ => { $interp.instruction_result = InstructionResult::OutOfGas; return; } @@ -52,11 +51,9 @@ macro_rules! gas_or_fail { } macro_rules! memory_resize { - ($interp:expr, $offset:expr, $len:expr) => {{ - let len: usize = $len; - let offset: usize = $offset; + ($interp:expr, $offset:expr, $len:expr) => { if let Some(new_size) = - crate::interpreter::memory::next_multiple_of_32(offset.saturating_add(len)) + crate::interpreter::memory::next_multiple_of_32($offset.saturating_add($len)) { #[cfg(feature = "memory_limit")] if new_size > ($interp.memory_limit as usize) { @@ -78,11 +75,11 @@ macro_rules! memory_resize { $interp.instruction_result = InstructionResult::MemoryOOG; return; } - }}; + }; } macro_rules! pop_address { - ( $interp:expr, $x1:ident) => { + ($interp:expr, $x1:ident) => { if $interp.stack.len() < 1 { $interp.instruction_result = InstructionResult::StackUnderflow; return; @@ -94,12 +91,11 @@ macro_rules! pop_address { .unwrap(), ); }; - ( $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..] @@ -115,7 +111,7 @@ macro_rules! pop_address { } macro_rules! pop { - ( $interp:expr, $x1:ident) => { + ($interp:expr, $x1:ident) => { if $interp.stack.len() < 1 { $interp.instruction_result = InstructionResult::StackUnderflow; return; @@ -123,7 +119,7 @@ macro_rules! pop { // Safety: Length is checked above. let $x1 = 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; @@ -131,7 +127,7 @@ macro_rules! pop { // Safety: Length is checked above. let ($x1, $x2) = unsafe { $interp.stack.pop2_unsafe() }; }; - ( $interp:expr, $x1:ident, $x2:ident, $x3:ident) => { + ($interp:expr, $x1:ident, $x2:ident, $x3:ident) => { if $interp.stack.len() < 3 { $interp.instruction_result = InstructionResult::StackUnderflow; return; @@ -140,7 +136,7 @@ macro_rules! pop { let ($x1, $x2, $x3) = unsafe { $interp.stack.pop3_unsafe() }; }; - ( $interp:expr, $x1:ident, $x2:ident, $x3:ident, $x4:ident) => { + ($interp:expr, $x1:ident, $x2:ident, $x3:ident, $x4:ident) => { if $interp.stack.len() < 4 { $interp.instruction_result = InstructionResult::StackUnderflow; return; @@ -151,7 +147,7 @@ macro_rules! pop { } macro_rules! pop_top { - ( $interp:expr, $x1:ident) => { + ($interp:expr, $x1:ident) => { if $interp.stack.len() < 1 { $interp.instruction_result = InstructionResult::StackUnderflow; return; @@ -159,7 +155,7 @@ macro_rules! pop_top { // Safety: Length is checked above. let $x1 = unsafe { $interp.stack.top_unsafe() }; }; - ( $interp:expr, $x1:ident, $x2:ident) => { + ($interp:expr, $x1:ident, $x2:ident) => { if $interp.stack.len() < 2 { $interp.instruction_result = InstructionResult::StackUnderflow; return; @@ -167,7 +163,7 @@ macro_rules! pop_top { // Safety: Length is checked above. let ($x1, $x2) = unsafe { $interp.stack.pop_top_unsafe() }; }; - ( $interp:expr, $x1:ident, $x2:ident, $x3:ident) => { + ($interp:expr, $x1:ident, $x2:ident, $x3:ident) => { if $interp.stack.len() < 3 { $interp.instruction_result = InstructionResult::StackUnderflow; return; @@ -178,59 +174,57 @@ macro_rules! pop_top { } macro_rules! push_b256 { - ( $interp:expr, $( $x:expr ),* ) => ( - $( - match $interp.stack.push_b256($x) { - Ok(()) => (), - Err(e) => { - $interp.instruction_result = e; - return - }, - } - )* - ) + ($interp:expr, $($x:expr),* $(,)?) => ($( + match $interp.stack.push_b256($x) { + Ok(()) => {}, + Err(e) => { + $interp.instruction_result = e; + return; + }, + } + )*) } macro_rules! push { - ( $interp:expr, $( $x:expr ),* ) => ( - $( - match $interp.stack.push($x) { - Ok(()) => (), - Err(e) => { $interp.instruction_result = e; - return - } , - } - )* - ) + ($interp:expr, $($x:expr),* $(,)?) => ($( + match $interp.stack.push($x) { + Ok(()) => {}, + Err(e) => { + $interp.instruction_result = e; + return; + } + } + )*) } macro_rules! as_u64_saturated { - ( $v:expr ) => {{ - if $v.as_limbs()[1] != 0 || $v.as_limbs()[2] != 0 || $v.as_limbs()[3] != 0 { - u64::MAX + ($v:expr) => {{ + let x: &[u64; 4] = $v.as_limbs(); + if x[1] == 0 && x[2] == 0 && x[3] == 0 { + x[0] } else { - $v.as_limbs()[0] + u64::MAX } }}; } macro_rules! as_usize_saturated { - ( $v:expr ) => {{ + ($v:expr) => { as_u64_saturated!($v) as usize - }}; + }; } macro_rules! as_usize_or_fail { - ( $interp:expr, $v:expr ) => {{ + ($interp:expr, $v:expr) => { as_usize_or_fail!($interp, $v, InstructionResult::InvalidOperandOOG) - }}; + }; - ( $interp:expr, $v:expr, $reason:expr ) => {{ - if $v.as_limbs()[1] != 0 || $v.as_limbs()[2] != 0 || $v.as_limbs()[3] != 0 { + ($interp:expr, $v:expr, $reason:expr) => {{ + let x = $v.as_limbs(); + if x[1] != 0 || x[2] != 0 || x[3] != 0 { $interp.instruction_result = $reason; return; } - - $v.as_limbs()[0] as usize + x[0] as usize }}; } diff --git a/crates/interpreter/src/instructions/memory.rs b/crates/interpreter/src/instructions/memory.rs index a6580d031b..d35639e14e 100644 --- a/crates/interpreter/src/instructions/memory.rs +++ b/crates/interpreter/src/instructions/memory.rs @@ -1,72 +1,56 @@ +use super::prelude::*; use core::cmp::max; -use revm_primitives::SpecId::CANCUN; - -use crate::{ - gas, - interpreter::Interpreter, - primitives::{Spec, U256}, - Host, InstructionResult, -}; - -pub fn mload(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn mload(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::VERYLOW); pop!(interpreter, index); - let index = as_usize_or_fail!(interpreter, index, InstructionResult::InvalidOperandOOG); + let index = as_usize_or_fail!(interpreter, index); memory_resize!(interpreter, index, 32); push!( interpreter, - U256::from_be_bytes::<{ U256::BYTES }>( - interpreter.memory.get_slice(index, 32).try_into().unwrap() - ) + U256::from_be_bytes::<32>(interpreter.memory.get_slice(index, 32).try_into().unwrap()) ); } -pub fn mstore(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn mstore(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::VERYLOW); pop!(interpreter, index, value); - let index = as_usize_or_fail!(interpreter, index, InstructionResult::InvalidOperandOOG); + let index = as_usize_or_fail!(interpreter, index); memory_resize!(interpreter, index, 32); interpreter.memory.set_u256(index, value); } -pub fn mstore8(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn mstore8(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::VERYLOW); pop!(interpreter, index, value); - let index = as_usize_or_fail!(interpreter, index, InstructionResult::InvalidOperandOOG); + let index = as_usize_or_fail!(interpreter, index); memory_resize!(interpreter, index, 1); - let value = value.as_le_bytes()[0]; - // Safety: we resized our memory two lines above. - unsafe { interpreter.memory.set_byte(index, value) } + interpreter.memory.set_byte(index, value.byte(0)) } -pub fn msize(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn msize(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::BASE); - push!(interpreter, U256::from(interpreter.memory.effective_len())); + push!(interpreter, U256::from(interpreter.memory.len())); } -// From EIP-5656 MCOPY -pub fn mcopy(interpreter: &mut Interpreter, _host: &mut dyn Host) { - // Opcode enabled in Cancun. - // EIP-5656: MCOPY - Memory copying instruction - check!(interpreter, SPEC::enabled(CANCUN)); - // get src and dest and length from stack - pop!(interpreter, dest, src, len); +// EIP-5656: MCOPY - Memory copying instruction +pub(super) fn mcopy(interpreter: &mut Interpreter, _host: &mut dyn Host) { + check!(interpreter, CANCUN); + pop!(interpreter, dst, src, len); // into usize or fail - let len = as_usize_or_fail!(interpreter, len, InstructionResult::InvalidOperandOOG); + let len = as_usize_or_fail!(interpreter, len); // deduce gas gas_or_fail!(interpreter, gas::verylowcopy_cost(len as u64)); if len == 0 { return; } - let dest = as_usize_or_fail!(interpreter, dest, InstructionResult::InvalidOperandOOG); - let src = as_usize_or_fail!(interpreter, src, InstructionResult::InvalidOperandOOG); + let dst = as_usize_or_fail!(interpreter, dst); + let src = as_usize_or_fail!(interpreter, src); // memory resize - let resize = max(dest, src).saturating_add(len); - // resize memory + let resize = max(dst, src).saturating_add(len); memory_resize!(interpreter, src, resize); // copy memory in place - interpreter.memory.copy(dest, src, len); + interpreter.memory.copy(dst, src, len); } diff --git a/crates/interpreter/src/instructions/mod.rs b/crates/interpreter/src/instructions/mod.rs new file mode 100644 index 0000000000..fc1d3a1734 --- /dev/null +++ b/crates/interpreter/src/instructions/mod.rs @@ -0,0 +1,23 @@ +#[macro_use] +mod macros; + +mod arithmetic; +mod bitwise; +mod control; +mod host; +mod host_env; +mod i256; +mod memory; +pub mod opcode; +mod stack; +mod system; + +mod prelude { + pub(super) use crate::primitives::{ + Bytes, Spec, SpecId, SpecId::*, B160, B256, KECCAK_EMPTY, U256, + }; + pub(super) use crate::{gas, Host, InstructionResult, Interpreter}; + pub(super) use core::cmp::Ordering; +} + +pub use opcode::{OpCode, OPCODE_JUMPMAP}; diff --git a/crates/interpreter/src/instructions/opcode.rs b/crates/interpreter/src/instructions/opcode.rs index 7c2f80d71e..f50f389b73 100644 --- a/crates/interpreter/src/instructions/opcode.rs +++ b/crates/interpreter/src/instructions/opcode.rs @@ -1,170 +1,262 @@ -use crate::gas; -use crate::primitives::SpecId; +//! EVM opcode definitions and utilities. -#[derive(Debug, Clone, Copy, Eq, PartialEq)] +use super::{prelude::*, *}; +use core::fmt; + +macro_rules! opcodes { + ($($val:literal => $name:ident => $f:expr),* $(,)?) => { + // Constants for each opcode. This also takes care of duplicate names. + $( + #[doc = concat!("The `", stringify!($val), "` (\"", stringify!($name),"\") opcode.")] + pub const $name: u8 = $val; + )* + + /// Maps each opcode to its name. + pub const OPCODE_JUMPMAP: [Option<&'static str>; 256] = { + let mut map = [None; 256]; + let mut prev: u8 = 0; + $( + let val: u8 = $val; + assert!(val == 0 || val > prev, "opcodes must be sorted in ascending order"); + prev = val; + map[$val] = Some(stringify!($name)); + )* + let _ = prev; + map + }; + + /// Evaluates the opcode in the given context. + #[inline(always)] + pub(crate) fn eval(opcode: u8, interpreter: &mut Interpreter, host: &mut dyn Host) { + // type Instruction = fn(&mut Interpreter, &mut dyn Host, SpecId); + // const INSTRUCTIONS: [Instruction; 256] = { + // #[allow(unused_mut)] + // let mut instructions: [Instruction; 256] = [control::not_found; 256]; + // $( + // instructions[$val] = $f; + // )* + // instructions + // }; + // INSTRUCTIONS[opcode as usize](interpreter, host, spec); + + match opcode { + $($name => $f(interpreter, host),)* + _ => control::not_found(interpreter, host), + } + } + }; +} + +// When adding new opcodes: +// 1. add the opcode to the list below; make sure it's sorted by opcode value +// 2. add its gas info in the `opcode_gas_info` function below +// 3. implement the opcode in the corresponding module; +// the function signature must be the exact same as the others +opcodes! { + 0x00 => STOP => control::stop, + + 0x01 => ADD => arithmetic::wrapped_add, + 0x02 => MUL => arithmetic::wrapping_mul, + 0x03 => SUB => arithmetic::wrapping_sub, + 0x04 => DIV => arithmetic::div, + 0x05 => SDIV => arithmetic::sdiv, + 0x06 => MOD => arithmetic::rem, + 0x07 => SMOD => arithmetic::smod, + 0x08 => ADDMOD => arithmetic::addmod, + 0x09 => MULMOD => arithmetic::mulmod, + 0x0A => EXP => arithmetic::exp::, + 0x0B => SIGNEXTEND => arithmetic::signextend, + + 0x10 => LT => bitwise::lt, + 0x11 => GT => bitwise::gt, + 0x12 => SLT => bitwise::slt, + 0x13 => SGT => bitwise::sgt, + 0x14 => EQ => bitwise::eq, + 0x15 => ISZERO => bitwise::iszero, + 0x16 => AND => bitwise::bitand, + 0x17 => OR => bitwise::bitor, + 0x18 => XOR => bitwise::bitxor, + 0x19 => NOT => bitwise::not, + 0x1A => BYTE => bitwise::byte, + 0x1B => SHL => bitwise::shl::, + 0x1C => SHR => bitwise::shr::, + 0x1D => SAR => bitwise::sar::, + + 0x20 => KECCAK256 => system::keccak256, + + 0x30 => ADDRESS => system::address, + 0x31 => BALANCE => host::balance::, + 0x32 => ORIGIN => host_env::origin, + 0x33 => CALLER => system::caller, + 0x34 => CALLVALUE => system::callvalue, + + 0x35 => CALLDATALOAD => system::calldataload, + 0x36 => CALLDATASIZE => system::calldatasize, + 0x37 => CALLDATACOPY => system::calldatacopy, + 0x38 => CODESIZE => system::codesize, + 0x39 => CODECOPY => system::codecopy, + + 0x3A => GASPRICE => host_env::gasprice, + 0x3B => EXTCODESIZE => host::extcodesize::, + 0x3C => EXTCODECOPY => host::extcodecopy::, + 0x3D => RETURNDATASIZE => system::returndatasize::, + 0x3E => RETURNDATACOPY => system::returndatacopy::, + 0x3F => EXTCODEHASH => host::extcodehash::, + 0x40 => BLOCKHASH => host::blockhash, + 0x41 => COINBASE => host_env::coinbase, + 0x42 => TIMESTAMP => host_env::timestamp, + 0x43 => NUMBER => host_env::number, + 0x44 => DIFFICULTY => host_env::difficulty::, + 0x45 => GASLIMIT => host_env::gaslimit, + 0x46 => CHAINID => host_env::chainid::, + 0x47 => SELFBALANCE => host::selfbalance::, + 0x48 => BASEFEE => host_env::basefee::, + + 0x50 => POP => stack::pop, + 0x51 => MLOAD => memory::mload, + 0x52 => MSTORE => memory::mstore, + 0x53 => MSTORE8 => memory::mstore8, + 0x54 => SLOAD => host::sload::, + 0x55 => SSTORE => host::sstore::, + 0x56 => JUMP => control::jump, + 0x57 => JUMPI => control::jumpi, + 0x58 => PC => control::pc, + 0x59 => MSIZE => memory::msize, + 0x5A => GAS => system::gas, + 0x5B => JUMPDEST => control::jumpdest, + 0x5C => TSTORE => host::tstore::, + 0x5D => TLOAD => host::tload::, + 0x5E => MCOPY => memory::mcopy::, + + 0x5F => PUSH0 => stack::push0::, + 0x60 => PUSH1 => stack::push::<1>, + 0x61 => PUSH2 => stack::push::<2>, + 0x62 => PUSH3 => stack::push::<3>, + 0x63 => PUSH4 => stack::push::<4>, + 0x64 => PUSH5 => stack::push::<5>, + 0x65 => PUSH6 => stack::push::<6>, + 0x66 => PUSH7 => stack::push::<7>, + 0x67 => PUSH8 => stack::push::<8>, + 0x68 => PUSH9 => stack::push::<9>, + 0x69 => PUSH10 => stack::push::<10>, + 0x6A => PUSH11 => stack::push::<11>, + 0x6B => PUSH12 => stack::push::<12>, + 0x6C => PUSH13 => stack::push::<13>, + 0x6D => PUSH14 => stack::push::<14>, + 0x6E => PUSH15 => stack::push::<15>, + 0x6F => PUSH16 => stack::push::<16>, + 0x70 => PUSH17 => stack::push::<17>, + 0x71 => PUSH18 => stack::push::<18>, + 0x72 => PUSH19 => stack::push::<19>, + 0x73 => PUSH20 => stack::push::<20>, + 0x74 => PUSH21 => stack::push::<21>, + 0x75 => PUSH22 => stack::push::<22>, + 0x76 => PUSH23 => stack::push::<23>, + 0x77 => PUSH24 => stack::push::<24>, + 0x78 => PUSH25 => stack::push::<25>, + 0x79 => PUSH26 => stack::push::<26>, + 0x7A => PUSH27 => stack::push::<27>, + 0x7B => PUSH28 => stack::push::<28>, + 0x7C => PUSH29 => stack::push::<29>, + 0x7D => PUSH30 => stack::push::<30>, + 0x7E => PUSH31 => stack::push::<31>, + 0x7F => PUSH32 => stack::push::<32>, + + 0x80 => DUP1 => stack::dup::<1>, + 0x81 => DUP2 => stack::dup::<2>, + 0x82 => DUP3 => stack::dup::<3>, + 0x83 => DUP4 => stack::dup::<4>, + 0x84 => DUP5 => stack::dup::<5>, + 0x85 => DUP6 => stack::dup::<6>, + 0x86 => DUP7 => stack::dup::<7>, + 0x87 => DUP8 => stack::dup::<8>, + 0x88 => DUP9 => stack::dup::<9>, + 0x89 => DUP10 => stack::dup::<10>, + 0x8A => DUP11 => stack::dup::<11>, + 0x8B => DUP12 => stack::dup::<12>, + 0x8C => DUP13 => stack::dup::<13>, + 0x8D => DUP14 => stack::dup::<14>, + 0x8E => DUP15 => stack::dup::<15>, + 0x8F => DUP16 => stack::dup::<16>, + + 0x90 => SWAP1 => stack::swap::<1>, + 0x91 => SWAP2 => stack::swap::<2>, + 0x92 => SWAP3 => stack::swap::<3>, + 0x93 => SWAP4 => stack::swap::<4>, + 0x94 => SWAP5 => stack::swap::<5>, + 0x95 => SWAP6 => stack::swap::<6>, + 0x96 => SWAP7 => stack::swap::<7>, + 0x97 => SWAP8 => stack::swap::<8>, + 0x98 => SWAP9 => stack::swap::<9>, + 0x99 => SWAP10 => stack::swap::<10>, + 0x9A => SWAP11 => stack::swap::<11>, + 0x9B => SWAP12 => stack::swap::<12>, + 0x9C => SWAP13 => stack::swap::<13>, + 0x9D => SWAP14 => stack::swap::<14>, + 0x9E => SWAP15 => stack::swap::<15>, + 0x9F => SWAP16 => stack::swap::<16>, + + 0xA0 => LOG0 => host::log::<0>, + 0xA1 => LOG1 => host::log::<1>, + 0xA2 => LOG2 => host::log::<2>, + 0xA3 => LOG3 => host::log::<3>, + 0xA4 => LOG4 => host::log::<4>, + + 0xF0 => CREATE => host::create::, + 0xF1 => CALL => host::call::, + 0xF2 => CALLCODE => host::call_code::, + 0xF3 => RETURN => control::ret, + 0xF4 => DELEGATECALL => host::delegate_call::, + 0xF5 => CREATE2 => host::create::, + 0xFA => STATICCALL => host::static_call::, + 0xFD => REVERT => control::revert::, + 0xFE => INVALID => control::invalid, + 0xFF => SELFDESTRUCT => host::selfdestruct::, +} + +/// An EVM opcode. +/// +/// This is always a valid opcode, as declared in the [`opcode`][self] module or the +/// [`OPCODE_JUMPMAP`] constant. +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[repr(transparent)] pub struct OpCode(u8); -pub const STOP: u8 = 0x00; -pub const ADD: u8 = 0x01; -pub const MUL: u8 = 0x02; -pub const SUB: u8 = 0x03; -pub const DIV: u8 = 0x04; -pub const SDIV: u8 = 0x05; -pub const MOD: u8 = 0x06; -pub const SMOD: u8 = 0x07; -pub const ADDMOD: u8 = 0x08; -pub const MULMOD: u8 = 0x09; -pub const EXP: u8 = 0x0a; -pub const SIGNEXTEND: u8 = 0x0b; - -pub const LT: u8 = 0x10; -pub const GT: u8 = 0x11; -pub const SLT: u8 = 0x12; -pub const SGT: u8 = 0x13; -pub const EQ: u8 = 0x14; -pub const ISZERO: u8 = 0x15; -pub const AND: u8 = 0x16; -pub const OR: u8 = 0x17; -pub const XOR: u8 = 0x18; -pub const NOT: u8 = 0x19; -pub const BYTE: u8 = 0x1a; - -pub const CALLDATALOAD: u8 = 0x35; -pub const CALLDATASIZE: u8 = 0x36; -pub const CALLDATACOPY: u8 = 0x37; -pub const CODESIZE: u8 = 0x38; -pub const CODECOPY: u8 = 0x39; - -pub const SHL: u8 = 0x1b; -pub const SHR: u8 = 0x1c; -pub const SAR: u8 = 0x1d; -pub const KECCAK256: u8 = 0x20; -pub const POP: u8 = 0x50; -pub const MLOAD: u8 = 0x51; -pub const MSTORE: u8 = 0x52; -pub const MSTORE8: u8 = 0x53; -pub const JUMP: u8 = 0x56; -pub const JUMPI: u8 = 0x57; -pub const PC: u8 = 0x58; -pub const MSIZE: u8 = 0x59; -pub const JUMPDEST: u8 = 0x5b; - -pub const TLOAD: u8 = 0x5c; -pub const TSTORE: u8 = 0x5d; - -pub const MCOPY: u8 = 0x5e; -pub const PUSH0: u8 = 0x5f; -pub const PUSH1: u8 = 0x60; -pub const PUSH2: u8 = 0x61; -pub const PUSH3: u8 = 0x62; -pub const PUSH4: u8 = 0x63; -pub const PUSH5: u8 = 0x64; -pub const PUSH6: u8 = 0x65; -pub const PUSH7: u8 = 0x66; -pub const PUSH8: u8 = 0x67; -pub const PUSH9: u8 = 0x68; -pub const PUSH10: u8 = 0x69; -pub const PUSH11: u8 = 0x6a; -pub const PUSH12: u8 = 0x6b; -pub const PUSH13: u8 = 0x6c; -pub const PUSH14: u8 = 0x6d; -pub const PUSH15: u8 = 0x6e; -pub const PUSH16: u8 = 0x6f; -pub const PUSH17: u8 = 0x70; -pub const PUSH18: u8 = 0x71; -pub const PUSH19: u8 = 0x72; -pub const PUSH20: u8 = 0x73; -pub const PUSH21: u8 = 0x74; -pub const PUSH22: u8 = 0x75; -pub const PUSH23: u8 = 0x76; -pub const PUSH24: u8 = 0x77; -pub const PUSH25: u8 = 0x78; -pub const PUSH26: u8 = 0x79; -pub const PUSH27: u8 = 0x7a; -pub const PUSH28: u8 = 0x7b; -pub const PUSH29: u8 = 0x7c; -pub const PUSH30: u8 = 0x7d; -pub const PUSH31: u8 = 0x7e; -pub const PUSH32: u8 = 0x7f; -pub const DUP1: u8 = 0x80; -pub const DUP2: u8 = 0x81; -pub const DUP3: u8 = 0x82; -pub const DUP4: u8 = 0x83; -pub const DUP5: u8 = 0x84; -pub const DUP6: u8 = 0x85; -pub const DUP7: u8 = 0x86; -pub const DUP8: u8 = 0x87; -pub const DUP9: u8 = 0x88; -pub const DUP10: u8 = 0x89; -pub const DUP11: u8 = 0x8a; -pub const DUP12: u8 = 0x8b; -pub const DUP13: u8 = 0x8c; -pub const DUP14: u8 = 0x8d; -pub const DUP15: u8 = 0x8e; -pub const DUP16: u8 = 0x8f; -pub const SWAP1: u8 = 0x90; -pub const SWAP2: u8 = 0x91; -pub const SWAP3: u8 = 0x92; -pub const SWAP4: u8 = 0x93; -pub const SWAP5: u8 = 0x94; -pub const SWAP6: u8 = 0x95; -pub const SWAP7: u8 = 0x96; -pub const SWAP8: u8 = 0x97; -pub const SWAP9: u8 = 0x98; -pub const SWAP10: u8 = 0x99; -pub const SWAP11: u8 = 0x9a; -pub const SWAP12: u8 = 0x9b; -pub const SWAP13: u8 = 0x9c; -pub const SWAP14: u8 = 0x9d; -pub const SWAP15: u8 = 0x9e; -pub const SWAP16: u8 = 0x9f; -pub const RETURN: u8 = 0xf3; -pub const REVERT: u8 = 0xfd; -pub const INVALID: u8 = 0xfe; -pub const ADDRESS: u8 = 0x30; -pub const BALANCE: u8 = 0x31; -pub const BASEFEE: u8 = 0x48; -pub const ORIGIN: u8 = 0x32; -pub const CALLER: u8 = 0x33; -pub const CALLVALUE: u8 = 0x34; -pub const GASPRICE: u8 = 0x3a; -pub const EXTCODESIZE: u8 = 0x3b; -pub const EXTCODECOPY: u8 = 0x3c; -pub const EXTCODEHASH: u8 = 0x3f; -pub const RETURNDATASIZE: u8 = 0x3d; -pub const RETURNDATACOPY: u8 = 0x3e; -pub const BLOCKHASH: u8 = 0x40; -pub const COINBASE: u8 = 0x41; -pub const TIMESTAMP: u8 = 0x42; -pub const NUMBER: u8 = 0x43; -pub const DIFFICULTY: u8 = 0x44; -pub const GASLIMIT: u8 = 0x45; -pub const SELFBALANCE: u8 = 0x47; -pub const SLOAD: u8 = 0x54; -pub const SSTORE: u8 = 0x55; -pub const GAS: u8 = 0x5a; - -pub const LOG0: u8 = 0xa0; -pub const LOG1: u8 = 0xa1; -pub const LOG2: u8 = 0xa2; -pub const LOG3: u8 = 0xa3; -pub const LOG4: u8 = 0xa4; - -pub const CREATE: u8 = 0xf0; -pub const CREATE2: u8 = 0xf5; -pub const CALL: u8 = 0xf1; -pub const CALLCODE: u8 = 0xf2; -pub const DELEGATECALL: u8 = 0xf4; -pub const STATICCALL: u8 = 0xfa; -pub const SELFDESTRUCT: u8 = 0xff; -pub const CHAINID: u8 = 0x46; +impl fmt::Display for OpCode { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let n = self.get(); + if let Some(val) = OPCODE_JUMPMAP[n as usize] { + f.write_str(val) + } else { + write!(f, "UNKNOWN(0x{n:02X})") + } + } +} impl OpCode { - pub fn try_from_u8(opcode: u8) -> Option { - OPCODE_JUMPMAP[opcode as usize].map(|_| OpCode(opcode)) + /// Instantiate a new opcode from a u8. + #[inline] + pub const fn new(opcode: u8) -> Option { + match OPCODE_JUMPMAP[opcode as usize] { + Some(_) => Some(Self(opcode)), + None => None, + } } - pub const fn as_str(&self) -> &'static str { + /// Instantiate a new opcode from a u8 without checking if it is valid. + /// + /// # Safety + /// + /// All code using `Opcode` values assume that they are valid opcodes, so providing an invalid + /// opcode may cause undefined behavior. + #[inline] + pub unsafe fn new_unchecked(opcode: u8) -> Self { + Self(opcode) + } + + /// Returns the opcode as a string. + #[inline] + pub const fn as_str(self) -> &'static str { if let Some(str) = OPCODE_JUMPMAP[self.0 as usize] { str } else { @@ -172,282 +264,28 @@ impl OpCode { } } - #[inline(always)] - pub const fn u8(&self) -> u8 { + /// Returns the opcode as a u8. + #[inline] + pub const fn get(self) -> u8 { self.0 } -} -impl core::fmt::Display for OpCode { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - if let Some(val) = OPCODE_JUMPMAP[self.0 as usize] { - f.write_str(val) - } else { - write!(f, "UNKNOWN(0x{:02x})", self.0) - } + #[inline] + #[deprecated(note = "use `new` instead")] + #[doc(hidden)] + pub const fn try_from_u8(opcode: u8) -> Option { + Self::new(opcode) + } + + #[inline] + #[deprecated(note = "use `get` instead")] + #[doc(hidden)] + pub const fn u8(self) -> u8 { + self.get() } } -pub const OPCODE_JUMPMAP: [Option<&'static str>; 256] = [ - /* 0x00 */ Some("STOP"), - /* 0x01 */ Some("ADD"), - /* 0x02 */ Some("MUL"), - /* 0x03 */ Some("SUB"), - /* 0x04 */ Some("DIV"), - /* 0x05 */ Some("SDIV"), - /* 0x06 */ Some("MOD"), - /* 0x07 */ Some("SMOD"), - /* 0x08 */ Some("ADDMOD"), - /* 0x09 */ Some("MULMOD"), - /* 0x0a */ Some("EXP"), - /* 0x0b */ Some("SIGNEXTEND"), - /* 0x0c */ None, - /* 0x0d */ None, - /* 0x0e */ None, - /* 0x0f */ None, - /* 0x10 */ Some("LT"), - /* 0x11 */ Some("GT"), - /* 0x12 */ Some("SLT"), - /* 0x13 */ Some("SGT"), - /* 0x14 */ Some("EQ"), - /* 0x15 */ Some("ISZERO"), - /* 0x16 */ Some("AND"), - /* 0x17 */ Some("OR"), - /* 0x18 */ Some("XOR"), - /* 0x19 */ Some("NOT"), - /* 0x1a */ Some("BYTE"), - /* 0x1b */ Some("SHL"), - /* 0x1c */ Some("SHR"), - /* 0x1d */ Some("SAR"), - /* 0x1e */ None, - /* 0x1f */ None, - /* 0x20 */ Some("KECCAK256"), - /* 0x21 */ None, - /* 0x22 */ None, - /* 0x23 */ None, - /* 0x24 */ None, - /* 0x25 */ None, - /* 0x26 */ None, - /* 0x27 */ None, - /* 0x28 */ None, - /* 0x29 */ None, - /* 0x2a */ None, - /* 0x2b */ None, - /* 0x2c */ None, - /* 0x2d */ None, - /* 0x2e */ None, - /* 0x2f */ None, - /* 0x30 */ Some("ADDRESS"), - /* 0x31 */ Some("BALANCE"), - /* 0x32 */ Some("ORIGIN"), - /* 0x33 */ Some("CALLER"), - /* 0x34 */ Some("CALLVALUE"), - /* 0x35 */ Some("CALLDATALOAD"), - /* 0x36 */ Some("CALLDATASIZE"), - /* 0x37 */ Some("CALLDATACOPY"), - /* 0x38 */ Some("CODESIZE"), - /* 0x39 */ Some("CODECOPY"), - /* 0x3a */ Some("GASPRICE"), - /* 0x3b */ Some("EXTCODESIZE"), - /* 0x3c */ Some("EXTCODECOPY"), - /* 0x3d */ Some("RETURNDATASIZE"), - /* 0x3e */ Some("RETURNDATACOPY"), - /* 0x3f */ Some("EXTCODEHASH"), - /* 0x40 */ Some("BLOCKHASH"), - /* 0x41 */ Some("COINBASE"), - /* 0x42 */ Some("TIMESTAMP"), - /* 0x43 */ Some("NUMBER"), - /* 0x44 */ Some("DIFFICULTY"), - /* 0x45 */ Some("GASLIMIT"), - /* 0x46 */ Some("CHAINID"), - /* 0x47 */ Some("SELFBALANCE"), - /* 0x48 */ Some("BASEFEE"), - /* 0x49 */ None, - /* 0x4a */ None, - /* 0x4b */ None, - /* 0x4c */ None, - /* 0x4d */ None, - /* 0x4e */ None, - /* 0x4f */ None, - /* 0x50 */ Some("POP"), - /* 0x51 */ Some("MLOAD"), - /* 0x52 */ Some("MSTORE"), - /* 0x53 */ Some("MSTORE8"), - /* 0x54 */ Some("SLOAD"), - /* 0x55 */ Some("SSTORE"), - /* 0x56 */ Some("JUMP"), - /* 0x57 */ Some("JUMPI"), - /* 0x58 */ Some("PC"), - /* 0x59 */ Some("MSIZE"), - /* 0x5a */ Some("GAS"), - /* 0x5b */ Some("JUMPDEST"), - /* 0x5c */ Some("TLOAD"), - /* 0x5d */ Some("TSTORE"), - /* 0x5e */ Some("MCOPY"), - /* 0x5f */ Some("PUSH0"), - /* 0x60 */ Some("PUSH1"), - /* 0x61 */ Some("PUSH2"), - /* 0x62 */ Some("PUSH3"), - /* 0x63 */ Some("PUSH4"), - /* 0x64 */ Some("PUSH5"), - /* 0x65 */ Some("PUSH6"), - /* 0x66 */ Some("PUSH7"), - /* 0x67 */ Some("PUSH8"), - /* 0x68 */ Some("PUSH9"), - /* 0x69 */ Some("PUSH10"), - /* 0x6a */ Some("PUSH11"), - /* 0x6b */ Some("PUSH12"), - /* 0x6c */ Some("PUSH13"), - /* 0x6d */ Some("PUSH14"), - /* 0x6e */ Some("PUSH15"), - /* 0x6f */ Some("PUSH16"), - /* 0x70 */ Some("PUSH17"), - /* 0x71 */ Some("PUSH18"), - /* 0x72 */ Some("PUSH19"), - /* 0x73 */ Some("PUSH20"), - /* 0x74 */ Some("PUSH21"), - /* 0x75 */ Some("PUSH22"), - /* 0x76 */ Some("PUSH23"), - /* 0x77 */ Some("PUSH24"), - /* 0x78 */ Some("PUSH25"), - /* 0x79 */ Some("PUSH26"), - /* 0x7a */ Some("PUSH27"), - /* 0x7b */ Some("PUSH28"), - /* 0x7c */ Some("PUSH29"), - /* 0x7d */ Some("PUSH30"), - /* 0x7e */ Some("PUSH31"), - /* 0x7f */ Some("PUSH32"), - /* 0x80 */ Some("DUP1"), - /* 0x81 */ Some("DUP2"), - /* 0x82 */ Some("DUP3"), - /* 0x83 */ Some("DUP4"), - /* 0x84 */ Some("DUP5"), - /* 0x85 */ Some("DUP6"), - /* 0x86 */ Some("DUP7"), - /* 0x87 */ Some("DUP8"), - /* 0x88 */ Some("DUP9"), - /* 0x89 */ Some("DUP10"), - /* 0x8a */ Some("DUP11"), - /* 0x8b */ Some("DUP12"), - /* 0x8c */ Some("DUP13"), - /* 0x8d */ Some("DUP14"), - /* 0x8e */ Some("DUP15"), - /* 0x8f */ Some("DUP16"), - /* 0x90 */ Some("SWAP1"), - /* 0x91 */ Some("SWAP2"), - /* 0x92 */ Some("SWAP3"), - /* 0x93 */ Some("SWAP4"), - /* 0x94 */ Some("SWAP5"), - /* 0x95 */ Some("SWAP6"), - /* 0x96 */ Some("SWAP7"), - /* 0x97 */ Some("SWAP8"), - /* 0x98 */ Some("SWAP9"), - /* 0x99 */ Some("SWAP10"), - /* 0x9a */ Some("SWAP11"), - /* 0x9b */ Some("SWAP12"), - /* 0x9c */ Some("SWAP13"), - /* 0x9d */ Some("SWAP14"), - /* 0x9e */ Some("SWAP15"), - /* 0x9f */ Some("SWAP16"), - /* 0xa0 */ Some("LOG0"), - /* 0xa1 */ Some("LOG1"), - /* 0xa2 */ Some("LOG2"), - /* 0xa3 */ Some("LOG3"), - /* 0xa4 */ Some("LOG4"), - /* 0xa5 */ None, - /* 0xa6 */ None, - /* 0xa7 */ None, - /* 0xa8 */ None, - /* 0xa9 */ None, - /* 0xaa */ None, - /* 0xab */ None, - /* 0xac */ None, - /* 0xad */ None, - /* 0xae */ None, - /* 0xaf */ None, - /* 0xb0 */ None, - /* 0xb1 */ None, - /* 0xb2 */ None, - /* 0xb3 */ None, - /* 0xb4 */ None, - /* 0xb5 */ None, - /* 0xb6 */ None, - /* 0xb7 */ None, - /* 0xb8 */ None, - /* 0xb9 */ None, - /* 0xba */ None, - /* 0xbb */ None, - /* 0xbc */ None, - /* 0xbd */ None, - /* 0xbe */ None, - /* 0xbf */ None, - /* 0xc0 */ None, - /* 0xc1 */ None, - /* 0xc2 */ None, - /* 0xc3 */ None, - /* 0xc4 */ None, - /* 0xc5 */ None, - /* 0xc6 */ None, - /* 0xc7 */ None, - /* 0xc8 */ None, - /* 0xc9 */ None, - /* 0xca */ None, - /* 0xcb */ None, - /* 0xcc */ None, - /* 0xcd */ None, - /* 0xce */ None, - /* 0xcf */ None, - /* 0xd0 */ None, - /* 0xd1 */ None, - /* 0xd2 */ None, - /* 0xd3 */ None, - /* 0xd4 */ None, - /* 0xd5 */ None, - /* 0xd6 */ None, - /* 0xd7 */ None, - /* 0xd8 */ None, - /* 0xd9 */ None, - /* 0xda */ None, - /* 0xdb */ None, - /* 0xdc */ None, - /* 0xdd */ None, - /* 0xde */ None, - /* 0xdf */ None, - /* 0xe0 */ None, - /* 0xe1 */ None, - /* 0xe2 */ None, - /* 0xe3 */ None, - /* 0xe4 */ None, - /* 0xe5 */ None, - /* 0xe6 */ None, - /* 0xe7 */ None, - /* 0xe8 */ None, - /* 0xe9 */ None, - /* 0xea */ None, - /* 0xeb */ None, - /* 0xec */ None, - /* 0xed */ None, - /* 0xee */ None, - /* 0xef */ None, - /* 0xf0 */ Some("CREATE"), - /* 0xf1 */ Some("CALL"), - /* 0xf2 */ Some("CALLCODE"), - /* 0xf3 */ Some("RETURN"), - /* 0xf4 */ Some("DELEGATECALL"), - /* 0xf5 */ Some("CREATE2"), - /* 0xf6 */ None, - /* 0xf7 */ None, - /* 0xf8 */ None, - /* 0xf9 */ None, - /* 0xfa */ Some("STATICCALL"), - /* 0xfb */ None, - /* 0xfc */ None, - /* 0xfd */ Some("REVERT"), - /* 0xfe */ Some("INVALID"), - /* 0xff */ Some("SELFDESTRUCT"), -]; - -#[derive(Debug)] +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct OpInfo { /// Data contains few information packed inside u32: /// IS_JUMP (1bit) | IS_GAS_BLOCK_END (1bit) | IS_PUSH (1bit) | gas (29bits) @@ -460,469 +298,336 @@ const IS_PUSH_MASK: u32 = 0x20000000; const GAS_MASK: u32 = 0x1FFFFFFF; impl OpInfo { - #[inline(always)] - pub fn is_jump(&self) -> bool { - self.data & JUMP_MASK == JUMP_MASK - } - #[inline(always)] - pub fn is_gas_block_end(&self) -> bool { - self.data & GAS_BLOCK_END_MASK == GAS_BLOCK_END_MASK - } - #[inline(always)] - pub fn is_push(&self) -> bool { - self.data & IS_PUSH_MASK == IS_PUSH_MASK - } - - #[inline(always)] - pub fn get_gas(&self) -> u32 { - self.data & GAS_MASK + /// Creates a new empty [`OpInfo`]. + pub const fn none() -> Self { + Self { data: 0 } } - pub const fn none() -> Self { + /// Creates a new dynamic gas [`OpInfo`]. + pub const fn dynamic_gas() -> Self { Self { data: 0 } } + /// Creates a new gas block end [`OpInfo`]. pub const fn gas_block_end(gas: u64) -> Self { Self { data: gas as u32 | GAS_BLOCK_END_MASK, } } - pub const fn dynamic_gas() -> Self { - Self { data: 0 } - } + /// Creates a new [`OpInfo`] with the given gas value. pub const fn gas(gas: u64) -> Self { Self { data: gas as u32 } } + + /// Creates a new push [`OpInfo`]. pub const fn push_opcode() -> Self { Self { data: gas::VERYLOW as u32 | IS_PUSH_MASK, } } + /// Creates a new jumpdest [`OpInfo`]. pub const fn jumpdest() -> Self { Self { data: JUMP_MASK | GAS_BLOCK_END_MASK, } } + + /// Returns whether the opcode is a jump. + #[inline] + pub fn is_jump(self) -> bool { + self.data & JUMP_MASK == JUMP_MASK + } + + /// Returns whether the opcode is a gas block end. + #[inline] + pub fn is_gas_block_end(self) -> bool { + self.data & GAS_BLOCK_END_MASK == GAS_BLOCK_END_MASK + } + + /// Returns whether the opcode is a push. + #[inline] + pub fn is_push(self) -> bool { + self.data & IS_PUSH_MASK == IS_PUSH_MASK + } + + /// Returns the gas cost of the opcode. + #[inline] + pub fn get_gas(self) -> u32 { + self.data & GAS_MASK + } } -macro_rules! gas_opcodee { - ($name:ident, $spec_id:expr) => { - const $name: &'static [OpInfo; 256] = &[ - /* 0x00 STOP */ OpInfo::gas_block_end(0), - /* 0x01 ADD */ OpInfo::gas(gas::VERYLOW), - /* 0x02 MUL */ OpInfo::gas(gas::LOW), - /* 0x03 SUB */ OpInfo::gas(gas::VERYLOW), - /* 0x04 DIV */ OpInfo::gas(gas::LOW), - /* 0x05 SDIV */ OpInfo::gas(gas::LOW), - /* 0x06 MOD */ OpInfo::gas(gas::LOW), - /* 0x07 SMOD */ OpInfo::gas(gas::LOW), - /* 0x08 ADDMOD */ OpInfo::gas(gas::MID), - /* 0x09 MULMOD */ OpInfo::gas(gas::MID), - /* 0x0a EXP */ OpInfo::dynamic_gas(), - /* 0x0b SIGNEXTEND */ OpInfo::gas(gas::LOW), - /* 0x0c */ OpInfo::none(), - /* 0x0d */ OpInfo::none(), - /* 0x0e */ OpInfo::none(), - /* 0x0f */ OpInfo::none(), - /* 0x10 LT */ OpInfo::gas(gas::VERYLOW), - /* 0x11 GT */ OpInfo::gas(gas::VERYLOW), - /* 0x12 SLT */ OpInfo::gas(gas::VERYLOW), - /* 0x13 SGT */ OpInfo::gas(gas::VERYLOW), - /* 0x14 EQ */ OpInfo::gas(gas::VERYLOW), - /* 0x15 ISZERO */ OpInfo::gas(gas::VERYLOW), - /* 0x16 AND */ OpInfo::gas(gas::VERYLOW), - /* 0x17 OR */ OpInfo::gas(gas::VERYLOW), - /* 0x18 XOR */ OpInfo::gas(gas::VERYLOW), - /* 0x19 NOT */ OpInfo::gas(gas::VERYLOW), - /* 0x1a BYTE */ OpInfo::gas(gas::VERYLOW), - /* 0x1b SHL */ - OpInfo::gas(if SpecId::enabled($spec_id, SpecId::CONSTANTINOPLE) { - gas::VERYLOW - } else { - 0 - }), - /* 0x1c SHR */ - OpInfo::gas(if SpecId::enabled($spec_id, SpecId::CONSTANTINOPLE) { - gas::VERYLOW - } else { - 0 - }), - /* 0x1d SAR */ - OpInfo::gas(if SpecId::enabled($spec_id, SpecId::CONSTANTINOPLE) { - gas::VERYLOW - } else { - 0 - }), - /* 0x1e */ OpInfo::none(), - /* 0x1f */ OpInfo::none(), - /* 0x20 KECCAK256 */ OpInfo::dynamic_gas(), - /* 0x21 */ OpInfo::none(), - /* 0x22 */ OpInfo::none(), - /* 0x23 */ OpInfo::none(), - /* 0x24 */ OpInfo::none(), - /* 0x25 */ OpInfo::none(), - /* 0x26 */ OpInfo::none(), - /* 0x27 */ OpInfo::none(), - /* 0x28 */ OpInfo::none(), - /* 0x29 */ OpInfo::none(), - /* 0x2a */ OpInfo::none(), - /* 0x2b */ OpInfo::none(), - /* 0x2c */ OpInfo::none(), - /* 0x2d */ OpInfo::none(), - /* 0x2e */ OpInfo::none(), - /* 0x2f */ OpInfo::none(), - /* 0x30 ADDRESS */ OpInfo::gas(gas::BASE), - /* 0x31 BALANCE */ OpInfo::dynamic_gas(), - /* 0x32 ORIGIN */ OpInfo::gas(gas::BASE), - /* 0x33 CALLER */ OpInfo::gas(gas::BASE), - /* 0x34 CALLVALUE */ OpInfo::gas(gas::BASE), - /* 0x35 CALLDATALOAD */ OpInfo::gas(gas::VERYLOW), - /* 0x36 CALLDATASIZE */ OpInfo::gas(gas::BASE), - /* 0x37 CALLDATACOPY */ OpInfo::dynamic_gas(), - /* 0x38 CODESIZE */ OpInfo::gas(gas::BASE), - /* 0x39 CODECOPY */ OpInfo::dynamic_gas(), - /* 0x3a GASPRICE */ OpInfo::gas(gas::BASE), - /* 0x3b EXTCODESIZE */ - OpInfo::gas(if SpecId::enabled($spec_id, SpecId::BERLIN) { - gas::WARM_STORAGE_READ_COST // add only part of gas - } else if SpecId::enabled($spec_id, SpecId::TANGERINE) { - 700 - } else { - 20 - }), - /* 0x3c EXTCODECOPY */ - OpInfo::gas(if SpecId::enabled($spec_id, SpecId::BERLIN) { - gas::WARM_STORAGE_READ_COST // add only part of gas - } else if SpecId::enabled($spec_id, SpecId::TANGERINE) { - 700 - } else { - 20 - }), - /* 0x3d RETURNDATASIZE */ - OpInfo::gas(if SpecId::enabled($spec_id, SpecId::BYZANTIUM) { - gas::BASE - } else { - 0 - }), - /* 0x3e RETURNDATACOPY */ OpInfo::dynamic_gas(), - /* 0x3f EXTCODEHASH */ - OpInfo::gas(if SpecId::enabled($spec_id, SpecId::BERLIN) { - gas::WARM_STORAGE_READ_COST // add only part of gas - } else if SpecId::enabled($spec_id, SpecId::ISTANBUL) { - 700 - } else if SpecId::enabled($spec_id, SpecId::PETERSBURG) { - // constantinople - 400 - } else { - 0 // not enabled - }), - /* 0x40 BLOCKHASH */ OpInfo::gas(gas::BLOCKHASH), - /* 0x41 COINBASE */ OpInfo::gas(gas::BASE), - /* 0x42 TIMESTAMP */ OpInfo::gas(gas::BASE), - /* 0x43 NUMBER */ OpInfo::gas(gas::BASE), - /* 0x44 DIFFICULTY */ OpInfo::gas(gas::BASE), - /* 0x45 GASLIMIT */ OpInfo::gas(gas::BASE), - /* 0x46 CHAINID */ - OpInfo::gas(if SpecId::enabled($spec_id, SpecId::ISTANBUL) { - gas::BASE - } else { - 0 - }), - /* 0x47 SELFBALANCE */ - OpInfo::gas(if SpecId::enabled($spec_id, SpecId::ISTANBUL) { - gas::LOW - } else { - 0 - }), - /* 0x48 BASEFEE */ - OpInfo::gas(if SpecId::enabled($spec_id, SpecId::LONDON) { - gas::BASE - } else { - 0 - }), - /* 0x49 */ OpInfo::none(), - /* 0x4a */ OpInfo::none(), - /* 0x4b */ OpInfo::none(), - /* 0x4c */ OpInfo::none(), - /* 0x4d */ OpInfo::none(), - /* 0x4e */ OpInfo::none(), - /* 0x4f */ OpInfo::none(), - /* 0x50 POP */ OpInfo::gas(gas::BASE), - /* 0x51 MLOAD */ OpInfo::gas(gas::VERYLOW), - /* 0x52 MSTORE */ OpInfo::gas(gas::VERYLOW), - /* 0x53 MSTORE8 */ OpInfo::gas(gas::VERYLOW), - /* 0x54 SLOAD */ OpInfo::dynamic_gas(), - /* 0x55 SSTORE */ OpInfo::gas_block_end(0), - /* 0x56 JUMP */ OpInfo::gas_block_end(gas::MID), - /* 0x57 JUMPI */ OpInfo::gas_block_end(gas::HIGH), - /* 0x58 PC */ OpInfo::gas(gas::BASE), - /* 0x59 MSIZE */ OpInfo::gas(gas::BASE), - /* 0x5a GAS */ OpInfo::gas_block_end(gas::BASE), - /* 0x5b JUMPDEST */ - // gas::JUMPDEST gas is calculated in function call, - OpInfo::jumpdest(), - /* 0x5c TLOAD */ - OpInfo::gas(if SpecId::enabled($spec_id, SpecId::CANCUN) { - gas::WARM_STORAGE_READ_COST - } else { - 0 - }), - /* 0x5d TSTORE */ - OpInfo::gas(if SpecId::enabled($spec_id, SpecId::CANCUN) { - gas::WARM_STORAGE_READ_COST - } else { - 0 - }), - /* 0x5e MCOPY */ OpInfo::dynamic_gas(), - /* 0x5f PUSH0 */ - OpInfo::gas(if SpecId::enabled($spec_id, SpecId::SHANGHAI) { - gas::BASE - } else { - 0 - }), - /* 0x60 PUSH1 */ OpInfo::push_opcode(), - /* 0x61 PUSH2 */ OpInfo::push_opcode(), - /* 0x62 PUSH3 */ OpInfo::push_opcode(), - /* 0x63 PUSH4 */ OpInfo::push_opcode(), - /* 0x64 PUSH5 */ OpInfo::push_opcode(), - /* 0x65 PUSH6 */ OpInfo::push_opcode(), - /* 0x66 PUSH7 */ OpInfo::push_opcode(), - /* 0x67 PUSH8 */ OpInfo::push_opcode(), - /* 0x68 PUSH9 */ OpInfo::push_opcode(), - /* 0x69 PUSH10 */ OpInfo::push_opcode(), - /* 0x6a PUSH11 */ OpInfo::push_opcode(), - /* 0x6b PUSH12 */ OpInfo::push_opcode(), - /* 0x6c PUSH13 */ OpInfo::push_opcode(), - /* 0x6d PUSH14 */ OpInfo::push_opcode(), - /* 0x6e PUSH15 */ OpInfo::push_opcode(), - /* 0x6f PUSH16 */ OpInfo::push_opcode(), - /* 0x70 PUSH17 */ OpInfo::push_opcode(), - /* 0x71 PUSH18 */ OpInfo::push_opcode(), - /* 0x72 PUSH19 */ OpInfo::push_opcode(), - /* 0x73 PUSH20 */ OpInfo::push_opcode(), - /* 0x74 PUSH21 */ OpInfo::push_opcode(), - /* 0x75 PUSH22 */ OpInfo::push_opcode(), - /* 0x76 PUSH23 */ OpInfo::push_opcode(), - /* 0x77 PUSH24 */ OpInfo::push_opcode(), - /* 0x78 PUSH25 */ OpInfo::push_opcode(), - /* 0x79 PUSH26 */ OpInfo::push_opcode(), - /* 0x7a PUSH27 */ OpInfo::push_opcode(), - /* 0x7b PUSH28 */ OpInfo::push_opcode(), - /* 0x7c PUSH29 */ OpInfo::push_opcode(), - /* 0x7d PUSH30 */ OpInfo::push_opcode(), - /* 0x7e PUSH31 */ OpInfo::push_opcode(), - /* 0x7f PUSH32 */ OpInfo::push_opcode(), - /* 0x80 DUP1 */ OpInfo::gas(gas::VERYLOW), - /* 0x81 DUP2 */ OpInfo::gas(gas::VERYLOW), - /* 0x82 DUP3 */ OpInfo::gas(gas::VERYLOW), - /* 0x83 DUP4 */ OpInfo::gas(gas::VERYLOW), - /* 0x84 DUP5 */ OpInfo::gas(gas::VERYLOW), - /* 0x85 DUP6 */ OpInfo::gas(gas::VERYLOW), - /* 0x86 DUP7 */ OpInfo::gas(gas::VERYLOW), - /* 0x87 DUP8 */ OpInfo::gas(gas::VERYLOW), - /* 0x88 DUP9 */ OpInfo::gas(gas::VERYLOW), - /* 0x89 DUP10 */ OpInfo::gas(gas::VERYLOW), - /* 0x8a DUP11 */ OpInfo::gas(gas::VERYLOW), - /* 0x8b DUP12 */ OpInfo::gas(gas::VERYLOW), - /* 0x8c DUP13 */ OpInfo::gas(gas::VERYLOW), - /* 0x8d DUP14 */ OpInfo::gas(gas::VERYLOW), - /* 0x8e DUP15 */ OpInfo::gas(gas::VERYLOW), - /* 0x8f DUP16 */ OpInfo::gas(gas::VERYLOW), - /* 0x90 SWAP1 */ OpInfo::gas(gas::VERYLOW), - /* 0x91 SWAP2 */ OpInfo::gas(gas::VERYLOW), - /* 0x92 SWAP3 */ OpInfo::gas(gas::VERYLOW), - /* 0x93 SWAP4 */ OpInfo::gas(gas::VERYLOW), - /* 0x94 SWAP5 */ OpInfo::gas(gas::VERYLOW), - /* 0x95 SWAP6 */ OpInfo::gas(gas::VERYLOW), - /* 0x96 SWAP7 */ OpInfo::gas(gas::VERYLOW), - /* 0x97 SWAP8 */ OpInfo::gas(gas::VERYLOW), - /* 0x98 SWAP9 */ OpInfo::gas(gas::VERYLOW), - /* 0x99 SWAP10 */ OpInfo::gas(gas::VERYLOW), - /* 0x9a SWAP11 */ OpInfo::gas(gas::VERYLOW), - /* 0x9b SWAP12 */ OpInfo::gas(gas::VERYLOW), - /* 0x9c SWAP13 */ OpInfo::gas(gas::VERYLOW), - /* 0x9d SWAP14 */ OpInfo::gas(gas::VERYLOW), - /* 0x9e SWAP15 */ OpInfo::gas(gas::VERYLOW), - /* 0x9f SWAP16 */ OpInfo::gas(gas::VERYLOW), - /* 0xa0 LOG0 */ OpInfo::dynamic_gas(), - /* 0xa1 LOG1 */ OpInfo::dynamic_gas(), - /* 0xa2 LOG2 */ OpInfo::dynamic_gas(), - /* 0xa3 LOG3 */ OpInfo::dynamic_gas(), - /* 0xa4 LOG4 */ OpInfo::dynamic_gas(), - /* 0xa5 */ OpInfo::none(), - /* 0xa6 */ OpInfo::none(), - /* 0xa7 */ OpInfo::none(), - /* 0xa8 */ OpInfo::none(), - /* 0xa9 */ OpInfo::none(), - /* 0xaa */ OpInfo::none(), - /* 0xab */ OpInfo::none(), - /* 0xac */ OpInfo::none(), - /* 0xad */ OpInfo::none(), - /* 0xae */ OpInfo::none(), - /* 0xaf */ OpInfo::none(), - /* 0xb0 */ OpInfo::none(), - /* 0xb1 */ OpInfo::none(), - /* 0xb2 */ OpInfo::none(), - /* 0xb3 */ OpInfo::none(), - /* 0xb4 */ OpInfo::none(), - /* 0xb5 */ OpInfo::none(), - /* 0xb6 */ OpInfo::none(), - /* 0xb7 */ OpInfo::none(), - /* 0xb8 */ OpInfo::none(), - /* 0xb9 */ OpInfo::none(), - /* 0xba */ OpInfo::none(), - /* 0xbb */ OpInfo::none(), - /* 0xbc */ OpInfo::none(), - /* 0xbd */ OpInfo::none(), - /* 0xbe */ OpInfo::none(), - /* 0xbf */ OpInfo::none(), - /* 0xc0 */ OpInfo::none(), - /* 0xc1 */ OpInfo::none(), - /* 0xc2 */ OpInfo::none(), - /* 0xc3 */ OpInfo::none(), - /* 0xc4 */ OpInfo::none(), - /* 0xc5 */ OpInfo::none(), - /* 0xc6 */ OpInfo::none(), - /* 0xc7 */ OpInfo::none(), - /* 0xc8 */ OpInfo::none(), - /* 0xc9 */ OpInfo::none(), - /* 0xca */ OpInfo::none(), - /* 0xcb */ OpInfo::none(), - /* 0xcc */ OpInfo::none(), - /* 0xcd */ OpInfo::none(), - /* 0xce */ OpInfo::none(), - /* 0xcf */ OpInfo::none(), - /* 0xd0 */ OpInfo::none(), - /* 0xd1 */ OpInfo::none(), - /* 0xd2 */ OpInfo::none(), - /* 0xd3 */ OpInfo::none(), - /* 0xd4 */ OpInfo::none(), - /* 0xd5 */ OpInfo::none(), - /* 0xd6 */ OpInfo::none(), - /* 0xd7 */ OpInfo::none(), - /* 0xd8 */ OpInfo::none(), - /* 0xd9 */ OpInfo::none(), - /* 0xda */ OpInfo::none(), - /* 0xdb */ OpInfo::none(), - /* 0xdc */ OpInfo::none(), - /* 0xdd */ OpInfo::none(), - /* 0xde */ OpInfo::none(), - /* 0xdf */ OpInfo::none(), - /* 0xe0 */ OpInfo::none(), - /* 0xe1 */ OpInfo::none(), - /* 0xe2 */ OpInfo::none(), - /* 0xe3 */ OpInfo::none(), - /* 0xe4 */ OpInfo::none(), - /* 0xe5 */ OpInfo::none(), - /* 0xe6 */ OpInfo::none(), - /* 0xe7 */ OpInfo::none(), - /* 0xe8 */ OpInfo::none(), - /* 0xe9 */ OpInfo::none(), - /* 0xea */ OpInfo::none(), - /* 0xeb */ OpInfo::none(), - /* 0xec */ OpInfo::none(), - /* 0xed */ OpInfo::none(), - /* 0xee */ OpInfo::none(), - /* 0xef */ OpInfo::none(), - /* 0xf0 CREATE */ OpInfo::gas_block_end(0), - /* 0xf1 CALL */ OpInfo::gas_block_end(0), - /* 0xf2 CALLCODE */ OpInfo::gas_block_end(0), - /* 0xf3 RETURN */ OpInfo::gas_block_end(0), - /* 0xf4 DELEGATECALL */ OpInfo::gas_block_end(0), - /* 0xf5 CREATE2 */ OpInfo::gas_block_end(0), - /* 0xf6 */ OpInfo::none(), - /* 0xf7 */ OpInfo::none(), - /* 0xf8 */ OpInfo::none(), - /* 0xf9 */ OpInfo::none(), - /* 0xfa STATICCALL */ OpInfo::gas_block_end(0), - /* 0xfb */ OpInfo::none(), - /* 0xfc */ OpInfo::none(), - /* 0xfd REVERT */ OpInfo::gas_block_end(0), - /* 0xfe INVALID */ OpInfo::gas_block_end(0), - /* 0xff SELFDESTRUCT */ OpInfo::gas_block_end(0), - ]; - }; +const fn opcode_gas_info(opcode: u8, spec: SpecId) -> OpInfo { + match opcode { + STOP => OpInfo::gas_block_end(0), + ADD => OpInfo::gas(gas::VERYLOW), + MUL => OpInfo::gas(gas::LOW), + SUB => OpInfo::gas(gas::VERYLOW), + DIV => OpInfo::gas(gas::LOW), + SDIV => OpInfo::gas(gas::LOW), + MOD => OpInfo::gas(gas::LOW), + SMOD => OpInfo::gas(gas::LOW), + ADDMOD => OpInfo::gas(gas::MID), + MULMOD => OpInfo::gas(gas::MID), + EXP => OpInfo::dynamic_gas(), + SIGNEXTEND => OpInfo::gas(gas::LOW), + + LT => OpInfo::gas(gas::VERYLOW), + GT => OpInfo::gas(gas::VERYLOW), + SLT => OpInfo::gas(gas::VERYLOW), + SGT => OpInfo::gas(gas::VERYLOW), + EQ => OpInfo::gas(gas::VERYLOW), + ISZERO => OpInfo::gas(gas::VERYLOW), + AND => OpInfo::gas(gas::VERYLOW), + OR => OpInfo::gas(gas::VERYLOW), + XOR => OpInfo::gas(gas::VERYLOW), + NOT => OpInfo::gas(gas::VERYLOW), + BYTE => OpInfo::gas(gas::VERYLOW), + SHL => OpInfo::gas(if SpecId::enabled(spec, SpecId::CONSTANTINOPLE) { + gas::VERYLOW + } else { + 0 + }), + SHR => OpInfo::gas(if SpecId::enabled(spec, SpecId::CONSTANTINOPLE) { + gas::VERYLOW + } else { + 0 + }), + SAR => OpInfo::gas(if SpecId::enabled(spec, SpecId::CONSTANTINOPLE) { + gas::VERYLOW + } else { + 0 + }), + + KECCAK256 => OpInfo::dynamic_gas(), + + ADDRESS => OpInfo::gas(gas::BASE), + BALANCE => OpInfo::dynamic_gas(), + ORIGIN => OpInfo::gas(gas::BASE), + CALLER => OpInfo::gas(gas::BASE), + CALLVALUE => OpInfo::gas(gas::BASE), + CALLDATALOAD => OpInfo::gas(gas::VERYLOW), + CALLDATASIZE => OpInfo::gas(gas::BASE), + CALLDATACOPY => OpInfo::dynamic_gas(), + CODESIZE => OpInfo::gas(gas::BASE), + CODECOPY => OpInfo::dynamic_gas(), + GASPRICE => OpInfo::gas(gas::BASE), + EXTCODESIZE => OpInfo::gas(if SpecId::enabled(spec, SpecId::BERLIN) { + gas::WARM_STORAGE_READ_COST // add only part of gas + } else if SpecId::enabled(spec, SpecId::TANGERINE) { + 700 + } else { + 20 + }), + EXTCODECOPY => OpInfo::gas(if SpecId::enabled(spec, SpecId::BERLIN) { + gas::WARM_STORAGE_READ_COST // add only part of gas + } else if SpecId::enabled(spec, SpecId::TANGERINE) { + 700 + } else { + 20 + }), + RETURNDATASIZE => OpInfo::gas(if SpecId::enabled(spec, SpecId::BYZANTIUM) { + gas::BASE + } else { + 0 + }), + RETURNDATACOPY => OpInfo::dynamic_gas(), + EXTCODEHASH => OpInfo::gas(if SpecId::enabled(spec, SpecId::BERLIN) { + gas::WARM_STORAGE_READ_COST // add only part of gas + } else if SpecId::enabled(spec, SpecId::ISTANBUL) { + 700 + } else if SpecId::enabled(spec, SpecId::PETERSBURG) { + 400 // constantinople + } else { + 0 // not enabled + }), + BLOCKHASH => OpInfo::gas(gas::BLOCKHASH), + COINBASE => OpInfo::gas(gas::BASE), + TIMESTAMP => OpInfo::gas(gas::BASE), + NUMBER => OpInfo::gas(gas::BASE), + DIFFICULTY => OpInfo::gas(gas::BASE), + GASLIMIT => OpInfo::gas(gas::BASE), + CHAINID => OpInfo::gas(if SpecId::enabled(spec, SpecId::ISTANBUL) { + gas::BASE + } else { + 0 + }), + SELFBALANCE => OpInfo::gas(if SpecId::enabled(spec, SpecId::ISTANBUL) { + gas::LOW + } else { + 0 + }), + BASEFEE => OpInfo::gas(if SpecId::enabled(spec, SpecId::LONDON) { + gas::BASE + } else { + 0 + }), + + POP => OpInfo::gas(gas::BASE), + MLOAD => OpInfo::gas(gas::VERYLOW), + MSTORE => OpInfo::gas(gas::VERYLOW), + MSTORE8 => OpInfo::gas(gas::VERYLOW), + SLOAD => OpInfo::dynamic_gas(), + SSTORE => OpInfo::gas_block_end(0), + JUMP => OpInfo::gas_block_end(gas::MID), + JUMPI => OpInfo::gas_block_end(gas::HIGH), + PC => OpInfo::gas(gas::BASE), + MSIZE => OpInfo::gas(gas::BASE), + GAS => OpInfo::gas_block_end(gas::BASE), + // gas::JUMPDEST gas is calculated in function call + JUMPDEST => OpInfo::jumpdest(), + TLOAD => OpInfo::gas(if SpecId::enabled(spec, SpecId::CANCUN) { + gas::WARM_STORAGE_READ_COST + } else { + 0 + }), + TSTORE => OpInfo::gas(if SpecId::enabled(spec, SpecId::CANCUN) { + gas::WARM_STORAGE_READ_COST + } else { + 0 + }), + MCOPY => OpInfo::dynamic_gas(), + + PUSH0 => OpInfo::gas(if SpecId::enabled(spec, SpecId::SHANGHAI) { + gas::BASE + } else { + 0 + }), + PUSH1 => OpInfo::push_opcode(), + PUSH2 => OpInfo::push_opcode(), + PUSH3 => OpInfo::push_opcode(), + PUSH4 => OpInfo::push_opcode(), + PUSH5 => OpInfo::push_opcode(), + PUSH6 => OpInfo::push_opcode(), + PUSH7 => OpInfo::push_opcode(), + PUSH8 => OpInfo::push_opcode(), + PUSH9 => OpInfo::push_opcode(), + PUSH10 => OpInfo::push_opcode(), + PUSH11 => OpInfo::push_opcode(), + PUSH12 => OpInfo::push_opcode(), + PUSH13 => OpInfo::push_opcode(), + PUSH14 => OpInfo::push_opcode(), + PUSH15 => OpInfo::push_opcode(), + PUSH16 => OpInfo::push_opcode(), + PUSH17 => OpInfo::push_opcode(), + PUSH18 => OpInfo::push_opcode(), + PUSH19 => OpInfo::push_opcode(), + PUSH20 => OpInfo::push_opcode(), + PUSH21 => OpInfo::push_opcode(), + PUSH22 => OpInfo::push_opcode(), + PUSH23 => OpInfo::push_opcode(), + PUSH24 => OpInfo::push_opcode(), + PUSH25 => OpInfo::push_opcode(), + PUSH26 => OpInfo::push_opcode(), + PUSH27 => OpInfo::push_opcode(), + PUSH28 => OpInfo::push_opcode(), + PUSH29 => OpInfo::push_opcode(), + PUSH30 => OpInfo::push_opcode(), + PUSH31 => OpInfo::push_opcode(), + PUSH32 => OpInfo::push_opcode(), + + DUP1 => OpInfo::gas(gas::VERYLOW), + DUP2 => OpInfo::gas(gas::VERYLOW), + DUP3 => OpInfo::gas(gas::VERYLOW), + DUP4 => OpInfo::gas(gas::VERYLOW), + DUP5 => OpInfo::gas(gas::VERYLOW), + DUP6 => OpInfo::gas(gas::VERYLOW), + DUP7 => OpInfo::gas(gas::VERYLOW), + DUP8 => OpInfo::gas(gas::VERYLOW), + DUP9 => OpInfo::gas(gas::VERYLOW), + DUP10 => OpInfo::gas(gas::VERYLOW), + DUP11 => OpInfo::gas(gas::VERYLOW), + DUP12 => OpInfo::gas(gas::VERYLOW), + DUP13 => OpInfo::gas(gas::VERYLOW), + DUP14 => OpInfo::gas(gas::VERYLOW), + DUP15 => OpInfo::gas(gas::VERYLOW), + DUP16 => OpInfo::gas(gas::VERYLOW), + + SWAP1 => OpInfo::gas(gas::VERYLOW), + SWAP2 => OpInfo::gas(gas::VERYLOW), + SWAP3 => OpInfo::gas(gas::VERYLOW), + SWAP4 => OpInfo::gas(gas::VERYLOW), + SWAP5 => OpInfo::gas(gas::VERYLOW), + SWAP6 => OpInfo::gas(gas::VERYLOW), + SWAP7 => OpInfo::gas(gas::VERYLOW), + SWAP8 => OpInfo::gas(gas::VERYLOW), + SWAP9 => OpInfo::gas(gas::VERYLOW), + SWAP10 => OpInfo::gas(gas::VERYLOW), + SWAP11 => OpInfo::gas(gas::VERYLOW), + SWAP12 => OpInfo::gas(gas::VERYLOW), + SWAP13 => OpInfo::gas(gas::VERYLOW), + SWAP14 => OpInfo::gas(gas::VERYLOW), + SWAP15 => OpInfo::gas(gas::VERYLOW), + SWAP16 => OpInfo::gas(gas::VERYLOW), + + LOG0 => OpInfo::dynamic_gas(), + LOG1 => OpInfo::dynamic_gas(), + LOG2 => OpInfo::dynamic_gas(), + LOG3 => OpInfo::dynamic_gas(), + LOG4 => OpInfo::dynamic_gas(), + + CREATE => OpInfo::gas_block_end(0), + CALL => OpInfo::gas_block_end(0), + CALLCODE => OpInfo::gas_block_end(0), + RETURN => OpInfo::gas_block_end(0), + DELEGATECALL => OpInfo::gas_block_end(0), + CREATE2 => OpInfo::gas_block_end(0), + + STATICCALL => OpInfo::gas_block_end(0), + + REVERT => OpInfo::gas_block_end(0), + INVALID => OpInfo::gas_block_end(0), + SELFDESTRUCT => OpInfo::gas_block_end(0), + + _ => OpInfo::none(), + } +} + +const fn make_gas_table(spec: SpecId) -> [OpInfo; 256] { + let mut table = [OpInfo::none(); 256]; + let mut i = 0; + while i < 256 { + table[i] = opcode_gas_info(i as u8, spec); + i += 1; + } + table } +/// Returns a lookup table of opcode gas info for the given [`SpecId`]. +#[inline] pub const fn spec_opcode_gas(spec_id: SpecId) -> &'static [OpInfo; 256] { - match spec_id { - SpecId::FRONTIER => { - gas_opcodee!(FRONTIER, SpecId::FRONTIER); - FRONTIER - } - SpecId::FRONTIER_THAWING => { - gas_opcodee!(FRONTIER_THAWING, SpecId::FRONTIER_THAWING); - FRONTIER_THAWING - } - SpecId::HOMESTEAD => { - gas_opcodee!(HOMESTEAD, SpecId::HOMESTEAD); - HOMESTEAD - } - SpecId::DAO_FORK => { - gas_opcodee!(DAO_FORK, SpecId::DAO_FORK); - DAO_FORK - } - SpecId::TANGERINE => { - gas_opcodee!(TANGERINE, SpecId::TANGERINE); - TANGERINE - } - SpecId::SPURIOUS_DRAGON => { - gas_opcodee!(SPURIOUS_DRAGON, SpecId::SPURIOUS_DRAGON); - SPURIOUS_DRAGON - } - SpecId::BYZANTIUM => { - gas_opcodee!(BYZANTIUM, SpecId::BYZANTIUM); - BYZANTIUM - } - SpecId::CONSTANTINOPLE => { - gas_opcodee!(CONSTANTINOPLE, SpecId::CONSTANTINOPLE); - CONSTANTINOPLE - } - SpecId::PETERSBURG => { - gas_opcodee!(PETERSBURG, SpecId::PETERSBURG); - PETERSBURG - } - SpecId::ISTANBUL => { - gas_opcodee!(ISTANBUL, SpecId::ISTANBUL); - ISTANBUL - } - SpecId::MUIR_GLACIER => { - gas_opcodee!(MUIRGLACIER, SpecId::MUIR_GLACIER); - MUIRGLACIER - } - SpecId::BERLIN => { - gas_opcodee!(BERLIN, SpecId::BERLIN); - BERLIN - } - SpecId::LONDON => { - gas_opcodee!(LONDON, SpecId::LONDON); - LONDON - } - SpecId::ARROW_GLACIER => { - gas_opcodee!(ARROW_GLACIER, SpecId::ARROW_GLACIER); - ARROW_GLACIER - } - SpecId::GRAY_GLACIER => { - gas_opcodee!(GRAY_GLACIER, SpecId::GRAY_GLACIER); - GRAY_GLACIER - } - SpecId::MERGE => { - gas_opcodee!(MERGE, SpecId::MERGE); - MERGE - } - SpecId::SHANGHAI => { - gas_opcodee!(SHANGAI, SpecId::SHANGHAI); - SHANGAI - } - SpecId::CANCUN => { - gas_opcodee!(CANCUN, SpecId::CANCUN); - CANCUN - } - SpecId::LATEST => { - gas_opcodee!(LATEST, SpecId::LATEST); - LATEST - } + macro_rules! gas_maps { + ($($id:ident),* $(,)?) => { + match spec_id {$( + SpecId::$id => { + const TABLE: &[OpInfo; 256] = &make_gas_table(SpecId::$id); + TABLE + } + )*} + }; } + + gas_maps!( + FRONTIER, + FRONTIER_THAWING, + HOMESTEAD, + DAO_FORK, + TANGERINE, + SPURIOUS_DRAGON, + BYZANTIUM, + CONSTANTINOPLE, + PETERSBURG, + ISTANBUL, + MUIR_GLACIER, + BERLIN, + LONDON, + ARROW_GLACIER, + GRAY_GLACIER, + MERGE, + SHANGHAI, + CANCUN, + LATEST, + ) } diff --git a/crates/interpreter/src/instructions/stack.rs b/crates/interpreter/src/instructions/stack.rs index 34b4c3f03d..9f9b737447 100644 --- a/crates/interpreter/src/instructions/stack.rs +++ b/crates/interpreter/src/instructions/stack.rs @@ -1,52 +1,48 @@ -use crate::gas; -use crate::InstructionResult; -use revm_primitives::{Spec, SpecId::SHANGHAI, U256}; +use super::prelude::*; -use crate::{interpreter::Interpreter, Host}; - -pub fn pop(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn pop(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::BASE); - if let Some(ret) = interpreter.stack.reduce_one() { - interpreter.instruction_result = ret; + if let Err(result) = interpreter.stack.pop() { + interpreter.instruction_result = result; } } -/// EIP-3855: PUSH0 instruction -/// Introduce a new instruction which pushes the constant value 0 onto the stack -pub fn push0(interpreter: &mut Interpreter, _host: &mut dyn Host) { - // EIP-3855: PUSH0 instruction - check!(interpreter, SPEC::enabled(SHANGHAI)); +/// EIP-3855: PUSH0 instruction +/// +/// Introduce a new instruction which pushes the constant value 0 onto the stack. +pub(super) fn push0(interpreter: &mut Interpreter, _host: &mut dyn Host) { + check!(interpreter, SHANGHAI); gas!(interpreter, gas::BASE); if let Err(result) = interpreter.stack.push(U256::ZERO) { interpreter.instruction_result = result; } } -pub fn push(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn push(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::VERYLOW); let start = interpreter.instruction_pointer; // Safety: In Analysis we appended needed bytes for bytecode so that we are safe to just add without // checking if it is out of bound. This makes both of our unsafes block safe to do. - if let Some(ret) = interpreter + if let Err(result) = interpreter .stack .push_slice::(unsafe { core::slice::from_raw_parts(start, N) }) { - interpreter.instruction_result = ret; + interpreter.instruction_result = result; return; } - interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.add(N) }; + interpreter.instruction_pointer = unsafe { start.add(N) }; } -pub fn dup(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn dup(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::VERYLOW); - if let Some(ret) = interpreter.stack.dup::() { - interpreter.instruction_result = ret; + if let Err(result) = interpreter.stack.dup::() { + interpreter.instruction_result = result; } } -pub fn swap(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn swap(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::VERYLOW); - if let Some(ret) = interpreter.stack.swap::() { - interpreter.instruction_result = ret; + if let Err(result) = interpreter.stack.swap::() { + interpreter.instruction_result = result; } } diff --git a/crates/interpreter/src/instructions/system.rs b/crates/interpreter/src/instructions/system.rs index a40a6c6cf5..2e09798b95 100644 --- a/crates/interpreter/src/instructions/system.rs +++ b/crates/interpreter/src/instructions/system.rs @@ -1,53 +1,43 @@ -use crate::{ - gas, - interpreter::Interpreter, - primitives::{keccak256, Spec, SpecId::*, B256, KECCAK_EMPTY, U256}, - Host, InstructionResult, -}; -use core::cmp::min; - -pub fn calculate_keccak256(interpreter: &mut Interpreter, _host: &mut dyn Host) { +use super::prelude::*; + +pub(super) fn keccak256(interpreter: &mut Interpreter, _host: &mut dyn Host) { pop!(interpreter, from, len); - let len = as_usize_or_fail!(interpreter, len, InstructionResult::InvalidOperandOOG); + let len = as_usize_or_fail!(interpreter, len); gas_or_fail!(interpreter, gas::keccak256_cost(len as u64)); let hash = if len == 0 { KECCAK_EMPTY } else { - let from = as_usize_or_fail!(interpreter, from, InstructionResult::InvalidOperandOOG); + let from = as_usize_or_fail!(interpreter, from); memory_resize!(interpreter, from, len); - keccak256(interpreter.memory.get_slice(from, len)) + crate::primitives::keccak256(interpreter.memory.get_slice(from, len)) }; push_b256!(interpreter, hash); } -pub fn address(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn address(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::BASE); push_b256!(interpreter, B256::from(interpreter.contract.address)); } -pub fn caller(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn caller(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::BASE); push_b256!(interpreter, B256::from(interpreter.contract.caller)); } -pub fn codesize(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn codesize(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::BASE); push!(interpreter, U256::from(interpreter.contract.bytecode.len())); } -pub fn codecopy(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn codecopy(interpreter: &mut Interpreter, _host: &mut dyn Host) { pop!(interpreter, memory_offset, code_offset, len); - let len = as_usize_or_fail!(interpreter, len, InstructionResult::InvalidOperandOOG); + let len = as_usize_or_fail!(interpreter, len); gas_or_fail!(interpreter, gas::verylowcopy_cost(len as u64)); if len == 0 { return; } - let memory_offset = as_usize_or_fail!( - interpreter, - memory_offset, - InstructionResult::InvalidOperandOOG - ); + let memory_offset = as_usize_or_fail!(interpreter, memory_offset); let code_offset = as_usize_saturated!(code_offset); memory_resize!(interpreter, memory_offset, len); @@ -60,45 +50,41 @@ pub fn codecopy(interpreter: &mut Interpreter, _host: &mut dyn Host) { ); } -pub fn calldataload(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn calldataload(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::VERYLOW); pop!(interpreter, index); let index = as_usize_saturated!(index); let load = if index < interpreter.contract.input.len() { - let have_bytes = min(interpreter.contract.input.len() - index, 32); + let n = 32.min(interpreter.contract.input.len() - index); let mut bytes = [0u8; 32]; - bytes[..have_bytes].copy_from_slice(&interpreter.contract.input[index..index + have_bytes]); - B256(bytes) + bytes[..n].copy_from_slice(&interpreter.contract.input[index..index + n]); + U256::from_be_bytes(bytes) } else { - B256::zero() + U256::ZERO }; - push_b256!(interpreter, load); + push!(interpreter, load); } -pub fn calldatasize(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn calldatasize(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::BASE); push!(interpreter, U256::from(interpreter.contract.input.len())); } -pub fn callvalue(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn callvalue(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::BASE); push!(interpreter, interpreter.contract.value); } -pub fn calldatacopy(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn calldatacopy(interpreter: &mut Interpreter, _host: &mut dyn Host) { pop!(interpreter, memory_offset, data_offset, len); - let len = as_usize_or_fail!(interpreter, len, InstructionResult::InvalidOperandOOG); + let len = as_usize_or_fail!(interpreter, len); gas_or_fail!(interpreter, gas::verylowcopy_cost(len as u64)); if len == 0 { return; } - let memory_offset = as_usize_or_fail!( - interpreter, - memory_offset, - InstructionResult::InvalidOperandOOG - ); + let memory_offset = as_usize_or_fail!(interpreter, memory_offset); let data_offset = as_usize_saturated!(data_offset); memory_resize!(interpreter, memory_offset, len); @@ -108,21 +94,21 @@ pub fn calldatacopy(interpreter: &mut Interpreter, _host: &mut dyn Host) { .set_data(memory_offset, data_offset, len, &interpreter.contract.input); } -pub fn returndatasize(interpreter: &mut Interpreter, _host: &mut dyn Host) { +// EIP-211: New opcodes: RETURNDATASIZE and RETURNDATACOPY +pub(super) fn returndatasize(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::BASE); - // EIP-211: New opcodes: RETURNDATASIZE and RETURNDATACOPY - check!(interpreter, SPEC::enabled(BYZANTIUM)); + check!(interpreter, BYZANTIUM); push!( interpreter, U256::from(interpreter.return_data_buffer.len()) ); } -pub fn returndatacopy(interpreter: &mut Interpreter, _host: &mut dyn Host) { - // EIP-211: New opcodes: RETURNDATASIZE and RETURNDATACOPY - check!(interpreter, SPEC::enabled(BYZANTIUM)); +// EIP-211: New opcodes: RETURNDATASIZE and RETURNDATACOPY +pub(super) fn returndatacopy(interpreter: &mut Interpreter, _host: &mut dyn Host) { + check!(interpreter, BYZANTIUM); pop!(interpreter, memory_offset, offset, len); - let len = as_usize_or_fail!(interpreter, len, InstructionResult::InvalidOperandOOG); + let len = as_usize_or_fail!(interpreter, len); gas_or_fail!(interpreter, gas::verylowcopy_cost(len as u64)); let data_offset = as_usize_saturated!(offset); let (data_end, overflow) = data_offset.overflowing_add(len); @@ -131,11 +117,7 @@ pub fn returndatacopy(interpreter: &mut Interpreter, _host: &mut dyn return; } if len != 0 { - let memory_offset = as_usize_or_fail!( - interpreter, - memory_offset, - InstructionResult::InvalidOperandOOG - ); + let memory_offset = as_usize_or_fail!(interpreter, memory_offset); memory_resize!(interpreter, memory_offset, len); interpreter.memory.set( memory_offset, @@ -144,7 +126,7 @@ pub fn returndatacopy(interpreter: &mut Interpreter, _host: &mut dyn } } -pub fn gas(interpreter: &mut Interpreter, _host: &mut dyn Host) { +pub(super) fn gas(interpreter: &mut Interpreter, _host: &mut dyn Host) { gas!(interpreter, gas::BASE); push!(interpreter, U256::from(interpreter.gas.remaining())); } diff --git a/crates/interpreter/src/interpreter/analysis.rs b/crates/interpreter/src/interpreter/analysis.rs index ccfab4253b..9fec465da8 100644 --- a/crates/interpreter/src/interpreter/analysis.rs +++ b/crates/interpreter/src/interpreter/analysis.rs @@ -1,13 +1,12 @@ use crate::opcode; -use crate::primitives::{Bytecode, BytecodeState, Bytes, B256}; +use crate::primitives::{ + bitvec::prelude::{bitvec, BitVec, Lsb0}, + Bytecode, BytecodeState, Bytes, JumpMap, B256, +}; use alloc::sync::Arc; // use bitvec::order::Lsb0; // use bitvec::prelude::bitvec; // use bitvec::vec::BitVec; -use revm_primitives::{ - bitvec::prelude::{bitvec, BitVec, Lsb0}, - JumpMap, -}; /// Perform bytecode analysis. /// @@ -72,6 +71,7 @@ pub struct BytecodeLocked { } impl Default for BytecodeLocked { + #[inline] fn default() -> Self { Bytecode::default() .try_into() @@ -82,6 +82,7 @@ impl Default for BytecodeLocked { impl TryFrom for BytecodeLocked { type Error = (); + #[inline] fn try_from(bytecode: Bytecode) -> Result { if let BytecodeState::Analysed { len, jump_map } = bytecode.state { Ok(BytecodeLocked { @@ -97,21 +98,31 @@ impl TryFrom for BytecodeLocked { } impl BytecodeLocked { + /// Returns a raw pointer to the underlying byte slice. + #[inline] pub fn as_ptr(&self) -> *const u8 { self.bytecode.as_ptr() } + + /// Returns the length of the bytecode. + #[inline] pub fn len(&self) -> usize { self.len } - pub fn hash(&self) -> B256 { - self.hash - } - + /// Returns whether the bytecode is empty. + #[inline] pub fn is_empty(&self) -> bool { self.len == 0 } + /// Returns the hash of the bytecode. + #[inline] + pub fn hash(&self) -> B256 { + self.hash + } + + #[inline] pub fn unlock(self) -> Bytecode { Bytecode { bytecode: self.bytecode, @@ -122,14 +133,21 @@ impl BytecodeLocked { }, } } + + /// Returns the bytecode as a byte slice. + #[inline] pub fn bytecode(&self) -> &[u8] { - self.bytecode.as_ref() + &self.bytecode } + /// Returns the original bytecode as a byte slice. + #[inline] pub fn original_bytecode_slice(&self) -> &[u8] { - &self.bytecode.as_ref()[..self.len] + &self.bytecode[..self.len] } + /// Returns a reference to the jump map. + #[inline] pub fn jump_map(&self) -> &JumpMap { &self.jump_map } diff --git a/crates/interpreter/src/interpreter/contract.rs b/crates/interpreter/src/interpreter/contract.rs index 434c1c7156..f82ea0a76b 100644 --- a/crates/interpreter/src/interpreter/contract.rs +++ b/crates/interpreter/src/interpreter/contract.rs @@ -1,7 +1,6 @@ use super::analysis::{to_analysed, BytecodeLocked}; -use crate::primitives::{Bytecode, Bytes, B160, U256}; +use crate::primitives::{Bytecode, Bytes, Env, TransactTo, B160, U256}; use crate::CallContext; -use revm_primitives::{Env, TransactTo}; #[derive(Clone, Default)] pub struct Contract { @@ -19,6 +18,8 @@ pub struct Contract { } impl Contract { + /// Instantiates a new contract by analyzing the given bytecode. + #[inline] pub fn new(input: Bytes, bytecode: Bytecode, address: B160, caller: B160, value: U256) -> Self { let bytecode = to_analysed(bytecode).try_into().expect("it is analyzed"); @@ -31,7 +32,8 @@ impl Contract { } } - /// Create new contract from environment + /// Creates a new contract from the given [`Env`]. + #[inline] pub fn new_env(env: &Env, bytecode: Bytecode) -> Self { let contract_address = match env.tx.transact_to { TransactTo::Call(caller) => caller, @@ -46,10 +48,8 @@ impl Contract { ) } - pub fn is_valid_jump(&self, possition: usize) -> bool { - self.bytecode.jump_map().is_valid(possition) - } - + /// Creates a new contract from the given [`CallContext`]. + #[inline] pub fn new_with_context(input: Bytes, bytecode: Bytecode, call_context: &CallContext) -> Self { Self::new( input, @@ -59,4 +59,10 @@ impl Contract { call_context.apparent_value, ) } + + /// Returns whether the given position is a valid jump destination. + #[inline] + pub fn is_valid_jump(&self, pos: usize) -> bool { + self.bytecode.jump_map().is_valid(pos) + } } diff --git a/crates/interpreter/src/interpreter/memory.rs b/crates/interpreter/src/interpreter/memory.rs index 4fa4daa70d..73fedf0e16 100644 --- a/crates/interpreter/src/interpreter/memory.rs +++ b/crates/interpreter/src/interpreter/memory.rs @@ -13,6 +13,7 @@ pub struct Memory { } impl Default for Memory { + #[inline] fn default() -> Self { Memory::new() } @@ -20,69 +21,78 @@ impl Default for Memory { impl Memory { /// Create a new memory with the given limit. + #[inline] pub fn new() -> Self { Self { data: Vec::with_capacity(4 * 1024), // took it from evmone } } + #[deprecated = "Use `len` instead"] + #[doc(hidden)] + #[inline] pub fn effective_len(&self) -> usize { - self.data.len() + self.len() } - /// Get the length of the current memory range. + /// Returns the length of the current memory range. + #[inline] pub fn len(&self) -> usize { self.data.len() } - /// Return true if current effective memory range is zero. + /// Returns true if current memory range length is zero. + #[inline] pub fn is_empty(&self) -> bool { self.len() == 0 } - /// Return the full memory. + /// Return a reference to the full memory. + #[inline] pub fn data(&self) -> &Vec { &self.data } /// Consumes the type and returns the full memory. + #[inline] pub fn into_data(self) -> Vec { self.data } /// Shrinks the capacity of the data buffer as much as possible. + #[inline] pub fn shrink_to_fit(&mut self) { self.data.shrink_to_fit() } - /// Resize the memory. asume that we already checked if - /// we have enought gas to resize this vector and that we made new_size as multiply of 32 + /// Resizes the stack in-place so that then length is equal to `new_size`. + /// + /// `new_size` should be a multiple of 32. + #[inline] pub fn resize(&mut self, new_size: usize) { self.data.resize(new_size, 0); } - /// Get memory region at given offset. Dont check offset and size - #[inline(always)] + /// Returns a byte slice of the memory region at the given offset. + #[inline] pub fn get_slice(&self, offset: usize, size: usize) -> &[u8] { &self.data[offset..offset + size] } - /// Set memory region at given offset - /// - /// # Safety - /// The caller is responsible for checking the offset and value - #[inline(always)] - pub unsafe fn set_byte(&mut self, index: usize, byte: u8) { - *self.data.get_mut(index).unwrap() = byte; + /// Sets the `byte` at the given `index`. + #[inline] + pub fn set_byte(&mut self, index: usize, byte: u8) { + self.data[index] = byte; } - #[inline(always)] + /// Sets the given `value` to the memory region at the given `offset`. + #[inline] pub fn set_u256(&mut self, index: usize, value: U256) { self.data[index..index + 32].copy_from_slice(&value.to_be_bytes::<{ U256::BYTES }>()); } - /// Set memory region at given offset. The offset and value are already checked - #[inline(always)] + /// Set memory region at given `offset`. + #[inline] pub fn set(&mut self, offset: usize, value: &[u8]) { if !value.is_empty() { self.data[offset..(value.len() + offset)].copy_from_slice(value); @@ -91,7 +101,7 @@ impl Memory { /// Set memory from data. Our memory offset+len is expected to be correct but we /// are doing bound checks on data/data_offeset/len and zeroing parts that is not copied. - #[inline(always)] + #[inline] pub fn set_data(&mut self, memory_offset: usize, data_offset: usize, len: usize, data: &[u8]) { if data_offset >= data.len() { // nulify all memory slots @@ -112,12 +122,9 @@ impl Memory { } /// In memory copy given a src, dst, and length - /// - /// # Safety - /// The caller is responsible to check that we resized memory properly. #[inline(always)] - pub fn copy(&mut self, dst: usize, src: usize, length: usize) { - self.data.copy_within(src..src + length, dst); + pub fn copy(&mut self, dst: usize, src: usize, len: usize) { + self.data.copy_within(src..src + len, dst); } } @@ -130,9 +137,8 @@ pub(crate) fn next_multiple_of_32(x: usize) -> Option { #[cfg(test)] mod tests { - use crate::Memory; - use super::next_multiple_of_32; + use crate::Memory; #[test] fn test_copy() { diff --git a/crates/interpreter/src/interpreter.rs b/crates/interpreter/src/interpreter/mod.rs similarity index 53% rename from crates/interpreter/src/interpreter.rs rename to crates/interpreter/src/interpreter/mod.rs index f99effe93d..2e30f9d726 100644 --- a/crates/interpreter/src/interpreter.rs +++ b/crates/interpreter/src/interpreter/mod.rs @@ -6,79 +6,83 @@ mod stack; pub use analysis::BytecodeLocked; pub use contract::Contract; pub use memory::Memory; -pub use stack::Stack; +pub use stack::{Stack, STACK_LIMIT}; use crate::primitives::{Bytes, Spec}; -use crate::{ - alloc::boxed::Box, - instructions::{eval, InstructionResult}, - Gas, Host, -}; -use core::ops::Range; - -pub const STACK_LIMIT: u64 = 1024; +use crate::{alloc::boxed::Box, opcode::eval, Gas, Host, InstructionResult}; + pub const CALL_STACK_LIMIT: u64 = 1024; /// EIP-170: Contract code size limit -/// By default limit is 0x6000 (~25kb) +/// +/// By default this limit is 0x6000 (~25kb) pub const MAX_CODE_SIZE: usize = 0x6000; + /// EIP-3860: Limit and meter initcode pub const MAX_INITCODE_SIZE: usize = 2 * MAX_CODE_SIZE; pub struct Interpreter { - /// Instruction pointer. + /// Contract information and invoking data. + pub contract: Box, + + /// The current instruction pointer. pub instruction_pointer: *const u8, - /// Return is main control flag, it tell us if we should continue interpreter or break from it + + /// The execution control flag. If this is not set to `Continue`, the interpreter will stop + /// execution. pub instruction_result: InstructionResult, - /// left gas. Memory gas can be found in Memory field. + + /// The gas state. pub gas: Gas, - /// Memory. + + /// The memory. pub memory: Memory, - /// Stack. + + /// The stack. pub stack: Stack, - /// After call returns, its return data is saved here. + + /// The return data buffer for internal calls. pub return_data_buffer: Bytes, - /// Return value. - pub return_range: Range, - /// Is interpreter call static. + + /// The offset into `self.memory` of the return data. + /// + /// This value must be ignored if `self.return_len` is 0. + pub return_offset: usize, + + /// The length of the return data. + pub return_len: usize, + + /// Whether the interpreter is in "staticcall" mode, meaning no state changes can happen. pub is_static: bool, - /// Contract information and invoking data - pub contract: Box, + /// Memory limit. See [`crate::CfgEnv`]. #[cfg(feature = "memory_limit")] pub memory_limit: u64, } impl Interpreter { - /// Current opcode - pub fn current_opcode(&self) -> u8 { - unsafe { *self.instruction_pointer } - } - - /// Create new interpreter + /// Instantiates a new interpreter. + #[inline] pub fn new(contract: Box, gas_limit: u64, is_static: bool) -> Self { - #[cfg(not(feature = "memory_limit"))] - { - Self { - instruction_pointer: contract.bytecode.as_ptr(), - return_range: Range::default(), - memory: Memory::new(), - stack: Stack::new(), - return_data_buffer: Bytes::new(), - contract, - instruction_result: InstructionResult::Continue, - is_static, - gas: Gas::new(gas_limit), - } - } - - #[cfg(feature = "memory_limit")] - { - Self::new_with_memory_limit(contract, gas_limit, is_static, u64::MAX) + Self { + instruction_pointer: contract.bytecode.as_ptr(), + contract, + instruction_result: InstructionResult::Continue, + gas: Gas::new(gas_limit), + memory: Memory::new(), + stack: Stack::new(), + return_data_buffer: Bytes::new(), + return_offset: 0, + return_len: 0, + is_static, + #[cfg(feature = "memory_limit")] + memory_limit: u64::MAX, } } + /// Instantiates a new interpreter with the given memory limit. #[cfg(feature = "memory_limit")] + #[inline] pub fn new_with_memory_limit( contract: Box, gas_limit: u64, @@ -86,38 +90,43 @@ impl Interpreter { memory_limit: u64, ) -> Self { Self { - instruction_pointer: contract.bytecode.as_ptr(), - return_range: Range::default(), - memory: Memory::new(), - stack: Stack::new(), - return_data_buffer: Bytes::new(), - contract, - instruction_result: InstructionResult::Continue, - is_static, - gas: Gas::new(gas_limit), memory_limit, + ..Self::new(contract, gas_limit, is_static) } } + /// Returns the opcode at the current instruction pointer. + #[inline] + pub fn current_opcode(&self) -> u8 { + unsafe { *self.instruction_pointer } + } + + /// Returns a reference to the contract. + #[inline] pub fn contract(&self) -> &Contract { &self.contract } + /// Returns a reference to the interpreter's gas state. + #[inline] pub fn gas(&self) -> &Gas { &self.gas } - /// Reference of interpreter memory. + /// Returns a reference to the interpreter's memory. + #[inline] pub fn memory(&self) -> &Memory { &self.memory } - /// Reference of interpreter stack. + /// Returns a reference to the interpreter's stack. + #[inline] pub fn stack(&self) -> &Stack { &self.stack } - /// Return a reference of the program counter. + /// Returns the current program counter. + #[inline] pub fn program_counter(&self) -> usize { // Safety: this is just subtraction of pointers, it is safe to do. unsafe { @@ -126,55 +135,64 @@ impl Interpreter { } } - /// Execute next instruction + /// Executes the instruction at the current instruction pointer. #[inline(always)] - pub fn step(&mut self, host: &mut H) { + pub fn step(&mut self, host: &mut dyn Host) { // step. let opcode = unsafe { *self.instruction_pointer }; // Safety: In analysis we are doing padding of bytecode so that we are sure that last // byte instruction is STOP so we are safe to just increment program_counter bcs on last instruction // it will do noop and just stop execution of this contract self.instruction_pointer = unsafe { self.instruction_pointer.offset(1) }; - eval::(opcode, self, host); + eval::(opcode, self, host); } - /// loop steps until we are finished with execution + /// Executes the interpreter until it returns or stops. pub fn run(&mut self, host: &mut H) -> InstructionResult { while self.instruction_result == InstructionResult::Continue { - self.step::(host) + self.step::(host); } self.instruction_result } - /// loop steps until we are finished with execution + /// Executes the interpreter until it returns or stops. Same as `run` but with + /// calls to the [`Host::step`] and [`Host::step_end`] callbacks. pub fn run_inspect(&mut self, host: &mut H) -> InstructionResult { while self.instruction_result == InstructionResult::Continue { // step - let ret = host.step(self); - if ret != InstructionResult::Continue { - return ret; + let result = host.step(self); + if result != InstructionResult::Continue { + return result; } - self.step::(host); + + self.step::(host); // step ends - let ret = host.step_end(self, self.instruction_result); - if ret != InstructionResult::Continue { - return ret; + let result = host.step_end(self, self.instruction_result); + if result != InstructionResult::Continue { + return result; } } self.instruction_result } - /// Copy and get the return value of the interpreter, if any. + /// Returns a copy of the interpreter's return value, if any. + #[inline] pub fn return_value(&self) -> Bytes { - // if start is usize max it means that our return len is zero and we need to return empty - if self.return_range.start == usize::MAX { + if self.return_len == 0 { Bytes::new() } else { - Bytes::copy_from_slice(self.memory.get_slice( - self.return_range.start, - self.return_range.end - self.return_range.start, - )) + Bytes::copy_from_slice(self.memory.get_slice(self.return_offset, self.return_len)) + } + } + + /// Returns a reference to the interpreter's return value, if any. + #[inline] + pub fn return_value_slice(&self) -> &[u8] { + if self.return_len == 0 { + &[] + } else { + self.memory.get_slice(self.return_offset, self.return_len) } } } diff --git a/crates/interpreter/src/interpreter/stack.rs b/crates/interpreter/src/interpreter/stack.rs index 7b20e8e758..38bb0c0acd 100644 --- a/crates/interpreter/src/interpreter/stack.rs +++ b/crates/interpreter/src/interpreter/stack.rs @@ -1,6 +1,8 @@ use crate::primitives::{B256, U256}; use crate::{alloc::vec::Vec, InstructionResult}; +use core::fmt; +/// The EVM stack limit, in number of words. pub const STACK_LIMIT: usize = 1024; /// EVM stack. @@ -10,117 +12,107 @@ pub struct Stack { data: Vec, } -#[cfg(feature = "std")] -impl std::fmt::Display for Stack { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { - if self.data.is_empty() { - f.write_str("[]")?; - } else { - f.write_str("[")?; - for i in self.data[..self.data.len() - 1].iter() { - f.write_str(&i.to_string())?; +impl fmt::Display for Stack { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("[")?; + for (i, x) in self.data.iter().enumerate() { + if i > 0 { f.write_str(", ")?; } - f.write_str(&self.data.last().unwrap().to_string())?; - f.write_str("]")?; + write!(f, "{x}")?; } - Ok(()) + f.write_str("]") } } impl Default for Stack { + #[inline] fn default() -> Self { Self::new() } } impl Stack { - /// Create a new stack with given limit. + /// Instantiate a new stack with the [default stack limit][STACK_LIMIT]. + #[inline] pub fn new() -> Self { Self { - // Safety: A lot of functions assumes that capacity is STACK_LIMIT + // Safety: A lot of functions assume that capacity is STACK_LIMIT data: Vec::with_capacity(STACK_LIMIT), } } + /// Returns the length of the stack in words. #[inline] - /// Stack length. pub fn len(&self) -> usize { self.data.len() } + /// Returns whether the stack is empty. #[inline] - /// Whether the stack is empty. pub fn is_empty(&self) -> bool { self.data.is_empty() } + /// Returns the underlying data of the stack. #[inline] - /// Stack data. pub fn data(&self) -> &Vec { &self.data } - #[inline(always)] - pub fn reduce_one(&mut self) -> Option { - let len = self.data.len(); - if len < 1 { - return Some(InstructionResult::StackUnderflow); - } - unsafe { - self.data.set_len(len - 1); - } - None + /// Remove the topmost value from the stack. If the stack is empty, returns a `StackUnderflow` + /// error. + #[inline] + pub fn reduce_one(&mut self) -> Result<(), InstructionResult> { + self.pop().map(drop) } + /// Removes the topmost element from the stack and returns it, or `StackUnderflow` if it is + /// empty. #[inline] - /// Pop a value from the stack. If the stack is already empty, returns the - /// `StackUnderflow` error. pub fn pop(&mut self) -> Result { self.data.pop().ok_or(InstructionResult::StackUnderflow) } - #[inline(always)] - /// Pops a value from the stack, returning it. + /// Removes the topmost element from the stack and returns it. /// /// # Safety - /// The caller is responsible to check length of array + /// + /// The caller is responsible for checking the length of the stack. + #[inline(always)] pub unsafe fn pop_unsafe(&mut self) -> U256 { - let mut len = self.data.len(); - len -= 1; - self.data.set_len(len); - *self.data.get_unchecked(len) + self.data.pop().unwrap_unchecked() } - #[inline(always)] /// Peeks the top of the stack. /// /// # Safety - /// The caller is responsible to check length of array + /// + /// The caller is responsible for checking the length of the stack. + #[inline(always)] pub unsafe fn top_unsafe(&mut self) -> &mut U256 { let len = self.data.len(); self.data.get_unchecked_mut(len - 1) } - #[inline(always)] /// Pop the topmost value, returning the value and the new topmost value. /// /// # Safety - /// The caller is responsible to check length of array + /// + /// The caller is responsible for checking the length of the stack. + #[inline(always)] pub unsafe fn pop_top_unsafe(&mut self) -> (U256, &mut U256) { - let mut len = self.data.len(); - let pop = *self.data.get_unchecked(len - 1); - len -= 1; - self.data.set_len(len); - - (pop, self.data.get_unchecked_mut(len - 1)) + let pop = self.pop_unsafe(); + let top = self.top_unsafe(); + (pop, top) } - #[inline(always)] /// Pops 2 values from the stack and returns them, in addition to the new topmost value. /// /// # Safety - /// The caller is responsible to check length of array + /// + /// The caller is responsible for checking the length of the stack. + #[inline(always)] pub unsafe fn pop2_top_unsafe(&mut self) -> (U256, U256, &mut U256) { let mut len = self.data.len(); let pop1 = *self.data.get_unchecked(len - 1); @@ -131,11 +123,12 @@ impl Stack { (pop1, pop2, self.data.get_unchecked_mut(len - 1)) } - #[inline(always)] /// Pops 2 values from the stack. /// /// # Safety - /// The caller is responsible to check length of array + /// + /// The caller is responsible for checking the length of the stack. + #[inline(always)] pub unsafe fn pop2_unsafe(&mut self) -> (U256, U256) { let mut len = self.data.len(); len -= 2; @@ -146,11 +139,12 @@ impl Stack { ) } - #[inline(always)] /// Pops 3 values from the stack. /// /// # Safety - /// The caller is responsible to check length of array + /// + /// The caller is responsible for checking the length of the stack. + #[inline(always)] pub unsafe fn pop3_unsafe(&mut self) -> (U256, U256, U256) { let mut len = self.data.len(); len -= 3; @@ -162,11 +156,12 @@ impl Stack { ) } - #[inline(always)] /// Pops 4 values from the stack. /// /// # Safety - /// The caller is responsible to check length of array + /// + /// The caller is responsible for checking the length of the stack. + #[inline(always)] pub unsafe fn pop4_unsafe(&mut self) -> (U256, U256, U256, U256) { let mut len = self.data.len(); len -= 4; @@ -179,9 +174,9 @@ impl Stack { ) } - #[inline] /// Push a new value into the stack. If it will exceed the stack limit, /// returns `StackOverflow` error and leaves the stack unchanged. + #[inline] pub fn push_b256(&mut self, value: B256) -> Result<(), InstructionResult> { if self.data.len() + 1 > STACK_LIMIT { return Err(InstructionResult::StackOverflow); @@ -190,9 +185,11 @@ impl Stack { Ok(()) } + /// Push a new value onto the stack. + /// + /// If it will exceed the stack limit, returns `StackOverflow` error and leaves the stack + /// unchanged. #[inline] - /// Push a new value into the stack. If it will exceed the stack limit, - /// returns `StackOverflow` error and leaves the stack unchanged. pub fn push(&mut self, value: U256) -> Result<(), InstructionResult> { if self.data.len() + 1 > STACK_LIMIT { return Err(InstructionResult::StackOverflow); @@ -201,10 +198,10 @@ impl Stack { Ok(()) } - #[inline] /// Peek a value at given index for the stack, where the top of /// the stack is at index `0`. If the index is too large, /// `StackError::Underflow` is returned. + #[inline] pub fn peek(&self, no_from_top: usize) -> Result { if self.data.len() > no_from_top { Ok(self.data[self.data.len() - no_from_top - 1]) @@ -213,44 +210,45 @@ impl Stack { } } + /// Duplicates the `N`th value from the top of the stack. #[inline(always)] - pub fn dup(&mut self) -> Option { + pub fn dup(&mut self) -> Result<(), InstructionResult> { let len = self.data.len(); if len < N { - Some(InstructionResult::StackUnderflow) + Err(InstructionResult::StackUnderflow) } else if len + 1 > STACK_LIMIT { - Some(InstructionResult::StackOverflow) + Err(InstructionResult::StackOverflow) } else { // Safety: check for out of bounds is done above and it makes this safe to do. unsafe { *self.data.get_unchecked_mut(len) = *self.data.get_unchecked(len - N); self.data.set_len(len + 1); } - None + Ok(()) } } + /// Swaps the topmost value with the `N`th value from the top. #[inline(always)] - pub fn swap(&mut self) -> Option { + pub fn swap(&mut self) -> Result<(), InstructionResult> { let len = self.data.len(); if len <= N { - return Some(InstructionResult::StackUnderflow); - } - // Safety: length is checked before so we are okay to switch bytes in unsafe way. - unsafe { - let pa: *mut U256 = self.data.get_unchecked_mut(len - 1); - let pb: *mut U256 = self.data.get_unchecked_mut(len - 1 - N); - core::ptr::swap(pa, pb); + return Err(InstructionResult::StackUnderflow); } - None + let last = len - 1; + self.data.swap(last, last - N); + Ok(()) } - /// push slice onto memory it is expected to be max 32 bytes and be contains inside B256 + /// Push a slice of bytes of `N` length onto the stack. + /// + /// If it will exceed the stack limit, returns `StackOverflow` error and leaves the stack + /// unchanged. #[inline(always)] - pub fn push_slice(&mut self, slice: &[u8]) -> Option { + pub fn push_slice(&mut self, slice: &[u8]) -> Result<(), InstructionResult> { let new_len = self.data.len() + 1; if new_len > STACK_LIMIT { - return Some(InstructionResult::StackOverflow); + return Err(InstructionResult::StackOverflow); } let slot; @@ -299,13 +297,13 @@ impl Stack { } } } - None + Ok(()) } - #[inline] /// Set a value at given index for the stack, where the top of the /// stack is at index `0`. If the index is too large, /// `StackError::Underflow` is returned. + #[inline] pub fn set(&mut self, no_from_top: usize, val: U256) -> Result<(), InstructionResult> { if self.data.len() > no_from_top { let len = self.data.len(); diff --git a/crates/interpreter/src/lib.rs b/crates/interpreter/src/lib.rs index a82107503d..5256d0a200 100644 --- a/crates/interpreter/src/lib.rs +++ b/crates/interpreter/src/lib.rs @@ -1,5 +1,7 @@ #![cfg_attr(not(feature = "std"), no_std)] +extern crate alloc; + pub mod gas; mod host; pub mod inner_models; @@ -7,9 +9,6 @@ pub mod instruction_result; mod instructions; mod interpreter; -extern crate alloc; -extern crate core; - pub(crate) const USE_GAS: bool = !cfg!(feature = "no_gas_measuring"); // Reexport primary types. @@ -17,7 +16,7 @@ pub use gas::Gas; pub use host::{DummyHost, Host}; pub use inner_models::*; pub use instruction_result::InstructionResult; -pub use instructions::opcode::{self, OpCode, OPCODE_JUMPMAP}; +pub use instructions::*; pub use interpreter::*; pub use interpreter::{BytecodeLocked, Contract, Interpreter, Memory, Stack}; diff --git a/crates/precompile/src/lib.rs b/crates/precompile/src/lib.rs index cec8e885c7..888335ef13 100644 --- a/crates/precompile/src/lib.rs +++ b/crates/precompile/src/lib.rs @@ -1,5 +1,8 @@ #![no_std] +#[macro_use] +extern crate alloc; + mod blake2; mod bn128; mod hash; @@ -18,9 +21,6 @@ pub use revm_primitives as primitives; pub type B160 = [u8; 20]; pub type B256 = [u8; 32]; -/// libraries for no_std flag -#[macro_use] -extern crate alloc; use alloc::vec::Vec; use core::fmt; @@ -121,7 +121,7 @@ impl Precompiles { pub fn homestead() -> &'static Self { static INSTANCE: OnceCell = OnceCell::new(); INSTANCE.get_or_init(|| { - let fun = vec![ + let fun = [ secp256k1::ECRECOVER, hash::SHA256, hash::RIPEMD160, @@ -139,7 +139,7 @@ impl Precompiles { INSTANCE.get_or_init(|| { let mut precompiles = Self::homestead().clone(); precompiles.fun.extend( - vec![ + [ // EIP-196: Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128. // EIP-197: Precompiled contracts for optimal ate pairing check on the elliptic curve alt_bn128. bn128::add::BYZANTIUM, @@ -160,7 +160,7 @@ impl Precompiles { INSTANCE.get_or_init(|| { let mut precompiles = Self::byzantium().clone(); precompiles.fun.extend( - vec![ + [ // EIP-152: Add BLAKE2 compression function `F` precompile. blake2::FUN, // EIP-1108: Reduce alt_bn128 precompile gas costs. @@ -180,7 +180,7 @@ impl Precompiles { INSTANCE.get_or_init(|| { let mut precompiles = Self::istanbul().clone(); precompiles.fun.extend( - vec![ + [ // EIP-2565: ModExp Gas Cost. modexp::BERLIN, ] diff --git a/crates/precompile/src/modexp.rs b/crates/precompile/src/modexp.rs index 7b650ed0f3..4344f5cce9 100644 --- a/crates/precompile/src/modexp.rs +++ b/crates/precompile/src/modexp.rs @@ -47,7 +47,7 @@ fn calculate_iteration_count(exp_length: u64, exp_highp: &BigUint) -> u64 { } macro_rules! read_u64_with_overflow { - ($input:expr,$from:expr,$to:expr, $overflow_limit:expr) => {{ + ($input:expr, $from:expr, $to:expr, $overflow_limit:expr) => {{ const SPLIT: usize = 32 - size_of::(); let len = $input.len(); let from_zero = min($from, len); @@ -94,7 +94,7 @@ where let mod_end = exp_end + mod_len; let exp_highp = { - let mut out = vec![0; 32]; + let mut out = [0; 32]; let from = min(base_end, len); let to = min(exp_highp_end, len); let target_from = 32 - (exp_highp_end - base_end); // 32 - exp length diff --git a/crates/primitives/Cargo.toml b/crates/primitives/Cargo.toml index f584ccc81d..6129ceee4f 100644 --- a/crates/primitives/Cargo.toml +++ b/crates/primitives/Cargo.toml @@ -11,20 +11,18 @@ readme = "../../README.md" [dependencies] bytes = { version = "1.4", default-features = false } -hashbrown = { version = "0.14" } +hashbrown = "0.14" hex = { version = "0.4", default-features = false } 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"] } +rlp = { version = "0.5", default-features = false } # used for create2 address calculation +ruint = { version = "1.10.1", default-features = false, features = ["primitive-types", "rlp"] } auto_impl = "1.1" bitvec = { version = "1", default-features = false, features = ["alloc"] } -bitflags = { version = "2.2.1", 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", -] } +fixed-hash = { version = "0.8", default-features = false, features = ["rustc-hex"] } #utility hex-literal = "0.4" @@ -32,7 +30,7 @@ derive_more = "0.99" enumn = "0.1" # sha3 keccak hasher -sha3 = { version = "0.10", default-features = false, features = [] } +sha3 = { version = "0.10", default-features = false } # optional serde = { version = "1.0", features = ["derive", "rc"], optional = true } @@ -42,14 +40,9 @@ proptest-derive = { version = "0.3", optional = true } [dev-dependencies] arbitrary = { version = "1.3", features = ["derive"] } -proptest = { version = "1.1" } +proptest = "1.1" proptest-derive = "0.3" -ruint = { version = "1.8.0", features = [ - "primitive-types", - "rlp", - "proptest", - "arbitrary", -] } +ruint = { version = "1.10.1", features = ["primitive-types", "rlp", "proptest", "arbitrary"] } [features] default = ["std"] diff --git a/crates/primitives/src/bytecode.rs b/crates/primitives/src/bytecode.rs index 1cd8aa8f9b..4890726e8e 100644 --- a/crates/primitives/src/bytecode.rs +++ b/crates/primitives/src/bytecode.rs @@ -1,5 +1,5 @@ use crate::{keccak256, B256, KECCAK_EMPTY}; -use alloc::{sync::Arc, vec, vec::Vec}; +use alloc::{sync::Arc, vec::Vec}; use bitvec::prelude::{bitvec, Lsb0}; use bitvec::vec::BitVec; use bytes::Bytes; @@ -11,16 +11,19 @@ pub struct JumpMap(pub Arc>); impl JumpMap { /// Get the raw bytes of the jump map + #[inline] pub fn as_slice(&self) -> &[u8] { self.0.as_raw_slice() } /// Construct a jump map from raw bytes + #[inline] pub fn from_slice(slice: &[u8]) -> Self { Self(Arc::new(BitVec::from_slice(slice))) } /// Check if `pc` is a valid jump destination. + #[inline] pub fn is_valid(&self, pc: usize) -> bool { pc < self.0.len() && self.0[pc] } @@ -44,16 +47,18 @@ pub struct Bytecode { } impl Default for Bytecode { + #[inline] fn default() -> Self { Bytecode::new() } } impl Bytecode { - /// Create [`Bytecode`] with one STOP opcode. + /// Creates a new [`Bytecode`] with exactly one STOP opcode. + #[inline] pub fn new() -> Self { Bytecode { - bytecode: vec![0].into(), + bytecode: Bytes::from_static(&[0]), hash: KECCAK_EMPTY, state: BytecodeState::Analysed { len: 0, @@ -62,6 +67,8 @@ impl Bytecode { } } + /// Creates a new raw [`Bytecode`]. + #[inline] pub fn new_raw(bytecode: Bytes) -> Self { let hash = if bytecode.is_empty() { KECCAK_EMPTY @@ -75,11 +82,15 @@ impl Bytecode { } } - /// Create new raw Bytecode with hash + /// Creates a new raw Bytecode with the given hash. /// /// # Safety - /// Hash need to be appropriate keccak256 over bytecode. + /// + /// The given `hash` has to be equal to the [`keccak256`] hash of the given `bytecode`. + #[inline] + #[cfg_attr(debug_assertions, track_caller)] pub unsafe fn new_raw_with_hash(bytecode: Bytes, hash: B256) -> Self { + debug_assert_eq!(keccak256(&bytecode), hash, "Invalid bytecode hash"); Self { bytecode, hash, @@ -90,8 +101,10 @@ impl Bytecode { /// Create new checked bytecode /// /// # Safety + /// /// Bytecode need to end with STOP (0x00) opcode as checked bytecode assumes /// that it is safe to iterate over bytecode without checking lengths + #[inline] pub unsafe fn new_checked(bytecode: Bytes, len: usize, hash: Option) -> Self { let hash = match hash { None if len == 0 => KECCAK_EMPTY, @@ -105,10 +118,14 @@ impl Bytecode { } } + /// Returns a reference to the bytecode. + #[inline] pub fn bytes(&self) -> &Bytes { &self.bytecode } + /// Returns a reference to the original bytecode. + #[inline] pub fn original_bytes(&self) -> Bytes { match self.state { BytecodeState::Raw => self.bytecode.clone(), @@ -118,28 +135,31 @@ impl Bytecode { } } - pub fn hash(&self) -> B256 { - self.hash + /// Returns the length of the bytecode. + #[inline] + pub fn len(&self) -> usize { + match self.state { + BytecodeState::Raw => self.bytecode.len(), + BytecodeState::Checked { len, .. } | BytecodeState::Analysed { len, .. } => len, + } } - pub fn state(&self) -> &BytecodeState { - &self.state + /// Returns whether the bytecode is empty. + #[inline] + pub fn is_empty(&self) -> bool { + self.len() == 0 } - pub fn is_empty(&self) -> bool { - match self.state { - BytecodeState::Raw => self.bytecode.is_empty(), - BytecodeState::Checked { len } => len == 0, - BytecodeState::Analysed { len, .. } => len == 0, - } + /// Returns the hash of the bytecode. + #[inline] + pub fn hash(&self) -> B256 { + self.hash } - pub fn len(&self) -> usize { - match self.state { - BytecodeState::Raw => self.bytecode.len(), - BytecodeState::Checked { len, .. } => len, - BytecodeState::Analysed { len, .. } => len, - } + /// Returns the [`BytecodeState`]. + #[inline] + pub fn state(&self) -> &BytecodeState { + &self.state } pub fn to_checked(self) -> Self { diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index 1502cf80e5..9f9e85b63b 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -1,5 +1,7 @@ #![cfg_attr(not(feature = "std"), no_std)] +extern crate alloc; + pub mod bits; pub mod bytecode; pub mod constants; @@ -12,8 +14,6 @@ pub mod specification; pub mod state; pub mod utilities; -extern crate alloc; - pub use bits::B160; pub use bits::B256; pub use bytes; diff --git a/crates/primitives/src/specification.rs b/crates/primitives/src/specification.rs index cb6e7102eb..1544dc42df 100644 --- a/crates/primitives/src/specification.rs +++ b/crates/primitives/src/specification.rs @@ -1,9 +1,10 @@ +#![allow(non_camel_case_types)] + /// SpecId and their activation block /// Information was obtained from: https://github.com/ethereum/execution-specs #[repr(u8)] #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd, enumn::N)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[allow(non_camel_case_types)] pub enum SpecId { FRONTIER = 0, // Frontier 0 FRONTIER_THAWING = 1, // Frontier Thawing 200000 @@ -64,15 +65,16 @@ impl SpecId { } pub trait Spec: Sized { + const SPEC_ID: SpecId; + #[inline(always)] fn enabled(spec_id: SpecId) -> bool { Self::SPEC_ID as u8 >= spec_id as u8 } - const SPEC_ID: SpecId; } macro_rules! spec { - ($spec_id:tt,$spec_name:tt) => { + ($spec_id:tt, $spec_name:tt) => { pub struct $spec_name; impl Spec for $spec_name { diff --git a/crates/revm/Cargo.toml b/crates/revm/Cargo.toml index 0d102a82d2..2fd0fcb312 100644 --- a/crates/revm/Cargo.toml +++ b/crates/revm/Cargo.toml @@ -20,10 +20,7 @@ serde = { version = "1.0", features = ["derive", "rc"], optional = true } serde_json = { version = "1.0", features = ["preserve_order"], optional = true } # ethersdb -tokio = { version = "1.28", features = [ - "rt-multi-thread", - "macros", -], optional = true } +tokio = { version = "1.28", 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 } @@ -34,6 +31,7 @@ ethers-contract = { version = "2.0.3", default-features = false } hex = "0.4.3" bytes = "1.4.0" anyhow = "1.0.71" +criterion = "0.5" [features] default = ["std", "secp256k1"] @@ -64,3 +62,8 @@ with-serde = [] [[example]] name = "fork_ref_transact" path = "../../examples/fork_ref_transact.rs" + +[[bench]] +name = "bench" +path = "benches/bench.rs" +harness = false diff --git a/crates/revm/benches/bench.rs b/crates/revm/benches/bench.rs new file mode 100644 index 0000000000..d51e174d0c --- /dev/null +++ b/crates/revm/benches/bench.rs @@ -0,0 +1,137 @@ +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}, +}; +use std::time::Duration; + +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()); + + let contract_data: Bytes = hex::decode(ANALYSIS).unwrap().into(); + + let mut g = c.benchmark_group("analysis"); + g.noise_threshold(0.03) + .warm_up_time(Duration::from_secs(3)) + .measurement_time(Duration::from_secs(10)) + .sample_size(10); + + let raw = Bytecode::new_raw(contract_data.clone()); + evm.database(BenchmarkDB::new_bytecode(raw)); + bench_transact(&mut g, &mut evm); + + let checked = Bytecode::new_raw(contract_data.clone()).to_checked(); + evm.database(BenchmarkDB::new_bytecode(checked)); + bench_transact(&mut g, &mut evm); + + let analysed = to_analysed(Bytecode::new_raw(contract_data)); + evm.database(BenchmarkDB::new_bytecode(analysed)); + bench_transact(&mut g, &mut evm); + + g.finish(); +} + +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()); + + let mut g = c.benchmark_group("snailtracer"); + g.noise_threshold(0.03) + .warm_up_time(Duration::from_secs(3)) + .measurement_time(Duration::from_secs(10)) + .sample_size(10); + bench_transact(&mut g, &mut evm); + bench_eval(&mut g, &evm); + g.finish(); +} + +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.value = U256::from(10); + + let mut g = c.benchmark_group("transfer"); + g.noise_threshold(0.03).warm_up_time(Duration::from_secs(1)); + bench_transact(&mut g, &mut evm); + g.finish(); +} + +fn bench_transact(g: &mut BenchmarkGroup<'_, WallTime>, evm: &mut Evm) { + let state = match evm.db.as_mut().unwrap().0.state { + BytecodeState::Raw => "raw", + BytecodeState::Checked { .. } => "checked", + BytecodeState::Analysed { .. } => "analysed", + }; + let id = format!("transact/{state}"); + g.bench_function(id, |b| b.iter(|| evm.transact().unwrap())); +} + +fn bench_eval(g: &mut BenchmarkGroup<'_, WallTime>, evm: &Evm) { + g.bench_function("eval", |b| { + let contract = Contract { + input: evm.env.tx.data.clone(), + bytecode: BytecodeLocked::try_from(evm.db.as_ref().unwrap().0.clone()).unwrap(), + ..Default::default() + }; + let mut host = DummyHost::new(evm.env.clone()); + b.iter(|| { + let mut interpreter = Interpreter::new(Box::new(contract.clone()), u64::MAX, false); + let res = interpreter.run::<_, BerlinSpec>(&mut host); + host.clear(); + res + }) + }); +} + +fn bytecode(s: &str) -> Bytecode { + to_analysed(Bytecode::new_raw(hex::decode(s).unwrap().into())) +} + +#[rustfmt::skip] +criterion_group!( + benches, + analysis, + snailtracer, + transfer, +); +criterion_main!(benches); + +const ANALYSIS: &str = "6060604052341561000f57600080fd5b604051610dd1380380610dd18339810160405280805190602001909190805182019190602001805190602001909190805182019190505083600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508360008190555082600390805190602001906100a79291906100e3565b5081600460006101000a81548160ff021916908360ff16021790555080600590805190602001906100d99291906100e3565b5050505050610188565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061012457805160ff1916838001178555610152565b82800160010185558215610152579182015b82811115610151578251825591602001919060010190610136565b5b50905061015f9190610163565b5090565b61018591905b80821115610181576000816000905550600101610169565b5090565b90565b610c3a806101976000396000f3006060604052600436106100af576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100b4578063095ea7b31461014257806318160ddd1461019c57806323b872dd146101c557806327e235e31461023e578063313ce5671461028b5780635c658165146102ba57806370a082311461032657806395d89b4114610373578063a9059cbb14610401578063dd62ed3e1461045b575b600080fd5b34156100bf57600080fd5b6100c76104c7565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101075780820151818401526020810190506100ec565b50505050905090810190601f1680156101345780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561014d57600080fd5b610182600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610565565b604051808215151515815260200191505060405180910390f35b34156101a757600080fd5b6101af610657565b6040518082815260200191505060405180910390f35b34156101d057600080fd5b610224600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061065d565b604051808215151515815260200191505060405180910390f35b341561024957600080fd5b610275600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506108f7565b6040518082815260200191505060405180910390f35b341561029657600080fd5b61029e61090f565b604051808260ff1660ff16815260200191505060405180910390f35b34156102c557600080fd5b610310600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610922565b6040518082815260200191505060405180910390f35b341561033157600080fd5b61035d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610947565b6040518082815260200191505060405180910390f35b341561037e57600080fd5b610386610990565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156103c65780820151818401526020810190506103ab565b50505050905090810190601f1680156103f35780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561040c57600080fd5b610441600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610a2e565b604051808215151515815260200191505060405180910390f35b341561046657600080fd5b6104b1600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610b87565b6040518082815260200191505060405180910390f35b60038054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561055d5780601f106105325761010080835404028352916020019161055d565b820191906000526020600020905b81548152906001019060200180831161054057829003601f168201915b505050505081565b600081600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60005481565b600080600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905082600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015801561072e5750828110155b151561073957600080fd5b82600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555082600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8110156108865782600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a360019150509392505050565b60016020528060005260406000206000915090505481565b600460009054906101000a900460ff1681565b6002602052816000526040600020602052806000526040600020600091509150505481565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60058054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610a265780601f106109fb57610100808354040283529160200191610a26565b820191906000526020600020905b815481529060010190602001808311610a0957829003601f168201915b505050505081565b600081600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610a7e57600080fd5b81600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a36001905092915050565b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050929150505600a165627a7a72305820df254047bc8f2904ad3e966b6db116d703bebd40efadadb5e738c836ffc8f58a0029"; + +const SNAILTRACER: &str = "608060405234801561001057600080fd5b506004361061004c5760003560e01c806330627b7c1461005157806375ac892a14610085578063784f13661461011d578063c294360114610146575b600080fd5b610059610163565b604080516001600160f81b03199485168152928416602084015292168183015290519081900360600190f35b6100a86004803603604081101561009b57600080fd5b50803590602001356102d1565b6040805160208082528351818301528351919283929083019185019080838360005b838110156100e25781810151838201526020016100ca565b50505050905090810190601f16801561010f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6100596004803603606081101561013357600080fd5b508035906020810135906040013561055b565b6100a86004803603602081101561015c57600080fd5b5035610590565b6000806000610176610400610300610834565b60405180606001604052806001546000546207d5dc028161019357fe5b058152600060208083018290526040928301919091528251600b81905583820151600c81905593830151600d819055835160608082018652928152808401959095528484015282519081018352600654815260075491810191909152600854918101919091526102259161021c916102139161020e91612ef7565b612f64565b6207d5dc612feb565b620f424061301e565b8051600e556020810151600f55604001516010556102416142dd565b61025a816102556102006101806008613064565b613212565b90506102708161025561014561021c6008613064565b905061028481610255610258806008613064565b905061029a8161025561020a61020c6008613064565b90506102a781600461301e565b90506102b1613250565b8051602082015160409092015160f891821b9692821b9550901b92509050565b606060005b6000548112156104c95760006102ed828686613064565b90506002816000015160f81b90808054603f811680603e811461032a576002830184556001831661031c578192505b600160028404019350610342565b600084815260209081902060ff198516905560419094555b505050600190038154600116156103685790600052602060002090602091828204019190065b909190919091601f036101000a81548160ff02191690600160f81b840402179055506002816020015160f81b90808054603f811680603e81146103c557600283018455600183166103b7578192505b6001600284040193506103dd565b600084815260209081902060ff198516905560419094555b505050600190038154600116156104035790600052602060002090602091828204019190065b909190919091601f036101000a81548160ff02191690600160f81b840402179055506002816040015160f81b90808054603f811680603e81146104605760028301845560018316610452578192505b600160028404019350610478565b600084815260209081902060ff198516905560419094555b5050506001900381546001161561049e5790600052602060002090602091828204019190065b815460ff601f929092036101000a9182021916600160f81b90930402919091179055506001016102d6565b506002805460408051602060018416156101000260001901909316849004601f8101849004840282018401909252818152929183018282801561054d5780601f106105225761010080835404028352916020019161054d565b820191906000526020600020905b81548152906001019060200180831161053057829003601f168201915b505050505090505b92915050565b60008060008061056c878787613064565b8051602082015160409092015160f891821b9a92821b9950901b9650945050505050565b600154606090600019015b600081126107a35760005b6000548112156107995760006105bd828487613064565b90506002816000015160f81b90808054603f811680603e81146105fa57600283018455600183166105ec578192505b600160028404019350610612565b600084815260209081902060ff198516905560419094555b505050600190038154600116156106385790600052602060002090602091828204019190065b909190919091601f036101000a81548160ff02191690600160f81b840402179055506002816020015160f81b90808054603f811680603e81146106955760028301845560018316610687578192505b6001600284040193506106ad565b600084815260209081902060ff198516905560419094555b505050600190038154600116156106d35790600052602060002090602091828204019190065b909190919091601f036101000a81548160ff02191690600160f81b840402179055506002816040015160f81b90808054603f811680603e81146107305760028301845560018316610722578192505b600160028404019350610748565b600084815260209081902060ff198516905560419094555b5050506001900381546001161561076e5790600052602060002090602091828204019190065b815460ff601f929092036101000a9182021916600160f81b90930402919091179055506001016105a6565b506000190161059b565b506002805460408051602060018416156101000260001901909316849004601f810184900484028201840190925281815292918301828280156108275780601f106107fc57610100808354040283529160200191610827565b820191906000526020600020905b81548152906001019060200180831161080a57829003601f168201915b505050505090505b919050565b8160008190555080600181905550604051806080016040528060405180606001604052806302faf08081526020016303197500815260200163119e7f8081525081526020016108a460405180606001604052806000815260200161a673198152602001620f423f19815250612f64565b815260006020808301829052604092830182905283518051600355808201516004558301516005558381015180516006559081015160075582015160085582820151600955606092830151600a805460ff1916911515919091179055815192830190915260015490548291906207d5dc028161091c57fe5b058152600060208083018290526040928301919091528251600b81905583820151600c81905593830151600d819055835160608082018652928152808401959095528484015282519081018352600654815260075491810191909152600854918101919091526109979161021c916102139161020e91612ef7565b8051600e55602080820151600f55604091820151601055815160a08101835264174876e8008152825160608082018552641748862a40825263026e8f00828501526304dd1e008286015282840191825284518082018652600080825281860181905281870181905284870191825286518084018852620b71b081526203d09081880181905281890152928501928352608085018181526011805460018082018355919093528651600b9093027f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c688101938455955180517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c69880155808901517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6a8801558901517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6b870155925180517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6c870155808801517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6d8701558801517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6e860155925180517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6f860155958601517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c7085015594909501517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c71830155517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c72909101805492949192909160ff1990911690836002811115610c1057fe5b0217905550505060116040518060a0016040528064174876e8008152602001604051806060016040528064174290493f19815260200163026e8f0081526020016304dd1e008152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806203d09081526020016203d0908152602001620b71b0815250815260200160006002811115610cb657fe5b905281546001818101845560009384526020938490208351600b90930201918255838301518051838301558085015160028085019190915560409182015160038501558185015180516004860155808701516005860155820151600685015560608501518051600786015595860151600885015594015160098301556080830151600a83018054949593949193909260ff1990921691908490811115610d5857fe5b0217905550505060116040518060a0016040528064174876e800815260200160405180606001604052806302faf080815260200163026e8f00815260200164174876e800815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620b71b08152602001620b71b08152602001620b71b0815250815260200160006002811115610dfd57fe5b905281546001818101845560009384526020938490208351600b90930201918255838301518051838301558085015160028085019190915560409182015160038501558185015180516004860155808701516005860155820151600685015560608501518051600786015595860151600885015594015160098301556080830151600a83018054949593949193909260ff1990921691908490811115610e9f57fe5b0217905550505060116040518060a0016040528064174876e800815260200160405180606001604052806302faf080815260200163026e8f00815260200164173e54e97f1981525081526020016040518060600160405280600081526020016000815260200160008152508152602001604051806060016040528060008152602001600081526020016000815250815260200160006002811115610f3f57fe5b905281546001818101845560009384526020938490208351600b90930201918255838301518051838301558085015160028085019190915560409182015160038501558185015180516004860155808701516005860155820151600685015560608501518051600786015595860151600885015594015160098301556080830151600a83018054949593949193909260ff1990921691908490811115610fe157fe5b0217905550505060116040518060a0016040528064174876e800815260200160405180606001604052806302faf080815260200164174876e80081526020016304dd1e00815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620b71b08152602001620b71b08152602001620b71b081525081526020016000600281111561108657fe5b905281546001818101845560009384526020938490208351600b90930201918255838301518051838301558085015160028085019190915560409182015160038501558185015180516004860155808701516005860155820151600685015560608501518051600786015595860151600885015594015160098301556080830151600a83018054949593949193909260ff199092169190849081111561112857fe5b0217905550505060116040518060a0016040528064174876e800815260200160405180606001604052806302faf080815260200164174399c9ff1981526020016304dd1e00815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620b71b08152602001620b71b08152602001620b71b08152508152602001600060028111156111ce57fe5b905281546001818101845560009384526020938490208351600b90930201918255838301518051838301558085015160028085019190915560409182015160038501558185015180516004860155808701516005860155820151600685015560608501518051600786015595860151600885015594015160098301556080830151600a83018054949593949193909260ff199092169190849081111561127057fe5b0217905550505060116040518060a0016040528062fbc5208152602001604051806060016040528063019bfcc0815260200162fbc52081526020016302cd29c0815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e5881525081526020016001600281111561131157fe5b905281546001818101845560009384526020938490208351600b90930201918255838301518051838301558085015160028085019190915560409182015160038501558185015180516004860155808701516005860155820151600685015560608501518051600786015595860151600885015594015160098301556080830151600a83018054949593949193909260ff19909216919084908111156113b357fe5b0217905550505060116040518060a001604052806323c34600815260200160405180606001604052806302faf080815260200163289c455081526020016304dd1e008152508152602001604051806060016040528062b71b00815260200162b71b00815260200162b71b00815250815260200160405180606001604052806000815260200160008152602001600081525081526020016000600281111561145657fe5b905281546001818101845560009384526020938490208351600b90930201918255838301518051838301558085015160028085019190915560409182015160038501558185015180516004860155808701516005860155820151600685015560608501518051600786015595860151600885015594015160098301556080830151600a83018054949593949193909260ff19909216919084908111156114f857fe5b0217905550505060126040518060e00160405280604051806060016040528063035e1f208152602001630188c2e081526020016304a62f8081525081526020016040518060600160405280630459e4408152602001630188c2e081526020016305a1f4a081525081526020016040518060600160405280630459e44081526020016302f34f6081526020016304a62f808152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e5881525081526020016001600281111561160c57fe5b905281546001818101845560009384526020938490208351805160139094029091019283558085015183830155604090810151600280850191909155858501518051600386015580870151600486015582015160058501558185015180516006860155808701516007860155820151600885015560608501518051600986015580870151600a860155820151600b85015560808501518051600c86015580870151600d860155820151600e85015560a08501518051600f860155958601516010850155940151601183015560c0830151601283018054949593949193909260ff19909216919084908111156116fd57fe5b0217905550505060126040518060e00160405280604051806060016040528063035e1f20815260200163016a8c8081526020016304a62f8081525081526020016040518060600160405280630459e4408152602001600081526020016304a62f8081525081526020016040518060600160405280630459e440815260200163016a8c8081526020016305a1f4a08152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e5881525081526020016001600281111561180e57fe5b905281546001818101845560009384526020938490208351805160139094029091019283558085015183830155604090810151600280850191909155858501518051600386015580870151600486015582015160058501558185015180516006860155808701516007860155820151600885015560608501518051600986015580870151600a860155820151600b85015560808501518051600c86015580870151600d860155820151600e85015560a08501518051600f860155958601516010850155940151601183015560c0830151601283018054949593949193909260ff19909216919084908111156118ff57fe5b0217905550505060126040518060e001604052806040518060600160405280630555a9608152602001630188c2e081526020016304a62f8081525081526020016040518060600160405280630459e44081526020016302f34f6081526020016304a62f8081525081526020016040518060600160405280630459e4408152602001630188c2e081526020016305a1f4a08152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e58815250815260200160016002811115611a1357fe5b905281546001818101845560009384526020938490208351805160139094029091019283558085015183830155604090810151600280850191909155858501518051600386015580870151600486015582015160058501558185015180516006860155808701516007860155820151600885015560608501518051600986015580870151600a860155820151600b85015560808501518051600c86015580870151600d860155820151600e85015560a08501518051600f860155958601516010850155940151601183015560c0830151601283018054949593949193909260ff1990921691908490811115611b0457fe5b0217905550505060126040518060e001604052806040518060600160405280630555a960815260200163016a8c8081526020016304a62f8081525081526020016040518060600160405280630459e440815260200163016a8c8081526020016305a1f4a081525081526020016040518060600160405280630459e4408152602001600081526020016304a62f808152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e58815250815260200160016002811115611c1557fe5b905281546001818101845560009384526020938490208351805160139094029091019283558085015183830155604090810151600280850191909155858501518051600386015580870151600486015582015160058501558185015180516006860155808701516007860155820151600885015560608501518051600986015580870151600a860155820151600b85015560808501518051600c86015580870151600d860155820151600e85015560a08501518051600f860155958601516010850155940151601183015560c0830151601283018054949593949193909260ff1990921691908490811115611d0657fe5b0217905550505060126040518060e00160405280604051806060016040528063035e1f208152602001630188c2e081526020016304a62f8081525081526020016040518060600160405280630459e44081526020016302f34f6081526020016304a62f8081525081526020016040518060600160405280630459e4408152602001630188c2e081526020016303aa6a608152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e58815250815260200160016002811115611e1a57fe5b905281546001818101845560009384526020938490208351805160139094029091019283558085015183830155604090810151600280850191909155858501518051600386015580870151600486015582015160058501558185015180516006860155808701516007860155820151600885015560608501518051600986015580870151600a860155820151600b85015560808501518051600c86015580870151600d860155820151600e85015560a08501518051600f860155958601516010850155940151601183015560c0830151601283018054949593949193909260ff1990921691908490811115611f0b57fe5b0217905550505060126040518060e00160405280604051806060016040528063035e1f20815260200163016a8c8081526020016304a62f8081525081526020016040518060600160405280630459e440815260200163016a8c8081526020016303aa6a6081525081526020016040518060600160405280630459e4408152602001600081526020016304a62f808152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e5881525081526020016001600281111561201c57fe5b905281546001818101845560009384526020938490208351805160139094029091019283558085015183830155604090810151600280850191909155858501518051600386015580870151600486015582015160058501558185015180516006860155808701516007860155820151600885015560608501518051600986015580870151600a860155820151600b85015560808501518051600c86015580870151600d860155820151600e85015560a08501518051600f860155958601516010850155940151601183015560c0830151601283018054949593949193909260ff199092169190849081111561210d57fe5b0217905550505060126040518060e001604052806040518060600160405280630555a9608152602001630188c2e081526020016304a62f8081525081526020016040518060600160405280630459e4408152602001630188c2e081526020016303aa6a6081525081526020016040518060600160405280630459e44081526020016302f34f6081526020016304a62f808152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e5881525081526020016001600281111561222157fe5b905281546001818101845560009384526020938490208351805160139094029091019283558085015183830155604090810151600280850191909155858501518051600386015580870151600486015582015160058501558185015180516006860155808701516007860155820151600885015560608501518051600986015580870151600a860155820151600b85015560808501518051600c86015580870151600d860155820151600e85015560a08501518051600f860155958601516010850155940151601183015560c0830151601283018054949593949193909260ff199092169190849081111561231257fe5b0217905550505060126040518060e001604052806040518060600160405280630555a960815260200163016a8c8081526020016304a62f8081525081526020016040518060600160405280630459e4408152602001600081526020016304a62f8081525081526020016040518060600160405280630459e440815260200163016a8c8081526020016303aa6a608152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e5881525081526020016001600281111561242357fe5b905281546001818101845560009384526020938490208351805160139094029091019283558085015183830155604090810151600280850191909155858501518051600386015580870151600486015582015160058501558185015180516006860155808701516007860155820151600885015560608501518051600986015580870151600a860155820151600b85015560808501518051600c86015580870151600d860155820151600e85015560a08501518051600f860155958601516010850155940151601183015560c0830151601283018054949593949193909260ff199092169190849081111561251457fe5b0217905550505060126040518060e00160405280604051806060016040528063035e1f208152602001630188c2e081526020016304a62f8081525081526020016040518060600160405280630459e4408152602001630188c2e081526020016303aa6a6081525081526020016040518060600160405280630555a9608152602001630188c2e081526020016304a62f808152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e5881525081526020016001600281111561262857fe5b905281546001818101845560009384526020938490208351805160139094029091019283558085015183830155604090810151600280850191909155858501518051600386015580870151600486015582015160058501558185015180516006860155808701516007860155820151600885015560608501518051600986015580870151600a860155820151600b85015560808501518051600c86015580870151600d860155820151600e85015560a08501518051600f860155958601516010850155940151601183015560c0830151601283018054949593949193909260ff199092169190849081111561271957fe5b0217905550505060126040518060e00160405280604051806060016040528063035e1f208152602001630188c2e081526020016304a62f8081525081526020016040518060600160405280630555a9608152602001630188c2e081526020016304a62f8081525081526020016040518060600160405280630459e4408152602001630188c2e081526020016305a1f4a08152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e5881525081526020016001600281111561282d57fe5b905281546001818101845560009384526020938490208351805160139094029091019283558085015183830155604090810151600280850191909155858501518051600386015580870151600486015582015160058501558185015180516006860155808701516007860155820151600885015560608501518051600986015580870151600a860155820151600b85015560808501518051600c86015580870151600d860155820151600e85015560a08501518051600f860155958601516010850155940151601183015560c0830151601283018054949593949193909260ff199092169190849081111561291e57fe5b0217905550505060126040518060e00160405280604051806060016040528063035e1f20815260200163016a8c8081526020016304a62f8081525081526020016040518060600160405280630555a960815260200163016a8c8081526020016304a62f8081525081526020016040518060600160405280630459e440815260200163016a8c8081526020016303aa6a608152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e58815250815260200160016002811115612a3257fe5b905281546001818101845560009384526020938490208351805160139094029091019283558085015183830155604090810151600280850191909155858501518051600386015580870151600486015582015160058501558185015180516006860155808701516007860155820151600885015560608501518051600986015580870151600a860155820151600b85015560808501518051600c86015580870151600d860155820151600e85015560a08501518051600f860155958601516010850155940151601183015560c0830151601283018054949593949193909260ff1990921691908490811115612b2357fe5b0217905550505060126040518060e00160405280604051806060016040528063035e1f20815260200163016a8c8081526020016304a62f8081525081526020016040518060600160405280630459e440815260200163016a8c8081526020016305a1f4a081525081526020016040518060600160405280630555a960815260200163016a8c8081526020016304a62f808152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e58815250815260200160016002811115612c3757fe5b905281546001818101845560009384526020938490208351805160139094029091019283558085015183830155604090810151600280850191909155858501518051600386015580870151600486015582015160058501558185015180516006860155808701516007860155820151600885015560608501518051600986015580870151600a860155820151600b85015560808501518051600c86015580870151600d860155820151600e85015560a08501518051600f860155958601516010850155940151601183015560c0830151601283018054949593949193909260ff1990921691908490811115612d2857fe5b0217905550505060005b601254811015612ef257600060128281548110612d4b57fe5b600091825260209182902060408051610140810182526013909302909101805460e08401908152600182015461010085015260028083015461012086015290845282516060818101855260038401548252600484015482880152600584015482860152858701919091528351808201855260068401548152600784015481880152600884015481860152858501528351808201855260098401548152600a84015481880152600b840154818601528186015283518082018552600c8401548152600d84015481880152600e84015481860152608086015283519081018452600f830154815260108301549581019590955260118201549285019290925260a0830193909352601283015491929160c084019160ff90911690811115612e6c57fe5b6002811115612e7757fe5b815250509050612eac61020e612e95836020015184600001516132cd565b612ea7846040015185600001516132cd565b612ef7565b60128381548110612eb957fe5b60009182526020918290208351600960139093029091019182015590820151600a820155604090910151600b9091015550600101612d32565b505050565b612eff6142dd565b604051806060016040528083602001518560400151028460400151866020015102038152602001836040015185600001510284600001518660400151020381526020018360000151856020015102846020015186600001510203815250905092915050565b612f6c6142dd565b604082015160208301518351600092612f9292918002918002919091019080020161330c565b90506040518060600160405280828560000151620f42400281612fb157fe5b058152602001828560200151620f42400281612fc957fe5b058152602001828560400151620f42400281612fe157fe5b0590529392505050565b612ff36142dd565b5060408051606081018252835183028152602080850151840290820152928101519091029082015290565b6130266142dd565b60405180606001604052808385600001518161303e57fe5b0581526020018385602001518161305157fe5b05815260200183856040015181612fe157fe5b61306c6142dd565b6000546013805463ffffffff1916918502860163ffffffff169190911790556130936142dd565b905060005b828112156131f157600061317261314c61021c613115600b60405180606001604052908160008201548152602001600182015481526020016002820154815250506207a1206000546207a1206130ec613343565b63ffffffff16816130f957fe5b0663ffffffff168d620f424002018161310e57fe5b0503612feb565b60408051606081018252600e548152600f5460208201526010549181019190915260015461025591906207a12090816130ec613343565b604080516060810182526006548152600754602082015260085491810191909152613212565b6040805160e081019091526003546080820190815260045460a083015260055460c083015291925060009181906131ae9061025586608c612feb565b81526020016131bc84612f64565b815260006020820181905260409091015290506131e5846102556131df8461336c565b8861301e565b93505050600101613098565b5061320861021c61320183613753565b60ff612feb565b90505b9392505050565b61321a6142dd565b50604080516060810182528251845101815260208084015181860151019082015291810151928101519092019181019190915290565b60008080556001819055613266906002906142fe565b60006003819055600481905560058190556006819055600781905560088190556009819055600a805460ff19169055600b819055600c819055600d819055600e819055600f81905560108190556132bf90601190614345565b6132cb60126000614366565b565b6132d56142dd565b5060408051606081018252825184510381526020808401518186015103908201528282015184830151039181019190915292915050565b80600260018201055b8181121561333d5780915060028182858161332c57fe5b05018161333557fe5b059050613315565b50919050565b6013805463ffffffff19811663ffffffff9182166341c64e6d0261303901821617918290551690565b6133746142dd565b600a826040015113156133a657604051806060016040528060008152602001600081526020016000815250905061082f565b60008060006133b48561379f565b91945092509050826133e857604051806060016040528060008152602001600081526020016000815250935050505061082f565b6133f0614387565b6133f86143c7565b6134006142dd565b6134086142dd565b600086600181111561341657fe5b1415613505576011858154811061342957fe5b60009182526020918290206040805160a081018252600b90930290910180548352815160608082018452600183015482526002808401548388015260038401548386015285870192909252835180820185526004840154815260058401548188015260068401548186015285850152835180820185526007840154815260088401549681019690965260098301549386019390935291830193909352600a830154919291608084019160ff909116908111156134e157fe5b60028111156134ec57fe5b8152505093508360600151915083604001519050613653565b6012858154811061351257fe5b600091825260209182902060408051610140810182526013909302909101805460e08401908152600182015461010085015260028083015461012086015290845282516060818101855260038401548252600484015482880152600584015482860152858701919091528351808201855260068401548152600784015481880152600884015481860152858501528351808201855260098401548152600a84015481880152600b840154818601528186015283518082018552600c8401548152600d84015481880152600e84015481860152608086015283519081018452600f830154815260108301549581019590955260118201549285019290925260a0830193909352601283015491929160c084019160ff9091169081111561363357fe5b600281111561363e57fe5b8152505092508260a001519150826080015190505b6040820151600190811215613669575060408201515b808360200151131561367c575060208201515b808360400151131561368f575060408201515b60408a01805160010190819052600512156136f75780620f42406136b1613343565b63ffffffff16816136be57fe5b0663ffffffff1612156136e8576136e16136db84620f4240612feb565b8261301e565b92506136f7565b50965061082f95505050505050565b6136ff6142dd565b600088600181111561370d57fe5b14156137255761371e8b878b613a57565b9050613733565b6137308b868b613aec565b90505b6137448361025561021c8785613baa565b9b9a5050505050505050505050565b61375b6142dd565b60405180606001604052806137738460000151613be8565b81526020016137858460200151613be8565b81526020016137978460400151613be8565b905292915050565b60008080808080805b6011548110156138c2576000613890601183815481106137c457fe5b60009182526020918290206040805160a081018252600b90930290910180548352815160608082018452600183015482526002808401548388015260038401548386015285870192909252835180820185526004840154815260058401548188015260068401548186015285850152835180820185526007840154815260088401549681019690965260098301549386019390935291830193909352600a830154919291608084019160ff9091169081111561387c57fe5b600281111561388757fe5b9052508a613c13565b90506000811380156138a957508415806138a957508481125b156138b957809450600093508192505b506001016137a8565b5060005b601254811015613a49576000613a17601283815481106138e257fe5b600091825260209182902060408051610140810182526013909302909101805460e08401908152600182015461010085015260028083015461012086015290845282516060818101855260038401548252600484015482880152600584015482860152858701919091528351808201855260068401548152600784015481880152600884015481860152858501528351808201855260098401548152600a84015481880152600b840154818601528186015283518082018552600c8401548152600d84015481880152600e84015481860152608086015283519081018452600f830154815260108301549581019590955260118201549285019290925260a0830193909352601283015491929160c084019160ff90911690811115613a0357fe5b6002811115613a0e57fe5b9052508a613cbb565b9050600081138015613a305750841580613a3057508481125b15613a4057809450600193508192505b506001016138c6565b509196909550909350915050565b613a5f6142dd565b6000613a7a856000015161025561021c886020015187612feb565b90506000613a8f61020e8387602001516132cd565b9050600085608001516002811115613aa357fe5b1415613ae1576000613ab9828860200151613e0c565b12613acd57613aca81600019612feb565b90505b613ad8868383613e31565b9250505061320b565b613ad8868383613fc1565b613af46142dd565b6000613b0f856000015161025561021c886020015187612feb565b6060860151909150620a2c2a9015613b2757506216e3605b6000620f4240613b3f87606001518960200151613e0c565b81613b4657fe5b05905060008112613b55576000035b64e8d4a5100081800281038380020281900590036000811215613b8c57613b8188858960600151613fc1565b94505050505061320b565b613b9e88858960600151868686614039565b98975050505050505050565b613bb26142dd565b50604080516060810182528251845102815260208084015181860151029082015291810151928101519092029181019190915290565b600080821215613bfa5750600061082f565b620f4240821315613c0f5750620f424061082f565b5090565b600080613c28846020015184600001516132cd565b90506000620f4240613c3e838660200151613e0c565b81613c4557fe5b865191900591506000908002613c5b8480613e0c565b838402030190506000811215613c775760009350505050610555565b613c808161330c565b90506103e88183031315613c9957900391506105559050565b6103e88183011315613caf570191506105559050565b50600095945050505050565b600080613cd0846020015185600001516132cd565b90506000613ce6856040015186600001516132cd565b90506000613cf8856020015183612ef7565b90506000620f4240613d0a8584613e0c565b81613d1157fe5b0590506103e71981138015613d2757506103e881125b15613d39576000945050505050610555565b85518751600091613d49916132cd565b9050600082613d588386613e0c565b81613d5f57fe5b0590506000811280613d735750620f424081135b15613d875760009650505050505050610555565b6000613d938388612ef7565b9050600084613da68b6020015184613e0c565b81613dad57fe5b0590506000811280613dc35750620f4240818401135b15613dd957600098505050505050505050610555565b600085613de68985613e0c565b81613ded57fe5b0590506103e88112156137445760009950505050505050505050610555565b6040808201519083015160208084015190850151845186510291020191020192915050565b613e396142dd565b6000620f424080613e48613343565b63ffffffff1681613e5557fe5b0663ffffffff16625fdfb00281613e6857fe5b0590506000620f4240613e79613343565b63ffffffff1681613e8657fe5b0663ffffffff1690506000613e9a8261330c565b6103e8029050613ea86142dd565b620186a0613eb98760000151614216565b1315613ee657604051806060016040528060008152602001620f4240815260200160008152509050613f09565b6040518060600160405280620f4240815260200160008152602001600081525090505b613f1661020e8288612ef7565b90506000613f2761020e8884612ef7565b9050613f7f61020e613f64613f5285620f424088613f448c61422e565b0281613f4c57fe5b05612feb565b61025585620f424089613f448d61424e565b6102558a613f7689620f42400361330c565b6103e802612feb565b9150613fb460405180608001604052808a81526020018481526020018b6040015181526020018b60600151151581525061336c565b9998505050505050505050565b613fc96142dd565b6000613ffb61020e8660200151613ff686620f4240613fec898c60200151613e0c565b60020281613f4c57fe5b6132cd565b90506140306040518060800160405280868152602001838152602001876040015181526020018760600151151581525061336c565b95945050505050565b6140416142dd565b60608701516000199015614053575060015b600061408961020e61021c61406c8c602001518a612feb565b613ff68b6140798a61330c565b620f42408c8e0205018802612feb565b60608a0151909150620f42408601906140ba57620f42406140aa838a613e0c565b816140b157fe5b05620f42400390505b60408a0151619c406c0c9f2c9cd04674edea40000000620ea6008480028502850285020205019060021261415e5761412a61411f60405180608001604052808d81526020018681526020018e6040015181526020018e6060015115151581525061336c565b82620f424003612feb565b92506141448361025561413e8e8e8e613fc1565b84612feb565b925061415383620f424061301e565b94505050505061420c565b600281056203d09001620f4240614173613343565b63ffffffff168161418057fe5b0663ffffffff1612156141b2576141536141a461419e8d8d8d613fc1565b83612feb565b600283056203d0900161301e565b6142056141f76141ec60405180608001604052808e81526020018781526020018f6040015181526020018f6060015115151581525061336c565b83620f424003612feb565b60028305620b71b00361301e565b9450505050505b9695505050505050565b60008082131561422757508061082f565b5060000390565b60008061423a8361424e565b905061320b81820264e8d4a510000361330c565b60005b600082121561426757625fdfb082019150614251565b5b625fdfb0821261427f57625fdfb082039150614268565b6001828160025b818313156142d457818385028161429957fe5b0585019450620f4240808788860202816142af57fe5b05816142b757fe5b600095909503940592506001810181029190910290600201614286565b50505050919050565b60405180606001604052806000815260200160008152602001600081525090565b50805460018160011615610100020316600290046000825580601f106143245750614342565b601f0160209004906000526020600020908101906143429190614401565b50565b50805460008255600b02906000526020600020908101906143429190614416565b50805460008255601302906000526020600020908101906143429190614475565b6040518060a00160405280600081526020016143a16142dd565b81526020016143ae6142dd565b81526020016143bb6142dd565b81526020016000905290565b6040518060e001604052806143da6142dd565b81526020016143e76142dd565b81526020016143f46142dd565b81526020016143a16142dd565b5b80821115613c0f5760008155600101614402565b5b80821115613c0f57600080825560018201819055600282018190556003820181905560048201819055600582018190556006820181905560078201819055600882018190556009820155600a8101805460ff19169055600b01614417565b5b80821115613c0f576000808255600182018190556002820181905560038201819055600482018190556005820181905560068201819055600782018190556008820181905560098201819055600a8201819055600b8201819055600c8201819055600d8201819055600e8201819055600f820181905560108201819055601182015560128101805460ff1916905560130161447656fea2646970667358221220037024f5647853879c58fbcc61ac3616455f6f731cc6e84f91eb5a3b4e06c00464736f6c63430007060033"; diff --git a/crates/revm/src/evm.rs b/crates/revm/src/evm.rs index 298b09b18a..c8be62c91f 100644 --- a/crates/revm/src/evm.rs +++ b/crates/revm/src/evm.rs @@ -143,7 +143,7 @@ impl EVM { } macro_rules! create_evm { - ($spec:ident, $db:ident,$env:ident,$inspector:ident) => { + ($spec:ident, $db:ident, $env:ident, $inspector:ident) => { Box::new(EVMImpl::<'a, $spec, DB, INSPECT>::new( $db, $env, diff --git a/crates/revm/src/inspector/gas.rs b/crates/revm/src/inspector/gas.rs index 28ccf87f28..7886ed00be 100644 --- a/crates/revm/src/inspector/gas.rs +++ b/crates/revm/src/inspector/gas.rs @@ -241,7 +241,7 @@ mod tests { for (pc, gas) in inspector.gas_remaining_steps { println!( "{pc} {} {gas:?}", - OpCode::try_from_u8(bytecode.bytes()[pc]).unwrap().as_str(), + OpCode::new(bytecode.bytes()[pc]).unwrap().as_str(), ); } } diff --git a/crates/revm/src/journaled_state.rs b/crates/revm/src/journaled_state.rs index 020f18bd17..92b983dc9e 100644 --- a/crates/revm/src/journaled_state.rs +++ b/crates/revm/src/journaled_state.rs @@ -1,12 +1,10 @@ use crate::interpreter::{inner_models::SelfDestructResult, InstructionResult}; use crate::primitives::{ - db::Database, hash_map::Entry, Account, Bytecode, HashMap, Log, State, StorageSlot, - TransientStorage, B160, KECCAK_EMPTY, U256, + db::Database, hash_map::Entry, Account, Bytecode, HashMap, Log, Spec, SpecId::*, State, + StorageSlot, TransientStorage, B160, KECCAK_EMPTY, U256, }; -use alloc::{vec, vec::Vec}; -use core::mem::{self}; -use revm_interpreter::primitives::Spec; -use revm_interpreter::primitives::SpecId::SPURIOUS_DRAGON; +use alloc::vec::Vec; +use core::mem; #[derive(Debug, Clone, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] diff --git a/crates/revm/src/lib.rs b/crates/revm/src/lib.rs index 39f030d57a..01f6635909 100644 --- a/crates/revm/src/lib.rs +++ b/crates/revm/src/lib.rs @@ -1,5 +1,8 @@ #![cfg_attr(not(feature = "std"), no_std)] +#[macro_use] +extern crate alloc; + pub mod db; mod evm; mod evm_impl; @@ -17,8 +20,6 @@ pub use evm::{evm_inner, new, EVM}; pub use evm_impl::EVMData; pub use journaled_state::{JournalEntry, JournaledState}; -extern crate alloc; - // reexport `revm_precompiles` #[doc(inline)] pub use revm_precompile as precompile; diff --git a/examples/fork_ref_transact.rs b/examples/fork_ref_transact.rs index 0fba487d2b..3eae558b19 100644 --- a/examples/fork_ref_transact.rs +++ b/examples/fork_ref_transact.rs @@ -89,16 +89,15 @@ async fn main() -> Result<()> { // unpack output call enum into raw bytes let value = match result { - ExecutionResult::Success { output, .. } => match output { - Output::Call(value) => Some(value), - _ => None, - }, - _ => None, + ExecutionResult::Success { + output: Output::Call(value), + .. + } => value, + result => panic!("Execution failed: {result:?}"), }; // decode bytes to reserves + ts via ethers-rs's abi decode - let (reserve0, reserve1, ts): (u128, u128, u32) = - abi.decode_output("getReserves", value.unwrap())?; + let (reserve0, reserve1, ts): (u128, u128, u32) = abi.decode_output("getReserves", value)?; // Print emulated getReserves() call output println!("Reserve0: {:#?}", reserve0);