diff --git a/Cargo.lock b/Cargo.lock index 5809d17fd8..3002d67918 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -32,10 +32,13 @@ dependencies = [ ] [[package]] -name = "arrayref" -version = "0.3.6" +name = "arbitrary" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" +checksum = "b0224938f92e7aef515fac2ff2d18bd1115c1394ddf4a092e0c87e8be9499ee5" +dependencies = [ + "derive_arbitrary", +] [[package]] name = "arrayvec" @@ -45,13 +48,13 @@ checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" [[package]] name = "async-trait" -version = "0.1.59" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6e93155431f3931513b243d371981bb2770112b370c82745a1d19d2f99364" +checksum = "705339e0e4a9690e2908d2b3d049d85682cf19fbd5782494498fbf7003a6a282" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.49", + "quote 1.0.23", + "syn 1.0.107", ] [[package]] @@ -71,7 +74,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", "winapi", ] @@ -83,9 +86,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a8c1df849285fbacd587de7818cc7d13be6cd2cbcd47a04fb1801b0e2706e33" dependencies = [ "proc-macro-error", - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.49", + "quote 1.0.23", + "syn 1.0.107", ] [[package]] @@ -112,6 +115,21 @@ version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf" +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + [[package]] name = "bitflags" version = "1.3.2" @@ -183,9 +201,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.77" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4" +checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" [[package]] name = "cfg-if" @@ -220,16 +238,15 @@ dependencies = [ [[package]] name = "console" -version = "0.15.2" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c050367d967ced717c04b65d8c619d863ef9292ce0c5760028655a2fb298718c" +checksum = "c9b6515d269224923b26b5febea2ed42b2d5f2ce37284a4dd670fedd6cb8347a" dependencies = [ "encode_unicode", "lazy_static", "libc", - "terminal_size", "unicode-width", - "winapi", + "windows-sys", ] [[package]] @@ -283,14 +300,25 @@ dependencies = [ [[package]] name = "der" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dd2ae565c0a381dde7fade45fce95984c568bdcb4700a4fdbe3175e0380b2f" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" dependencies = [ "const-oid", "zeroize", ] +[[package]] +name = "derive_arbitrary" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf460bbff5f571bfc762da5102729f59f338be7db17a21fade44c5c4f5005350" +dependencies = [ + "proc-macro2 1.0.49", + "quote 1.0.23", + "syn 1.0.107", +] + [[package]] name = "derive_more" version = "0.99.17" @@ -298,10 +326,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" dependencies = [ "convert_case", - "proc-macro2", - "quote", + "proc-macro2 1.0.49", + "quote 1.0.23", "rustc_version", - "syn", + "syn 1.0.107", ] [[package]] @@ -361,6 +389,17 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "enumn" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88bcb3a067a6555d577aba299e75eff9942da276e6506fc6274327daa026132" +dependencies = [ + "proc-macro2 1.0.49", + "quote 1.0.23", + "syn 1.0.107", +] + [[package]] name = "ethabi" version = "18.0.0" @@ -432,7 +471,7 @@ dependencies = [ "strum", "thiserror", "tiny-keccak", - "unicode-xid", + "unicode-xid 0.2.4", ] [[package]] @@ -472,6 +511,15 @@ dependencies = [ "ws_stream_wasm", ] +[[package]] +name = "fastrand" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" +dependencies = [ + "instant", +] + [[package]] name = "ff" version = "0.12.1" @@ -569,9 +617,9 @@ version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.49", + "quote 1.0.23", + "syn 1.0.107", ] [[package]] @@ -727,6 +775,15 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + [[package]] name = "hex" version = "0.4.3" @@ -865,9 +922,9 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.49", + "quote 1.0.23", + "syn 1.0.107", ] [[package]] @@ -906,15 +963,15 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.5.1" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f88c5561171189e69df9d98bcf18fd5f9558300f7ea7b801eb8a0fd748bd8745" +checksum = "30e22bd8629359895450b59ea7a776c850561b96a3b1d31321c1949d9e6c9146" [[package]] name = "itoa" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" +checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" [[package]] name = "js-sys" @@ -958,9 +1015,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.138" +version = "0.2.139" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" +checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" [[package]] name = "lock_api" @@ -1089,35 +1146,14 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.14.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" dependencies = [ - "hermit-abi", + "hermit-abi 0.2.6", "libc", ] -[[package]] -name = "num_enum" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf5395665662ef45796a4ff5486c5d41d29e0c09640af4c5f17fd94ee2c119c9" -dependencies = [ - "num_enum_derive", -] - -[[package]] -name = "num_enum_derive" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b0498641e53dd6ac1a4f22547548caa6864cc4933784319cd1775271c5a46ce" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "number_prefix" version = "0.4.0" @@ -1150,9 +1186,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "003b2be5c6c53c1cfeb0a238b8a1c3915cd410feb684457a36c10038f764bb1c" dependencies = [ "bytes", - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.49", + "quote 1.0.23", + "syn 1.0.107", ] [[package]] @@ -1176,9 +1212,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9299338969a3d2f491d65f140b00ddec470858402f888af98e8642fb5e8965cd" dependencies = [ "proc-macro-crate", - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.49", + "quote 1.0.23", + "syn 1.0.107", ] [[package]] @@ -1237,9 +1273,9 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.49", + "quote 1.0.23", + "syn 1.0.107", ] [[package]] @@ -1275,9 +1311,9 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "0.3.15" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15eb2c6e362923af47e13c23ca5afb859e83d54452c55b0b9ac763b8f7c1ac16" +checksum = "26f6a7b87c2e435a3241addceeeff740ff8b7e76b74c13bf9acb17fa454ea00b" [[package]] name = "ppv-lite86" @@ -1317,9 +1353,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.49", + "quote 1.0.23", + "syn 1.0.107", "version_check", ] @@ -1329,27 +1365,88 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ - "proc-macro2", - "quote", + "proc-macro2 1.0.49", + "quote 1.0.23", "version_check", ] [[package]] name = "proc-macro2" -version = "1.0.47" +version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" +dependencies = [ + "unicode-xid 0.1.0", +] + +[[package]] +name = "proc-macro2" +version = "1.0.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" dependencies = [ "unicode-ident", ] +[[package]] +name = "proptest" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0d9cc07f18492d879586c92b485def06bc850da3118075cd45d50e9c95b0e5" +dependencies = [ + "bit-set", + "bitflags", + "byteorder", + "lazy_static", + "num-traits", + "quick-error 2.0.1", + "rand", + "rand_chacha", + "rand_xorshift", + "regex-syntax", + "rusty-fork", + "tempfile", +] + +[[package]] +name = "proptest-derive" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "051d9d20dbe9e9dfe594328b6eaab72ccf571fee818991dd1c1ba5469b5f32d4" +dependencies = [ + "proc-macro2 0.4.30", + "quote 0.6.13", + "syn 0.15.44", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + [[package]] name = "quote" -version = "1.0.21" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" dependencies = [ - "proc-macro2", + "proc-macro2 0.4.30", +] + +[[package]] +name = "quote" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +dependencies = [ + "proc-macro2 1.0.49", ] [[package]] @@ -1388,6 +1485,15 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rand_xorshift" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +dependencies = [ + "rand_core", +] + [[package]] name = "redox_syscall" version = "0.2.16" @@ -1414,6 +1520,15 @@ version = "0.6.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + [[package]] name = "reqwest" version = "0.11.13" @@ -1457,38 +1572,42 @@ dependencies = [ name = "revm" version = "2.3.1" dependencies = [ - "arrayref", "auto_impl", "bytes", - "derive_more", "ethers-core", "ethers-providers", - "fixed-hash", "futures", "hashbrown 0.13.1", "hex", "hex-literal", - "num_enum", - "revm_precompiles", - "rlp", - "ruint", + "revm-interpreter", + "revm-precompiles", "serde", - "sha3", "tokio", ] [[package]] -name = "revm-test" -version = "0.1.0" +name = "revm-interpreter" +version = "3.0.0" dependencies = [ + "arbitrary", "bytes", + "derive_more", + "enumn", + "fixed-hash", + "hashbrown 0.13.1", "hex", - "microbench", - "revm", + "hex-literal", + "proptest", + "proptest-derive", + "rlp", + "ruint", + "serde", + "sha3", ] [[package]] -name = "revm_precompiles" +name = "revm-precompiles" version = "1.1.2" dependencies = [ "bytes", @@ -1505,6 +1624,17 @@ dependencies = [ "substrate-bn", ] +[[package]] +name = "revm-test" +version = "0.1.0" +dependencies = [ + "bytes", + "hex", + "microbench", + "revm", + "revm-interpreter", +] + [[package]] name = "revme" version = "0.2.0" @@ -1595,9 +1725,9 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e33d7b2abe0c340d8797fe2907d3f20d3b5ea5908683618bfe80df7f621f672a" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.49", + "quote 1.0.23", + "syn 1.0.107", ] [[package]] @@ -1606,9 +1736,11 @@ version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ad3a104dc8c3867f653b0fec89c65e00b0ceb752718ad282177a7e0f33257ac" dependencies = [ + "arbitrary", "bn-rs", "derive_more", "primitive-types", + "proptest", "rlp", "ruint-macro", "rustc_version", @@ -1660,15 +1792,27 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.9" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" +checksum = "5583e89e108996506031660fe09baa5011b9dd0341b89029313006d1fb508d70" + +[[package]] +name = "rusty-fork" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" +dependencies = [ + "fnv", + "quick-error 1.2.3", + "tempfile", + "wait-timeout", +] [[package]] name = "ryu" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" [[package]] name = "same-file" @@ -1698,9 +1842,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "303959cf613a6f6efd19ed4b4ad5bf79966a13352716299ad532cfb115f4205c" dependencies = [ "proc-macro-crate", - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.49", + "quote 1.0.23", + "syn 1.0.107", ] [[package]] @@ -1753,9 +1897,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.14" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" +checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a" [[package]] name = "send_wrapper" @@ -1778,9 +1922,9 @@ version = "1.0.152" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.49", + "quote 1.0.23", + "syn 1.0.107", ] [[package]] @@ -1920,9 +2064,9 @@ checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" dependencies = [ "heck 0.3.3", "proc-macro-error", - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.49", + "quote 1.0.23", + "syn 1.0.107", ] [[package]] @@ -1941,10 +2085,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" dependencies = [ "heck 0.4.0", - "proc-macro2", - "quote", + "proc-macro2 1.0.49", + "quote 1.0.23", "rustversion", - "syn", + "syn 1.0.107", ] [[package]] @@ -1968,12 +2112,23 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.105" +version = "0.15.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" +dependencies = [ + "proc-macro2 0.4.30", + "quote 0.6.13", + "unicode-xid 0.1.0", +] + +[[package]] +name = "syn" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" +checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" dependencies = [ - "proc-macro2", - "quote", + "proc-macro2 1.0.49", + "quote 1.0.23", "unicode-ident", ] @@ -1984,12 +2139,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] -name = "terminal_size" -version = "0.1.17" +name = "tempfile" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" dependencies = [ + "cfg-if", + "fastrand", "libc", + "redox_syscall", + "remove_dir_all", "winapi", ] @@ -2017,9 +2176,9 @@ version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.49", + "quote 1.0.23", + "syn 1.0.107", ] [[package]] @@ -2048,9 +2207,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.23.0" +version = "1.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eab6d665857cc6ca78d6e80303a02cea7a7851e85dfbd77cbdc09bd129f1ef46" +checksum = "1d9f76183f91ecfb55e1d7d5602bd1d979e38a3a522fe900241cf195624d67ae" dependencies = [ "autocfg", "bytes", @@ -2070,9 +2229,9 @@ version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.49", + "quote 1.0.23", + "syn 1.0.107", ] [[package]] @@ -2118,9 +2277,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.9" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +checksum = "1333c76748e868a4d9d1017b5ab53171dfd095f70c712fdb4653a406547f598f" dependencies = [ "serde", ] @@ -2173,9 +2332,9 @@ dependencies = [ [[package]] name = "try-lock" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "tungstenite" @@ -2200,9 +2359,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "uint" @@ -2224,9 +2383,9 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" [[package]] name = "unicode-ident" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" [[package]] name = "unicode-normalization" @@ -2249,6 +2408,12 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +[[package]] +name = "unicode-xid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" + [[package]] name = "unicode-xid" version = "0.2.4" @@ -2290,6 +2455,15 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + [[package]] name = "walkdir" version = "2.3.2" @@ -2336,9 +2510,9 @@ dependencies = [ "bumpalo", "log", "once_cell", - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.49", + "quote 1.0.23", + "syn 1.0.107", "wasm-bindgen-shared", ] @@ -2360,7 +2534,7 @@ version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" dependencies = [ - "quote", + "quote 1.0.23", "wasm-bindgen-macro-support", ] @@ -2370,9 +2544,9 @@ version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.49", + "quote 1.0.23", + "syn 1.0.107", "wasm-bindgen-backend", "wasm-bindgen-shared", ] diff --git a/bins/revm-test/Cargo.toml b/bins/revm-test/Cargo.toml index 84eafe6527..6a16efa985 100644 --- a/bins/revm-test/Cargo.toml +++ b/bins/revm-test/Cargo.toml @@ -8,6 +8,7 @@ edition = "2021" bytes = "1.1" hex = "0.4" revm = { path = "../../crates/revm", version = "2.3.1" } +revm-interpreter = { path = "../../crates/interpreter", version = "3.0.0" } microbench = "0.5" [[bin]] diff --git a/bins/revm-test/src/bin/snailtracer.rs b/bins/revm-test/src/bin/snailtracer.rs index bf1a9aa8f1..89564584af 100644 --- a/bins/revm-test/src/bin/snailtracer.rs +++ b/bins/revm-test/src/bin/snailtracer.rs @@ -1,8 +1,9 @@ use std::time::Duration; use bytes::Bytes; -use revm::{db::BenchmarkDB, Bytecode, TransactTo}; +use revm::{db::BenchmarkDB, Bytecode, CallContext, TransactTo, B160, U256}; +use revm_interpreter::{specification::BerlinSpec, DummyHost}; extern crate alloc; pub fn simple_example() { @@ -10,7 +11,8 @@ pub fn simple_example() { // BenchmarkDB is dummy state that implements Database trait. let mut evm = revm::new(); - evm.database(BenchmarkDB::new_bytecode(Bytecode::new_raw(contract_data))); + let bytecode = 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" @@ -24,15 +26,42 @@ pub fn simple_example() { evm.env.tx.data = Bytes::from(hex::decode("30627b7c").unwrap()); // Microbenchmark - let bench_options = microbench::Options::default().time(Duration::from_secs(3)); + let bench_options = microbench::Options::default().time(Duration::from_secs(2)); - microbench::bench(&bench_options, "Snailtracer benchmark", || { - let (_, _) = evm.transact(); + let env = evm.env.clone(); + microbench::bench( + &bench_options, + "Snailtracer Host+Interpreter benchmark", + || { + let (_, _) = evm.transact(); + }, + ); + + // revm interpreter + + let contract = revm_interpreter::Contract::new_with_context::( + evm.env.tx.data, + bytecode, + &CallContext { + address: B160::zero(), + caller: evm.env.tx.caller, + code_address: B160::zero(), + apparent_value: U256::from(0), + scheme: revm::CallScheme::Call, + }, + ); + + let mut host = DummyHost::new(env); + microbench::bench(&bench_options, "Snailtracer Interpreter benchmark", || { + let mut interpreter = + revm_interpreter::Interpreter::new::(contract.clone(), u64::MAX, false); + interpreter.run::<_, BerlinSpec>(&mut host); + host.clear() }); } fn main() { - println!("Hello, world!"); + println!("Running snailtracer bench!"); simple_example(); println!("end!"); } diff --git a/bins/revme/Cargo.toml b/bins/revme/Cargo.toml index 73df9fc9b8..0d431cb137 100644 --- a/bins/revme/Cargo.toml +++ b/bins/revme/Cargo.toml @@ -21,7 +21,7 @@ revm = { path = "../../crates/revm", version = "2.3.1", default-features = false "ethersdb", "std", "secp256k1", - "with-serde", + "serde", ] } rlp = { version = "0.5", default-features = false } ruint = { version = "1.7.0", features = ["rlp", "serde"] } diff --git a/bins/revme/src/statetest/models/spec.rs b/bins/revme/src/statetest/models/spec.rs index b7ad099c1d..b7e33a2b62 100644 --- a/bins/revme/src/statetest/models/spec.rs +++ b/bins/revme/src/statetest/models/spec.rs @@ -27,6 +27,8 @@ pub enum SpecName { MergeMeterInitCode, #[serde(alias = "Merge+3855")] MergePush0, + #[serde(other)] + Unknown, } impl SpecName { @@ -49,7 +51,8 @@ impl SpecName { Self::MergePush0 => SpecId::MERGE_EOF, Self::ByzantiumToConstantinopleAt5 | Self::Constantinople => { panic!("Overriden with PETERSBURG") - } //_ => panic!("Conversion failed"), + } + Self::Unknown => panic!("Unknown spec"), } } } diff --git a/bins/revme/src/statetest/runner.rs b/bins/revme/src/statetest/runner.rs index bb6ad20bb8..5b9e68c45d 100644 --- a/bins/revme/src/statetest/runner.rs +++ b/bins/revme/src/statetest/runner.rs @@ -8,10 +8,8 @@ use std::{ use indicatif::ProgressBar; use revm::{ - bits::{B160, B256}, - db::AccountState, - inspectors::CustomPrintTracer, - Bytecode, CreateScheme, Env, ExecutionResult, SpecId, TransactTo, U256, + db::AccountState, inspectors::CustomPrintTracer, Bytecode, CreateScheme, Env, ExecutionResult, + SpecId, TransactTo, B160, B256, U256, }; use std::sync::atomic::Ordering; use walkdir::{DirEntry, WalkDir}; @@ -189,6 +187,7 @@ pub fn execute_test_suit(path: &Path, elapsed: &Arc>) -> Result< | SpecName::MergeEOF | SpecName::MergeMeterInitCode | SpecName::MergePush0 + | SpecName::Unknown ) { continue; } diff --git a/crates/interpreter/CHANGELOG.md b/crates/interpreter/CHANGELOG.md new file mode 100644 index 0000000000..7e7c3799e5 --- /dev/null +++ b/crates/interpreter/CHANGELOG.md @@ -0,0 +1,3 @@ +# v3.0.0 + +Interpreter was extracted from main REVM crate. Before v3.0.0 version, this code was part of REVM. \ No newline at end of file diff --git a/crates/interpreter/Cargo.toml b/crates/interpreter/Cargo.toml new file mode 100644 index 0000000000..e3a32a0699 --- /dev/null +++ b/crates/interpreter/Cargo.toml @@ -0,0 +1,71 @@ +[package] +authors = ["Dragan Rakita "] +description = "REVM Interpreter" +edition = "2021" +keywords = ["no_std", "ethereum", "vm", "evm", "revm", "interpreter"] +license = "MIT" +name = "revm-interpreter" +repository = "https://github.com/bluealloy/revm" +version = "3.0.0" +readme = "../../README.md" + +[dependencies] +bytes = { version = "1.1", default-features = false } +hashbrown = { version = "0.13" } +hex = { version = "0.4", default-features = false } +rlp = { version = "0.5", default-features = false } # used for create2 address calculation +ruint = { version = "1.7.0", features = ["primitive-types", "rlp"] } + + +# bits B256 B160 crate +fixed-hash = { version = "0.8", default-features = false, features = [ + "rustc-hex", +] } + +#utility +hex-literal = "0.3" +derive_more = "0.99" +enumn = "0.1" + +# sha3 keccak hasher +sha3 = { version = "0.10", default-features = false, features = [] } + +# optional +serde = { version = "1.0", features = ["derive", "rc"], optional = true } +arbitrary = { version = "1.2", features = ["derive"], optional = true } + +[dev-dependencies] +arbitrary = { version = "1.2", features = ["derive"] } +proptest = { version = "1.0" } +proptest-derive = "0.2.0" +ruint = { version = "1.7.0", features = [ + "primitive-types", + "rlp", + "proptest", + "arbitrary", +] } + +[features] +default = ["std"] +dev = [ + "memory_limit", + "optional_balance_check", + "optional_block_gas_limit", + "optional_eip3607", + "optional_gas_refund", +] +memory_limit = [] +no_gas_measuring = [] +optional_balance_check = [] +optional_block_gas_limit = [] +optional_eip3607 = [] +optional_gas_refund = [] +std = ["bytes/std", "rlp/std", "hex/std"] +serde = [ + "dep:serde", + "hex/serde", + "hashbrown/serde", + "ruint/serde", + "bytes/serde", +] +arbitrary = ["dep:arbitrary", "ruint/arbitrary", "ruint/proptest"] diff --git a/crates/revm_precompiles/LICENSE b/crates/interpreter/LICENSE similarity index 100% rename from crates/revm_precompiles/LICENSE rename to crates/interpreter/LICENSE diff --git a/crates/revm/src/bits.rs b/crates/interpreter/src/bits.rs similarity index 93% rename from crates/revm/src/bits.rs rename to crates/interpreter/src/bits.rs index 717c55415e..bf42f773e6 100644 --- a/crates/revm/src/bits.rs +++ b/crates/interpreter/src/bits.rs @@ -1,14 +1,24 @@ use derive_more::{AsRef, Deref}; use fixed_hash::{construct_fixed_hash, impl_fixed_hash_conversions}; +#[cfg(test)] +use proptest_derive::Arbitrary as PropTestArbitrary; + +#[cfg(any(test, feature = "arbitrary"))] +use arbitrary::Arbitrary; + construct_fixed_hash! { /// revm 256 bits type. + #[cfg_attr(test, derive(PropTestArbitrary))] + #[cfg_attr(any(test, feature = "arbitrary"), derive(Arbitrary))] #[derive(AsRef,Deref)] pub struct B256(32); } construct_fixed_hash! { /// revm 160 bits type. + #[cfg_attr(test, derive(PropTestArbitrary))] + #[cfg_attr(any(test, feature = "arbitrary"), derive(Arbitrary))] #[derive(AsRef,Deref)] pub struct B160(20); } @@ -25,7 +35,7 @@ impl From for B160 { impl_fixed_hash_conversions!(B256, B160); -#[cfg(feature = "with-serde")] +#[cfg(feature = "serde")] impl serde::Serialize for B256 { fn serialize(&self, serializer: S) -> Result where @@ -35,7 +45,7 @@ impl serde::Serialize for B256 { serialize::serialize_raw(&mut slice, &self.0, serializer) } } -#[cfg(feature = "with-serde")] +#[cfg(feature = "serde")] impl<'de> serde::Deserialize<'de> for B256 { fn deserialize(deserializer: D) -> Result where @@ -46,7 +56,7 @@ impl<'de> serde::Deserialize<'de> for B256 { Ok(B256(bytes)) } } -#[cfg(feature = "with-serde")] +#[cfg(feature = "serde")] impl serde::Serialize for B160 { fn serialize(&self, serializer: S) -> Result where @@ -57,7 +67,7 @@ impl serde::Serialize for B160 { } } -#[cfg(feature = "with-serde")] +#[cfg(feature = "serde")] impl<'de> serde::Deserialize<'de> for B160 { fn deserialize(deserializer: D) -> Result where @@ -70,7 +80,7 @@ impl<'de> serde::Deserialize<'de> for B160 { } // code optained from: https://docs.rs/impl-serde/0.4.0/impl_serde/ -#[cfg(feature = "with-serde")] +#[cfg(feature = "serde")] mod serialize { use alloc::{string::String, vec::Vec}; @@ -294,3 +304,13 @@ mod serialize { deserializer.deserialize_str(Visitor { len }) } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn arbitrary() { + proptest::proptest!(|(_v1: B160, _v2: B256)| {}); + } +} diff --git a/crates/interpreter/src/common.rs b/crates/interpreter/src/common.rs new file mode 100644 index 0000000000..b658f06967 --- /dev/null +++ b/crates/interpreter/src/common.rs @@ -0,0 +1,55 @@ +use crate::{B160, B256, U256}; +use sha3::{Digest, Keccak256}; + +#[inline(always)] +pub fn keccak256(input: &[u8]) -> B256 { + B256::from_slice(Keccak256::digest(input).as_slice()) +} + +/// Returns the address for the legacy `CREATE` scheme: [`CreateScheme::Create`] +pub fn create_address(caller: B160, nonce: u64) -> B160 { + let mut stream = rlp::RlpStream::new_list(2); + stream.append(&caller.0.as_ref()); + stream.append(&nonce); + let out = keccak256(&stream.out()); + B160(out[12..].try_into().unwrap()) +} + +/// Returns the address for the `CREATE2` scheme: [`CreateScheme::Create2`] +pub fn create2_address(caller: B160, code_hash: B256, salt: U256) -> B160 { + let mut hasher = Keccak256::new(); + hasher.update([0xff]); + hasher.update(&caller[..]); + hasher.update(salt.to_be_bytes::<{ U256::BYTES }>()); + hasher.update(&code_hash[..]); + + B160(hasher.finalize().as_slice()[12..].try_into().unwrap()) +} + +/// Serde functions to serde as [bytes::Bytes] hex string +#[cfg(feature = "serde")] +pub(crate) mod serde_hex_bytes { + use serde::{Deserialize, Deserializer, Serializer}; + + pub fn serialize(x: T, s: S) -> Result + where + S: Serializer, + T: AsRef<[u8]>, + { + s.serialize_str(&format!("0x{}", hex::encode(x.as_ref()))) + } + + pub fn deserialize<'de, D>(d: D) -> Result + where + D: Deserializer<'de>, + { + let value = String::deserialize(d)?; + if let Some(value) = value.strip_prefix("0x") { + hex::decode(value) + } else { + hex::decode(&value) + } + .map(Into::into) + .map_err(|e| serde::de::Error::custom(e.to_string())) + } +} diff --git a/crates/revm/src/gas.rs b/crates/interpreter/src/gas.rs similarity index 100% rename from crates/revm/src/gas.rs rename to crates/interpreter/src/gas.rs diff --git a/crates/revm/src/gas/calc.rs b/crates/interpreter/src/gas/calc.rs similarity index 100% rename from crates/revm/src/gas/calc.rs rename to crates/interpreter/src/gas/calc.rs diff --git a/crates/revm/src/gas/constants.rs b/crates/interpreter/src/gas/constants.rs similarity index 100% rename from crates/revm/src/gas/constants.rs rename to crates/interpreter/src/gas/constants.rs diff --git a/crates/interpreter/src/host.rs b/crates/interpreter/src/host.rs new file mode 100644 index 0000000000..2e4ab58165 --- /dev/null +++ b/crates/interpreter/src/host.rs @@ -0,0 +1,44 @@ +mod dummy_host; + +use crate::{ + Bytecode, Bytes, CallInputs, CreateInputs, Env, Gas, Interpreter, Return, SelfDestructResult, + B160, B256, U256, +}; +pub use dummy_host::DummyHost; + +/// EVM context host. +pub trait Host { + fn step(&mut self, interpreter: &mut Interpreter, is_static: bool) -> Return; + fn step_end(&mut self, interpreter: &mut Interpreter, is_static: bool, ret: Return) -> Return; + + fn env(&mut self) -> &mut Env; + + /// load account. Returns (is_cold,is_new_account) + fn load_account(&mut self, address: B160) -> Option<(bool, bool)>; + /// Get environmental block hash. + fn block_hash(&mut self, number: U256) -> Option; + /// Get balance of address and if account is cold loaded. + fn balance(&mut self, address: B160) -> Option<(U256, bool)>; + /// Get code of address and if account is cold loaded. + fn code(&mut self, address: B160) -> Option<(Bytecode, bool)>; + /// Get code hash of address and if account is cold loaded. + fn code_hash(&mut self, address: B160) -> Option<(B256, bool)>; + /// Get storage value of address at index and if account is cold loaded. + fn sload(&mut self, address: B160, index: U256) -> Option<(U256, bool)>; + /// Set storage value of account address at index. + /// Returns (original, present, new, sis_cold) + fn sstore( + &mut self, + address: B160, + index: U256, + value: U256, + ) -> Option<(U256, U256, U256, bool)>; + /// Create a log owned by address with given topics and data. + fn log(&mut self, address: B160, topics: Vec, data: Bytes); + /// Mark an address to be deleted, with funds transferred to target. + fn selfdestruct(&mut self, address: B160, target: B160) -> Option; + /// Invoke a create operation. + fn create(&mut self, inputs: &mut CreateInputs) -> (Return, Option, Gas, Bytes); + /// Invoke a call operation. + fn call(&mut self, input: &mut CallInputs) -> (Return, Gas, Bytes); +} diff --git a/crates/interpreter/src/host/dummy_host.rs b/crates/interpreter/src/host/dummy_host.rs new file mode 100644 index 0000000000..d532150939 --- /dev/null +++ b/crates/interpreter/src/host/dummy_host.rs @@ -0,0 +1,117 @@ +use hashbrown::{hash_map::Entry, HashMap}; +use ruint::aliases::U256; + +use crate::{ + Bytecode, CallInputs, CreateInputs, Env, Gas, Host, Interpreter, Log, Return, + SelfDestructResult, B160, B256, KECCAK_EMPTY, +}; + +pub struct DummyHost { + pub env: Env, + pub storage: HashMap, + pub log: Vec, +} + +impl DummyHost { + pub fn new(env: Env) -> Self { + Self { + env, + storage: HashMap::new(), + log: Vec::new(), + } + } + pub fn clear(&mut self) { + self.storage.clear(); + self.log.clear(); + } +} + +impl Host for DummyHost { + fn step(&mut self, _interp: &mut Interpreter, _is_static: bool) -> Return { + Return::Continue + } + + fn step_end(&mut self, _interp: &mut Interpreter, _is_static: bool, _ret: Return) -> Return { + Return::Continue + } + + fn env(&mut self) -> &mut Env { + &mut self.env + } + + fn load_account(&mut self, _address: B160) -> Option<(bool, bool)> { + Some((true, true)) + } + + fn block_hash(&mut self, _number: ruint::aliases::U256) -> Option { + Some(B256::zero()) + } + + fn balance(&mut self, _address: B160) -> Option<(ruint::aliases::U256, bool)> { + Some((U256::ZERO, false)) + } + + fn code(&mut self, _address: B160) -> Option<(Bytecode, bool)> { + Some((Bytecode::default(), false)) + } + + fn code_hash(&mut self, __address: B160) -> Option<(B256, bool)> { + Some((KECCAK_EMPTY, false)) + } + + fn sload( + &mut self, + __address: B160, + index: ruint::aliases::U256, + ) -> Option<(ruint::aliases::U256, bool)> { + match self.storage.entry(index) { + Entry::Occupied(entry) => Some((*entry.get(), false)), + Entry::Vacant(entry) => { + entry.insert(U256::ZERO); + Some((U256::ZERO, true)) + } + } + } + + fn sstore( + &mut self, + _address: B160, + index: ruint::aliases::U256, + value: ruint::aliases::U256, + ) -> Option<( + ruint::aliases::U256, + ruint::aliases::U256, + ruint::aliases::U256, + bool, + )> { + let (present, is_cold) = match self.storage.entry(index) { + Entry::Occupied(mut entry) => (entry.insert(value), false), + Entry::Vacant(entry) => { + entry.insert(value); + (U256::ZERO, true) + } + }; + + Some((U256::ZERO, present, value, is_cold)) + } + + fn log(&mut self, address: B160, topics: Vec, data: bytes::Bytes) { + self.log.push(Log { + address, + topics, + data, + }) + } + + fn selfdestruct(&mut self, _address: B160, _target: B160) -> Option { + panic!("Create is not supported for this host") + } + + fn create(&mut self, _inputs: &mut CreateInputs) -> (Return, Option, Gas, bytes::Bytes) { + panic!("Create is not supported for this host") + } + + fn call(&mut self, _input: &mut CallInputs) -> (Return, Gas, bytes::Bytes) { + panic!("Call is not supported for this host") + } +} diff --git a/crates/revm/src/instructions.rs b/crates/interpreter/src/instructions.rs similarity index 100% rename from crates/revm/src/instructions.rs rename to crates/interpreter/src/instructions.rs diff --git a/crates/revm/src/instructions/arithmetic.rs b/crates/interpreter/src/instructions/arithmetic.rs similarity index 100% rename from crates/revm/src/instructions/arithmetic.rs rename to crates/interpreter/src/instructions/arithmetic.rs diff --git a/crates/revm/src/instructions/bitwise.rs b/crates/interpreter/src/instructions/bitwise.rs similarity index 98% rename from crates/revm/src/instructions/bitwise.rs rename to crates/interpreter/src/instructions/bitwise.rs index 6a15426934..02a7c3897b 100644 --- a/crates/revm/src/instructions/bitwise.rs +++ b/crates/interpreter/src/instructions/bitwise.rs @@ -1,7 +1,7 @@ use super::i256::{i256_cmp, i256_sign, two_compl, Sign}; use crate::{Host, Interpreter, Return, Spec, SpecId::CONSTANTINOPLE, U256}; use core::cmp::Ordering; -use std::ops::{BitAnd, BitOr, BitXor}; +use core::ops::{BitAnd, BitOr, BitXor}; pub fn lt(interpreter: &mut Interpreter, _host: &mut dyn Host) { pop_top!(interpreter, op1, op2); diff --git a/crates/revm/src/instructions/control.rs b/crates/interpreter/src/instructions/control.rs similarity index 100% rename from crates/revm/src/instructions/control.rs rename to crates/interpreter/src/instructions/control.rs diff --git a/crates/revm/src/instructions/host.rs b/crates/interpreter/src/instructions/host.rs similarity index 100% rename from crates/revm/src/instructions/host.rs rename to crates/interpreter/src/instructions/host.rs diff --git a/crates/revm/src/instructions/host_env.rs b/crates/interpreter/src/instructions/host_env.rs similarity index 100% rename from crates/revm/src/instructions/host_env.rs rename to crates/interpreter/src/instructions/host_env.rs diff --git a/crates/revm/src/instructions/i256.rs b/crates/interpreter/src/instructions/i256.rs similarity index 91% rename from crates/revm/src/instructions/i256.rs rename to crates/interpreter/src/instructions/i256.rs index f374763a16..9b58185229 100644 --- a/crates/revm/src/instructions/i256.rs +++ b/crates/interpreter/src/instructions/i256.rs @@ -2,6 +2,14 @@ use crate::U256; use core::cmp::Ordering; use ruint::uint; +#[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 { Plus, @@ -15,6 +23,9 @@ pub const MIN_NEGATIVE_VALUE: U256 = uint!(0x8000000000000000_0000000000000000_0000000000000000_0000000000000000_U256); 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); @@ -153,4 +164,9 @@ mod tests { assert_eq!(i256_div(one_hundred, minus_one), neg_one_hundred); assert_eq!(i256_div(one_hundred, two), fifty); } + + #[test] + fn arbitrary() { + proptest::proptest!(|(_value: I256)| { }) + } } diff --git a/crates/revm/src/instructions/macros.rs b/crates/interpreter/src/instructions/macros.rs similarity index 100% rename from crates/revm/src/instructions/macros.rs rename to crates/interpreter/src/instructions/macros.rs diff --git a/crates/revm/src/instructions/memory.rs b/crates/interpreter/src/instructions/memory.rs similarity index 100% rename from crates/revm/src/instructions/memory.rs rename to crates/interpreter/src/instructions/memory.rs diff --git a/crates/revm/src/instructions/opcode.rs b/crates/interpreter/src/instructions/opcode.rs similarity index 100% rename from crates/revm/src/instructions/opcode.rs rename to crates/interpreter/src/instructions/opcode.rs diff --git a/crates/revm/src/instructions/stack.rs b/crates/interpreter/src/instructions/stack.rs similarity index 100% rename from crates/revm/src/instructions/stack.rs rename to crates/interpreter/src/instructions/stack.rs diff --git a/crates/revm/src/instructions/system.rs b/crates/interpreter/src/instructions/system.rs similarity index 100% rename from crates/revm/src/instructions/system.rs rename to crates/interpreter/src/instructions/system.rs diff --git a/crates/revm/src/interpreter.rs b/crates/interpreter/src/interpreter.rs similarity index 59% rename from crates/revm/src/interpreter.rs rename to crates/interpreter/src/interpreter.rs index b8d2310770..3711f22621 100644 --- a/crates/revm/src/interpreter.rs +++ b/crates/interpreter/src/interpreter.rs @@ -46,18 +46,26 @@ impl Interpreter { pub fn current_opcode(&self) -> u8 { unsafe { *self.instruction_pointer } } - #[cfg(not(feature = "memory_limit"))] + pub fn new(contract: Contract, gas_limit: u64, is_static: bool) -> 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: Return::Continue, - is_static, - gas: Gas::new(gas_limit), + #[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: Return::Continue, + is_static, + gas: Gas::new(gas_limit), + } + } + + #[cfg(feature = "memory_limit")] + { + Self::new_with_memory_limit::(contract, gas_limit, is_static, u64::MAX) } } @@ -116,40 +124,46 @@ impl Interpreter { } /// loop steps until we are finished with execution - pub fn run(&mut self, host: &mut H, inspect: bool) -> Return { - //let timer = std::time::Instant::now(); + pub fn run(&mut self, host: &mut H) -> Return { + // add first gas_block + if USE_GAS && !self.gas.record_cost(self.contract.first_gas_block()) { + return Return::OutOfGas; + } + while self.instruction_result == Return::Continue { + // 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); + } + self.instruction_result + } + + /// loop steps until we are finished with execution + pub fn run_inspect(&mut self, host: &mut H) -> Return { // add first gas_block if USE_GAS && !self.gas.record_cost(self.contract.first_gas_block()) { return Return::OutOfGas; } - if inspect { - while self.instruction_result == Return::Continue { - // step - let ret = host.step(self, self.is_static); - if ret != Return::Continue { - return ret; - } - 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); - - let ret = host.step_end(self, self.is_static, self.instruction_result); - if ret != Return::Continue { - return ret; - } + while self.instruction_result == Return::Continue { + // step + let ret = host.step(self, self.is_static); + if ret != Return::Continue { + return ret; } - } else { - while self.instruction_result == Return::Continue { - // 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); + 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); + + // step ends + let ret = host.step_end(self, self.is_static, self.instruction_result); + if ret != Return::Continue { + return ret; } } self.instruction_result diff --git a/crates/revm/src/interpreter/bytecode.rs b/crates/interpreter/src/interpreter/bytecode.rs similarity index 97% rename from crates/revm/src/interpreter/bytecode.rs rename to crates/interpreter/src/interpreter/bytecode.rs index 573252726e..b1fef52f8a 100644 --- a/crates/revm/src/interpreter/bytecode.rs +++ b/crates/interpreter/src/interpreter/bytecode.rs @@ -4,7 +4,7 @@ use bytes::Bytes; use std::sync::Arc; #[derive(Clone, Debug, Eq, PartialEq)] -#[cfg_attr(feature = "with-serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum BytecodeState { Raw, Checked { @@ -17,9 +17,9 @@ pub enum BytecodeState { } #[derive(Clone, Debug, Eq, PartialEq)] -#[cfg_attr(feature = "with-serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Bytecode { - #[cfg_attr(feature = "with-serde", serde(with = "crate::models::serde_hex_bytes"))] + #[cfg_attr(feature = "serde", serde(with = "crate::common::serde_hex_bytes"))] bytecode: Bytes, hash: B256, state: BytecodeState, @@ -262,6 +262,7 @@ impl Bytecode { } } +#[derive(Clone)] pub struct BytecodeLocked { bytecode: Bytes, len: usize, diff --git a/crates/revm/src/interpreter/contract.rs b/crates/interpreter/src/interpreter/contract.rs similarity index 96% rename from crates/revm/src/interpreter/contract.rs rename to crates/interpreter/src/interpreter/contract.rs index 35f8a9c7f3..b2aad58faa 100644 --- a/crates/revm/src/interpreter/contract.rs +++ b/crates/interpreter/src/interpreter/contract.rs @@ -3,6 +3,7 @@ use crate::{alloc::vec::Vec, CallContext, Spec, B160, U256}; use bytes::Bytes; use std::sync::Arc; +#[derive(Clone)] pub struct Contract { /// Contracts data pub input: Bytes, @@ -27,7 +28,7 @@ pub enum Analysis { const JUMP_MASK: u32 = 0x80000000; #[derive(Clone, Copy, Debug, Eq, PartialEq)] -#[cfg_attr(feature = "with-serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct AnalysisData { /// This variable packs two informations: /// IS_JUMP (1bit) | gas block ( 31bits) @@ -105,7 +106,7 @@ impl Contract { /// Mapping of valid jump destination from code. #[derive(Clone, Debug, Eq, PartialEq)] -#[cfg_attr(feature = "with-serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct ValidJumpAddress { pub first_gas_block: u32, /// Rc is used here so that we dont need to copy vector. We can move it to more suitable more accessable structure diff --git a/crates/revm/src/interpreter/memory.rs b/crates/interpreter/src/interpreter/memory.rs similarity index 100% rename from crates/revm/src/interpreter/memory.rs rename to crates/interpreter/src/interpreter/memory.rs diff --git a/crates/revm/src/interpreter/stack.rs b/crates/interpreter/src/interpreter/stack.rs similarity index 92% rename from crates/revm/src/interpreter/stack.rs rename to crates/interpreter/src/interpreter/stack.rs index 9c44483554..9f61458c63 100644 --- a/crates/revm/src/interpreter/stack.rs +++ b/crates/interpreter/src/interpreter/stack.rs @@ -266,28 +266,32 @@ impl Stack { dangling[8 - N..].copy_from_slice(slice); slot.as_limbs_mut()[0] = u64::from_be_bytes(dangling); } else if N < 16 { - slot.as_limbs_mut()[0] = u64::from_be_bytes(*arrayref::array_ref!(slice, N - 8, 8)); + slot.as_limbs_mut()[0] = + u64::from_be_bytes(slice[N - 8..N].try_into().expect("Infallible")); if N != 8 { dangling[8 * 2 - N..].copy_from_slice(&slice[..N - 8]); slot.as_limbs_mut()[1] = u64::from_be_bytes(dangling); } } else if N < 24 { - slot.as_limbs_mut()[0] = u64::from_be_bytes(*arrayref::array_ref!(slice, N - 8, 8)); + slot.as_limbs_mut()[0] = + u64::from_be_bytes(slice[N - 8..N].try_into().expect("Infallible")); slot.as_limbs_mut()[1] = - u64::from_be_bytes(*arrayref::array_ref!(slice, N - 16, 8)); + u64::from_be_bytes(slice[N - 16..N - 8].try_into().expect("Infallible")); if N != 16 { dangling[8 * 3 - N..].copy_from_slice(&slice[..N - 16]); slot.as_limbs_mut()[2] = u64::from_be_bytes(dangling); } } else { // M<32 - slot.as_limbs_mut()[0] = u64::from_be_bytes(*arrayref::array_ref!(slice, N - 8, 8)); + slot.as_limbs_mut()[0] = + u64::from_be_bytes(slice[N - 8..N].try_into().expect("Infallible")); slot.as_limbs_mut()[1] = - u64::from_be_bytes(*arrayref::array_ref!(slice, N - 16, 8)); + u64::from_be_bytes(slice[N - 16..N - 8].try_into().expect("Infallible")); slot.as_limbs_mut()[2] = - u64::from_be_bytes(*arrayref::array_ref!(slice, N - 24, 8)); + u64::from_be_bytes(slice[N - 24..N - 16].try_into().expect("Infallible")); if N == 32 { - slot.as_limbs_mut()[3] = u64::from_be_bytes(*arrayref::array_ref!(slice, 0, 8)); + slot.as_limbs_mut()[3] = + u64::from_be_bytes(slice[..N - 24].try_into().expect("Infallible")); } else if N != 24 { dangling[8 * 4 - N..].copy_from_slice(&slice[..N - 24]); slot.as_limbs_mut()[3] = u64::from_be_bytes(dangling); diff --git a/crates/interpreter/src/lib.rs b/crates/interpreter/src/lib.rs new file mode 100644 index 0000000000..1b773b3ea0 --- /dev/null +++ b/crates/interpreter/src/lib.rs @@ -0,0 +1,33 @@ +#![allow(dead_code)] +//#![no_std] + +pub mod bits; +pub mod common; +pub mod gas; +mod host; +mod instructions; +mod interpreter; +pub mod models; +pub mod specification; + +extern crate alloc; + +pub(crate) const USE_GAS: bool = !cfg!(feature = "no_gas_measuring"); + +// Reexport primary types. +pub use bits::{B160, B256}; +pub use bytes::Bytes; +pub use gas::Gas; +pub use host::{DummyHost, Host}; +pub use instructions::{ + opcode::{self, spec_opcode_gas, OpCode, OPCODE_JUMPMAP}, + Return, +}; +pub use interpreter::*; +pub use interpreter::{ + Bytecode, BytecodeLocked, BytecodeState, Contract, Interpreter, Memory, Stack, +}; +pub use models::*; +pub use ruint; +pub use ruint::aliases::U256; +pub use specification::*; diff --git a/crates/revm/src/models.rs b/crates/interpreter/src/models.rs similarity index 72% rename from crates/revm/src/models.rs rename to crates/interpreter/src/models.rs index a09315529c..dc15eb8b00 100644 --- a/crates/revm/src/models.rs +++ b/crates/interpreter/src/models.rs @@ -1,21 +1,94 @@ use core::cmp::min; -use crate::{ - alloc::vec::Vec, - bits::{B160, B256}, - interpreter::bytecode::Bytecode, - Return, SpecId, U256, -}; +use crate::{alloc::vec::Vec, interpreter::bytecode::Bytecode, Return, SpecId, B160, B256, U256}; use bytes::Bytes; +use hashbrown::HashMap as Map; use hex_literal::hex; pub const KECCAK_EMPTY: B256 = B256(hex!( "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" )); +#[derive(Debug, Clone, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct Account { + /// Balance of the account. + pub info: AccountInfo, + /// storage cache + pub storage: Map, + /// If account is newly created, we will not ask database for storage values + pub storage_cleared: bool, + /// if account is destroyed it will be scheduled for removal. + pub is_destroyed: bool, + /// if account is touched + pub is_touched: bool, + /// used only for pre spurious dragon hardforks where exisnting and empty was two saparate states. + /// it became same state after EIP-161: State trie clearing + pub is_not_existing: bool, +} + +impl Account { + pub fn is_empty(&self) -> bool { + self.info.is_empty() + } + pub fn new_not_existing() -> Self { + Self { + info: AccountInfo::default(), + storage: Map::new(), + storage_cleared: false, + is_destroyed: false, + is_touched: false, + is_not_existing: true, + } + } +} + +impl From for Account { + fn from(info: AccountInfo) -> Self { + Self { + info, + storage: Map::new(), + storage_cleared: false, + is_destroyed: false, + is_touched: false, + is_not_existing: false, + } + } +} + +#[derive(Debug, Clone, Default, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct StorageSlot { + pub original_value: U256, + /// When loaded with sload present value is set to original value + pub present_value: U256, +} + +impl StorageSlot { + pub fn new(original: U256) -> Self { + Self { + original_value: original, + present_value: original, + } + } + + /// Returns true if the present value differs from the original value + pub fn is_changed(&self) -> bool { + self.original_value != self.present_value + } + + pub fn original_value(&self) -> U256 { + self.original_value + } + + pub fn present_value(&self) -> U256 { + self.present_value + } +} + /// AccountInfo account information. #[derive(Clone, Debug, Eq)] -#[cfg_attr(feature = "with-serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct AccountInfo { /// Account balance. pub balance: U256, @@ -76,14 +149,14 @@ impl AccountInfo { } /// Inputs for a call. -#[cfg_attr(feature = "with-serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct CallInputs { /// The target of the call. pub contract: B160, /// The transfer, if any, in this call. pub transfer: Transfer, /// The call data of the call. - #[cfg_attr(feature = "with-serde", serde(with = "serde_hex_bytes"))] + #[cfg_attr(feature = "serde", serde(with = "crate::common::serde_hex_bytes"))] pub input: Bytes, /// The gas limit of the call. pub gas_limit: u64, @@ -93,12 +166,12 @@ pub struct CallInputs { pub is_static: bool, } -#[cfg_attr(feature = "with-serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct CreateInputs { pub caller: B160, pub scheme: CreateScheme, pub value: U256, - #[cfg_attr(feature = "with-serde", serde(with = "serde_hex_bytes"))] + #[cfg_attr(feature = "serde", serde(with = "crate::common::serde_hex_bytes"))] pub init_code: Bytes, pub gas_limit: u64, } @@ -106,7 +179,7 @@ pub struct CreateInputs { pub struct CreateData {} #[derive(Clone, Debug)] -#[cfg_attr(feature = "with-serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum TransactTo { Call(B160), Create(CreateScheme), @@ -119,20 +192,20 @@ impl TransactTo { } #[derive(Clone, Debug)] -#[cfg_attr(feature = "with-serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum TransactOut { None, - #[cfg_attr(feature = "with-serde", serde(with = "serde_hex_bytes"))] + #[cfg_attr(feature = "serde", serde(with = "crate::common::serde_hex_bytes"))] Call(Bytes), Create( - #[cfg_attr(feature = "with-serde", serde(with = "serde_hex_bytes"))] Bytes, + #[cfg_attr(feature = "serde", serde(with = "crate::common::serde_hex_bytes"))] Bytes, Option, ), } /// Create scheme. #[derive(Clone, Copy, Eq, PartialEq, Debug)] -#[cfg_attr(feature = "with-serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum CreateScheme { /// Legacy create scheme of `CREATE`. Create, @@ -145,7 +218,7 @@ pub enum CreateScheme { /// Call schemes. #[derive(Clone, Copy, Eq, PartialEq, Debug)] -#[cfg_attr(feature = "with-serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum CallScheme { /// `CALL` Call, @@ -159,7 +232,7 @@ pub enum CallScheme { /// CallContext of the runtime. #[derive(Clone, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "with-serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct CallContext { /// Execution address. pub address: B160, @@ -186,14 +259,14 @@ impl Default for CallContext { } #[derive(Clone, Debug, Default)] -#[cfg_attr(feature = "with-serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Env { pub cfg: CfgEnv, pub block: BlockEnv, pub tx: TxEnv, } #[derive(Clone, Debug, Eq, PartialEq)] -#[cfg_attr(feature = "with-serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BlockEnv { pub number: U256, /// Coinbase or miner or address that created and signed the block. @@ -211,7 +284,7 @@ pub struct BlockEnv { } #[derive(Clone, Debug)] -#[cfg_attr(feature = "with-serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct TxEnv { /// Caller or Author or tx signer pub caller: B160, @@ -220,14 +293,14 @@ pub struct TxEnv { pub gas_priority_fee: Option, pub transact_to: TransactTo, pub value: U256, - #[cfg_attr(feature = "with-serde", serde(with = "serde_hex_bytes"))] + #[cfg_attr(feature = "serde", serde(with = "crate::common::serde_hex_bytes"))] pub data: Bytes, pub chain_id: Option, pub nonce: Option, pub access_list: Vec<(B160, Vec)>, } #[derive(Clone, Debug, Eq, PartialEq)] -#[cfg_attr(feature = "with-serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct CfgEnv { pub chain_id: U256, pub spec_id: SpecId, @@ -271,7 +344,7 @@ pub struct CfgEnv { } #[derive(Clone, Default, Debug, Eq, PartialEq)] -#[cfg_attr(feature = "with-serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum AnalysisKind { Raw, Check, @@ -347,7 +420,7 @@ impl Env { /// Transfer from source to target, with given value. #[derive(Clone, Debug)] -#[cfg_attr(feature = "with-serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Transfer { /// Source address. pub source: B160, @@ -358,92 +431,22 @@ pub struct Transfer { } #[derive(Clone, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "with-serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Log { pub address: B160, pub topics: Vec, - #[cfg_attr(feature = "with-serde", serde(with = "serde_hex_bytes"))] + #[cfg_attr(feature = "serde", serde(with = "crate::common::serde_hex_bytes"))] pub data: Bytes, } #[derive(Default)] -#[cfg_attr(feature = "with-serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct SelfDestructResult { pub had_value: bool, pub target_exists: bool, pub is_cold: bool, pub previously_destroyed: bool, } -/// Serde functions to serde as [bytes::Bytes] hex string -#[cfg(feature = "with-serde")] -pub(crate) mod serde_hex_bytes { - use serde::{Deserialize, Deserializer, Serializer}; - - pub fn serialize(x: T, s: S) -> Result - where - S: Serializer, - T: AsRef<[u8]>, - { - s.serialize_str(&format!("0x{}", hex::encode(x.as_ref()))) - } - - pub fn deserialize<'de, D>(d: D) -> Result - where - D: Deserializer<'de>, - { - let value = String::deserialize(d)?; - if let Some(value) = value.strip_prefix("0x") { - hex::decode(value) - } else { - hex::decode(&value) - } - .map(Into::into) - .map_err(|e| serde::de::Error::custom(e.to_string())) - } -} -/// Serde functions to serde an Option [bytes::Bytes] hex string -#[cfg(feature = "with-serde")] -pub(crate) mod serde_hex_bytes_opt { - use super::serde_hex_bytes; - use serde::{Deserialize, Deserializer, Serializer}; - - pub fn serialize(value: &Option, serializer: S) -> Result - where - S: Serializer, - T: AsRef<[u8]>, - { - if let Some(value) = value { - serde_hex_bytes::serialize(value, serializer) - } else { - serializer.serialize_none() - } - } - - pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> - where - D: Deserializer<'de>, - { - #[derive(Deserialize)] - #[serde(transparent)] - struct OptionalBytes(Option); - - struct DeserializeBytes(bytes::Bytes); - - impl<'de> Deserialize<'de> for DeserializeBytes { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - Ok(DeserializeBytes(serde_hex_bytes::deserialize( - deserializer, - )?)) - } - } - - let value = OptionalBytes::deserialize(deserializer)?; - Ok(value.0.map(|b| b.0)) - } -} #[derive(Clone, Debug)] pub struct ExecutionResult { diff --git a/crates/interpreter/src/specification.rs b/crates/interpreter/src/specification.rs new file mode 100644 index 0000000000..2aefdb8fe0 --- /dev/null +++ b/crates/interpreter/src/specification.rs @@ -0,0 +1,100 @@ +/// 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 + HOMESTEAD = 2, // Homestead 1150000 + DAO_FORK = 3, // DAO Fork 1920000 + TANGERINE = 4, // Tangerine Whistle 2463000 + SPURIOUS_DRAGON = 5, // Spurious Dragon 2675000 + BYZANTIUM = 6, // Byzantium 4370000 + CONSTANTINOPLE = 7, // Constantinople 7280000 is overwritten with PETERSBURG + PETERSBURG = 8, // Petersburg 7280000 + ISTANBUL = 9, // Istanbul 9069000 + MUIR_GLACIER = 10, // Muir Glacier 9200000 + BERLIN = 11, // Berlin 12244000 + LONDON = 12, // London 12965000 + ARROW_GLACIER = 13, // Arrow Glacier 13773000 + GRAY_GLACIER = 14, // Gray Glacier 15050000 + MERGE = 15, // Paris/Merge TBD (Depends on difficulty) + MERGE_EOF = 16, // Merge+EOF TBD + LATEST = 17, +} + +impl SpecId { + pub fn try_from_u8(spec_id: u8) -> Option { + Self::n(spec_id) + } +} + +pub use SpecId::*; + +impl From<&str> for SpecId { + fn from(name: &str) -> Self { + match name { + "Frontier" => SpecId::FRONTIER, + "Homestead" => SpecId::HOMESTEAD, + "Tangerine" => SpecId::TANGERINE, + "Spurious" => SpecId::SPURIOUS_DRAGON, + "Byzantium" => SpecId::BYZANTIUM, + "Constantinople" => SpecId::CONSTANTINOPLE, + "Petersburg" => SpecId::PETERSBURG, + "Istanbul" => SpecId::ISTANBUL, + "MuirGlacier" => SpecId::MUIR_GLACIER, + "Berlin" => SpecId::BERLIN, + "London" => SpecId::LONDON, + "Merge" => SpecId::MERGE, + "MergeEOF" => SpecId::MERGE_EOF, + _ => SpecId::LATEST, + } + } +} + +impl SpecId { + #[inline] + pub const fn enabled(our: SpecId, other: SpecId) -> bool { + our as u8 >= other as u8 + } +} + +pub trait Spec: Sized { + #[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) => { + pub struct $spec_name; + + impl Spec for $spec_name { + //specification id + const SPEC_ID: SpecId = $spec_id; + } + }; +} + +spec!(FRONTIER, FrontierSpec); +// FRONTIER_THAWING no EVM spec change +spec!(HOMESTEAD, HomesteadSpec); +// DAO_FORK no EVM spec change +spec!(TANGERINE, TangerineSpec); +spec!(SPURIOUS_DRAGON, SpuriousDragonSpec); +spec!(BYZANTIUM, ByzantiumSpec); +// CONSTANTINOPLE was overriden with PETERSBURG +spec!(PETERSBURG, PetersburgSpec); +spec!(ISTANBUL, IstanbulSpec); +// MUIR_GLACIER no EVM spec change +spec!(BERLIN, BerlinSpec); +spec!(LONDON, LondonSpec); +// ARROW_GLACIER no EVM spec change +// GRAY_GLACIER no EVM spec change +spec!(MERGE, MergeSpec); +// MERGE_EOF is pending EVM change +spec!(LATEST, LatestSpec); diff --git a/crates/revm_precompiles/CHANGELOG.md b/crates/precompiles/CHANGELOG.md similarity index 100% rename from crates/revm_precompiles/CHANGELOG.md rename to crates/precompiles/CHANGELOG.md diff --git a/crates/revm_precompiles/Cargo.toml b/crates/precompiles/Cargo.toml similarity index 98% rename from crates/revm_precompiles/Cargo.toml rename to crates/precompiles/Cargo.toml index f7f0e69666..e8e98a6e8c 100644 --- a/crates/revm_precompiles/Cargo.toml +++ b/crates/precompiles/Cargo.toml @@ -4,7 +4,7 @@ description = "REVM Precompiles - Ethereum compatible precompiled contracts" edition = "2021" keywords = ["no_std", "ethereum", "evm", "precompiles"] license = "MIT" -name = "revm_precompiles" +name = "revm-precompiles" repository = "https://github.com/bluealloy/revm" version = "1.1.2" diff --git a/crates/precompiles/LICENSE b/crates/precompiles/LICENSE new file mode 100644 index 0000000000..fb60ef41ea --- /dev/null +++ b/crates/precompiles/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 draganrakita + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/crates/precompiles/README.md b/crates/precompiles/README.md new file mode 100644 index 0000000000..94b09439a7 --- /dev/null +++ b/crates/precompiles/README.md @@ -0,0 +1,3 @@ +### REVM Precompiles - Ethereum compatible precompiled contracts + +Used inside REVM and passes all eth/tests. It supports all Ethereum hardforks. \ No newline at end of file diff --git a/crates/revm_precompiles/src/blake2.rs b/crates/precompiles/src/blake2.rs similarity index 100% rename from crates/revm_precompiles/src/blake2.rs rename to crates/precompiles/src/blake2.rs diff --git a/crates/revm_precompiles/src/bn128.rs b/crates/precompiles/src/bn128.rs similarity index 100% rename from crates/revm_precompiles/src/bn128.rs rename to crates/precompiles/src/bn128.rs diff --git a/crates/revm_precompiles/src/error.rs b/crates/precompiles/src/error.rs similarity index 100% rename from crates/revm_precompiles/src/error.rs rename to crates/precompiles/src/error.rs diff --git a/crates/revm_precompiles/src/hash.rs b/crates/precompiles/src/hash.rs similarity index 100% rename from crates/revm_precompiles/src/hash.rs rename to crates/precompiles/src/hash.rs diff --git a/crates/revm_precompiles/src/identity.rs b/crates/precompiles/src/identity.rs similarity index 100% rename from crates/revm_precompiles/src/identity.rs rename to crates/precompiles/src/identity.rs diff --git a/crates/revm_precompiles/src/lib.rs b/crates/precompiles/src/lib.rs similarity index 100% rename from crates/revm_precompiles/src/lib.rs rename to crates/precompiles/src/lib.rs diff --git a/crates/revm_precompiles/src/modexp.rs b/crates/precompiles/src/modexp.rs similarity index 100% rename from crates/revm_precompiles/src/modexp.rs rename to crates/precompiles/src/modexp.rs diff --git a/crates/revm_precompiles/src/secp256k1.rs b/crates/precompiles/src/secp256k1.rs similarity index 100% rename from crates/revm_precompiles/src/secp256k1.rs rename to crates/precompiles/src/secp256k1.rs diff --git a/crates/revm/Cargo.toml b/crates/revm/Cargo.toml index d6ae924e83..0435a4b066 100644 --- a/crates/revm/Cargo.toml +++ b/crates/revm/Cargo.toml @@ -10,33 +10,28 @@ version = "2.3.1" readme = "../../README.md" [dependencies] -arrayref = "0.3" auto_impl = { version = "1.0", default-features = false } bytes = { version = "1.1", default-features = false } -futures = { version = "0.3.24", optional = true } hashbrown = { version = "0.13" } hex = { version = "0.4", default-features = false } -num_enum = { version = "0.5", default-features = false } # used for SpecId from u8 cast -revm_precompiles = { path = "../revm_precompiles", version = "1.1.2", default-features = false } -rlp = { version = "0.5", default-features = false } # used for create2 address calculation -ruint = { version = "1.7.0", features = ["primitive-types", "rlp"] } +revm-precompiles = { path = "../precompiles", version = "1.1.2", default-features = false } +revm-interpreter = { path = "../interpreter", default-features = false } + +# Optional serde = { version = "1.0", features = ["derive", "rc"], optional = true } + +# ethersdb tokio = { version = "1.23", features = [ "rt-multi-thread", "macros", ], optional = true } ethers-providers = { version = "1.0.2", optional = true } ethers-core = { version = "1.0.2", optional = true } +futures = { version = "0.3.24", optional = true } -# bits B256 B160 crate -fixed-hash = { version = "0.8", default-features = false, features = [ - "rustc-hex", -] } -hex-literal = "0.3" -derive_more = "0.99" -# sha3 keccak hasher -sha3 = { version = "0.10", default-features = false, features = [] } +[dev-dependencies] +hex-literal = "0.3" [features] default = ["std", "secp256k1"] @@ -47,15 +42,15 @@ dev = [ "optional_eip3607", "optional_gas_refund", ] -ethersdb = ["tokio", "futures", "ethers-providers", "ethers-core"] -# deprecated feature -web3db = [] -secp256k1 = ["revm_precompiles/secp256k1"] +secp256k1 = ["revm-precompiles/secp256k1"] memory_limit = [] no_gas_measuring = [] optional_balance_check = [] optional_block_gas_limit = [] optional_eip3607 = [] optional_gas_refund = [] -std = ["bytes/std", "num_enum/std", "rlp/std"] -with-serde = ["serde", "hex/serde", "hashbrown/serde", "ruint/serde"] +std = ["bytes/std", "hex/std", "revm-interpreter/std"] +ethersdb = ["tokio", "futures", "ethers-providers", "ethers-core"] +serde = ["dep:serde", "hex/serde", "hashbrown/serde", "revm-interpreter/serde"] +# deprecated feature +web3db = [] diff --git a/crates/revm/src/common.rs b/crates/revm/src/common.rs deleted file mode 100644 index 929dd4e19e..0000000000 --- a/crates/revm/src/common.rs +++ /dev/null @@ -1,7 +0,0 @@ -use crate::bits::B256; -use sha3::{Digest, Keccak256}; - -#[inline(always)] -pub fn keccak256(input: &[u8]) -> B256 { - B256::from_slice(Keccak256::digest(input).as_slice()) -} diff --git a/crates/revm/src/db.rs b/crates/revm/src/db.rs index 072962a099..efbd39e47e 100644 --- a/crates/revm/src/db.rs +++ b/crates/revm/src/db.rs @@ -10,10 +10,10 @@ compile_error!( "`web3db` feature is deprecated, drop-in replacement can be found with feature `ethersdb`" ); -use crate::bits::{B160, B256}; use crate::AccountInfo; use crate::U256; use crate::{interpreter::bytecode::Bytecode, Account}; +use crate::{B160, B256}; use auto_impl::auto_impl; use hashbrown::HashMap as Map; pub use in_memory_db::{AccountState, BenchmarkDB, CacheDB, DbAccount, EmptyDB, InMemoryDB}; diff --git a/crates/revm/src/db/in_memory_db.rs b/crates/revm/src/db/in_memory_db.rs index 88d8e1b275..709c8fe7de 100644 --- a/crates/revm/src/db/in_memory_db.rs +++ b/crates/revm/src/db/in_memory_db.rs @@ -393,8 +393,7 @@ impl Database for BenchmarkDB { #[cfg(test)] mod tests { use super::{CacheDB, EmptyDB}; - use crate::{AccountInfo, Database}; - use ruint::aliases::U256; + use crate::{AccountInfo, Database, U256}; #[test] pub fn test_insert_account_storage() { diff --git a/crates/revm/src/evm.rs b/crates/revm/src/evm.rs index f6d1de5251..48aa13a60d 100644 --- a/crates/revm/src/evm.rs +++ b/crates/revm/src/evm.rs @@ -3,9 +3,10 @@ use crate::{ evm_impl::{EVMImpl, Transact}, inspectors::NoOpInspector, journaled_state::State, - specification, Env, ExecutionResult, Inspector, + Env, ExecutionResult, Inspector, }; use alloc::boxed::Box; +use revm_interpreter::{specification, SpecId}; use revm_precompiles::Precompiles; /// Struct that takes Database and enabled transact to update state directly to database. @@ -144,11 +145,33 @@ macro_rules! create_evm { $db, $env, $inspector, - Precompiles::new(SpecId::to_precompile_id($spec::SPEC_ID)).clone(), + Precompiles::new(to_precompile_id($spec::SPEC_ID)).clone(), )) as Box }; } +pub fn to_precompile_id(spec_id: SpecId) -> revm_precompiles::SpecId { + match spec_id { + SpecId::FRONTIER + | SpecId::FRONTIER_THAWING + | SpecId::HOMESTEAD + | SpecId::DAO_FORK + | SpecId::TANGERINE + | SpecId::SPURIOUS_DRAGON => revm_precompiles::SpecId::HOMESTEAD, + SpecId::BYZANTIUM | SpecId::CONSTANTINOPLE | SpecId::PETERSBURG => { + revm_precompiles::SpecId::BYZANTIUM + } + SpecId::ISTANBUL | SpecId::MUIR_GLACIER => revm_precompiles::SpecId::ISTANBUL, + SpecId::BERLIN + | SpecId::LONDON + | SpecId::ARROW_GLACIER + | SpecId::GRAY_GLACIER + | SpecId::MERGE + | SpecId::MERGE_EOF + | SpecId::LATEST => revm_precompiles::SpecId::BERLIN, + } +} + pub fn evm_inner<'a, DB: Database, const INSPECT: bool>( env: &'a mut Env, db: &'a mut DB, diff --git a/crates/revm/src/evm_impl.rs b/crates/revm/src/evm_impl.rs index 5eeb550247..f017b421a5 100644 --- a/crates/revm/src/evm_impl.rs +++ b/crates/revm/src/evm_impl.rs @@ -2,9 +2,9 @@ use crate::{ common::keccak256, db::Database, gas, - interpreter::{self, bytecode::Bytecode}, - interpreter::{Contract, Interpreter}, - journaled_state::{Account, JournaledState, State}, + interpreter::{self, Bytecode, Host}, + interpreter::{Account, Contract, Interpreter}, + journaled_state::{JournaledState, State}, models::SelfDestructResult, precompiles, return_ok, return_revert, AnalysisKind, CallContext, CallInputs, CallScheme, CreateInputs, CreateScheme, Env, ExecutionResult, Gas, Inspector, Log, Return, Spec, @@ -15,6 +15,7 @@ use alloc::vec::Vec; use bytes::Bytes; use core::{cmp::min, marker::PhantomData}; use hashbrown::HashMap as Map; +use revm_interpreter::common::{create2_address, create_address}; use revm_precompiles::{Precompile, Precompiles}; pub struct EVMData<'a, DB: Database> { @@ -503,8 +504,11 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> EVMImpl<'a, GSPEC, DB, self.inspector .initialize_interp(&mut interpreter, &mut self.data, false); } - let exit_reason = interpreter.run::(self, INSPECT); - + let exit_reason = if INSPECT { + interpreter.run_inspect::(self) + } else { + interpreter.run::(self) + }; // Host error if present on execution\ let (ret, address, gas, out) = match exit_reason { return_ok!() => { @@ -704,7 +708,12 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> EVMImpl<'a, GSPEC, DB, self.inspector .initialize_interp(&mut interpreter, &mut self.data, false); } - let exit_reason = interpreter.run::(self, INSPECT); + let exit_reason = if INSPECT { + interpreter.run_inspect::(self) + } else { + interpreter.run::(self) + }; + if matches!(exit_reason, return_ok!()) { self.data.journaled_state.checkpoint_commit(); } else { @@ -854,60 +863,3 @@ impl<'a, GSPEC: Spec, DB: Database + 'a, const INSPECT: bool> Host self.call_inner(inputs) } } - -/// Returns the address for the legacy `CREATE` scheme: [`CreateScheme::Create`] -pub fn create_address(caller: B160, nonce: u64) -> B160 { - let mut stream = rlp::RlpStream::new_list(2); - stream.append(&caller.0.as_ref()); - stream.append(&nonce); - let out = keccak256(&stream.out()); - B160(out[12..].try_into().unwrap()) -} - -/// Returns the address for the `CREATE2` scheme: [`CreateScheme::Create2`] -pub fn create2_address(caller: B160, code_hash: B256, salt: U256) -> B160 { - use sha3::{Digest, Keccak256}; - let mut hasher = Keccak256::new(); - hasher.update([0xff]); - hasher.update(&caller[..]); - hasher.update(salt.to_be_bytes::<{ U256::BYTES }>()); - hasher.update(&code_hash[..]); - - B160(hasher.finalize().as_slice()[12..].try_into().unwrap()) -} - -/// EVM context host. -pub trait Host { - fn step(&mut self, interp: &mut Interpreter, is_static: bool) -> Return; - fn step_end(&mut self, interp: &mut Interpreter, is_static: bool, ret: Return) -> Return; - - fn env(&mut self) -> &mut Env; - - /// load account. Returns (is_cold,is_new_account) - fn load_account(&mut self, address: B160) -> Option<(bool, bool)>; - /// Get environmental block hash. - fn block_hash(&mut self, number: U256) -> Option; - /// Get balance of address. - fn balance(&mut self, address: B160) -> Option<(U256, bool)>; - /// Get code of address. - fn code(&mut self, address: B160) -> Option<(Bytecode, bool)>; - /// Get code hash of address. - fn code_hash(&mut self, address: B160) -> Option<(B256, bool)>; - /// Get storage value of address at index. - fn sload(&mut self, address: B160, index: U256) -> Option<(U256, bool)>; - /// Set storage value of address at index. Return if slot is cold/hot access. - fn sstore( - &mut self, - address: B160, - index: U256, - value: U256, - ) -> Option<(U256, U256, U256, bool)>; - /// Create a log owned by address with given topics and data. - fn log(&mut self, address: B160, topics: Vec, data: Bytes); - /// Mark an address to be deleted, with funds transferred to target. - fn selfdestruct(&mut self, address: B160, target: B160) -> Option; - /// Invoke a create operation. - fn create(&mut self, inputs: &mut CreateInputs) -> (Return, Option, Gas, Bytes); - /// Invoke a call operation. - fn call(&mut self, input: &mut CallInputs) -> (Return, Gas, Bytes); -} diff --git a/crates/revm/src/inspector.rs b/crates/revm/src/inspector.rs index f18d36a0e1..21a16aa71f 100644 --- a/crates/revm/src/inspector.rs +++ b/crates/revm/src/inspector.rs @@ -1,7 +1,5 @@ use crate::{ - bits::{B160, B256}, - evm_impl::EVMData, - CallInputs, CreateInputs, Database, Gas, Interpreter, Return, + evm_impl::EVMData, CallInputs, CreateInputs, Database, Gas, Interpreter, Return, B160, B256, }; use auto_impl::auto_impl; use bytes::Bytes; diff --git a/crates/revm/src/inspector/customprinter.rs b/crates/revm/src/inspector/customprinter.rs index 0dadf2c2a4..320292987f 100644 --- a/crates/revm/src/inspector/customprinter.rs +++ b/crates/revm/src/inspector/customprinter.rs @@ -2,10 +2,9 @@ //! It is great tool if some debugging is needed. //! use crate::{ - bits::B160, inspectors::GasInspector, opcode::{self}, - Bytes, CallInputs, CreateInputs, Database, EVMData, Gas, Inspector, Interpreter, Return, + Bytes, CallInputs, CreateInputs, Database, EVMData, Gas, Inspector, Interpreter, Return, B160, }; use hex; #[derive(Clone, Default)] diff --git a/crates/revm/src/inspector/gas.rs b/crates/revm/src/inspector/gas.rs index 394940164b..5da2719627 100644 --- a/crates/revm/src/inspector/gas.rs +++ b/crates/revm/src/inspector/gas.rs @@ -1,8 +1,6 @@ //! GasIspector. Helper Inspector to calculte gas for others. //! -use crate::{ - bits::B160, evm_impl::EVMData, CallInputs, CreateInputs, Database, Gas, Inspector, Return, -}; +use crate::{evm_impl::EVMData, CallInputs, CreateInputs, Database, Gas, Inspector, Return, B160}; use bytes::Bytes; #[derive(Clone, Copy, Debug, Default)] diff --git a/crates/revm/src/journaled_state.rs b/crates/revm/src/journaled_state.rs index c89f80e031..c33fe900ea 100644 --- a/crates/revm/src/journaled_state.rs +++ b/crates/revm/src/journaled_state.rs @@ -1,10 +1,11 @@ -use crate::{interpreter::bytecode::Bytecode, models::SelfDestructResult, Return, KECCAK_EMPTY}; +use crate::{db::Database, Log, B160}; +use crate::{ + interpreter::{models::SelfDestructResult, Account, Bytecode, Return, StorageSlot, U256}, + KECCAK_EMPTY, +}; use alloc::{vec, vec::Vec}; use core::mem::{self}; use hashbrown::{hash_map::Entry, HashMap as Map}; -use ruint::aliases::U256; - -use crate::{bits::B160, db::Database, AccountInfo, Log}; #[derive(Debug, Clone, Eq, PartialEq)] #[cfg_attr(feature = "with-serde", derive(serde::Serialize, serde::Deserialize))] @@ -29,83 +30,6 @@ pub struct JournaledState { pub type State = Map; pub type Storage = Map; -#[derive(Debug, Clone, Eq, PartialEq)] -#[cfg_attr(feature = "with-serde", derive(serde::Serialize, serde::Deserialize))] -pub struct Account { - /// Balance of the account. - pub info: AccountInfo, - /// storage cache - pub storage: Map, - /// If account is newly created, we will not ask database for storage values - pub storage_cleared: bool, - /// if account is destroyed it will be scheduled for removal. - pub is_destroyed: bool, - /// if account is touched - pub is_touched: bool, - /// used only for pre spurious dragon hardforks where exisnting and empty was two saparate states. - /// it became same state after EIP-161: State trie clearing - pub is_not_existing: bool, -} - -impl Account { - pub fn is_empty(&self) -> bool { - self.info.is_empty() - } - pub fn new_not_existing() -> Self { - Self { - info: AccountInfo::default(), - storage: Map::new(), - storage_cleared: false, - is_destroyed: false, - is_touched: false, - is_not_existing: true, - } - } -} - -impl From for Account { - fn from(info: AccountInfo) -> Self { - Self { - info, - storage: Map::new(), - storage_cleared: false, - is_destroyed: false, - is_touched: false, - is_not_existing: false, - } - } -} - -#[derive(Debug, Clone, Default, Eq, PartialEq)] -#[cfg_attr(feature = "with-serde", derive(serde::Serialize, serde::Deserialize))] -pub struct StorageSlot { - original_value: U256, - /// When loaded with sload present value is set to original value - present_value: U256, -} - -impl StorageSlot { - pub fn new(original: U256) -> Self { - Self { - original_value: original, - present_value: original, - } - } - - /// Returns true if the present value differs from the original value - pub fn is_changed(&self) -> bool { - self.original_value != self.present_value - } - - pub fn original_value(&self) -> U256 { - self.original_value - } - - pub fn present_value(&self) -> U256 { - self.present_value - } -} - #[derive(Debug, Clone, Eq, PartialEq)] #[cfg_attr(feature = "with-serde", derive(serde::Serialize, serde::Deserialize))] pub enum JournalEntry { diff --git a/crates/revm/src/lib.rs b/crates/revm/src/lib.rs index 3e89538f82..24cf98a634 100644 --- a/crates/revm/src/lib.rs +++ b/crates/revm/src/lib.rs @@ -1,50 +1,30 @@ #![allow(dead_code)] //#![no_std] - -pub mod bits; -pub mod common; pub mod db; mod evm; mod evm_impl; -pub(crate) mod gas; mod inspector; -mod instructions; -mod interpreter; mod journaled_state; -mod models; -mod specification; - -// Reexport primary types. -pub use bits::{B160, B256}; -pub use bytes::Bytes; -pub use ruint::aliases::U256; - -pub use evm_impl::{create2_address, create_address, EVMData, Host}; +pub(crate) const USE_GAS: bool = !cfg!(feature = "no_gas_measuring"); pub type DummyStateDB = InMemoryDB; pub use db::{Database, DatabaseCommit, InMemoryDB}; pub use evm::{evm_inner, new, EVM}; -pub use gas::Gas; -pub use instructions::{ - opcode::{self, spec_opcode_gas, OpCode, OPCODE_JUMPMAP}, - Return, -}; -pub use interpreter::{ - Bytecode, BytecodeLocked, BytecodeState, Contract, Interpreter, Memory, Stack, -}; -pub use journaled_state::{Account, JournalEntry, JournaledState, StorageSlot}; -pub use models::*; -pub use specification::*; +pub use evm_impl::EVMData; +pub use journaled_state::{JournalEntry, JournaledState}; +pub use revm_interpreter::*; extern crate alloc; -pub(crate) const USE_GAS: bool = !cfg!(feature = "no_gas_measuring"); - /// reexport `revm_precompiles` pub mod precompiles { pub use revm_precompiles::*; } +// reexport `revm_interpreter` +pub mod interpreter { + pub use revm_interpreter::*; +} /// Reexport Inspector implementations pub use inspector::inspectors; diff --git a/crates/revm/src/specification.rs b/crates/revm/src/specification.rs deleted file mode 100644 index 2e21dc669c..0000000000 --- a/crates/revm/src/specification.rs +++ /dev/null @@ -1,136 +0,0 @@ -use core::convert::TryFrom; -use num_enum::TryFromPrimitive; -use revm_precompiles::SpecId as PrecompileId; - -/// SpecId and their activation block -/// Information was obtained from: https://github.com/ethereum/execution-specs -#[repr(u8)] -#[derive(Debug, Copy, Clone, TryFromPrimitive, Eq, PartialEq, Hash, Ord, PartialOrd)] -#[cfg_attr(feature = "with-serde", derive(serde::Serialize, serde::Deserialize))] -#[allow(non_camel_case_types)] -pub enum SpecId { - FRONTIER = 0, // Frontier 0 - FRONTIER_THAWING = 1, // Frontier Thawing 200000 - HOMESTEAD = 2, // Homestead 1150000 - DAO_FORK = 3, // DAO Fork 1920000 - TANGERINE = 4, // Tangerine Whistle 2463000 - SPURIOUS_DRAGON = 5, // Spurious Dragon 2675000 - BYZANTIUM = 6, // Byzantium 4370000 - CONSTANTINOPLE = 7, // Constantinople 7280000 is overwriten with PETERSBURG - PETERSBURG = 8, // Petersburg 7280000 - ISTANBUL = 9, // Istanbul 9069000 - MUIR_GLACIER = 10, // Muir Glacier 9200000 - BERLIN = 11, // Berlin 12244000 - LONDON = 12, // London 12965000 - ARROW_GLACIER = 13, // Arrow Glacier 13773000 - GRAY_GLACIER = 14, // Gray Glacier 15050000 - MERGE = 15, // Paris/Merge TBD (Depends on difficulty) - MERGE_EOF = 16, // Merge+EOF TBD - LATEST = 17, -} - -impl SpecId { - pub const fn to_precompile_id(self) -> PrecompileId { - match self { - FRONTIER | FRONTIER_THAWING | HOMESTEAD | DAO_FORK | TANGERINE | SPURIOUS_DRAGON => { - PrecompileId::HOMESTEAD - } - BYZANTIUM | CONSTANTINOPLE | PETERSBURG => PrecompileId::BYZANTIUM, - ISTANBUL | MUIR_GLACIER => PrecompileId::ISTANBUL, - BERLIN | LONDON | ARROW_GLACIER | GRAY_GLACIER | MERGE | MERGE_EOF | LATEST => { - PrecompileId::BERLIN - } - } - } - - pub fn try_from_u8(spec_id: u8) -> Option { - Self::try_from(spec_id).ok() - } -} - -pub use SpecId::*; - -impl From<&str> for SpecId { - fn from(name: &str) -> Self { - match name { - "Frontier" => SpecId::FRONTIER, - "Homestead" => SpecId::HOMESTEAD, - "Tangerine" => SpecId::TANGERINE, - "Spurious" => SpecId::SPURIOUS_DRAGON, - "Byzantium" => SpecId::BYZANTIUM, - "Constantinople" => SpecId::CONSTANTINOPLE, - "Petersburg" => SpecId::PETERSBURG, - "Istanbul" => SpecId::ISTANBUL, - "MuirGlacier" => SpecId::MUIR_GLACIER, - "Berlin" => SpecId::BERLIN, - "London" => SpecId::LONDON, - "Merge" => SpecId::MERGE, - "MergeEOF" => SpecId::MERGE_EOF, - _ => SpecId::LATEST, - } - } -} - -impl SpecId { - #[inline] - pub const fn enabled(our: SpecId, other: SpecId) -> bool { - our as u8 >= other as u8 - } -} - -pub trait Spec: Sized { - #[inline(always)] - fn enabled(spec_id: SpecId) -> bool { - Self::SPEC_ID as u8 >= spec_id as u8 - } - const SPEC_ID: SpecId; -} - -pub(crate) mod spec_impl { - - macro_rules! spec { - ($spec_id:tt) => { - #[allow(non_snake_case)] - pub mod $spec_id { - use crate::{Spec, SpecId}; - - pub struct SpecImpl {} - - impl Spec for SpecImpl { - //specification id - const SPEC_ID: SpecId = SpecId::$spec_id; - } - } - }; - } - - spec!(FRONTIER); - // FRONTIER_THAWING no EVM spec change - spec!(HOMESTEAD); - // DAO_FORK no EVM spec change - spec!(TANGERINE); - spec!(SPURIOUS_DRAGON); - spec!(BYZANTIUM); - // CONSTANTINOPLE was overriden with PETERSBURG - spec!(PETERSBURG); - spec!(ISTANBUL); - // MUIR_GLACIER no EVM spec change - spec!(BERLIN); - spec!(LONDON); - // ARROW_GLACIER no EVM spec change - // GRAT_GLACIER no EVM spec change - spec!(MERGE); - spec!(LATEST); -} - -pub use spec_impl::BERLIN::SpecImpl as BerlinSpec; -pub use spec_impl::BYZANTIUM::SpecImpl as ByzantiumSpec; -pub use spec_impl::FRONTIER::SpecImpl as FrontierSpec; -pub use spec_impl::HOMESTEAD::SpecImpl as HomesteadSpec; -pub use spec_impl::ISTANBUL::SpecImpl as IstanbulSpec; -pub use spec_impl::LATEST::SpecImpl as LatestSpec; -pub use spec_impl::LONDON::SpecImpl as LondonSpec; -pub use spec_impl::MERGE::SpecImpl as MergeSpec; -pub use spec_impl::PETERSBURG::SpecImpl as PetersburgSpec; -pub use spec_impl::SPURIOUS_DRAGON::SpecImpl as SpuriousDragonSpec; -pub use spec_impl::TANGERINE::SpecImpl as TangerineSpec; diff --git a/crates/revm_precompiles/README.md b/crates/revm_precompiles/README.md deleted file mode 100644 index 206228733e..0000000000 --- a/crates/revm_precompiles/README.md +++ /dev/null @@ -1,3 +0,0 @@ -### REVM Precompiles - Ethereum compatible precompiled contracts - -Used inside REVM and passes all eth/tests. It supports all latest Ethereum hard forks, including London. \ No newline at end of file