diff --git a/.github/workflows/cachegrind.yml b/.github/workflows/cachegrind.yml index ed1d42fa7c..1e21cc7a66 100644 --- a/.github/workflows/cachegrind.yml +++ b/.github/workflows/cachegrind.yml @@ -14,9 +14,7 @@ jobs: uses: actions/checkout@v2 - name: Setup | Rust - uses: ATiltedTree/setup-rust@v1 - with: - rust-version: stable + uses: dtolnay/rust-toolchain@stable - name: Install Valgrind run: | diff --git a/.gitignore b/.gitignore index 5a41425ea8..07d5efeddf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ /target/ **/*.rs.bk +**/.DS_Store target .vscode diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d214110e6..6d60f59271 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ Because this is workspace with multi libraries, tags will be simplified, and with this document you can match version of project with git tag. +# v35 tag +date: 02.04.2024 + +Small release. Alloy bump. Small refactors and deprecated functions removed. + +revme: 0.3.1 -> 0.4.0 (✓ API compatible changes) +revm: 7.2.0 -> 8.0.0 (⚠️ API breaking changes) +revm-interpreter: 3.4.0 -> 4.0.0 (⚠️ API breaking changes) +revm-primitives: 3.1.0 -> 3.1.1 (✓ API compatible changes) +revm-precompile: 5.1.0 -> 6.0.0 (⚠️ API breaking changes) +revm-test: 0.1.0 + # v34 tag date: 20.03.2024 diff --git a/Cargo.lock b/Cargo.lock index 40586934e9..2bb8257a0c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.8.8" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42cd52102d3df161c77a887b608d7a4897d7cc112886a9537b738a887a03aaff" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", "once_cell", @@ -31,9 +31,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] @@ -44,11 +44,75 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +[[package]] +name = "alloy-consensus" +version = "0.1.0" +source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +dependencies = [ + "alloy-eips", + "alloy-primitives", + "alloy-rlp", + "alloy-serde", + "serde", + "sha2", +] + +[[package]] +name = "alloy-eips" +version = "0.1.0" +source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "alloy-serde", + "c-kzg", + "once_cell", + "serde", +] + +[[package]] +name = "alloy-genesis" +version = "0.1.0" +source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +dependencies = [ + "alloy-primitives", + "alloy-serde", + "serde", +] + +[[package]] +name = "alloy-json-rpc" +version = "0.1.0" +source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +dependencies = [ + "alloy-primitives", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "alloy-network" +version = "0.1.0" +source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +dependencies = [ + "alloy-consensus", + "alloy-eips", + "alloy-json-rpc", + "alloy-primitives", + "alloy-rpc-types", + "alloy-signer", + "async-trait", + "futures-utils-wasm", + "serde", + "thiserror", +] + [[package]] name = "alloy-primitives" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "600d34d8de81e23b6d909c094e23b3d357e01ca36b78a8c5424c501eedbe86f0" +checksum = "99bbad0a6b588ef4aec1b5ddbbfdacd9ef04e00b979617765b03174318ee1f3a" dependencies = [ "alloy-rlp", "arbitrary", @@ -70,6 +134,32 @@ dependencies = [ "tiny-keccak", ] +[[package]] +name = "alloy-provider" +version = "0.1.0" +source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +dependencies = [ + "alloy-json-rpc", + "alloy-network", + "alloy-primitives", + "alloy-rpc-client", + "alloy-rpc-types", + "alloy-rpc-types-trace", + "alloy-transport", + "alloy-transport-http", + "async-stream", + "async-trait", + "auto_impl", + "dashmap", + "futures", + "lru", + "reqwest 0.12.2", + "serde_json", + "tokio", + "tracing", + "url", +] + [[package]] name = "alloy-rlp" version = "0.3.4" @@ -89,32 +179,120 @@ checksum = "1a047897373be4bbb0224c1afdabca92648dc57a9c9ef6e7b0be3aff7a859c83" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.55", +] + +[[package]] +name = "alloy-rpc-client" +version = "0.1.0" +source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +dependencies = [ + "alloy-json-rpc", + "alloy-transport", + "alloy-transport-http", + "futures", + "pin-project", + "reqwest 0.12.2", + "serde", + "serde_json", + "tokio", + "tokio-stream", + "tower", + "tracing", + "url", +] + +[[package]] +name = "alloy-rpc-types" +version = "0.1.0" +source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +dependencies = [ + "alloy-consensus", + "alloy-eips", + "alloy-genesis", + "alloy-primitives", + "alloy-rlp", + "alloy-serde", + "alloy-sol-types", + "itertools 0.12.1", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "alloy-rpc-types-trace" +version = "0.1.0" +source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +dependencies = [ + "alloy-primitives", + "alloy-rpc-types", + "alloy-serde", + "serde", + "serde_json", +] + +[[package]] +name = "alloy-serde" +version = "0.1.0" +source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +dependencies = [ + "alloy-primitives", + "serde", + "serde_json", +] + +[[package]] +name = "alloy-signer" +version = "0.1.0" +source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +dependencies = [ + "alloy-primitives", + "async-trait", + "auto_impl", + "elliptic-curve", + "k256", + "thiserror", ] [[package]] name = "alloy-sol-macro" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86ec0a47740b20bc5613b8712d0d321d031c4efc58e9645af96085d5cccfc27" +checksum = "452d929748ac948a10481fff4123affead32c553cf362841c5103dd508bdfc16" dependencies = [ + "alloy-sol-macro-input", "const-hex", - "dunce", "heck 0.4.1", "indexmap", "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.55", "syn-solidity", "tiny-keccak", ] +[[package]] +name = "alloy-sol-macro-input" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df64e094f6d2099339f9e82b5b38440b159757b6920878f28316243f8166c8d1" +dependencies = [ + "const-hex", + "dunce", + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.55", + "syn-solidity", +] + [[package]] name = "alloy-sol-types" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad09ec5853fa700d12d778ad224dcdec636af424d29fad84fb9a2f16a5b0ef09" +checksum = "43bc2d6dfc2a19fd56644494479510f98b1ee929e04cf0d4aa45e98baa3e545b" dependencies = [ "alloy-primitives", "alloy-sol-macro", @@ -122,6 +300,37 @@ dependencies = [ "serde", ] +[[package]] +name = "alloy-transport" +version = "0.1.0" +source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +dependencies = [ + "alloy-json-rpc", + "base64 0.22.0", + "futures-util", + "futures-utils-wasm", + "serde", + "serde_json", + "thiserror", + "tokio", + "tower", + "url", + "wasm-bindgen-futures", +] + +[[package]] +name = "alloy-transport-http" +version = "0.1.0" +source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +dependencies = [ + "alloy-json-rpc", + "alloy-transport", + "reqwest 0.12.2", + "serde_json", + "tower", + "url", +] + [[package]] name = "anes" version = "0.1.6" @@ -185,7 +394,7 @@ dependencies = [ "ark-std 0.4.0", "derivative", "digest 0.10.7", - "itertools", + "itertools 0.10.5", "num-bigint", "num-traits", "paste", @@ -285,15 +494,37 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +[[package]] +name = "async-stream" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + [[package]] name = "async-trait" -version = "0.1.77" +version = "0.1.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +checksum = "a507401cad91ec6a857ed5513a2073c82a9b9048762b885bb98655b306964681" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.55", ] [[package]] @@ -336,7 +567,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.55", ] [[package]] @@ -347,9 +578,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" dependencies = [ "addr2line", "cc", @@ -378,6 +609,12 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "base64" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51" + [[package]] name = "base64ct" version = "1.6.0" @@ -451,9 +688,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" [[package]] name = "byte-slice-cast" @@ -469,9 +706,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" dependencies = [ "serde", ] @@ -498,12 +735,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.0.83" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" -dependencies = [ - "libc", -] +checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" [[package]] name = "cfg-if" @@ -513,9 +747,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.34" +version = "0.4.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b" +checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a" dependencies = [ "num-traits", ] @@ -564,18 +798,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.0" +version = "4.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80c21025abd42669a92efc996ef13cfb2c5c627858421ea58d5c3b331a6c134f" +checksum = "949626d00e063efc93b6dca932419ceb5432f99769911c0b995f7e884c778813" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.0" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "458bf1f341769dfcf849846f65dffdf9146daa56bcd2a47cb4e1de9915567c99" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" dependencies = [ "anstyle", "clap_lex", @@ -602,9 +836,9 @@ dependencies = [ [[package]] name = "const-hex" -version = "1.11.0" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d59688ad0945eaf6b84cb44fedbe93484c81b48970e98f09db8a22832d7961" +checksum = "5ba00838774b4ab0233e355d26710fbfc8327a05c017f6dc4873f876d1f79f78" dependencies = [ "cfg-if", "cpufeatures", @@ -659,10 +893,10 @@ dependencies = [ "anes", "cast", "ciborium", - "clap 4.5.0", + "clap 4.5.3", "criterion-plot", "is-terminal", - "itertools", + "itertools 0.10.5", "num-traits", "once_cell", "oorandom", @@ -683,7 +917,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" dependencies = [ "cast", - "itertools", + "itertools 0.10.5", ] [[package]] @@ -739,6 +973,19 @@ dependencies = [ "typenum", ] +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown", + "lock_api", + "once_cell", + "parking_lot_core", +] + [[package]] name = "data-encoding" version = "2.5.0" @@ -783,7 +1030,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.55", ] [[package]] @@ -912,7 +1159,7 @@ checksum = "6fd000fd6988e73bbe993ea3db9b1aa64906ab88766d654973924340c8cddb42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.55", ] [[package]] @@ -986,7 +1233,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e61ffea29f26e8249d35128a82ec8d3bd4fbc80179ea5f5e5e3daafef6a80fcb" dependencies = [ "ethereum-types", - "itertools", + "itertools 0.10.5", "smallvec", ] @@ -1051,12 +1298,12 @@ dependencies = [ "futures-timer", "futures-util", "hashers", - "http", + "http 0.2.12", "instant", "jsonwebtoken", "once_cell", "pin-project", - "reqwest", + "reqwest 0.11.27", "serde", "serde_json", "thiserror", @@ -1083,9 +1330,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" [[package]] name = "fastrlp" @@ -1127,6 +1374,21 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -1198,7 +1460,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.55", ] [[package]] @@ -1215,9 +1477,9 @@ checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-timer" -version = "3.0.2" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" dependencies = [ "gloo-timers", "send_wrapper 0.4.0", @@ -1241,6 +1503,12 @@ dependencies = [ "slab", ] +[[package]] +name = "futures-utils-wasm" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42012b0f064e01aa58b545fe3727f90f7dd4020f4a3ea735b50344965f5a57e9" + [[package]] name = "fxhash" version = "0.2.1" @@ -1309,16 +1577,16 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" +checksum = "4fbd2820c5e49886948654ab546d0688ff24530286bdcf8fca3cefb16d4618eb" dependencies = [ "bytes", "fnv", "futures-core", "futures-sink", "futures-util", - "http", + "http 0.2.12", "indexmap", "slab", "tokio", @@ -1328,9 +1596,9 @@ dependencies = [ [[package]] name = "half" -version = "2.3.1" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc52e53916c08643f1b56ec082790d1e86a32e58dc5268f897f313fbae7b4872" +checksum = "b5eceaaeec696539ddaf7b333340f1af35a5aa87ae3e4f3ead0532f72affab2e" dependencies = [ "cfg-if", "crunchy", @@ -1377,6 +1645,12 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -1388,9 +1662,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.5" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0c62115964e08cb8039170eb33c1d0e2388a256930279edca206fff675f82c3" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hex" @@ -1418,9 +1692,20 @@ dependencies = [ [[package]] name = "http" -version = "0.2.11" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ "bytes", "fnv", @@ -1434,7 +1719,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", - "http", + "http 0.2.12", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +dependencies = [ + "bytes", + "http 1.1.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" +dependencies = [ + "bytes", + "futures-core", + "http 1.1.0", + "http-body 1.0.0", "pin-project-lite", ] @@ -1461,8 +1769,8 @@ dependencies = [ "futures-core", "futures-util", "h2", - "http", - "http-body", + "http 0.2.12", + "http-body 0.4.6", "httparse", "httpdate", "itoa", @@ -1474,6 +1782,25 @@ dependencies = [ "want", ] +[[package]] +name = "hyper" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "186548d73ac615b32a73aafe38fb4f56c0d340e110e5a200bcadbaf2e199263a" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + [[package]] name = "hyper-rustls" version = "0.24.2" @@ -1481,13 +1808,49 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", - "http", - "hyper", + "http 0.2.12", + "hyper 0.14.28", "rustls", "tokio", "tokio-rustls", ] +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper 1.2.0", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", + "hyper 1.2.0", + "pin-project-lite", + "socket2", + "tokio", + "tower", + "tower-service", + "tracing", +] + [[package]] name = "idna" version = "0.5.0" @@ -1544,9 +1907,9 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" [[package]] name = "indexmap" -version = "2.2.3" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", "hashbrown", @@ -1586,7 +1949,7 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" dependencies = [ - "hermit-abi 0.3.5", + "hermit-abi 0.3.9", "libc", "windows-sys 0.52.0", ] @@ -1600,6 +1963,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.10" @@ -1608,9 +1980,9 @@ checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "js-sys" -version = "0.3.68" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] @@ -1689,11 +2061,30 @@ version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + [[package]] name = "log" -version = "0.4.20" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + +[[package]] +name = "lru" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc" +dependencies = [ + "hashbrown", +] [[package]] name = "memchr" @@ -1724,15 +2115,33 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", "wasi", "windows-sys 0.48.0", ] +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "num" version = "0.4.1" @@ -1821,7 +2230,7 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.3.5", + "hermit-abi 0.3.9", "libc", ] @@ -1843,7 +2252,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.55", ] [[package]] @@ -1898,6 +2307,50 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "openssl" +version = "0.10.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +dependencies = [ + "bitflags 2.5.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "parity-scale-codec" version = "3.6.9" @@ -1924,6 +2377,19 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.48.5", +] + [[package]] name = "paste" version = "1.0.14" @@ -1947,9 +2413,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.7" +version = "2.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219c0dcc30b6a27553f9cc242972b67f75b60eb0db71f0b5462f38b058c41546" +checksum = "56f8023d0fb78c8e03784ea1c7f3fa36e68a723138990b8d5a47d916b651e7a8" dependencies = [ "memchr", "thiserror", @@ -1968,22 +2434,22 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.55", ] [[package]] @@ -2008,6 +2474,12 @@ dependencies = [ "spki", ] +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + [[package]] name = "plain_hasher" version = "0.2.3" @@ -2131,9 +2603,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" dependencies = [ "unicode-ident", ] @@ -2231,9 +2703,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.8.1" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -2249,11 +2721,20 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "regex" -version = "1.10.3" +version = "1.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" dependencies = [ "aho-corasick", "memchr", @@ -2263,9 +2744,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ "aho-corasick", "memchr", @@ -2280,9 +2761,9 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "reqwest" -version = "0.11.24" +version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6920094eb85afde5e4a138be3f2de8bbdf28000f0029e72c45025a56b042251" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ "base64 0.21.7", "bytes", @@ -2290,9 +2771,9 @@ dependencies = [ "futures-core", "futures-util", "h2", - "http", - "http-body", - "hyper", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.28", "hyper-rustls", "ipnet", "js-sys", @@ -2319,10 +2800,53 @@ dependencies = [ "winreg", ] +[[package]] +name = "reqwest" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d66674f2b6fb864665eea7a3c1ac4e3dfacd2fda83cf6f935a612e01b0e3338" +dependencies = [ + "base64 0.21.7", + "bytes", + "futures-core", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", + "http-body-util", + "hyper 1.2.0", + "hyper-tls", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + [[package]] name = "revm" -version = "7.2.0" +version = "8.1.0" dependencies = [ + "alloy-provider", + "alloy-rpc-types", + "alloy-transport", + "alloy-transport-http", "anyhow", "auto_impl", "cfg-if", @@ -2341,7 +2865,7 @@ dependencies = [ [[package]] name = "revm-interpreter" -version = "3.4.0" +version = "5.0.0" dependencies = [ "revm-primitives", "serde", @@ -2349,13 +2873,14 @@ dependencies = [ [[package]] name = "revm-precompile" -version = "5.1.0" +version = "6.0.1" dependencies = [ "aurora-engine-modexp", "c-kzg", "criterion", "k256", "once_cell", + "rand", "revm-primitives", "ripemd", "secp256k1", @@ -2365,7 +2890,7 @@ dependencies = [ [[package]] name = "revm-primitives" -version = "3.1.0" +version = "3.2.0" dependencies = [ "alloy-primitives", "auto_impl", @@ -2398,7 +2923,7 @@ dependencies = [ [[package]] name = "revme" -version = "0.3.1" +version = "0.4.1" dependencies = [ "alloy-rlp", "hash-db", @@ -2444,16 +2969,17 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.7" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", + "cfg-if", "getrandom", "libc", "spin 0.9.8", "untrusted 0.9.0", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2489,9 +3015,9 @@ dependencies = [ [[package]] name = "ruint" -version = "1.11.1" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608a5726529f2f0ef81b8fde9873c4bb829d6b5b5ca6be4d97345ddf0749c825" +checksum = "8f308135fef9fc398342da5472ce7c484529df23743fb7c734e0f3d472971e62" dependencies = [ "alloy-rlp", "arbitrary", @@ -2514,9 +3040,9 @@ dependencies = [ [[package]] name = "ruint-macro" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e666a5496a0b2186dbcd0ff6106e29e093c15591bde62c20d3842007c6978a09" +checksum = "f86854cf50259291520509879a5c294c3c9a4c334e9ff65071c51e42ef1e2343" [[package]] name = "rustc-demangle" @@ -2545,14 +3071,14 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.21", + "semver 1.0.22", ] [[package]] name = "rustix" -version = "0.38.31" +version = "0.38.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" dependencies = [ "bitflags 2.5.0", "errno", @@ -2568,7 +3094,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" dependencies = [ "log", - "ring 0.17.7", + "ring 0.17.8", "rustls-webpki", "sct", ] @@ -2588,7 +3114,7 @@ version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring 0.17.7", + "ring 0.17.8", "untrusted 0.9.0", ] @@ -2612,9 +3138,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" [[package]] name = "same-file" @@ -2627,9 +3153,9 @@ dependencies = [ [[package]] name = "scale-info" -version = "2.10.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7d66a1128282b7ef025a8ead62a4a9fcf017382ec53b8ffbf4d7bf77bd3c60" +checksum = "788745a868b0e751750388f4e6546eb921ef714a4317fa6954f7cde114eb2eb7" dependencies = [ "cfg-if", "derive_more", @@ -2639,9 +3165,9 @@ dependencies = [ [[package]] name = "scale-info-derive" -version = "2.10.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abf2c68b89cafb3b8d918dd07b42be0da66ff202cf1155c5739a4e0c1ea0dc19" +checksum = "7dc2f4e8bc344b9fc3d5f74f72c2e55bfc38d28dc2ebc69c194a3df424e4d9ac" dependencies = [ "proc-macro-crate 1.3.1", "proc-macro2", @@ -2649,13 +3175,28 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "schannel" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "sct" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring 0.17.7", + "ring 0.17.8", "untrusted 0.9.0", ] @@ -2675,9 +3216,9 @@ dependencies = [ [[package]] name = "secp256k1" -version = "0.28.2" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d24b59d129cdadea20aea4fb2352fa053712e5d713eee47d700cd4b2bc002f10" +checksum = "0e0cc0f1cf93f4969faf3ea1c7d8a9faed25918d96affa959720823dfe86d4f3" dependencies = [ "rand", "secp256k1-sys", @@ -2685,13 +3226,36 @@ dependencies = [ [[package]] name = "secp256k1-sys" -version = "0.9.2" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d1746aae42c19d583c3c1a8c646bfad910498e2051c551a7f2e3c0c9fbb7eb" +checksum = "1433bd67156263443f14d603720b082dd3121779323fce20cba2aa07b874bc1b" dependencies = [ "cc", ] +[[package]] +name = "security-framework" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "semver" version = "0.11.0" @@ -2703,9 +3267,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.21" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" [[package]] name = "semver-parser" @@ -2745,14 +3309,14 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.55", ] [[package]] name = "serde_json" -version = "1.0.114" +version = "1.0.115" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" dependencies = [ "indexmap", "itoa", @@ -2847,18 +3411,18 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" -version = "0.5.5" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2921,24 +3485,24 @@ dependencies = [ [[package]] name = "strum" -version = "0.26.1" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "723b93e8addf9aa965ebe2d11da6d7540fa2283fcea14b3371ff055f7ba13f5f" +checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" dependencies = [ "strum_macros", ] [[package]] name = "strum_macros" -version = "0.26.1" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a3417fc93d76740d974a01654a09777cb500428cc874ca9f45edfe0c4d4cd18" +checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946" dependencies = [ "heck 0.4.1", "proc-macro2", "quote", "rustversion", - "syn 2.0.48", + "syn 2.0.55", ] [[package]] @@ -2973,9 +3537,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.48" +version = "2.0.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "002a1b3dbf967edfafc32655d0f377ab0bb7b994aa1d32c8cc7e9b8bf3ebb8f0" dependencies = [ "proc-macro2", "quote", @@ -2984,14 +3548,14 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb3d0961cd53c23ea94eeec56ba940f636f6394788976e9f16ca5ee0aca7464a" +checksum = "4497156948bd342b52038035a6fa514a89626e37af9d2c52a5e8d8ebcc7ee479" dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.55", ] [[package]] @@ -3029,9 +3593,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.10.0" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", "fastrand", @@ -3065,7 +3629,7 @@ checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.55", ] [[package]] @@ -3144,9 +3708,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.36.0" +version = "1.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" +checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" dependencies = [ "backtrace", "bytes", @@ -3167,7 +3731,17 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.55", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", ] [[package]] @@ -3180,6 +3754,18 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-stream" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", + "tokio-util", +] + [[package]] name = "tokio-tungstenite" version = "0.20.1" @@ -3248,6 +3834,28 @@ dependencies = [ "winnow", ] +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + [[package]] name = "tower-service" version = "0.3.2" @@ -3260,6 +3868,7 @@ version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -3273,7 +3882,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.55", ] [[package]] @@ -3320,7 +3929,7 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http", + "http 0.2.12", "httparse", "log", "rand", @@ -3376,9 +3985,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" dependencies = [ "tinyvec", ] @@ -3436,6 +4045,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "vec_map" version = "0.8.2" @@ -3484,9 +4099,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -3494,24 +4109,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.55", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.41" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877b9c3f61ceea0e56331985743b13f3d25c406a7098d45180fb5f09bc19ed97" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" dependencies = [ "cfg-if", "js-sys", @@ -3521,9 +4136,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3531,28 +4146,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.55", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "web-sys" -version = "0.3.68" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96565907687f7aceb35bc5fc03770a8a0471d82e479f25832f54a0e3f4b28446" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" dependencies = [ "js-sys", "wasm-bindgen", @@ -3610,7 +4225,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.4", ] [[package]] @@ -3630,17 +4245,17 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.4", + "windows_aarch64_msvc 0.52.4", + "windows_i686_gnu 0.52.4", + "windows_i686_msvc 0.52.4", + "windows_x86_64_gnu 0.52.4", + "windows_x86_64_gnullvm 0.52.4", + "windows_x86_64_msvc 0.52.4", ] [[package]] @@ -3651,9 +4266,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" [[package]] name = "windows_aarch64_msvc" @@ -3663,9 +4278,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" [[package]] name = "windows_i686_gnu" @@ -3675,9 +4290,9 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" [[package]] name = "windows_i686_msvc" @@ -3687,9 +4302,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" [[package]] name = "windows_x86_64_gnu" @@ -3699,9 +4314,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" [[package]] name = "windows_x86_64_gnullvm" @@ -3711,9 +4326,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" [[package]] name = "windows_x86_64_msvc" @@ -3723,15 +4338,15 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" [[package]] name = "winnow" -version = "0.5.39" +version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5389a154b01683d28c77f8f68f49dea75f0a4da32557a58f68ee51ebba472d29" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" dependencies = [ "memchr", ] @@ -3791,7 +4406,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.55", ] [[package]] @@ -3811,5 +4426,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.55", ] diff --git a/bins/revm-test/Cargo.toml b/bins/revm-test/Cargo.toml index 5f26dbf8a2..51e1888399 100644 --- a/bins/revm-test/Cargo.toml +++ b/bins/revm-test/Cargo.toml @@ -5,13 +5,13 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -bytes = "1.4" +bytes = "1.6" hex = "0.4" -revm = { path = "../../crates/revm", version = "7.2.0",default-features=false } +revm = { path = "../../crates/revm", version = "8.1.0",default-features=false } microbench = "0.5" -alloy-sol-macro = "0.6.4" -alloy-sol-types = "0.6.4" -regex = "1.10.3" +alloy-sol-macro = "0.7.0" +alloy-sol-types = "0.7.0" +regex = "1.10.4" eyre = "0.6.12" diff --git a/bins/revm-test/src/bin/analysis.rs b/bins/revm-test/src/bin/analysis.rs index 49fdbc57a7..b8557b6926 100644 --- a/bins/revm-test/src/bin/analysis.rs +++ b/bins/revm-test/src/bin/analysis.rs @@ -25,7 +25,7 @@ fn main() { .with_db(BenchmarkDB::new_bytecode(bytecode_raw)) .build(); - // just to spead up processor. + // Just to warm up the processor. for _ in 0..10000 { let _ = evm.transact().unwrap(); } diff --git a/bins/revme/CHANGELOG.md b/bins/revme/CHANGELOG.md index ea97533f20..069b030a3b 100644 --- a/bins/revme/CHANGELOG.md +++ b/bins/revme/CHANGELOG.md @@ -6,6 +6,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.4.1](https://github.com/receivingpotman/revm/compare/revme-v0.4.0...revme-v0.4.1) - 2024-04-07 + +### Other +- update Cargo.lock dependencies + +## [0.4.0](https://github.com/bluealloy/revm/compare/revme-v0.3.1...revme-v0.4.0) - 2024-04-02 + +### Added +- [**breaking**] TracerEip3155 optionally traces memory ([#1234](https://github.com/bluealloy/revm/pull/1234)) + +### Other +- use uint macro & fix various small things ([#1253](https://github.com/bluealloy/revm/pull/1253)) + ## [0.3.1](https://github.com/bluealloy/revm/compare/revme-v0.3.0...revme-v0.3.1) - 2024-03-19 ### Other diff --git a/bins/revme/Cargo.toml b/bins/revme/Cargo.toml index 7caead93b0..58d8cf00ff 100644 --- a/bins/revme/Cargo.toml +++ b/bins/revme/Cargo.toml @@ -6,7 +6,7 @@ keywords = ["ethereum", "evm"] license = "MIT" repository = "https://github.com/bluealloy/revm" description = "Rust Ethereum Virtual Machine Executable" -version = "0.3.1" +version = "0.4.1" [dependencies] hash-db = "0.15" @@ -15,7 +15,7 @@ hashbrown = "0.14" indicatif = "0.17" microbench = "0.5" plain_hasher = "0.2" -revm = { path = "../../crates/revm", version = "7.2.0", default-features = false, features = [ +revm = { path = "../../crates/revm", version = "8.1.0", default-features = false, features = [ "ethersdb", "std", "serde-json", diff --git a/bins/revme/src/cmd/statetest/runner.rs b/bins/revme/src/cmd/statetest/runner.rs index 3c75f38e04..b62e20c306 100644 --- a/bins/revme/src/cmd/statetest/runner.rs +++ b/bins/revme/src/cmd/statetest/runner.rs @@ -48,7 +48,7 @@ pub enum TestErrorKind { got_exception: Option, }, #[error("Unexpected output: {got_output:?} but test expects:{expected_output:?}")] - UnexpecteOutput { + UnexpectedOutput { expected_output: Option, got_output: Option, }, @@ -79,7 +79,7 @@ fn skip_test(path: &Path) -> bool { | "RevertPrecompiledTouch_storage.json" | "RevertPrecompiledTouch.json" - // txbyte is of type 02 and we dont parse tx bytes for this test to fail. + // txbyte is of type 02 and we don't parse tx bytes for this test to fail. | "typeTwoBerlin.json" // Need to handle Test errors @@ -139,7 +139,7 @@ fn check_evm_execution( } }; - // if we expect exception revm should return error from execution. + // If we expect exception revm should return error from execution. // So we do not check logs and state root. // // Note that some tests that have exception and run tests from before state clear @@ -155,7 +155,7 @@ fn check_evm_execution( // check output if let Some((expected_output, output)) = expected_output.zip(result.output()) { if expected_output != output { - let kind = TestErrorKind::UnexpecteOutput { + let kind = TestErrorKind::UnexpectedOutput { expected_output: Some(expected_output.clone()), got_output: result.output().cloned(), }; @@ -355,10 +355,7 @@ pub fn execute_test_suite( let (e, exec_result) = if trace { let mut evm = evm .modify() - .reset_handler_with_external_context(TracerEip3155::new( - Box::new(stderr()), - false, - )) + .reset_handler_with_external_context(TracerEip3155::new(Box::new(stderr()))) .append_handler_register(inspector_handle_register) .build(); @@ -421,7 +418,7 @@ pub fn execute_test_suite( let mut evm = Evm::builder() .with_spec_id(spec_id) .with_db(state) - .with_external_context(TracerEip3155::new(Box::new(stdout()), false)) + .with_external_context(TracerEip3155::new(Box::new(stdout()))) .append_handler_register(inspector_handle_register) .build(); let _ = evm.transact_commit(); diff --git a/crates/interpreter/CHANGELOG.md b/crates/interpreter/CHANGELOG.md index 8647c3585b..420eee0952 100644 --- a/crates/interpreter/CHANGELOG.md +++ b/crates/interpreter/CHANGELOG.md @@ -6,6 +6,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [5.0.0](https://github.com/receivingpotman/revm/compare/revm-interpreter-v4.0.0...revm-interpreter-v5.0.0) - 2024-04-07 + +### Added +- *(interpreter)* derive Eq for InterpreterAction ([#1262](https://github.com/receivingpotman/revm/pull/1262)) +- *(interpreter)* remove SPEC generic from gas calculation functions ([#1243](https://github.com/receivingpotman/revm/pull/1243)) +- *(interpreter)* test Host object-safety, allow `dyn Host` in instructions ([#1245](https://github.com/receivingpotman/revm/pull/1245)) + +## [4.0.0](https://github.com/bluealloy/revm/compare/revm-interpreter-v3.4.0...revm-interpreter-v4.0.0) - 2024-04-02 + +### Added +- add tests for shift instructions ([#1254](https://github.com/bluealloy/revm/pull/1254)) +- derive serde for OpCode, improve implementations ([#1215](https://github.com/bluealloy/revm/pull/1215)) +- *(interpreter)* expose mutable access methods on stack and memory ([#1219](https://github.com/bluealloy/revm/pull/1219)) + +### Other +- use uint macro & fix various small things ([#1253](https://github.com/bluealloy/revm/pull/1253)) +- move div by zero check from smod to i256_mod ([#1248](https://github.com/bluealloy/revm/pull/1248)) +- *(interpreter)* unbox contract field ([#1228](https://github.com/bluealloy/revm/pull/1228)) +- *(interpreter)* keep track of remaining gas rather than spent ([#1221](https://github.com/bluealloy/revm/pull/1221)) +- *(interpreter)* don't run signextend with 31 too ([#1222](https://github.com/bluealloy/revm/pull/1222)) + ## [3.4.0](https://github.com/bluealloy/revm/compare/revm-interpreter-v3.3.0...revm-interpreter-v3.4.0) - 2024-03-19 ### Added diff --git a/crates/interpreter/Cargo.toml b/crates/interpreter/Cargo.toml index 945314e874..79f601df48 100644 --- a/crates/interpreter/Cargo.toml +++ b/crates/interpreter/Cargo.toml @@ -6,7 +6,7 @@ keywords = ["no_std", "ethereum", "evm", "revm", "interpreter"] license = "MIT" name = "revm-interpreter" repository = "https://github.com/bluealloy/revm" -version = "3.4.0" +version = "5.0.0" readme = "../../README.md" [package.metadata.docs.rs] @@ -14,7 +14,7 @@ all-features = true rustdoc-args = ["--cfg", "docsrs"] [dependencies] -revm-primitives = { path = "../primitives", version = "3.1.0", default-features = false } +revm-primitives = { path = "../primitives", version = "3.2.0", default-features = false } # optional serde = { version = "1.0", default-features = false, features = [ diff --git a/crates/interpreter/src/gas.rs b/crates/interpreter/src/gas.rs index 9a37bf67ee..51739b1057 100644 --- a/crates/interpreter/src/gas.rs +++ b/crates/interpreter/src/gas.rs @@ -5,18 +5,17 @@ mod constants; pub use calc::*; pub use constants::*; -use revm_primitives::{Spec, SpecId::LONDON}; /// Represents the state of gas during execution. #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)] pub struct Gas { - /// The initial gas limit. + /// The initial gas limit. This is constant throughout execution. limit: u64, - /// The total used gas. - all_used_gas: u64, - /// Used gas without memory expansion. - used: u64, - /// Used gas for memory expansion. + /// The remaining gas. + remaining: u64, + /// The remaining gas, without memory expansion. + remaining_nomem: u64, + /// The **last** memory expansion cost. memory: u64, /// Refunded gas. This is used only at the end of execution. refunded: i64, @@ -28,10 +27,10 @@ impl Gas { pub const fn new(limit: u64) -> Self { Self { limit, - used: 0, + remaining: limit, + remaining_nomem: limit, memory: 0, refunded: 0, - all_used_gas: 0, } } @@ -41,35 +40,42 @@ impl Gas { self.limit } - /// Returns the amount of gas that was used. + /// Returns the **last** memory expansion cost. #[inline] pub const fn memory(&self) -> u64 { self.memory } - /// Returns the amount of gas that was refunded. + /// Returns the total amount of gas that was refunded. #[inline] pub const fn refunded(&self) -> i64 { self.refunded } - /// Returns all the gas used in the execution. + /// Returns the total amount of gas spent. #[inline] + pub const fn spent(&self) -> u64 { + self.limit - self.remaining + } + + #[doc(hidden)] + #[inline] + #[deprecated(note = "use `spent` instead")] pub const fn spend(&self) -> u64 { - self.all_used_gas + self.spent() } /// Returns the amount of gas remaining. #[inline] pub const fn remaining(&self) -> u64 { - self.limit - self.all_used_gas + self.remaining } /// Erases a gas cost from the totals. #[inline] pub fn erase_cost(&mut self, returned: u64) { - self.used -= returned; - self.all_used_gas -= returned; + self.remaining_nomem += returned; + self.remaining += returned; } /// Records a refund value. @@ -86,12 +92,14 @@ impl Gas { /// Max refund value is limited to Nth part (depending of fork) of gas spend. /// /// Related to EIP-3529: Reduction in refunds - pub fn set_final_refund(&mut self) { - let max_refund_quotient = if SPEC::enabled(LONDON) { 5 } else { 2 }; - self.refunded = (self.refunded() as u64).min(self.spend() / max_refund_quotient) as i64; + #[inline] + pub fn set_final_refund(&mut self, is_london: bool) { + let max_refund_quotient = if is_london { 5 } else { 2 }; + self.refunded = (self.refunded() as u64).min(self.spent() / max_refund_quotient) as i64; } - /// Set a refund value + /// Set a refund value. This overrides the current refund value. + #[inline] pub fn set_refund(&mut self, refund: i64) { self.refunded = refund; } @@ -101,13 +109,13 @@ impl Gas { /// Returns `false` if the gas limit is exceeded. #[inline(always)] pub fn record_cost(&mut self, cost: u64) -> bool { - let all_used_gas = self.all_used_gas.saturating_add(cost); - if self.limit < all_used_gas { + let (remaining, overflow) = self.remaining.overflowing_sub(cost); + if overflow { return false; } - self.used += cost; - self.all_used_gas = all_used_gas; + self.remaining_nomem -= cost; + self.remaining = remaining; true } @@ -117,20 +125,13 @@ impl Gas { #[inline] pub fn record_memory(&mut self, gas_memory: u64) -> bool { if gas_memory > self.memory { - let all_used_gas = self.used.saturating_add(gas_memory); - if self.limit < all_used_gas { + let (remaining, overflow) = self.remaining_nomem.overflowing_sub(gas_memory); + if overflow { return false; } self.memory = gas_memory; - self.all_used_gas = all_used_gas; + self.remaining = remaining; } true } - - #[doc(hidden)] - #[deprecated = "use `record_refund` instead"] - #[inline] - pub fn gas_refund(&mut self, refund: i64) { - self.record_refund(refund); - } } diff --git a/crates/interpreter/src/gas/calc.rs b/crates/interpreter/src/gas/calc.rs index 092fff7c85..dcc949c008 100644 --- a/crates/interpreter/src/gas/calc.rs +++ b/crates/interpreter/src/gas/calc.rs @@ -1,13 +1,34 @@ use super::constants::*; use crate::inner_models::SelfDestructResult; -use crate::primitives::{Address, Spec, SpecId::*, U256}; +use crate::primitives::{Address, SpecId, U256}; use std::vec::Vec; +/// `const` Option `?`. +macro_rules! tri { + ($e:expr) => { + match $e { + Some(v) => v, + None => return None, + } + }; +} + +/// `const` unwrap. +macro_rules! opt_unwrap { + ($e:expr) => { + match $e { + Some(v) => v, + None => panic!("unwrap failed"), + } + }; +} + +/// `SSTORE` opcode refund calculation. #[allow(clippy::collapsible_else_if)] -pub fn sstore_refund(original: U256, current: U256, new: U256) -> i64 { - if SPEC::enabled(ISTANBUL) { +pub fn sstore_refund(spec_id: SpecId, original: U256, current: U256, new: U256) -> i64 { + if spec_id.is_enabled_in(SpecId::ISTANBUL) { // EIP-3529: Reduction in refunds - let sstore_clears_schedule = if SPEC::enabled(LONDON) { + let sstore_clears_schedule = if spec_id.is_enabled_in(SpecId::LONDON) { (SSTORE_RESET - COLD_SLOAD_COST + ACCESS_LIST_STORAGE_KEY) as i64 } else { REFUND_SSTORE_CLEARS @@ -29,10 +50,10 @@ pub fn sstore_refund(original: U256, current: U256, new: U256) -> i6 } if original == new { - let (gas_sstore_reset, gas_sload) = if SPEC::enabled(BERLIN) { + let (gas_sstore_reset, gas_sload) = if spec_id.is_enabled_in(SpecId::BERLIN) { (SSTORE_RESET - COLD_SLOAD_COST, WARM_STORAGE_READ_COST) } else { - (SSTORE_RESET, sload_cost::(false)) + (SSTORE_RESET, sload_cost(spec_id, false)) }; if original == U256::ZERO { refund += (SSTORE_SET - gas_sload) as i64; @@ -53,16 +74,12 @@ pub fn sstore_refund(original: U256, current: U256, new: U256) -> i6 } } +/// `CREATE2` opcode cost calculation. #[inline] -pub fn create2_cost(len: usize) -> Option { - let base = CREATE; - // ceil(len / 32.0) - let len = len as u64; - let sha_addup_base = (len / 32) + u64::from((len % 32) != 0); - let sha_addup = KECCAK256WORD.checked_mul(sha_addup_base)?; - let gas = base.checked_add(sha_addup)?; - - Some(gas) +pub const fn create2_cost(len: u64) -> Option { + let sha_addup_base = len.div_ceil(32); + let sha_addup = tri!(KECCAK256WORD.checked_mul(sha_addup_base)); + CREATE.checked_add(sha_addup) } #[inline] @@ -85,14 +102,15 @@ fn log2floor(value: U256) -> u64 { l } +/// `EXP` opcode cost calculation. #[inline] -pub fn exp_cost(power: U256) -> Option { +pub fn exp_cost(spec_id: SpecId, 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) { - 50u64 + let gas_byte = U256::from(if spec_id.is_enabled_in(SpecId::SPURIOUS_DRAGON) { + 50 } else { 10 }); @@ -103,55 +121,61 @@ pub fn exp_cost(power: U256) -> Option { } } +/// `*COPY` opcodes cost calculation. #[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 })?) +pub const fn verylowcopy_cost(len: u64) -> Option { + VERYLOW.checked_add(tri!(cost_per_word(len, COPY))) } +/// `EXTCODECOPY` opcode cost calculation. #[inline] -pub fn extcodecopy_cost(len: u64, is_cold: bool) -> Option { - let wordd = len / 32; - let wordr = len % 32; - - let base_gas: u64 = if SPEC::enabled(BERLIN) { +pub const fn extcodecopy_cost(spec_id: SpecId, len: u64, is_cold: bool) -> Option { + let base_gas = if spec_id.is_enabled_in(SpecId::BERLIN) { if is_cold { COLD_ACCOUNT_ACCESS_COST } else { WARM_STORAGE_READ_COST } - } else if SPEC::enabled(TANGERINE) { + } else if spec_id.is_enabled_in(SpecId::TANGERINE) { 700 } else { 20 }; - base_gas.checked_add(COPY.checked_mul(if wordr == 0 { wordd } else { wordd + 1 })?) + base_gas.checked_add(tri!(cost_per_word(len, COPY))) } -pub fn account_access_gas(is_cold: bool) -> u64 { - if SPEC::enabled(BERLIN) { +/// `BALANCE` opcode cost calculation. +#[inline] +pub const fn account_access_gas(spec_id: SpecId, is_cold: bool) -> u64 { + if spec_id.is_enabled_in(SpecId::BERLIN) { if is_cold { COLD_ACCOUNT_ACCESS_COST } else { WARM_STORAGE_READ_COST } - } else if SPEC::enabled(ISTANBUL) { + } else if spec_id.is_enabled_in(SpecId::ISTANBUL) { 700 } else { 20 } } -pub fn log_cost(n: u8, len: u64) -> Option { - LOG.checked_add(LOGDATA.checked_mul(len)?)? - .checked_add(LOGTOPIC * n as u64) +/// `LOG` opcode cost calculation. +#[inline] +pub const fn log_cost(n: u8, len: u64) -> Option { + tri!(LOG.checked_add(tri!(LOGDATA.checked_mul(len)))).checked_add(LOGTOPIC * n as u64) } -pub fn keccak256_cost(len: u64) -> Option { - let wordd = len / 32; - let wordr = len % 32; - KECCAK256.checked_add(KECCAK256WORD.checked_mul(if wordr == 0 { wordd } else { wordd + 1 })?) +/// `KECCAK256` opcode cost calculation. +#[inline] +pub const fn keccak256_cost(len: u64) -> Option { + KECCAK256.checked_add(tri!(cost_per_word(len, KECCAK256WORD))) +} + +/// Cost for memory length. `ceil(len / 32) * multiple`. +#[inline] +pub const fn cost_per_word(len: u64, multiple: u64) -> Option { + len.div_ceil(32).checked_mul(multiple) } /// EIP-3860: Limit and meter initcode @@ -160,24 +184,23 @@ pub fn keccak256_cost(len: u64) -> Option { /// /// 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 } +pub const fn initcode_cost(len: u64) -> u64 { + opt_unwrap!(cost_per_word(len, INITCODE_WORD_COST)) } +/// `SLOAD` opcode cost calculation. #[inline] -pub fn sload_cost(is_cold: bool) -> u64 { - if SPEC::enabled(BERLIN) { +pub const fn sload_cost(spec_id: SpecId, is_cold: bool) -> u64 { + if spec_id.is_enabled_in(SpecId::BERLIN) { if is_cold { COLD_SLOAD_COST } else { WARM_STORAGE_READ_COST } - } else if SPEC::enabled(ISTANBUL) { + } else if spec_id.is_enabled_in(SpecId::ISTANBUL) { // EIP-1884: Repricing for trie-size-dependent opcodes INSTANBUL_SLOAD_GAS - } else if SPEC::enabled(TANGERINE) { + } else if spec_id.is_enabled_in(SpecId::TANGERINE) { // EIP-150: Gas cost changes for IO-heavy operations 200 } else { @@ -185,8 +208,10 @@ pub fn sload_cost(is_cold: bool) -> u64 { } } -#[allow(clippy::collapsible_else_if)] -pub fn sstore_cost( +/// `SSTORE` opcode cost calculation. +#[inline] +pub fn sstore_cost( + spec_id: SpecId, original: U256, current: U256, new: U256, @@ -194,11 +219,11 @@ pub fn sstore_cost( is_cold: bool, ) -> Option { // EIP-1706 Disable SSTORE with gasleft lower than call stipend - if SPEC::enabled(ISTANBUL) && gas <= CALL_STIPEND { + if spec_id.is_enabled_in(SpecId::ISTANBUL) && gas <= CALL_STIPEND { return None; } - if SPEC::enabled(BERLIN) { + if spec_id.is_enabled_in(SpecId::BERLIN) { // Berlin specification logic let mut gas_cost = istanbul_sstore_cost::( original, current, new, @@ -208,7 +233,7 @@ pub fn sstore_cost( gas_cost += COLD_SLOAD_COST; } Some(gas_cost) - } else if SPEC::enabled(ISTANBUL) { + } else if spec_id.is_enabled_in(SpecId::ISTANBUL) { // Istanbul logic Some(istanbul_sstore_cost::( original, current, new, @@ -220,7 +245,7 @@ pub fn sstore_cost( } /// EIP-2200: Structured Definitions for Net Gas Metering -#[inline(always)] +#[inline] fn istanbul_sstore_cost( original: U256, current: U256, @@ -237,7 +262,8 @@ fn istanbul_sstore_cost( } } -/// Frontier sstore cost just had two cases set and reset values +/// Frontier sstore cost just had two cases set and reset values. +#[inline] fn frontier_sstore_cost(current: U256, new: U256) -> u64 { if current == U256::ZERO && new != U256::ZERO { SSTORE_SET @@ -246,39 +272,48 @@ fn frontier_sstore_cost(current: U256, new: U256) -> u64 { } } -pub fn selfdestruct_cost(res: SelfDestructResult) -> u64 { +/// `SELFDESTRUCT` opcode cost calculation. +#[inline] +pub const fn selfdestruct_cost(spec_id: SpecId, res: SelfDestructResult) -> u64 { // EIP-161: State trie clearing (invariant-preserving alternative) - let should_charge_topup = if SPEC::enabled(SPURIOUS_DRAGON) { + let should_charge_topup = if spec_id.is_enabled_in(SpecId::SPURIOUS_DRAGON) { res.had_value && !res.target_exists } else { !res.target_exists }; // EIP-150: Gas cost changes for IO-heavy operations - let selfdestruct_gas_topup = if SPEC::enabled(TANGERINE) && should_charge_topup { + let selfdestruct_gas_topup = if spec_id.is_enabled_in(SpecId::TANGERINE) && should_charge_topup + { 25000 } else { 0 }; // EIP-150: Gas cost changes for IO-heavy operations - let selfdestruct_gas = if SPEC::enabled(TANGERINE) { 5000 } else { 0 }; + let selfdestruct_gas = if spec_id.is_enabled_in(SpecId::TANGERINE) { + 5000 + } else { + 0 + }; let mut gas = selfdestruct_gas + selfdestruct_gas_topup; - if SPEC::enabled(BERLIN) && res.is_cold { + if spec_id.is_enabled_in(SpecId::BERLIN) && res.is_cold { gas += COLD_ACCOUNT_ACCESS_COST } gas } -pub fn call_gas(is_cold: bool) -> u64 { - if SPEC::enabled(BERLIN) { +/// Basic `CALL` opcode cost calculation, see [`call_cost`]. +#[inline] +pub const fn call_gas(spec_id: SpecId, is_cold: bool) -> u64 { + if spec_id.is_enabled_in(SpecId::BERLIN) { if is_cold { COLD_ACCOUNT_ACCESS_COST } else { WARM_STORAGE_READ_COST } - } else if SPEC::enabled(TANGERINE) { + } else if spec_id.is_enabled_in(SpecId::TANGERINE) { // EIP-150: Gas cost changes for IO-heavy operations 700 } else { @@ -286,33 +321,23 @@ pub fn call_gas(is_cold: bool) -> u64 { } } -pub fn call_cost( +/// `CALL` opcode cost calculation. +#[inline] +pub const fn call_cost( + spec_id: SpecId, transfers_value: bool, is_new: bool, is_cold: bool, is_call_or_callcode: bool, is_call_or_staticcall: bool, ) -> u64 { - call_gas::(is_cold) + call_gas(spec_id, is_cold) + xfer_cost(is_call_or_callcode, transfers_value) - + new_cost::(is_call_or_staticcall, is_new, transfers_value) -} - -#[inline] -pub fn warm_cold_cost(is_cold: bool, regular_value: u64) -> u64 { - if SPEC::enabled(BERLIN) { - if is_cold { - COLD_ACCOUNT_ACCESS_COST - } else { - WARM_STORAGE_READ_COST - } - } else { - regular_value - } + + new_cost(spec_id, is_call_or_staticcall, is_new, transfers_value) } #[inline] -fn xfer_cost(is_call_or_callcode: bool, transfers_value: bool) -> u64 { +const fn xfer_cost(is_call_or_callcode: bool, transfers_value: bool) -> u64 { if is_call_or_callcode && transfers_value { CALLVALUE } else { @@ -321,21 +346,27 @@ 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 { +const fn new_cost( + spec_id: SpecId, + is_call_or_staticcall: bool, + is_new: bool, + transfers_value: bool, +) -> u64 { if !is_call_or_staticcall || !is_new { return 0; } // EIP-161: State trie clearing (invariant-preserving alternative) - if SPEC::enabled(SPURIOUS_DRAGON) && !transfers_value { + if spec_id.is_enabled_in(SpecId::SPURIOUS_DRAGON) && !transfers_value { return 0; } NEWACCOUNT } +/// Memory expansion cost calculation. #[inline] -pub fn memory_gas(a: usize) -> u64 { +pub const fn memory_gas(a: usize) -> u64 { let a = a as u64; MEMORY .saturating_mul(a) @@ -344,7 +375,8 @@ pub fn memory_gas(a: usize) -> u64 { /// Initial gas that is deducted for transaction to be included. /// Initial gas contains initial stipend gas, gas for access list and input data. -pub fn validate_initial_tx_gas( +pub fn validate_initial_tx_gas( + spec_id: SpecId, input: &[u8], is_create: bool, access_list: &[(Address, Vec)], @@ -356,10 +388,15 @@ pub fn validate_initial_tx_gas( // initdate stipend initial_gas += zero_data_len * TRANSACTION_ZERO_DATA; // EIP-2028: Transaction data gas cost reduction - initial_gas += non_zero_data_len * if SPEC::enabled(ISTANBUL) { 16 } else { 68 }; + initial_gas += non_zero_data_len + * if spec_id.is_enabled_in(SpecId::ISTANBUL) { + 16 + } else { + 68 + }; // get number of access list account and storages. - if SPEC::enabled(BERLIN) { + if spec_id.is_enabled_in(SpecId::BERLIN) { let accessed_slots = access_list .iter() .fold(0, |slot_count, (_, slots)| slot_count + slots.len() as u64); @@ -369,7 +406,7 @@ pub fn validate_initial_tx_gas( // base stipend initial_gas += if is_create { - if SPEC::enabled(HOMESTEAD) { + if spec_id.is_enabled_in(SpecId::HOMESTEAD) { // EIP-2: Homestead Hard-fork Changes 53000 } else { @@ -381,7 +418,7 @@ pub fn validate_initial_tx_gas( // EIP-3860: Limit and meter initcode // Initcode stipend for bytecode analysis - if SPEC::enabled(SHANGHAI) && is_create { + if spec_id.is_enabled_in(SpecId::SHANGHAI) && is_create { initial_gas += initcode_cost(input.len() as u64) } diff --git a/crates/interpreter/src/host.rs b/crates/interpreter/src/host.rs index fff18bb848..6caecee479 100644 --- a/crates/interpreter/src/host.rs +++ b/crates/interpreter/src/host.rs @@ -65,3 +65,16 @@ pub struct SStoreResult { /// Is storage slot loaded from database pub is_cold: bool, } + +#[cfg(test)] +mod tests { + use super::*; + + fn assert_host() {} + + #[test] + fn object_safety() { + assert_host::(); + assert_host::(); + } +} diff --git a/crates/interpreter/src/instructions/arithmetic.rs b/crates/interpreter/src/instructions/arithmetic.rs index 209baae55c..8d1e512773 100644 --- a/crates/interpreter/src/instructions/arithmetic.rs +++ b/crates/interpreter/src/instructions/arithmetic.rs @@ -5,25 +5,25 @@ use crate::{ Host, Interpreter, }; -pub fn wrapping_add(interpreter: &mut Interpreter, _host: &mut H) { +pub fn wrapping_add(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); *op2 = op1.wrapping_add(*op2); } -pub fn wrapping_mul(interpreter: &mut Interpreter, _host: &mut H) { +pub fn wrapping_mul(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::LOW); pop_top!(interpreter, op1, op2); *op2 = op1.wrapping_mul(*op2); } -pub fn wrapping_sub(interpreter: &mut Interpreter, _host: &mut H) { +pub fn wrapping_sub(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); *op2 = op1.wrapping_sub(*op2); } -pub fn div(interpreter: &mut Interpreter, _host: &mut H) { +pub fn div(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::LOW); pop_top!(interpreter, op1, op2); if *op2 != U256::ZERO { @@ -31,13 +31,13 @@ pub fn div(interpreter: &mut Interpreter, _host: &mut H) { } } -pub fn sdiv(interpreter: &mut Interpreter, _host: &mut H) { +pub fn sdiv(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::LOW); pop_top!(interpreter, op1, op2); *op2 = i256_div(op1, *op2); } -pub fn rem(interpreter: &mut Interpreter, _host: &mut H) { +pub fn rem(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::LOW); pop_top!(interpreter, op1, op2); if *op2 != U256::ZERO { @@ -45,29 +45,27 @@ pub fn rem(interpreter: &mut Interpreter, _host: &mut H) { } } -pub fn smod(interpreter: &mut Interpreter, _host: &mut H) { +pub fn smod(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::LOW); pop_top!(interpreter, op1, op2); - if *op2 != U256::ZERO { - *op2 = i256_mod(op1, *op2) - } + *op2 = i256_mod(op1, *op2) } -pub fn addmod(interpreter: &mut Interpreter, _host: &mut H) { +pub fn addmod(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::MID); pop_top!(interpreter, op1, op2, op3); *op3 = op1.add_mod(op2, *op3) } -pub fn mulmod(interpreter: &mut Interpreter, _host: &mut H) { +pub fn mulmod(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::MID); pop_top!(interpreter, op1, op2, op3); *op3 = op1.mul_mod(op2, *op3) } -pub fn exp(interpreter: &mut Interpreter, _host: &mut H) { +pub fn exp(interpreter: &mut Interpreter, _host: &mut H) { pop_top!(interpreter, op1, op2); - gas_or_fail!(interpreter, gas::exp_cost::(*op2)); + gas_or_fail!(interpreter, gas::exp_cost(SPEC::SPEC_ID, *op2)); *op2 = op1.pow(*op2); } @@ -86,14 +84,15 @@ pub fn exp(interpreter: &mut Interpreter, _host: &mut H) { /// `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 H) { +pub fn signextend(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::LOW); - pop_top!(interpreter, op1, op2); - if op1 < U256::from(32) { - // `low_u32` works since op1 < 32 - let bit_index = (8 * op1.as_limbs()[0] + 7) as usize; - let bit = op2.bit(bit_index); + pop_top!(interpreter, ext, x); + // For 31 we also don't need to do anything. + if ext < U256::from(31) { + let ext = ext.as_limbs()[0]; + let bit_index = (8 * ext + 7) as usize; + let bit = x.bit(bit_index); let mask = (U256::from(1) << bit_index) - U256::from(1); - *op2 = if bit { *op2 | !mask } else { *op2 & mask }; + *x = if bit { *x | !mask } else { *x & mask }; } } diff --git a/crates/interpreter/src/instructions/bitwise.rs b/crates/interpreter/src/instructions/bitwise.rs index 3f49dc57eb..586af76ce3 100644 --- a/crates/interpreter/src/instructions/bitwise.rs +++ b/crates/interpreter/src/instructions/bitwise.rs @@ -5,68 +5,69 @@ use crate::{ Host, Interpreter, }; use core::cmp::Ordering; +use revm_primitives::uint; -pub fn lt(interpreter: &mut Interpreter, _host: &mut H) { +pub fn lt(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); *op2 = U256::from(op1 < *op2); } -pub fn gt(interpreter: &mut Interpreter, _host: &mut H) { +pub fn gt(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); *op2 = U256::from(op1 > *op2); } -pub fn slt(interpreter: &mut Interpreter, _host: &mut H) { +pub fn slt(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); *op2 = U256::from(i256_cmp(&op1, op2) == Ordering::Less); } -pub fn sgt(interpreter: &mut Interpreter, _host: &mut H) { +pub fn sgt(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); *op2 = U256::from(i256_cmp(&op1, op2) == Ordering::Greater); } -pub fn eq(interpreter: &mut Interpreter, _host: &mut H) { +pub fn eq(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); *op2 = U256::from(op1 == *op2); } -pub fn iszero(interpreter: &mut Interpreter, _host: &mut H) { +pub fn iszero(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1); *op1 = U256::from(*op1 == U256::ZERO); } -pub fn bitand(interpreter: &mut Interpreter, _host: &mut H) { +pub fn bitand(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); *op2 = op1 & *op2; } -pub fn bitor(interpreter: &mut Interpreter, _host: &mut H) { +pub fn bitor(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); *op2 = op1 | *op2; } -pub fn bitxor(interpreter: &mut Interpreter, _host: &mut H) { +pub fn bitxor(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); *op2 = op1 ^ *op2; } -pub fn not(interpreter: &mut Interpreter, _host: &mut H) { +pub fn not(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1); *op1 = !*op1; } -pub fn byte(interpreter: &mut Interpreter, _host: &mut H) { +pub fn byte(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); @@ -80,7 +81,7 @@ pub fn byte(interpreter: &mut Interpreter, _host: &mut H) { } /// EIP-145: Bitwise shifting instructions in EVM -pub fn shl(interpreter: &mut Interpreter, _host: &mut H) { +pub fn shl(interpreter: &mut Interpreter, _host: &mut H) { check!(interpreter, CONSTANTINOPLE); gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); @@ -88,7 +89,7 @@ pub fn shl(interpreter: &mut Interpreter, _host: &mut H) { } /// EIP-145: Bitwise shifting instructions in EVM -pub fn shr(interpreter: &mut Interpreter, _host: &mut H) { +pub fn shr(interpreter: &mut Interpreter, _host: &mut H) { check!(interpreter, CONSTANTINOPLE); gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); @@ -96,14 +97,18 @@ pub fn shr(interpreter: &mut Interpreter, _host: &mut H) { } /// EIP-145: Bitwise shifting instructions in EVM -pub fn sar(interpreter: &mut Interpreter, _host: &mut H) { +pub fn sar(interpreter: &mut Interpreter, _host: &mut H) { check!(interpreter, CONSTANTINOPLE); gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); let value_sign = i256_sign_compl(op2); - *op2 = if value_sign == Sign::Zero || op1 >= U256::from(256) { + // If the shift count is 255+, we can short-circuit. This is because shifting by 255 bits is the + // maximum shift that still leaves 1 bit in the original 256-bit number. Shifting by 256 bits or + // more would mean that no original bits remain. The result depends on what the highest bit of + // the value is. + *op2 = if value_sign == Sign::Zero || op1 >= U256::from(255) { match value_sign { // value is 0 or >=1, pushing 0 Sign::Plus | Sign::Zero => U256::ZERO, @@ -111,7 +116,8 @@ pub fn sar(interpreter: &mut Interpreter, _host: &mut H) { Sign::Minus => U256::MAX, } } else { - const ONE: U256 = U256::from_limbs([1, 0, 0, 0]); + const ONE: U256 = uint!(1_U256); + // SAFETY: shift count is checked above; it's less than 255. let shift = usize::try_from(op1).unwrap(); match value_sign { Sign::Plus | Sign::Zero => op2.wrapping_shr(shift), @@ -119,3 +125,278 @@ pub fn sar(interpreter: &mut Interpreter, _host: &mut H) { } }; } + +#[cfg(test)] +mod tests { + use crate::instructions::bitwise::{sar, shl, shr}; + use crate::{Contract, DummyHost, Interpreter}; + use revm_primitives::{uint, Env, LatestSpec, U256}; + + #[test] + fn test_shift_left() { + let mut host = DummyHost::new(Env::default()); + let mut interpreter = Interpreter::new(Contract::default(), u64::MAX, false); + + struct TestCase { + value: U256, + shift: U256, + expected: U256, + } + + uint! { + let test_cases = [ + TestCase { + value: 0x0000000000000000000000000000000000000000000000000000000000000001_U256, + shift: 0x00_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000001_U256, + }, + TestCase { + value: 0x0000000000000000000000000000000000000000000000000000000000000001_U256, + shift: 0x01_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000002_U256, + }, + TestCase { + value: 0x0000000000000000000000000000000000000000000000000000000000000001_U256, + shift: 0xff_U256, + expected: 0x8000000000000000000000000000000000000000000000000000000000000000_U256, + }, + TestCase { + value: 0x0000000000000000000000000000000000000000000000000000000000000001_U256, + shift: 0x0100_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256, + }, + TestCase { + value: 0x0000000000000000000000000000000000000000000000000000000000000001_U256, + shift: 0x0101_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256, + }, + TestCase { + value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + shift: 0x00_U256, + expected: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + }, + TestCase { + value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + shift: 0x01_U256, + expected: 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe_U256, + }, + TestCase { + value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + shift: 0xff_U256, + expected: 0x8000000000000000000000000000000000000000000000000000000000000000_U256, + }, + TestCase { + value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + shift: 0x0100_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256, + }, + TestCase { + value: 0x0000000000000000000000000000000000000000000000000000000000000000_U256, + shift: 0x01_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256, + }, + TestCase { + value: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + shift: 0x01_U256, + expected: 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe_U256, + }, + ]; + } + + for test in test_cases { + host.clear(); + push!(interpreter, test.value); + push!(interpreter, test.shift); + shl::(&mut interpreter, &mut host); + pop!(interpreter, res); + assert_eq!(res, test.expected); + } + } + + #[test] + fn test_logical_shift_right() { + let mut host = DummyHost::new(Env::default()); + let mut interpreter = Interpreter::new(Contract::default(), u64::MAX, false); + + struct TestCase { + value: U256, + shift: U256, + expected: U256, + } + + uint! { + let test_cases = [ + TestCase { + value: 0x0000000000000000000000000000000000000000000000000000000000000001_U256, + shift: 0x00_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000001_U256, + }, + TestCase { + value: 0x0000000000000000000000000000000000000000000000000000000000000001_U256, + shift: 0x01_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256, + }, + TestCase { + value: 0x8000000000000000000000000000000000000000000000000000000000000000_U256, + shift: 0x01_U256, + expected: 0x4000000000000000000000000000000000000000000000000000000000000000_U256, + }, + TestCase { + value: 0x8000000000000000000000000000000000000000000000000000000000000000_U256, + shift: 0xff_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000001_U256, + }, + TestCase { + value: 0x8000000000000000000000000000000000000000000000000000000000000000_U256, + shift: 0x0100_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256, + }, + TestCase { + value: 0x8000000000000000000000000000000000000000000000000000000000000000_U256, + shift: 0x0101_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256, + }, + TestCase { + value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + shift: 0x00_U256, + expected: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + }, + TestCase { + value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + shift: 0x01_U256, + expected: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + }, + TestCase { + value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + shift: 0xff_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000001_U256, + }, + TestCase { + value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + shift: 0x0100_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256, + }, + TestCase { + value: 0x0000000000000000000000000000000000000000000000000000000000000000_U256, + shift: 0x01_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256, + }, + ]; + } + + for test in test_cases { + host.clear(); + push!(interpreter, test.value); + push!(interpreter, test.shift); + shr::(&mut interpreter, &mut host); + pop!(interpreter, res); + assert_eq!(res, test.expected); + } + } + + #[test] + fn test_arithmetic_shift_right() { + let mut host = DummyHost::new(Env::default()); + let mut interpreter = Interpreter::new(Contract::default(), u64::MAX, false); + + struct TestCase { + value: U256, + shift: U256, + expected: U256, + } + + uint! { + let test_cases = [ + TestCase { + value: 0x0000000000000000000000000000000000000000000000000000000000000001_U256, + shift: 0x00_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000001_U256, + }, + TestCase { + value: 0x0000000000000000000000000000000000000000000000000000000000000001_U256, + shift: 0x01_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256, + }, + TestCase { + value: 0x8000000000000000000000000000000000000000000000000000000000000000_U256, + shift: 0x01_U256, + expected: 0xc000000000000000000000000000000000000000000000000000000000000000_U256, + }, + TestCase { + value: 0x8000000000000000000000000000000000000000000000000000000000000000_U256, + shift: 0xff_U256, + expected: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + }, + TestCase { + value: 0x8000000000000000000000000000000000000000000000000000000000000000_U256, + shift: 0x0100_U256, + expected: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + }, + TestCase { + value: 0x8000000000000000000000000000000000000000000000000000000000000000_U256, + shift: 0x0101_U256, + expected: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + }, + TestCase { + value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + shift: 0x00_U256, + expected: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + }, + TestCase { + value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + shift: 0x01_U256, + expected: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + }, + TestCase { + value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + shift: 0xff_U256, + expected: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + }, + TestCase { + value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + shift: 0x0100_U256, + expected: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + }, + TestCase { + value: 0x0000000000000000000000000000000000000000000000000000000000000000_U256, + shift: 0x01_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256, + }, + TestCase { + value: 0x4000000000000000000000000000000000000000000000000000000000000000_U256, + shift: 0xfe_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000001_U256, + }, + TestCase { + value: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + shift: 0xf8_U256, + expected: 0x000000000000000000000000000000000000000000000000000000000000007f_U256, + }, + TestCase { + value: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + shift: 0xfe_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000001_U256, + }, + TestCase { + value: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + shift: 0xff_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256, + }, + TestCase { + value: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + shift: 0x0100_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256, + }, + ]; + } + + for test in test_cases { + host.clear(); + push!(interpreter, test.value); + push!(interpreter, test.shift); + sar::(&mut interpreter, &mut host); + pop!(interpreter, res); + assert_eq!(res, test.expected); + } + } +} diff --git a/crates/interpreter/src/instructions/control.rs b/crates/interpreter/src/instructions/control.rs index 61a132e940..26333b77a7 100644 --- a/crates/interpreter/src/instructions/control.rs +++ b/crates/interpreter/src/instructions/control.rs @@ -4,13 +4,13 @@ use crate::{ Host, InstructionResult, Interpreter, InterpreterResult, }; -pub fn jump(interpreter: &mut Interpreter, _host: &mut H) { +pub fn jump(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::MID); pop!(interpreter, dest); jump_inner(interpreter, dest); } -pub fn jumpi(interpreter: &mut Interpreter, _host: &mut H) { +pub fn jumpi(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::HIGH); pop!(interpreter, dest, value); if value != U256::ZERO { @@ -29,11 +29,11 @@ fn jump_inner(interpreter: &mut Interpreter, dest: U256) { interpreter.instruction_pointer = unsafe { interpreter.contract.bytecode.as_ptr().add(dest) }; } -pub fn jumpdest(interpreter: &mut Interpreter, _host: &mut H) { +pub fn jumpdest(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::JUMPDEST); } -pub fn pc(interpreter: &mut Interpreter, _host: &mut H) { +pub fn pc(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::BASE); // - 1 because we have already advanced the instruction pointer in `Interpreter::step` push!(interpreter, U256::from(interpreter.program_counter() - 1)); @@ -63,27 +63,27 @@ fn return_inner(interpreter: &mut Interpreter, instruction_result: InstructionRe }; } -pub fn ret(interpreter: &mut Interpreter, _host: &mut H) { +pub fn ret(interpreter: &mut Interpreter, _host: &mut H) { return_inner(interpreter, InstructionResult::Return); } /// EIP-140: REVERT instruction -pub fn revert(interpreter: &mut Interpreter, _host: &mut H) { +pub fn revert(interpreter: &mut Interpreter, _host: &mut H) { check!(interpreter, BYZANTIUM); return_inner(interpreter, InstructionResult::Revert); } /// Stop opcode. This opcode halts the execution. -pub fn stop(interpreter: &mut Interpreter, _host: &mut H) { +pub fn stop(interpreter: &mut Interpreter, _host: &mut H) { interpreter.instruction_result = InstructionResult::Stop; } /// Invalid opcode. This opcode halts the execution. -pub fn invalid(interpreter: &mut Interpreter, _host: &mut H) { +pub fn invalid(interpreter: &mut Interpreter, _host: &mut H) { interpreter.instruction_result = InstructionResult::InvalidFEOpcode; } /// Unknown opcode. This opcode halts the execution. -pub fn unknown(interpreter: &mut Interpreter, _host: &mut H) { +pub fn unknown(interpreter: &mut Interpreter, _host: &mut H) { interpreter.instruction_result = InstructionResult::OpcodeNotFound; } diff --git a/crates/interpreter/src/instructions/host.rs b/crates/interpreter/src/instructions/host.rs index 7357adf4f3..cd5d735ef7 100644 --- a/crates/interpreter/src/instructions/host.rs +++ b/crates/interpreter/src/instructions/host.rs @@ -13,7 +13,7 @@ use core::cmp::min; use revm_primitives::BLOCK_HASH_HISTORY; use std::{boxed::Box, vec::Vec}; -pub fn balance(interpreter: &mut Interpreter, host: &mut H) { +pub fn balance(interpreter: &mut Interpreter, host: &mut H) { pop_address!(interpreter, address); let Some((balance, is_cold)) = host.balance(address) else { interpreter.instruction_result = InstructionResult::FatalExternalError; @@ -23,7 +23,7 @@ pub fn balance(interpreter: &mut Interpreter, host: &mut H) interpreter, if SPEC::enabled(ISTANBUL) { // EIP-1884: Repricing for trie-size-dependent opcodes - gas::account_access_gas::(is_cold) + gas::account_access_gas(SPEC::SPEC_ID, is_cold) } else if SPEC::enabled(TANGERINE) { 400 } else { @@ -34,7 +34,7 @@ pub fn balance(interpreter: &mut Interpreter, host: &mut H) } /// EIP-1884: Repricing for trie-size-dependent opcodes -pub fn selfbalance(interpreter: &mut Interpreter, host: &mut H) { +pub fn selfbalance(interpreter: &mut Interpreter, host: &mut H) { check!(interpreter, ISTANBUL); gas!(interpreter, gas::LOW); let Some((balance, _)) = host.balance(interpreter.contract.address) else { @@ -44,7 +44,7 @@ pub fn selfbalance(interpreter: &mut Interpreter, host: &mu push!(interpreter, balance); } -pub fn extcodesize(interpreter: &mut Interpreter, host: &mut H) { +pub fn extcodesize(interpreter: &mut Interpreter, host: &mut H) { pop_address!(interpreter, address); let Some((code, is_cold)) = host.code(address) else { interpreter.instruction_result = InstructionResult::FatalExternalError; @@ -69,7 +69,7 @@ pub fn extcodesize(interpreter: &mut Interpreter, host: &mu } /// EIP-1052: EXTCODEHASH opcode -pub fn extcodehash(interpreter: &mut Interpreter, host: &mut H) { +pub fn extcodehash(interpreter: &mut Interpreter, host: &mut H) { check!(interpreter, CONSTANTINOPLE); pop_address!(interpreter, address); let Some((code_hash, is_cold)) = host.code_hash(address) else { @@ -93,7 +93,7 @@ pub fn extcodehash(interpreter: &mut Interpreter, host: &mu push_b256!(interpreter, code_hash); } -pub fn extcodecopy(interpreter: &mut Interpreter, host: &mut H) { +pub fn extcodecopy(interpreter: &mut Interpreter, host: &mut H) { pop_address!(interpreter, address); pop!(interpreter, memory_offset, code_offset, len_u256); @@ -105,7 +105,7 @@ pub fn extcodecopy(interpreter: &mut Interpreter, host: &mu let len = as_usize_or_fail!(interpreter, len_u256); gas_or_fail!( interpreter, - gas::extcodecopy_cost::(len as u64, is_cold) + gas::extcodecopy_cost(SPEC::SPEC_ID, len as u64, is_cold) ); if len == 0 { return; @@ -120,7 +120,7 @@ pub fn extcodecopy(interpreter: &mut Interpreter, host: &mu .set_data(memory_offset, code_offset, len, code.bytes()); } -pub fn blockhash(interpreter: &mut Interpreter, host: &mut H) { +pub fn blockhash(interpreter: &mut Interpreter, host: &mut H) { gas!(interpreter, gas::BLOCKHASH); pop_top!(interpreter, number); @@ -139,18 +139,18 @@ pub fn blockhash(interpreter: &mut Interpreter, host: &mut H) { *number = U256::ZERO; } -pub fn sload(interpreter: &mut Interpreter, host: &mut H) { +pub fn sload(interpreter: &mut Interpreter, host: &mut H) { pop!(interpreter, index); let Some((value, is_cold)) = host.sload(interpreter.contract.address, index) else { interpreter.instruction_result = InstructionResult::FatalExternalError; return; }; - gas!(interpreter, gas::sload_cost::(is_cold)); + gas!(interpreter, gas::sload_cost(SPEC::SPEC_ID, is_cold)); push!(interpreter, value); } -pub fn sstore(interpreter: &mut Interpreter, host: &mut H) { +pub fn sstore(interpreter: &mut Interpreter, host: &mut H) { check_staticcall!(interpreter); pop!(interpreter, index, value); @@ -166,14 +166,17 @@ pub fn sstore(interpreter: &mut Interpreter, host: &mut H) }; gas_or_fail!(interpreter, { let remaining_gas = interpreter.gas.remaining(); - gas::sstore_cost::(original, old, new, remaining_gas, is_cold) + gas::sstore_cost(SPEC::SPEC_ID, original, old, new, remaining_gas, is_cold) }); - refund!(interpreter, gas::sstore_refund::(original, old, new)); + refund!( + interpreter, + gas::sstore_refund(SPEC::SPEC_ID, original, old, new) + ); } /// EIP-1153: Transient storage opcodes /// Store value to transient storage -pub fn tstore(interpreter: &mut Interpreter, host: &mut H) { +pub fn tstore(interpreter: &mut Interpreter, host: &mut H) { check!(interpreter, CANCUN); check_staticcall!(interpreter); gas!(interpreter, gas::WARM_STORAGE_READ_COST); @@ -185,7 +188,7 @@ pub fn tstore(interpreter: &mut Interpreter, host: &mut H) /// EIP-1153: Transient storage opcodes /// Load value from transient storage -pub fn tload(interpreter: &mut Interpreter, host: &mut H) { +pub fn tload(interpreter: &mut Interpreter, host: &mut H) { check!(interpreter, CANCUN); gas!(interpreter, gas::WARM_STORAGE_READ_COST); @@ -194,7 +197,7 @@ pub fn tload(interpreter: &mut Interpreter, host: &mut H) { *index = host.tload(interpreter.contract.address, *index); } -pub fn log(interpreter: &mut Interpreter, host: &mut H) { +pub fn log(interpreter: &mut Interpreter, host: &mut H) { check_staticcall!(interpreter); pop!(interpreter, offset, len); @@ -227,7 +230,7 @@ pub fn log(interpreter: &mut Interpreter, host: &mut H) host.log(log); } -pub fn selfdestruct(interpreter: &mut Interpreter, host: &mut H) { +pub fn selfdestruct(interpreter: &mut Interpreter, host: &mut H) { check_staticcall!(interpreter); pop_address!(interpreter, target); @@ -240,12 +243,12 @@ pub fn selfdestruct(interpreter: &mut Interpreter, host: &m if !SPEC::enabled(LONDON) && !res.previously_destroyed { refund!(interpreter, gas::SELFDESTRUCT) } - gas!(interpreter, gas::selfdestruct_cost::(res)); + gas!(interpreter, gas::selfdestruct_cost(SPEC::SPEC_ID, res)); interpreter.instruction_result = InstructionResult::SelfDestruct; } -pub fn create( +pub fn create( interpreter: &mut Interpreter, host: &mut H, ) { @@ -285,7 +288,7 @@ pub fn create( // EIP-1014: Skinny CREATE2 let scheme = if IS_CREATE2 { pop!(interpreter, salt); - gas_or_fail!(interpreter, gas::create2_cost(len)); + gas_or_fail!(interpreter, gas::create2_cost(len as u64)); CreateScheme::Create2 { salt } } else { gas!(interpreter, gas::CREATE); @@ -314,7 +317,7 @@ pub fn create( interpreter.instruction_result = InstructionResult::CallOrCreate; } -pub fn call(interpreter: &mut Interpreter, host: &mut H) { +pub fn call(interpreter: &mut Interpreter, host: &mut H) { pop!(interpreter, local_gas_limit); pop_address!(interpreter, to); // max gas limit is not possible in real ethereum situation. @@ -374,7 +377,7 @@ pub fn call(interpreter: &mut Interpreter, host: &mut H) { interpreter.instruction_result = InstructionResult::CallOrCreate; } -pub fn call_code(interpreter: &mut Interpreter, host: &mut H) { +pub fn call_code(interpreter: &mut Interpreter, host: &mut H) { pop!(interpreter, local_gas_limit); pop_address!(interpreter, to); // max gas limit is not possible in real ethereum situation. @@ -429,7 +432,7 @@ pub fn call_code(interpreter: &mut Interpreter, host: &mut interpreter.instruction_result = InstructionResult::CallOrCreate; } -pub fn delegate_call(interpreter: &mut Interpreter, host: &mut H) { +pub fn delegate_call(interpreter: &mut Interpreter, host: &mut H) { check!(interpreter, HOMESTEAD); pop!(interpreter, local_gas_limit); pop_address!(interpreter, to); @@ -475,7 +478,7 @@ pub fn delegate_call(interpreter: &mut Interpreter, host: & interpreter.instruction_result = InstructionResult::CallOrCreate; } -pub fn static_call(interpreter: &mut Interpreter, host: &mut H) { +pub fn static_call(interpreter: &mut Interpreter, host: &mut H) { check!(interpreter, BYZANTIUM); pop!(interpreter, local_gas_limit); pop_address!(interpreter, to); diff --git a/crates/interpreter/src/instructions/host/call_helpers.rs b/crates/interpreter/src/instructions/host/call_helpers.rs index 3156c9a75b..803d0e6235 100644 --- a/crates/interpreter/src/instructions/host/call_helpers.rs +++ b/crates/interpreter/src/instructions/host/call_helpers.rs @@ -34,7 +34,7 @@ pub fn get_memory_input_and_out_ranges( } #[inline] -pub fn calc_call_gas( +pub fn calc_call_gas( interpreter: &mut Interpreter, host: &mut H, to: Address, @@ -49,7 +49,8 @@ pub fn calc_call_gas( }; let is_new = !exist; - let call_cost = gas::call_cost::( + let call_cost = gas::call_cost( + SPEC::SPEC_ID, has_transfer, is_new, is_cold, diff --git a/crates/interpreter/src/instructions/host_env.rs b/crates/interpreter/src/instructions/host_env.rs index 230bb39b37..1b0c399559 100644 --- a/crates/interpreter/src/instructions/host_env.rs +++ b/crates/interpreter/src/instructions/host_env.rs @@ -5,28 +5,28 @@ use crate::{ }; /// EIP-1344: ChainID opcode -pub fn chainid(interpreter: &mut Interpreter, host: &mut H) { +pub fn chainid(interpreter: &mut Interpreter, host: &mut H) { check!(interpreter, ISTANBUL); gas!(interpreter, gas::BASE); push!(interpreter, U256::from(host.env().cfg.chain_id)); } -pub fn coinbase(interpreter: &mut Interpreter, host: &mut H) { +pub fn coinbase(interpreter: &mut Interpreter, host: &mut H) { gas!(interpreter, gas::BASE); push_b256!(interpreter, host.env().block.coinbase.into_word()); } -pub fn timestamp(interpreter: &mut Interpreter, host: &mut H) { +pub fn timestamp(interpreter: &mut Interpreter, host: &mut H) { gas!(interpreter, gas::BASE); push!(interpreter, host.env().block.timestamp); } -pub fn number(interpreter: &mut Interpreter, host: &mut H) { +pub fn number(interpreter: &mut Interpreter, host: &mut H) { gas!(interpreter, gas::BASE); push!(interpreter, host.env().block.number); } -pub fn difficulty(interpreter: &mut Interpreter, host: &mut H) { +pub fn difficulty(interpreter: &mut Interpreter, host: &mut H) { gas!(interpreter, gas::BASE); if SPEC::enabled(MERGE) { push_b256!(interpreter, host.env().block.prevrandao.unwrap()); @@ -35,30 +35,30 @@ pub fn difficulty(interpreter: &mut Interpreter, host: &mut } } -pub fn gaslimit(interpreter: &mut Interpreter, host: &mut H) { +pub fn gaslimit(interpreter: &mut Interpreter, host: &mut H) { gas!(interpreter, gas::BASE); push!(interpreter, host.env().block.gas_limit); } -pub fn gasprice(interpreter: &mut Interpreter, host: &mut H) { +pub fn gasprice(interpreter: &mut Interpreter, host: &mut H) { gas!(interpreter, gas::BASE); push!(interpreter, host.env().effective_gas_price()); } /// EIP-3198: BASEFEE opcode -pub fn basefee(interpreter: &mut Interpreter, host: &mut H) { +pub fn basefee(interpreter: &mut Interpreter, host: &mut H) { check!(interpreter, LONDON); gas!(interpreter, gas::BASE); push!(interpreter, host.env().block.basefee); } -pub fn origin(interpreter: &mut Interpreter, host: &mut H) { +pub fn origin(interpreter: &mut Interpreter, host: &mut H) { gas!(interpreter, gas::BASE); push_b256!(interpreter, host.env().tx.caller.into_word()); } // EIP-4844: Shard Blob Transactions -pub fn blob_hash(interpreter: &mut Interpreter, host: &mut H) { +pub fn blob_hash(interpreter: &mut Interpreter, host: &mut H) { check!(interpreter, CANCUN); gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, index); @@ -70,7 +70,7 @@ pub fn blob_hash(interpreter: &mut Interpreter, host: &mut } /// EIP-7516: BLOBBASEFEE opcode -pub fn blob_basefee(interpreter: &mut Interpreter, host: &mut H) { +pub fn blob_basefee(interpreter: &mut Interpreter, host: &mut H) { check!(interpreter, CANCUN); gas!(interpreter, gas::BASE); push!( diff --git a/crates/interpreter/src/instructions/i256.rs b/crates/interpreter/src/instructions/i256.rs index a26ae69ad4..0067c6668e 100644 --- a/crates/interpreter/src/instructions/i256.rs +++ b/crates/interpreter/src/instructions/i256.rs @@ -77,7 +77,7 @@ pub fn i256_div(mut first: U256, mut second: U256) -> U256 { } let first_sign = i256_sign_compl(&mut first); - if first_sign == Sign::Minus && first == MIN_NEGATIVE_VALUE && second == U256::from(1) { + if first == MIN_NEGATIVE_VALUE && second == U256::from(1) { return two_compl(MIN_NEGATIVE_VALUE); } @@ -105,9 +105,11 @@ pub fn i256_mod(mut first: U256, mut second: U256) -> U256 { return U256::ZERO; } - let _ = i256_sign_compl(&mut second); + let second_sign = i256_sign_compl(&mut second); + if second_sign == Sign::Zero { + return U256::ZERO; + } - // necessary overflow checks are done above, perform the operation let mut r = first % second; // set sign bit to zero @@ -124,6 +126,14 @@ pub fn i256_mod(mut first: U256, mut second: U256) -> U256 { mod tests { use super::*; use core::num::Wrapping; + use revm_primitives::uint; + + const MAX_POSITIVE_VALUE: U256 = U256::from_limbs([ + 0xffffffffffffffff, + 0xffffffffffffffff, + 0xffffffffffffffff, + 0x7fffffffffffffff, + ]); #[test] fn div_i256() { @@ -132,71 +142,101 @@ mod tests { assert_eq!(Wrapping(i8::MIN) / Wrapping(-1), Wrapping(i8::MIN)); assert_eq!(i8::MAX / -1, -i8::MAX); - // Now the same calculations based on i256 - let one = U256::from(1); - let one_hundred = U256::from(100); - let fifty = U256::from(50); - let two = U256::from(2); - let neg_one_hundred = U256::from(100); - let minus_one = U256::from(1); - let max_value = U256::from(2).pow(U256::from(255)) - U256::from(1); - let neg_max_value = U256::from(2).pow(U256::from(255)) - U256::from(1); - - assert_eq!(i256_div(MIN_NEGATIVE_VALUE, minus_one), MIN_NEGATIVE_VALUE); - assert_eq!(i256_div(MIN_NEGATIVE_VALUE, one), MIN_NEGATIVE_VALUE); - assert_eq!(i256_div(max_value, one), max_value); - assert_eq!(i256_div(max_value, minus_one), neg_max_value); - assert_eq!(i256_div(one_hundred, minus_one), neg_one_hundred); - assert_eq!(i256_div(one_hundred, two), fifty); + uint! { + assert_eq!(i256_div(MIN_NEGATIVE_VALUE, -1_U256), MIN_NEGATIVE_VALUE); + assert_eq!(i256_div(MIN_NEGATIVE_VALUE, 1_U256), MIN_NEGATIVE_VALUE); + assert_eq!(i256_div(MAX_POSITIVE_VALUE, 1_U256), MAX_POSITIVE_VALUE); + assert_eq!(i256_div(MAX_POSITIVE_VALUE, -1_U256), -1_U256 * MAX_POSITIVE_VALUE); + assert_eq!(i256_div(100_U256, -1_U256), -100_U256); + assert_eq!(i256_div(100_U256, 2_U256), 50_U256); + } } #[test] fn test_i256_sign() { - assert_eq!(i256_sign(&U256::ZERO), Sign::Zero); - assert_eq!(i256_sign(&U256::from(1)), Sign::Plus); - assert_eq!(i256_sign(&MIN_NEGATIVE_VALUE), Sign::Minus); + uint! { + assert_eq!(i256_sign(&0_U256), Sign::Zero); + assert_eq!(i256_sign(&1_U256), Sign::Plus); + assert_eq!(i256_sign(&-1_U256), Sign::Minus); + assert_eq!(i256_sign(&MIN_NEGATIVE_VALUE), Sign::Minus); + assert_eq!(i256_sign(&MAX_POSITIVE_VALUE), Sign::Plus); + } } #[test] fn test_i256_sign_compl() { - let mut positive = U256::from(1); - let mut negative = MIN_NEGATIVE_VALUE; - assert_eq!(i256_sign_compl(&mut positive), Sign::Plus); - assert_eq!(i256_sign_compl(&mut negative), Sign::Minus); + uint! { + let mut zero = 0_U256; + let mut positive = 1_U256; + let mut negative = -1_U256; + assert_eq!(i256_sign_compl(&mut zero), Sign::Zero); + assert_eq!(i256_sign_compl(&mut positive), Sign::Plus); + assert_eq!(i256_sign_compl(&mut negative), Sign::Minus); + } } #[test] fn test_two_compl() { - let value = U256::from(1); - assert_eq!(two_compl(value), U256::MAX); + uint! { + assert_eq!(two_compl(0_U256), 0_U256); + assert_eq!(two_compl(1_U256), -1_U256); + assert_eq!(two_compl(-1_U256), 1_U256); + assert_eq!(two_compl(2_U256), -2_U256); + assert_eq!(two_compl(-2_U256), 2_U256); + + // Two's complement of the min value is itself. + assert_eq!(two_compl(MIN_NEGATIVE_VALUE), MIN_NEGATIVE_VALUE); + } } #[test] fn test_two_compl_mut() { - let mut value = U256::from(1); - two_compl_mut(&mut value); - assert_eq!(value, U256::MAX); + uint! { + let mut value = 1_U256; + two_compl_mut(&mut value); + assert_eq!(value, -1_U256); + } } #[test] fn test_i256_cmp() { - assert_eq!(i256_cmp(&U256::from(1), &U256::from(2)), Ordering::Less); - assert_eq!(i256_cmp(&U256::from(2), &U256::from(2)), Ordering::Equal); - assert_eq!(i256_cmp(&U256::from(3), &U256::from(2)), Ordering::Greater); + uint! { + assert_eq!(i256_cmp(&1_U256, &2_U256), Ordering::Less); + assert_eq!(i256_cmp(&2_U256, &2_U256), Ordering::Equal); + assert_eq!(i256_cmp(&3_U256, &2_U256), Ordering::Greater); + assert_eq!(i256_cmp(&-1_U256, &-1_U256), Ordering::Equal); + assert_eq!(i256_cmp(&-1_U256, &-2_U256), Ordering::Greater); + assert_eq!(i256_cmp(&-1_U256, &0_U256), Ordering::Less); + assert_eq!(i256_cmp(&-2_U256, &2_U256), Ordering::Less); + } } #[test] fn test_i256_div() { - let one = U256::from(1); - let two = U256::from(2); - assert_eq!(i256_div(MIN_NEGATIVE_VALUE, one), MIN_NEGATIVE_VALUE); - assert_eq!(i256_div(U256::from(4), two), U256::from(2)); + uint! { + assert_eq!(i256_div(1_U256, 0_U256), 0_U256); + assert_eq!(i256_div(0_U256, 1_U256), 0_U256); + assert_eq!(i256_div(0_U256, -1_U256), 0_U256); + assert_eq!(i256_div(MIN_NEGATIVE_VALUE, 1_U256), MIN_NEGATIVE_VALUE); + assert_eq!(i256_div(4_U256, 2_U256), 2_U256); + assert_eq!(i256_div(MIN_NEGATIVE_VALUE, MIN_NEGATIVE_VALUE), 1_U256); + assert_eq!(i256_div(2_U256, -1_U256), -2_U256); + assert_eq!(i256_div(-2_U256, -1_U256), 2_U256); + } } #[test] fn test_i256_mod() { - let one = U256::from(1); - let two = U256::from(2); - assert_eq!(i256_mod(U256::from(4), two), U256::ZERO); - assert_eq!(i256_mod(U256::from(3), two), one); + uint! { + assert_eq!(i256_mod(0_U256, 1_U256), 0_U256); + assert_eq!(i256_mod(1_U256, 0_U256), 0_U256); + assert_eq!(i256_mod(4_U256, 2_U256), 0_U256); + assert_eq!(i256_mod(3_U256, 2_U256), 1_U256); + assert_eq!(i256_mod(MIN_NEGATIVE_VALUE, 1_U256), 0_U256); + assert_eq!(i256_mod(2_U256, 2_U256), 0_U256); + assert_eq!(i256_mod(2_U256, 3_U256), 2_U256); + assert_eq!(i256_mod(-2_U256, 3_U256), -2_U256); + assert_eq!(i256_mod(2_U256, -3_U256), 2_U256); + assert_eq!(i256_mod(-2_U256, -3_U256), -2_U256); + } } } diff --git a/crates/interpreter/src/instructions/macros.rs b/crates/interpreter/src/instructions/macros.rs index 861489d38f..b194f36ac9 100644 --- a/crates/interpreter/src/instructions/macros.rs +++ b/crates/interpreter/src/instructions/macros.rs @@ -1,4 +1,4 @@ -//! Utility macros to help implementementing opcode instruction functions. +//! Utility macros to help implementing opcode instruction functions. /// Fails the instruction if the current call is static. #[macro_export] @@ -78,7 +78,7 @@ macro_rules! resize_memory { return $ret; } - // Gas is calculated in evm words (256bits). + // Gas is calculated in evm words (256 bits). let words_num = rounded_size / 32; if !$interp .gas diff --git a/crates/interpreter/src/instructions/memory.rs b/crates/interpreter/src/instructions/memory.rs index 264c4c61c7..6ee2d88f93 100644 --- a/crates/interpreter/src/instructions/memory.rs +++ b/crates/interpreter/src/instructions/memory.rs @@ -5,7 +5,7 @@ use crate::{ }; use core::cmp::max; -pub fn mload(interpreter: &mut Interpreter, _host: &mut H) { +pub fn mload(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); pop!(interpreter, index); let index = as_usize_or_fail!(interpreter, index); @@ -13,7 +13,7 @@ pub fn mload(interpreter: &mut Interpreter, _host: &mut H) { push!(interpreter, interpreter.shared_memory.get_u256(index)); } -pub fn mstore(interpreter: &mut Interpreter, _host: &mut H) { +pub fn mstore(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); pop!(interpreter, index, value); let index = as_usize_or_fail!(interpreter, index); @@ -21,7 +21,7 @@ pub fn mstore(interpreter: &mut Interpreter, _host: &mut H) { interpreter.shared_memory.set_u256(index, value); } -pub fn mstore8(interpreter: &mut Interpreter, _host: &mut H) { +pub fn mstore8(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); pop!(interpreter, index, value); let index = as_usize_or_fail!(interpreter, index); @@ -29,13 +29,13 @@ pub fn mstore8(interpreter: &mut Interpreter, _host: &mut H) { interpreter.shared_memory.set_byte(index, value.byte(0)) } -pub fn msize(interpreter: &mut Interpreter, _host: &mut H) { +pub fn msize(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::BASE); push!(interpreter, U256::from(interpreter.shared_memory.len())); } // EIP-5656: MCOPY - Memory copying instruction -pub fn mcopy(interpreter: &mut Interpreter, _host: &mut H) { +pub fn mcopy(interpreter: &mut Interpreter, _host: &mut H) { check!(interpreter, CANCUN); pop!(interpreter, dst, src, len); diff --git a/crates/interpreter/src/instructions/opcode.rs b/crates/interpreter/src/instructions/opcode.rs index 687637b4bc..8896c9da27 100644 --- a/crates/interpreter/src/instructions/opcode.rs +++ b/crates/interpreter/src/instructions/opcode.rs @@ -28,12 +28,12 @@ pub type BoxedInstructionTable<'a, H> = [BoxedInstruction<'a, H>; 256]; /// Note that `Plain` variant gives us 10-20% faster Interpreter execution. /// /// Boxed variant can be used to wrap plain function pointer with closure. -pub enum InstructionTables<'a, H> { +pub enum InstructionTables<'a, H: ?Sized> { Plain(InstructionTable), Boxed(BoxedInstructionTable<'a, H>), } -impl InstructionTables<'_, H> { +impl InstructionTables<'_, H> { /// Creates a plain instruction table for the given spec. #[inline] pub const fn new_plain() -> Self { @@ -41,7 +41,7 @@ impl InstructionTables<'_, H> { } } -impl<'a, H: Host + 'a> InstructionTables<'a, H> { +impl<'a, H: Host + ?Sized + 'a> InstructionTables<'a, H> { /// Inserts a boxed instruction into the table with the specified index. /// /// This will convert the table into the [BoxedInstructionTable] variant if it is currently a @@ -93,13 +93,14 @@ impl<'a, H: Host + 'a> InstructionTables<'a, H> { /// Make instruction table. #[inline] -pub const fn make_instruction_table() -> InstructionTable { +pub const fn make_instruction_table() -> InstructionTable { // Force const-eval of the table creation, making this function trivial. // TODO: Replace this with a `const {}` block once it is stable. - struct ConstTable { - _phantom: core::marker::PhantomData<(H, SPEC)>, + struct ConstTable { + _host: core::marker::PhantomData, + _spec: core::marker::PhantomData, } - impl ConstTable { + impl ConstTable { const NEW: InstructionTable = { let mut tables: InstructionTable = [control::unknown; 256]; let mut i = 0; @@ -120,7 +121,7 @@ pub fn make_boxed_instruction_table<'a, H, SPEC, FN>( mut outer: FN, ) -> BoxedInstructionTable<'a, H> where - H: Host, + H: Host + ?Sized, SPEC: Spec + 'a, FN: FnMut(Instruction) -> BoxedInstruction<'a, H>, { @@ -154,7 +155,7 @@ macro_rules! opcodes { }; /// Returns the instruction function for the given opcode and spec. - pub const fn instruction(opcode: u8) -> Instruction { + pub const fn instruction(opcode: u8) -> Instruction { match opcode { $($name => $f,)* _ => control::unknown, @@ -437,10 +438,17 @@ opcodes! { /// /// 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)] +#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[repr(transparent)] pub struct OpCode(u8); +impl fmt::Debug for OpCode { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "OpCode::{self}") + } +} + impl fmt::Display for OpCode { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let n = self.get(); @@ -488,20 +496,6 @@ impl OpCode { pub const fn get(self) -> u8 { 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() - } } #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] diff --git a/crates/interpreter/src/instructions/stack.rs b/crates/interpreter/src/instructions/stack.rs index 14d9e35238..5267687591 100644 --- a/crates/interpreter/src/instructions/stack.rs +++ b/crates/interpreter/src/instructions/stack.rs @@ -4,7 +4,7 @@ use crate::{ Host, Interpreter, }; -pub fn pop(interpreter: &mut Interpreter, _host: &mut H) { +pub fn pop(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::BASE); if let Err(result) = interpreter.stack.pop() { interpreter.instruction_result = result; @@ -14,7 +14,7 @@ pub fn pop(interpreter: &mut Interpreter, _host: &mut H) { /// 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 H) { +pub fn push0(interpreter: &mut Interpreter, _host: &mut H) { check!(interpreter, SHANGHAI); gas!(interpreter, gas::BASE); if let Err(result) = interpreter.stack.push(U256::ZERO) { @@ -22,7 +22,7 @@ pub fn push0(interpreter: &mut Interpreter, _host: &mut H) } } -pub fn push(interpreter: &mut Interpreter, _host: &mut H) { +pub fn push(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); // SAFETY: In analysis we append trailing bytes to the bytecode so that this is safe to do // without bounds checking. @@ -37,14 +37,14 @@ pub fn push(interpreter: &mut Interpreter, _host: &mut interpreter.instruction_pointer = unsafe { ip.add(N) }; } -pub fn dup(interpreter: &mut Interpreter, _host: &mut H) { +pub fn dup(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); if let Err(result) = interpreter.stack.dup::() { interpreter.instruction_result = result; } } -pub fn swap(interpreter: &mut Interpreter, _host: &mut H) { +pub fn swap(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); 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 55109d8004..be81fb3116 100644 --- a/crates/interpreter/src/instructions/system.rs +++ b/crates/interpreter/src/instructions/system.rs @@ -4,7 +4,7 @@ use crate::{ Host, InstructionResult, Interpreter, }; -pub fn keccak256(interpreter: &mut Interpreter, _host: &mut H) { +pub fn keccak256(interpreter: &mut Interpreter, _host: &mut H) { pop!(interpreter, from, len); let len = as_usize_or_fail!(interpreter, len); gas_or_fail!(interpreter, gas::keccak256_cost(len as u64)); @@ -19,22 +19,22 @@ pub fn keccak256(interpreter: &mut Interpreter, _host: &mut H) { push_b256!(interpreter, hash); } -pub fn address(interpreter: &mut Interpreter, _host: &mut H) { +pub fn address(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::BASE); push_b256!(interpreter, interpreter.contract.address.into_word()); } -pub fn caller(interpreter: &mut Interpreter, _host: &mut H) { +pub fn caller(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::BASE); push_b256!(interpreter, interpreter.contract.caller.into_word()); } -pub fn codesize(interpreter: &mut Interpreter, _host: &mut H) { +pub fn codesize(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::BASE); push!(interpreter, U256::from(interpreter.contract.bytecode.len())); } -pub fn codecopy(interpreter: &mut Interpreter, _host: &mut H) { +pub fn codecopy(interpreter: &mut Interpreter, _host: &mut H) { pop!(interpreter, memory_offset, code_offset, len); let len = as_usize_or_fail!(interpreter, len); gas_or_fail!(interpreter, gas::verylowcopy_cost(len as u64)); @@ -54,7 +54,7 @@ pub fn codecopy(interpreter: &mut Interpreter, _host: &mut H) { ); } -pub fn calldataload(interpreter: &mut Interpreter, _host: &mut H) { +pub fn calldataload(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); pop!(interpreter, index); let index = as_usize_saturated!(index); @@ -70,17 +70,17 @@ pub fn calldataload(interpreter: &mut Interpreter, _host: &mut H) { push_b256!(interpreter, load); } -pub fn calldatasize(interpreter: &mut Interpreter, _host: &mut H) { +pub fn calldatasize(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::BASE); push!(interpreter, U256::from(interpreter.contract.input.len())); } -pub fn callvalue(interpreter: &mut Interpreter, _host: &mut H) { +pub fn callvalue(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::BASE); push!(interpreter, interpreter.contract.value); } -pub fn calldatacopy(interpreter: &mut Interpreter, _host: &mut H) { +pub fn calldatacopy(interpreter: &mut Interpreter, _host: &mut H) { pop!(interpreter, memory_offset, data_offset, len); let len = as_usize_or_fail!(interpreter, len); gas_or_fail!(interpreter, gas::verylowcopy_cost(len as u64)); @@ -101,7 +101,7 @@ pub fn calldatacopy(interpreter: &mut Interpreter, _host: &mut H) { } /// EIP-211: New opcodes: RETURNDATASIZE and RETURNDATACOPY -pub fn returndatasize(interpreter: &mut Interpreter, _host: &mut H) { +pub fn returndatasize(interpreter: &mut Interpreter, _host: &mut H) { check!(interpreter, BYZANTIUM); gas!(interpreter, gas::BASE); push!( @@ -111,7 +111,7 @@ pub fn returndatasize(interpreter: &mut Interpreter, _host: } /// EIP-211: New opcodes: RETURNDATASIZE and RETURNDATACOPY -pub fn returndatacopy(interpreter: &mut Interpreter, _host: &mut H) { +pub fn returndatacopy(interpreter: &mut Interpreter, _host: &mut H) { check!(interpreter, BYZANTIUM); pop!(interpreter, memory_offset, offset, len); let len = as_usize_or_fail!(interpreter, len); @@ -132,7 +132,7 @@ pub fn returndatacopy(interpreter: &mut Interpreter, _host: } } -pub fn gas(interpreter: &mut Interpreter, _host: &mut H) { +pub fn gas(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::BASE); push!(interpreter, U256::from(interpreter.gas.remaining())); } diff --git a/crates/interpreter/src/interpreter.rs b/crates/interpreter/src/interpreter.rs index 79620b9085..4da1b58df3 100644 --- a/crates/interpreter/src/interpreter.rs +++ b/crates/interpreter/src/interpreter.rs @@ -17,10 +17,11 @@ use revm_primitives::U256; use std::borrow::ToOwned; use std::boxed::Box; +/// EVM bytecode interpreter. #[derive(Debug)] pub struct Interpreter { /// Contract information and invoking data - pub contract: Box, + pub contract: Contract, /// The current instruction pointer. pub instruction_pointer: *const u8, /// The execution control flag. If this is not set to `Continue`, the interpreter will stop @@ -51,7 +52,7 @@ pub struct Interpreter { } /// The result of an interpreter operation. -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Eq)] pub struct InterpreterResult { /// The result of the instruction execution. pub result: InstructionResult, @@ -61,7 +62,7 @@ pub struct InterpreterResult { pub gas: Gas, } -#[derive(Debug, Default, Clone)] +#[derive(Clone, Debug, Default, PartialEq, Eq)] pub enum InterpreterAction { /// CALL, CALLCODE, DELEGATECALL or STATICCALL instruction called. Call { @@ -114,7 +115,7 @@ impl InterpreterAction { impl Interpreter { /// Create new interpreter - pub fn new(contract: Box, gas_limit: u64, is_static: bool) -> Self { + pub fn new(contract: Contract, gas_limit: u64, is_static: bool) -> Self { Self { instruction_pointer: contract.bytecode.as_ptr(), contract, @@ -216,7 +217,7 @@ impl Interpreter { let out_offset = call_outcome.memory_start(); let out_len = call_outcome.memory_length(); - self.return_data_buffer = call_outcome.output().to_owned(); + self.return_data_buffer.clone_from(call_outcome.output()); let target_len = min(out_len, self.return_data_buffer.len()); match call_outcome.instruction_result() { @@ -282,7 +283,7 @@ impl Interpreter { /// /// Internally it will increment instruction pointer by one. #[inline(always)] - fn step(&mut self, instruction_table: &[FN; 256], host: &mut H) + fn step(&mut self, instruction_table: &[FN; 256], host: &mut H) where FN: Fn(&mut Interpreter, &mut H), { @@ -304,7 +305,7 @@ impl Interpreter { } /// Executes the interpreter until it returns or stops. - pub fn run( + pub fn run( &mut self, shared_memory: SharedMemory, instruction_table: &[FN; 256], @@ -355,3 +356,25 @@ impl InterpreterResult { self.result.is_error() } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::{opcode::InstructionTable, DummyHost}; + use revm_primitives::CancunSpec; + + #[test] + fn object_safety() { + let mut interp = Interpreter::new(Contract::default(), u64::MAX, false); + + let mut host = crate::DummyHost::default(); + let table: InstructionTable = + crate::opcode::make_instruction_table::(); + let _ = interp.run(EMPTY_SHARED_MEMORY, &table, &mut host); + + let host: &mut dyn Host = &mut host as &mut dyn Host; + let table: InstructionTable = + crate::opcode::make_instruction_table::(); + let _ = interp.run(EMPTY_SHARED_MEMORY, &table, host); + } +} diff --git a/crates/interpreter/src/interpreter/shared_memory.rs b/crates/interpreter/src/interpreter/shared_memory.rs index c49cc319ed..433e24abb0 100644 --- a/crates/interpreter/src/interpreter/shared_memory.rs +++ b/crates/interpreter/src/interpreter/shared_memory.rs @@ -303,7 +303,8 @@ impl SharedMemory { } } -/// Rounds up `x` to the closest multiple of 32. If `x % 32 == 0` then `x` is returned. +/// Rounds up `x` to the closest multiple of 32. If `x % 32 == 0` then `x` is returned. Note, if `x` +/// is greater than `usize::MAX - 31` this will return `usize::MAX` which isn't a multiple of 32. #[inline] pub fn next_multiple_of_32(x: usize) -> usize { let r = x.bitand(31).not().wrapping_add(1).bitand(31); @@ -330,6 +331,9 @@ mod tests { let next_multiple = x + 32 - (x % 32); assert_eq!(next_multiple, next_multiple_of_32(x)); } + + // We expect large values to saturate and not overflow. + assert_eq!(usize::MAX, next_multiple_of_32(usize::MAX)); } #[test] diff --git a/crates/precompile/CHANGELOG.md b/crates/precompile/CHANGELOG.md index 9a23e04141..c6aba3c3bd 100644 --- a/crates/precompile/CHANGELOG.md +++ b/crates/precompile/CHANGELOG.md @@ -6,6 +6,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [6.0.1](https://github.com/receivingpotman/revm/compare/revm-precompile-v6.0.0...revm-precompile-v6.0.1) - 2024-04-07 + +### Other +- *(deps)* bump secp256k1 from 0.28.2 to 0.29.0 ([#1260](https://github.com/receivingpotman/revm/pull/1260)) + +## [6.0.0](https://github.com/bluealloy/revm/compare/revm-precompile-v5.1.0...revm-precompile-v6.0.0) - 2024-04-02 + +### Fixed +- update/enable bn128 tests ([#1242](https://github.com/bluealloy/revm/pull/1242)) +- use correct bn128 mul input length ([#1238](https://github.com/bluealloy/revm/pull/1238)) +- use correct rand package for thread_rng ([#1233](https://github.com/bluealloy/revm/pull/1233)) + +### Other +- remove unnecessary call to into_u256() for bn128 add ([#1239](https://github.com/bluealloy/revm/pull/1239)) + ## [5.1.0](https://github.com/bluealloy/revm/compare/revm-precompile-v5.0.0...revm-precompile-v5.1.0) - 2024-03-19 ### Added diff --git a/crates/precompile/Cargo.toml b/crates/precompile/Cargo.toml index 373e6850e1..15a8063050 100644 --- a/crates/precompile/Cargo.toml +++ b/crates/precompile/Cargo.toml @@ -6,14 +6,14 @@ keywords = ["no_std", "ethereum", "evm", "revm", "precompiles"] license = "MIT" name = "revm-precompile" repository = "https://github.com/bluealloy/revm" -version = "5.1.0" +version = "6.0.1" [package.metadata.docs.rs] all-features = true rustdoc-args = ["--cfg", "docsrs"] [dependencies] -revm-primitives = { path = "../primitives", version = "3.1.0", default-features = false } +revm-primitives = { path = "../primitives", version = "3.2.0", default-features = false } bn = { package = "substrate-bn", version = "0.6", default-features = false } once_cell = { version = "1.19", default-features = false, features = ["alloc"] } ripemd = { version = "0.1", default-features = false } @@ -26,7 +26,7 @@ c-kzg = { version = "1.0.0", default-features = false, optional = true } # ecRecover precompile k256 = { version = "0.13.3", default-features = false, features = ["ecdsa"] } -secp256k1 = { version = "0.28.2", default-features = false, features = [ +secp256k1 = { version = "0.29.0", default-features = false, features = [ "alloc", "recovery", "rand", @@ -35,6 +35,7 @@ secp256k1 = { version = "0.28.2", default-features = false, features = [ [dev-dependencies] criterion = { version = "0.5" } +rand = { version = "0.8", features = ["std"] } [features] default = ["std", "c-kzg", "secp256k1", "portable"] diff --git a/crates/precompile/benches/bench.rs b/crates/precompile/benches/bench.rs index 2a37013dea..48452b4abb 100644 --- a/crates/precompile/benches/bench.rs +++ b/crates/precompile/benches/bench.rs @@ -9,7 +9,7 @@ use revm_precompile::{ Bytes, }; use revm_primitives::{hex, keccak256, Env, U256, VERSIONED_HASH_VERSION_KZG}; -use secp256k1::{rand, Message, SecretKey, SECP256K1}; +use secp256k1::{Message, SecretKey, SECP256K1}; use sha2::{Digest, Sha256}; /// Benchmarks different cryptography-related precompiles. diff --git a/crates/precompile/src/bn128.rs b/crates/precompile/src/bn128.rs index c243e7e477..ce08da7994 100644 --- a/crates/precompile/src/bn128.rs +++ b/crates/precompile/src/bn128.rs @@ -3,31 +3,22 @@ use crate::{ Address, Error, Precompile, PrecompileResult, PrecompileWithAddress, }; use bn::{AffineG1, AffineG2, Fq, Fq2, Group, Gt, G1, G2}; -use revm_primitives::Bytes; pub mod add { use super::*; const ADDRESS: Address = crate::u64_to_address(6); + pub const ISTANBUL_ADD_GAS_COST: u64 = 150; pub const ISTANBUL: PrecompileWithAddress = PrecompileWithAddress( ADDRESS, - Precompile::Standard(|input, gas_limit| { - if 150 > gas_limit { - return Err(Error::OutOfGas); - } - Ok((150, super::run_add(input)?)) - }), + Precompile::Standard(|input, gas_limit| run_add(input, ISTANBUL_ADD_GAS_COST, gas_limit)), ); + pub const BYZANTIUM_ADD_GAS_COST: u64 = 500; pub const BYZANTIUM: PrecompileWithAddress = PrecompileWithAddress( ADDRESS, - Precompile::Standard(|input, gas_limit| { - if 500 > gas_limit { - return Err(Error::OutOfGas); - } - Ok((500, super::run_add(input)?)) - }), + Precompile::Standard(|input, gas_limit| run_add(input, BYZANTIUM_ADD_GAS_COST, gas_limit)), ); } @@ -36,24 +27,16 @@ pub mod mul { const ADDRESS: Address = crate::u64_to_address(7); + pub const ISTANBUL_MUL_GAS_COST: u64 = 6_000; pub const ISTANBUL: PrecompileWithAddress = PrecompileWithAddress( ADDRESS, - Precompile::Standard(|input, gas_limit| { - if 6_000 > gas_limit { - return Err(Error::OutOfGas); - } - Ok((6_000, super::run_mul(input)?)) - }), + Precompile::Standard(|input, gas_limit| run_mul(input, ISTANBUL_MUL_GAS_COST, gas_limit)), ); + pub const BYZANTIUM_MUL_GAS_COST: u64 = 40_000; pub const BYZANTIUM: PrecompileWithAddress = PrecompileWithAddress( ADDRESS, - Precompile::Standard(|input, gas_limit| { - if 40_000 > gas_limit { - return Err(Error::OutOfGas); - } - Ok((40_000, super::run_mul(input)?)) - }), + Precompile::Standard(|input, gas_limit| run_mul(input, BYZANTIUM_MUL_GAS_COST, gas_limit)), ); } @@ -67,7 +50,7 @@ pub mod pair { pub const ISTANBUL: PrecompileWithAddress = PrecompileWithAddress( ADDRESS, Precompile::Standard(|input, gas_limit| { - super::run_pair( + run_pair( input, ISTANBUL_PAIR_PER_POINT, ISTANBUL_PAIR_BASE, @@ -81,7 +64,7 @@ pub mod pair { pub const BYZANTIUM: PrecompileWithAddress = PrecompileWithAddress( ADDRESS, Precompile::Standard(|input, gas_limit| { - super::run_pair( + run_pair( input, BYZANTIUM_PAIR_PER_POINT, BYZANTIUM_PAIR_BASE, @@ -92,13 +75,17 @@ pub mod pair { } /// Input length for the add operation. -pub const ADD_INPUT_LEN: usize = 128; +/// `ADD` takes two uncompressed G1 points (64 bytes each). +pub const ADD_INPUT_LEN: usize = 64 + 64; /// Input length for the multiplication operation. -pub const MUL_INPUT_LEN: usize = 128; +/// `MUL` takes an uncompressed G1 point (64 bytes) and scalar (32 bytes). +pub const MUL_INPUT_LEN: usize = 64 + 32; /// Pair element length. -pub const PAIR_ELEMENT_LEN: usize = 192; +/// `PAIR` elements are composed of an uncompressed G1 point (64 bytes) and an uncompressed G2 point +/// (128 bytes). +pub const PAIR_ELEMENT_LEN: usize = 64 + 128; /// Reads a single `Fq` from the input slice. /// @@ -133,7 +120,11 @@ pub fn new_g1_point(px: Fq, py: Fq) -> Result { } } -pub fn run_add(input: &[u8]) -> Result { +pub fn run_add(input: &[u8], gas_cost: u64, gas_limit: u64) -> PrecompileResult { + if gas_cost > gas_limit { + return Err(Error::OutOfGas); + } + let input = right_pad::(input); let p1 = read_point(&input[..64])?; @@ -141,20 +132,17 @@ pub fn run_add(input: &[u8]) -> Result { let mut output = [0u8; 64]; if let Some(sum) = AffineG1::from_jacobian(p1 + p2) { - sum.x() - .into_u256() - .to_big_endian(&mut output[..32]) - .unwrap(); - sum.y() - .into_u256() - .to_big_endian(&mut output[32..]) - .unwrap(); + sum.x().to_big_endian(&mut output[..32]).unwrap(); + sum.y().to_big_endian(&mut output[32..]).unwrap(); } - - Ok(output.into()) + Ok((gas_cost, output.into())) } -pub fn run_mul(input: &[u8]) -> Result { +pub fn run_mul(input: &[u8], gas_cost: u64, gas_limit: u64) -> PrecompileResult { + if gas_cost > gas_limit { + return Err(Error::OutOfGas); + } + let input = right_pad::(input); let p = read_point(&input[..64])?; @@ -162,12 +150,12 @@ pub fn run_mul(input: &[u8]) -> Result { // `Fr::from_slice` can only fail when the length is not 32. let fr = bn::Fr::from_slice(&input[64..96]).unwrap(); - let mut out = [0u8; 64]; + let mut output = [0u8; 64]; if let Some(mul) = AffineG1::from_jacobian(p * fr) { - mul.x().to_big_endian(&mut out[..32]).unwrap(); - mul.y().to_big_endian(&mut out[32..]).unwrap(); + mul.x().to_big_endian(&mut output[..32]).unwrap(); + mul.y().to_big_endian(&mut output[32..]).unwrap(); } - Ok(out.into()) + Ok((gas_cost, output.into())) } pub fn run_pair( @@ -226,10 +214,12 @@ pub fn run_pair( Ok((gas_used, bool_to_bytes32(success))) } -/* #[cfg(test)] mod tests { - use crate::test_utils::new_context; + use crate::bn128::add::BYZANTIUM_ADD_GAS_COST; + use crate::bn128::mul::BYZANTIUM_MUL_GAS_COST; + use crate::bn128::pair::{BYZANTIUM_PAIR_BASE, BYZANTIUM_PAIR_PER_POINT}; + use revm_primitives::hex; use super::*; @@ -250,9 +240,7 @@ mod tests { ) .unwrap(); - let res = Bn128Add::::run(&input, 500, &new_context(), false) - .unwrap() - .output; + let (_, res) = run_add(&input, BYZANTIUM_ADD_GAS_COST, 500).unwrap(); assert_eq!(res, expected); // zero sum test @@ -271,9 +259,7 @@ mod tests { ) .unwrap(); - let res = Bn128Add::::run(&input, 500, &new_context(), false) - .unwrap() - .output; + let (_, res) = run_add(&input, BYZANTIUM_ADD_GAS_COST, 500).unwrap(); assert_eq!(res, expected); // out of gas test @@ -285,8 +271,10 @@ mod tests { 0000000000000000000000000000000000000000000000000000000000000000", ) .unwrap(); - let res = Bn128Add::::run(&input, 499, &new_context(), false); - assert!(matches!(res, Err(Return::OutOfGas))); + + let res = run_add(&input, BYZANTIUM_ADD_GAS_COST, 499); + println!("{:?}", res); + assert!(matches!(res, Err(Error::OutOfGas))); // no input test let input = [0u8; 0]; @@ -297,9 +285,7 @@ mod tests { ) .unwrap(); - let res = Bn128Add::::run(&input, 500, &new_context(), false) - .unwrap() - .output; + let (_, res) = run_add(&input, BYZANTIUM_ADD_GAS_COST, 500).unwrap(); assert_eq!(res, expected); // point not on curve fail @@ -312,11 +298,8 @@ mod tests { ) .unwrap(); - let res = Bn128Add::::run(&input, 500, &new_context(), false); - assert!(matches!( - res, - Err(Return::Other(Cow::Borrowed("ERR_BN128_INVALID_POINT"))) - )); + let res = run_add(&input, BYZANTIUM_ADD_GAS_COST, 500); + assert!(matches!(res, Err(Error::Bn128AffineGFailedToCreate))); } #[test] @@ -335,9 +318,7 @@ mod tests { ) .unwrap(); - let res = Bn128Mul::::run(&input, 40_000, &new_context(), false) - .unwrap() - .output; + let (_, res) = run_mul(&input, BYZANTIUM_MUL_GAS_COST, 40_000).unwrap(); assert_eq!(res, expected); // out of gas test @@ -348,8 +329,9 @@ mod tests { 0200000000000000000000000000000000000000000000000000000000000000", ) .unwrap(); - let res = Bn128Mul::::run(&input, 39_999, &new_context(), false); - assert!(matches!(res, Err(Return::OutOfGas))); + + let res = run_mul(&input, BYZANTIUM_MUL_GAS_COST, 39_999); + assert!(matches!(res, Err(Error::OutOfGas))); // zero multiplication test let input = hex::decode( @@ -366,9 +348,7 @@ mod tests { ) .unwrap(); - let res = Bn128Mul::::run(&input, 40_000, &new_context(), false) - .unwrap() - .output; + let (_, res) = run_mul(&input, BYZANTIUM_MUL_GAS_COST, 40_000).unwrap(); assert_eq!(res, expected); // no input test @@ -380,9 +360,7 @@ mod tests { ) .unwrap(); - let res = Bn128Mul::::run(&input, 40_000, &new_context(), false) - .unwrap() - .output; + let (_, res) = run_mul(&input, BYZANTIUM_MUL_GAS_COST, 40_000).unwrap(); assert_eq!(res, expected); // point not on curve fail @@ -394,11 +372,8 @@ mod tests { ) .unwrap(); - let res = Bn128Mul::::run(&input, 40_000, &new_context(), false); - assert!(matches!( - res, - Err(Return::Other(Cow::Borrowed("ERR_BN128_INVALID_POINT"))) - )); + let res = run_mul(&input, BYZANTIUM_MUL_GAS_COST, 40_000); + assert!(matches!(res, Err(Error::Bn128AffineGFailedToCreate))); } #[test] @@ -423,9 +398,13 @@ mod tests { hex::decode("0000000000000000000000000000000000000000000000000000000000000001") .unwrap(); - let res = Bn128Pair::::run(&input, 260_000, &new_context(), false) - .unwrap() - .output; + let (_, res) = run_pair( + &input, + BYZANTIUM_PAIR_PER_POINT, + BYZANTIUM_PAIR_BASE, + 260_000, + ) + .unwrap(); assert_eq!(res, expected); // out of gas test @@ -445,8 +424,14 @@ mod tests { 12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", ) .unwrap(); - let res = Bn128Pair::::run(&input, 259_999, &new_context(), false); - assert!(matches!(res, Err(Return::OutOfGas))); + + let res = run_pair( + &input, + BYZANTIUM_PAIR_PER_POINT, + BYZANTIUM_PAIR_BASE, + 259_999, + ); + assert!(matches!(res, Err(Error::OutOfGas))); // no input test let input = [0u8; 0]; @@ -454,9 +439,13 @@ mod tests { hex::decode("0000000000000000000000000000000000000000000000000000000000000001") .unwrap(); - let res = Bn128Pair::::run(&input, 260_000, &new_context(), false) - .unwrap() - .output; + let (_, res) = run_pair( + &input, + BYZANTIUM_PAIR_PER_POINT, + BYZANTIUM_PAIR_BASE, + 260_000, + ) + .unwrap(); assert_eq!(res, expected); // point not on curve fail @@ -471,11 +460,13 @@ mod tests { ) .unwrap(); - let res = Bn128Pair::::run(&input, 260_000, &new_context(), false); - assert!(matches!( - res, - Err(Return::Other(Cow::Borrowed("ERR_BN128_INVALID_A"))) - )); + let res = run_pair( + &input, + BYZANTIUM_PAIR_PER_POINT, + BYZANTIUM_PAIR_BASE, + 260_000, + ); + assert!(matches!(res, Err(Error::Bn128AffineGFailedToCreate))); // invalid input length let input = hex::decode( @@ -487,11 +478,12 @@ mod tests { ) .unwrap(); - let res = Bn128Pair::::run(&input, 260_000, &new_context(), false); - assert!(matches!( - res, - Err(Return::Other(Cow::Borrowed("ERR_BN128_INVALID_LEN",))) - )); + let res = run_pair( + &input, + BYZANTIUM_PAIR_PER_POINT, + BYZANTIUM_PAIR_BASE, + 260_000, + ); + assert!(matches!(res, Err(Error::Bn128PairLength))); } } -*/ diff --git a/crates/primitives/CHANGELOG.md b/crates/primitives/CHANGELOG.md index 626ef9d6da..a9dbbb2a52 100644 --- a/crates/primitives/CHANGELOG.md +++ b/crates/primitives/CHANGELOG.md @@ -6,6 +6,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [3.2.0](https://github.com/receivingpotman/revm/compare/revm-primitives-v3.1.1...revm-primitives-v3.2.0) - 2024-04-07 + +### Added +- *(interpreter)* remove SPEC generic from gas calculation functions ([#1243](https://github.com/receivingpotman/revm/pull/1243)) + +## [3.1.1](https://github.com/bluealloy/revm/compare/revm-primitives-v3.1.0...revm-primitives-v3.1.1) - 2024-04-02 + +### Fixed +- fix eip3155 summary gas_used bug and add fork name ([#1216](https://github.com/bluealloy/revm/pull/1216)) + +### Other +- use uint macro & fix various small things ([#1253](https://github.com/bluealloy/revm/pull/1253)) +- *(deps)* bump alloy 0.7.0 ([#1250](https://github.com/bluealloy/revm/pull/1250)) + ## [3.1.0](https://github.com/bluealloy/revm/compare/revm-primitives-v3.0.0...revm-primitives-v3.1.0) - 2024-03-19 ### Added diff --git a/crates/primitives/Cargo.toml b/crates/primitives/Cargo.toml index b50815fec2..0105042036 100644 --- a/crates/primitives/Cargo.toml +++ b/crates/primitives/Cargo.toml @@ -6,7 +6,7 @@ keywords = ["no_std", "ethereum", "evm", "revm", "types"] license = "MIT" name = "revm-primitives" repository = "https://github.com/bluealloy/revm" -version = "3.1.0" +version = "3.2.0" readme = "../../README.md" # Don't need to run build script outside of this repo @@ -17,7 +17,7 @@ all-features = true rustdoc-args = ["--cfg", "docsrs"] [dependencies] -alloy-primitives = { version = "0.6", default-features = false, features = [ +alloy-primitives = { version = "0.7", default-features = false, features = [ "rlp", ] } hashbrown = "0.14" diff --git a/crates/primitives/src/bytecode.rs b/crates/primitives/src/bytecode.rs index e13040bd43..8fc436a982 100644 --- a/crates/primitives/src/bytecode.rs +++ b/crates/primitives/src/bytecode.rs @@ -105,12 +105,12 @@ impl Bytecode { } } - /// Create new checked 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 + /// Bytecode needs to end with STOP (0x00) opcode as checked bytecode assumes + /// that it is safe to iterate over bytecode without checking lengths. pub unsafe fn new_checked(bytecode: Bytes, len: usize) -> Self { Self { bytecode, diff --git a/crates/primitives/src/specification.rs b/crates/primitives/src/specification.rs index 6d75e25c44..c976702839 100644 --- a/crates/primitives/src/specification.rs +++ b/crates/primitives/src/specification.rs @@ -67,15 +67,19 @@ pub enum SpecId { } impl SpecId { + /// Returns the `SpecId` for the given `u8`. #[inline] pub fn try_from_u8(spec_id: u8) -> Option { Self::n(spec_id) } - pub fn is_enabled_in(&self, other: Self) -> bool { - Self::enabled(*self, other) + /// Returns `true` if the given specification ID is enabled in this spec. + #[inline] + pub const fn is_enabled_in(self, other: Self) -> bool { + Self::enabled(self, other) } + /// Returns `true` if the given specification ID is enabled in this spec. #[inline] pub const fn enabled(our: SpecId, other: SpecId) -> bool { our as u8 >= other as u8 diff --git a/crates/revm/CHANGELOG.md b/crates/revm/CHANGELOG.md index 090b67cb26..71fb204e41 100644 --- a/crates/revm/CHANGELOG.md +++ b/crates/revm/CHANGELOG.md @@ -6,6 +6,34 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [8.1.0](https://github.com/receivingpotman/revm/compare/revm-v8.0.0...revm-v8.1.0) - 2024-04-07 + +### Added +- *(`db`)* Introduce `alloydb` ([#1257](https://github.com/receivingpotman/revm/pull/1257)) +- *(interpreter)* remove SPEC generic from gas calculation functions ([#1243](https://github.com/receivingpotman/revm/pull/1243)) +- *(interpreter)* test Host object-safety, allow `dyn Host` in instructions ([#1245](https://github.com/receivingpotman/revm/pull/1245)) + +### Other +- add and use EvmContext::take_error ([#1264](https://github.com/receivingpotman/revm/pull/1264)) + +## [8.0.0](https://github.com/bluealloy/revm/compare/revm-v7.2.0...revm-v8.0.0) - 2024-04-02 + +### Added +- [**breaking**] TracerEip3155 optionally traces memory ([#1234](https://github.com/bluealloy/revm/pull/1234)) + +### Fixed +- *(TracerEip3155)* clear Inspector data after transaction. ([#1230](https://github.com/bluealloy/revm/pull/1230)) +- *(GasInspector)* calculate correct remaining gas after call return ([#1236](https://github.com/bluealloy/revm/pull/1236)) +- fix eip3155 summary gas_used bug and add fork name ([#1216](https://github.com/bluealloy/revm/pull/1216)) + +### Other +- use uint macro & fix various small things ([#1253](https://github.com/bluealloy/revm/pull/1253)) +- *(deps)* bump tokio from 1.36.0 to 1.37.0 ([#1244](https://github.com/bluealloy/revm/pull/1244)) +- *(interpreter)* unbox contract field ([#1228](https://github.com/bluealloy/revm/pull/1228)) +- *(primitives)* kzg intro ([#1209](https://github.com/bluealloy/revm/pull/1209)) +- *(interpreter)* keep track of remaining gas rather than spent ([#1221](https://github.com/bluealloy/revm/pull/1221)) +- Improve `EthersDB` ([#1208](https://github.com/bluealloy/revm/pull/1208)) + ## [7.2.0](https://github.com/bluealloy/revm/compare/revm-v7.1.0...revm-v7.2.0) - 2024-03-19 ### Added diff --git a/crates/revm/Cargo.toml b/crates/revm/Cargo.toml index 5eca3309dd..7141095ee2 100644 --- a/crates/revm/Cargo.toml +++ b/crates/revm/Cargo.toml @@ -6,7 +6,7 @@ keywords = ["no_std", "ethereum", "evm", "revm"] license = "MIT" name = "revm" repository = "https://github.com/bluealloy/revm" -version = "7.2.0" +version = "8.1.0" readme = "../../README.md" [package.metadata.docs.rs] @@ -15,8 +15,8 @@ rustdoc-args = ["--cfg", "docsrs"] [dependencies] # revm -revm-interpreter = { path = "../interpreter", version = "3.4.0", default-features = false } -revm-precompile = { path = "../precompile", version = "5.1.0", default-features = false } +revm-interpreter = { path = "../interpreter", version = "5.0.0", default-features = false } +revm-precompile = { path = "../precompile", version = "6.0.1", default-features = false } # misc auto_impl = { version = "1.2", default-features = false } @@ -33,19 +33,28 @@ serde_json = { version = "1.0", default-features = false, features = [ ], optional = true } # ethersdb -tokio = { version = "1.36", features = [ +tokio = { version = "1.37", features = [ "rt-multi-thread", "macros", ], optional = true } ethers-providers = { version = "2.0", optional = true } ethers-core = { version = "2.0", optional = true } +# alloydb +alloy-provider = { git = "https://github.com/alloy-rs/alloy.git", optional = true, default-features = false } +alloy-rpc-types = {git = "https://github.com/alloy-rs/alloy.git", optional = true, default-features = false } +alloy-transport = {git = "https://github.com/alloy-rs/alloy.git", optional = true, default-features = false } + [dev-dependencies] ethers-contract = { version = "2.0.14", default-features = false } anyhow = "1.0.81" criterion = "0.5" indicatif = "0.17" +alloy-provider = { git = "https://github.com/alloy-rs/alloy.git", default-features = false, features = ["reqwest"] } +# needed for enabling TLS to use HTTPS connections when testing alloy DB +alloy-transport-http = { git = "https://github.com/alloy-rs/alloy.git" } + [features] default = ["std", "c-kzg", "secp256k1", "portable"] std = [ @@ -82,6 +91,14 @@ ethersdb = [ "ethers-core", ] # Negate optimism default handler +alloydb = [ + "std", + "tokio", + "alloy-provider", + "alloy-rpc-types", + "alloy-transport", +] + dev = [ "memory_limit", "optional_balance_check", diff --git a/crates/revm/benches/bench.rs b/crates/revm/benches/bench.rs index 73253cbae9..9d07334692 100644 --- a/crates/revm/benches/bench.rs +++ b/crates/revm/benches/bench.rs @@ -114,7 +114,7 @@ fn bench_eval(g: &mut BenchmarkGroup<'_, WallTime>, evm: &mut Evm<'static, (), B // replace memory with empty memory to use it inside interpreter. // Later return memory back. let temp = core::mem::replace(&mut shared_memory, EMPTY_SHARED_MEMORY); - let mut interpreter = Interpreter::new(Box::new(contract.clone()), u64::MAX, false); + let mut interpreter = Interpreter::new(contract.clone(), u64::MAX, false); let res = interpreter.run(temp, &instruction_table, &mut host); shared_memory = interpreter.take_memory(); host.clear(); diff --git a/crates/revm/src/context.rs b/crates/revm/src/context.rs index e58699a766..aba8f27d53 100644 --- a/crates/revm/src/context.rs +++ b/crates/revm/src/context.rs @@ -17,7 +17,7 @@ use std::boxed::Box; /// Main Context structure that contains both EvmContext and External context. pub struct Context { - /// Evm Context. + /// Evm Context (internal context). pub evm: EvmContext, /// External contexts. pub external: EXT, diff --git a/crates/revm/src/context/evm_context.rs b/crates/revm/src/context/evm_context.rs index 89138641c2..5435722e7d 100644 --- a/crates/revm/src/context/evm_context.rs +++ b/crates/revm/src/context/evm_context.rs @@ -198,12 +198,12 @@ impl EvmContext { inputs.return_memory_offset.clone(), )) } else if !bytecode.is_empty() { - let contract = Box::new(Contract::new_with_context( + let contract = Contract::new_with_context( inputs.input.clone(), bytecode, code_hash, &inputs.context, - )); + ); // Create interpreter and executes call and push new CallStackFrame. Ok(FrameOrResult::new_call_frame( inputs.return_memory_offset.clone(), diff --git a/crates/revm/src/context/inner_evm_context.rs b/crates/revm/src/context/inner_evm_context.rs index 81af977877..16ffe8a2f2 100644 --- a/crates/revm/src/context/inner_evm_context.rs +++ b/crates/revm/src/context/inner_evm_context.rs @@ -113,6 +113,11 @@ impl InnerEvmContext { &mut self.env } + /// Returns the error by replacing it with `Ok(())`, if any. + pub fn take_error(&mut self) -> Result<(), EVMError> { + core::mem::replace(&mut self.error, Ok(())) + } + /// Fetch block hash from database. #[inline] pub fn block_hash(&mut self, number: U256) -> Result> { @@ -289,14 +294,14 @@ impl InnerEvmContext { let bytecode = Bytecode::new_raw(inputs.init_code.clone()); - let contract = Box::new(Contract::new( + let contract = Contract::new( Bytes::new(), bytecode, init_code_hash, created_address, inputs.caller, inputs.value, - )); + ); Ok(FrameOrResult::new_create_frame( created_address, diff --git a/crates/revm/src/db.rs b/crates/revm/src/db.rs index f891358034..bcb3aa463c 100644 --- a/crates/revm/src/db.rs +++ b/crates/revm/src/db.rs @@ -1,5 +1,7 @@ //! [Database] implementations. +#[cfg(feature = "alloydb")] +pub mod alloydb; pub mod emptydb; #[cfg(feature = "ethersdb")] pub mod ethersdb; @@ -7,6 +9,8 @@ pub mod in_memory_db; pub mod states; pub use crate::primitives::db::*; +#[cfg(feature = "alloydb")] +pub use alloydb::AlloyDB; pub use emptydb::{EmptyDB, EmptyDBTyped}; #[cfg(feature = "ethersdb")] pub use ethersdb::EthersDB; diff --git a/crates/revm/src/db/alloydb.rs b/crates/revm/src/db/alloydb.rs new file mode 100644 index 0000000000..a9541991d9 --- /dev/null +++ b/crates/revm/src/db/alloydb.rs @@ -0,0 +1,180 @@ +use crate::{ + db::{Database, DatabaseRef}, + primitives::{AccountInfo, Address, Bytecode, B256, KECCAK_EMPTY, U256}, +}; +use alloy_provider::{Network, Provider}; +use alloy_rpc_types::BlockId; +use alloy_transport::{Transport, TransportError}; +use tokio::runtime::{Builder, Handle}; + +/// An alloy-powered REVM [Database]. +/// +/// When accessing the database, it'll use the given provider to fetch the corresponding account's data. +#[derive(Debug, Clone)] +pub struct AlloyDB> { + /// The provider to fetch the data from. + provider: P, + /// The block number on which the queries will be based on. + block_number: Option, + _marker: std::marker::PhantomData (T, N)>, +} + +impl> AlloyDB { + /// Create a new AlloyDB instance, with a [Provider] and a block (Use None for latest). + pub fn new(provider: P, block_number: Option) -> Self { + Self { + provider, + block_number, + _marker: std::marker::PhantomData, + } + } + + /// Internal utility function that allows us to block on a future regardless of the runtime flavor. + #[inline] + fn block_on(f: F) -> F::Output + where + F: std::future::Future + Send, + F::Output: Send, + { + match Handle::try_current() { + Ok(handle) => match handle.runtime_flavor() { + // This is essentially equal to tokio::task::spawn_blocking because tokio doesn't + // allow the current_thread runtime to block_in_place. + // See for more info. + tokio::runtime::RuntimeFlavor::CurrentThread => std::thread::scope(move |s| { + s.spawn(move || { + Builder::new_current_thread() + .enable_all() + .build() + .unwrap() + .block_on(f) + }) + .join() + .unwrap() + }), + _ => tokio::task::block_in_place(move || handle.block_on(f)), + }, + Err(_) => Builder::new_current_thread() + .enable_all() + .build() + .unwrap() + .block_on(f), + } + } + + /// Set the block number on which the queries will be based on. + pub fn set_block_number(&mut self, block_number: Option) { + self.block_number = block_number; + } +} + +impl> DatabaseRef for AlloyDB { + type Error = TransportError; + + fn basic_ref(&self, address: Address) -> Result, Self::Error> { + let f = async { + let nonce = self + .provider + .get_transaction_count(address, self.block_number); + let balance = self.provider.get_balance(address, self.block_number); + let code = self + .provider + .get_code_at(address, self.block_number.unwrap_or_default()); + tokio::join!(nonce, balance, code) + }; + + let (nonce, balance, code) = Self::block_on(f); + + let balance = balance?; + let code = Bytecode::new_raw(code?.0.into()); + let code_hash = code.hash_slow(); + let nonce = nonce?; + + Ok(Some(AccountInfo::new( + balance, + nonce.to::(), + code_hash, + code, + ))) + } + + fn block_hash_ref(&self, number: U256) -> Result { + // Saturate usize + if number > U256::from(u64::MAX) { + return Ok(KECCAK_EMPTY); + } + + let block = Self::block_on( + self.provider + // SAFETY: We know number <= u64::MAX, so we can safely convert it to u64 + .get_block_by_number(number.to::().into(), false), + )?; + // SAFETY: If the number is given, the block is supposed to be finalized, so unwrapping is safe. + Ok(B256::new(*block.unwrap().header.hash.unwrap())) + } + + fn code_by_hash_ref(&self, _code_hash: B256) -> Result { + panic!("This should not be called, as the code is already loaded"); + // This is not needed, as the code is already loaded with basic_ref + } + + fn storage_ref(&self, address: Address, index: U256) -> Result { + let slot_val = Self::block_on(self.provider.get_storage_at( + address, + index, + self.block_number, + ))?; + Ok(slot_val) + } +} + +impl> Database for AlloyDB { + type Error = TransportError; + + #[inline] + fn basic(&mut self, address: Address) -> Result, Self::Error> { + ::basic_ref(self, address) + } + + #[inline] + fn code_by_hash(&mut self, code_hash: B256) -> Result { + ::code_by_hash_ref(self, code_hash) + } + + #[inline] + fn storage(&mut self, address: Address, index: U256) -> Result { + ::storage_ref(self, address, index) + } + + #[inline] + fn block_hash(&mut self, number: U256) -> Result { + ::block_hash_ref(self, number) + } +} + +#[cfg(test)] +mod tests { + use alloy_provider::ProviderBuilder; + + use super::*; + + #[test] + fn can_get_basic() { + let client = ProviderBuilder::new() + .on_reqwest_http( + "https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27" + .parse() + .unwrap(), + ) + .unwrap(); + let alloydb = AlloyDB::new(client, Some(BlockId::from(16148323))); + + // ETH/USDT pair on Uniswap V2 + let address: Address = "0x0d4a11d5EEaaC28EC3F61d100daF4d40471f1852" + .parse() + .unwrap(); + + let acc_info = alloydb.basic_ref(address).unwrap().unwrap(); + assert!(acc_info.exists()); + } +} diff --git a/crates/revm/src/evm.rs b/crates/revm/src/evm.rs index f6a1a692d8..239aa64eee 100644 --- a/crates/revm/src/evm.rs +++ b/crates/revm/src/evm.rs @@ -25,7 +25,7 @@ pub const CALL_STACK_LIMIT: u64 = 1024; pub struct Evm<'a, EXT, DB: Database> { /// Context of execution, containing both EVM and external context. pub context: Context, - /// Handler of EVM that contains all the logic. Handler contains specification id + /// Handler is a component of the of EVM that contains all the logic. Handler contains specification id /// and it different depending on the specified fork. pub handler: Handler<'a, Self, EXT, DB>, } @@ -217,7 +217,7 @@ impl Evm<'_, EXT, DB> { &mut self, first_frame: Frame, ) -> Result> { - // take instruction talbe + // take instruction table let table = self .handler .take_instruction_table() @@ -265,8 +265,8 @@ impl Evm<'_, EXT, DB> { let next_action = interpreter.run(shared_memory, instruction_table, self); // take error and break the loop if there is any. - // This error is set From Interpreter when its interacting with Host. - core::mem::replace(&mut self.context.evm.error, Ok(()))?; + // This error is set From Interpreter when it's interacting with Host. + self.context.evm.take_error()?; // take shared memory back. shared_memory = interpreter.take_memory(); diff --git a/crates/revm/src/frame.rs b/crates/revm/src/frame.rs index 3a7ade26e6..a48fd3c14c 100644 --- a/crates/revm/src/frame.rs +++ b/crates/revm/src/frame.rs @@ -12,7 +12,7 @@ use std::boxed::Box; pub struct CallFrame { /// Call frame has return memory range where output will be stored. pub return_memory_range: Range, - /// Frame data + /// Frame data. pub frame_data: FrameData, } @@ -20,15 +20,15 @@ pub struct CallFrame { pub struct CreateFrame { /// Create frame has a created address. pub created_address: Address, - /// Frame data + /// Frame data. pub frame_data: FrameData, } #[derive(Debug)] pub struct FrameData { - /// Journal checkpoint + /// Journal checkpoint. pub checkpoint: JournalCheckpoint, - /// Interpreter + /// Interpreter. pub interpreter: Interpreter, } diff --git a/crates/revm/src/handler.rs b/crates/revm/src/handler.rs index 6cd2e5b244..a6dfde551e 100644 --- a/crates/revm/src/handler.rs +++ b/crates/revm/src/handler.rs @@ -21,7 +21,7 @@ use self::register::{HandleRegister, HandleRegisterBox}; /// sections of the code. This allows nice integration of different chains or /// to disable some mainnet behavior. pub struct Handler<'a, H: Host + 'a, EXT, DB: Database> { - /// Handler config. + /// Handler configuration. pub cfg: HandlerCfg, /// Instruction table type. pub instruction_table: Option>, @@ -29,9 +29,9 @@ pub struct Handler<'a, H: Host + 'a, EXT, DB: Database> { pub registers: Vec>, /// Validity handles. pub validation: ValidationHandler<'a, EXT, DB>, - /// Pre execution handle + /// Pre execution handle. pub pre_execution: PreExecutionHandler<'a, EXT, DB>, - /// post Execution handle + /// Post Execution handle. pub post_execution: PostExecutionHandler<'a, EXT, DB>, /// Execution loop that handles frames. pub execution: ExecutionHandler<'a, EXT, DB>, @@ -40,7 +40,7 @@ pub struct Handler<'a, H: Host + 'a, EXT, DB: Database> { impl<'a, EXT, DB: Database> EvmHandler<'a, EXT, DB> { /// Created new Handler with given configuration. /// - /// Internaly it calls `mainnet_with_spec` with the given spec id. + /// Internally it calls `mainnet_with_spec` with the given spec id. /// Or `optimism_with_spec` if the optimism feature is enabled and `cfg.is_optimism` is set. pub fn new(cfg: HandlerCfg) -> Self { cfg_if::cfg_if! { @@ -85,7 +85,7 @@ impl<'a, EXT, DB: Database> EvmHandler<'a, EXT, DB> { handler } - /// Optimism with spec. Similar to [`Self::mainnet_with_spec`] + /// Optimism with spec. Similar to [`Self::mainnet_with_spec`]. #[cfg(feature = "optimism")] pub fn optimism_with_spec(spec_id: SpecId) -> Self { spec_to_generic!(spec_id, Self::optimism::()) @@ -185,7 +185,7 @@ impl<'a, EXT, DB: Database> EvmHandler<'a, EXT, DB> { let registers = core::mem::take(&mut self.registers); // register for optimism is added as a register, so we need to create mainnet handler here. let mut handler = Handler::mainnet_with_spec(spec_id); - // apply all registers to default handeler and raw mainnet instruction table. + // apply all registers to default handler and raw mainnet instruction table. for register in registers { handler.append_handler_register(register) } diff --git a/crates/revm/src/handler/mainnet/execution.rs b/crates/revm/src/handler/mainnet/execution.rs index 941d3b8fd4..f5c0eb2964 100644 --- a/crates/revm/src/handler/mainnet/execution.rs +++ b/crates/revm/src/handler/mainnet/execution.rs @@ -4,12 +4,11 @@ use crate::{ return_ok, return_revert, CallInputs, CreateInputs, CreateOutcome, Gas, InstructionResult, SharedMemory, }, - primitives::{EVMError, Env, Spec}, + primitives::{EVMError, Env, Spec, SpecId}, CallFrame, Context, CreateFrame, Frame, FrameOrResult, FrameResult, }; -use std::boxed::Box; - use revm_interpreter::{CallOutcome, InterpreterResult}; +use std::boxed::Box; /// Helper function called inside [`last_frame_return`] #[inline] @@ -44,7 +43,7 @@ pub fn frame_return_with_refund_flag( // gas spend. (Before london it was 2th part of gas spend) if refund_enabled { // EIP-3529: Reduction in refunds - gas.set_final_refund::(); + gas.set_final_refund(SPEC::SPEC_ID.is_enabled_in(SpecId::LONDON)); } } @@ -89,7 +88,7 @@ pub fn insert_call_outcome( shared_memory: &mut SharedMemory, outcome: CallOutcome, ) -> Result<(), EVMError> { - core::mem::replace(&mut context.evm.error, Ok(()))?; + context.evm.take_error()?; frame .frame_data_mut() .interpreter @@ -129,7 +128,7 @@ pub fn insert_create_outcome( frame: &mut Frame, outcome: CreateOutcome, ) -> Result<(), EVMError> { - core::mem::replace(&mut context.evm.error, Ok(()))?; + context.evm.take_error()?; frame .frame_data_mut() .interpreter @@ -139,10 +138,9 @@ pub fn insert_create_outcome( #[cfg(test)] mod tests { - use revm_interpreter::{primitives::CancunSpec, InterpreterResult}; - use revm_precompile::Bytes; - use super::*; + use revm_interpreter::primitives::CancunSpec; + use revm_precompile::Bytes; /// Creates frame result. fn call_last_frame_return(instruction_result: InstructionResult, gas: Gas) -> Gas { @@ -165,7 +163,7 @@ mod tests { fn test_consume_gas() { let gas = call_last_frame_return(InstructionResult::Stop, Gas::new(90)); assert_eq!(gas.remaining(), 90); - assert_eq!(gas.spend(), 10); + assert_eq!(gas.spent(), 10); assert_eq!(gas.refunded(), 0); } @@ -177,12 +175,12 @@ mod tests { let gas = call_last_frame_return(InstructionResult::Stop, return_gas); assert_eq!(gas.remaining(), 90); - assert_eq!(gas.spend(), 10); + assert_eq!(gas.spent(), 10); assert_eq!(gas.refunded(), 2); let gas = call_last_frame_return(InstructionResult::Revert, return_gas); assert_eq!(gas.remaining(), 90); - assert_eq!(gas.spend(), 10); + assert_eq!(gas.spent(), 10); assert_eq!(gas.refunded(), 0); } @@ -190,7 +188,7 @@ mod tests { fn test_revert_gas() { let gas = call_last_frame_return(InstructionResult::Revert, Gas::new(90)); assert_eq!(gas.remaining(), 90); - assert_eq!(gas.spend(), 10); + assert_eq!(gas.spent(), 10); assert_eq!(gas.refunded(), 0); } } diff --git a/crates/revm/src/handler/mainnet/post_execution.rs b/crates/revm/src/handler/mainnet/post_execution.rs index 6d70b4fedf..6230b882fc 100644 --- a/crates/revm/src/handler/mainnet/post_execution.rs +++ b/crates/revm/src/handler/mainnet/post_execution.rs @@ -42,7 +42,7 @@ pub fn reward_beneficiary( coinbase_account.info.balance = coinbase_account .info .balance - .saturating_add(coinbase_gas_price * U256::from(gas.spend() - gas.refunded() as u64)); + .saturating_add(coinbase_gas_price * U256::from(gas.spent() - gas.refunded() as u64)); Ok(()) } @@ -76,10 +76,10 @@ pub fn output( context: &mut Context, result: FrameResult, ) -> Result> { - core::mem::replace(&mut context.evm.error, Ok(()))?; + context.evm.take_error()?; // used gas with refund calculated. let gas_refunded = result.gas().refunded() as u64; - let final_gas_used = result.gas().spend() - gas_refunded; + let final_gas_used = result.gas().spent() - gas_refunded; let output = result.output(); let instruction_result = result.into_interpreter_result(); diff --git a/crates/revm/src/handler/mainnet/validation.rs b/crates/revm/src/handler/mainnet/validation.rs index 29c441f135..176e0e8282 100644 --- a/crates/revm/src/handler/mainnet/validation.rs +++ b/crates/revm/src/handler/mainnet/validation.rs @@ -43,7 +43,8 @@ pub fn validate_initial_tx_gas( let is_create = env.tx.transact_to.is_create(); let access_list = &env.tx.access_list; - let initial_gas_spend = gas::validate_initial_tx_gas::(input, is_create, access_list); + let initial_gas_spend = + gas::validate_initial_tx_gas(SPEC::SPEC_ID, input, is_create, access_list); // Additional check to see if limit is big enough to cover initial gas. if initial_gas_spend > env.tx.gas_limit { diff --git a/crates/revm/src/inspector/eip3155.rs b/crates/revm/src/inspector/eip3155.rs index fc9ae809cc..ca1f6cc574 100644 --- a/crates/revm/src/inspector/eip3155.rs +++ b/crates/revm/src/inspector/eip3155.rs @@ -1,6 +1,9 @@ use crate::{ inspectors::GasInspector, - interpreter::{opcode, CallInputs, CallOutcome, Interpreter}, + interpreter::{ + opcode, CallInputs, CallOutcome, CreateInputs, CreateOutcome, Interpreter, + InterpreterResult, + }, primitives::{db::Database, hex, HashMap, B256, U256}, EvmContext, Inspector, }; @@ -22,6 +25,8 @@ pub struct TracerEip3155 { refunded: i64, mem_size: usize, skip: bool, + include_memory: bool, + memory: Option, } // # Output @@ -58,7 +63,7 @@ struct Output { error: Option, /// Array of all allocated values #[serde(default, skip_serializing_if = "Option::is_none")] - memory: Option>, + memory: Option, /// Array of all stored values #[serde(default, skip_serializing_if = "Option::is_none")] storage: Option>, @@ -95,15 +100,41 @@ impl TracerEip3155 { pub fn set_writer(&mut self, writer: Box) { self.output = writer; } + + /// Resets the Tracer to its initial state of [Self::new]. + /// This makes the inspector ready to be used again. + pub fn clear(&mut self) { + let Self { + gas_inspector, + stack, + pc, + opcode, + gas, + refunded, + mem_size, + skip, + .. + } = self; + *gas_inspector = GasInspector::default(); + stack.clear(); + *pc = 0; + *opcode = 0; + *gas = 0; + *refunded = 0; + *mem_size = 0; + *skip = false; + } } impl TracerEip3155 { - pub fn new(output: Box, print_summary: bool) -> Self { + pub fn new(output: Box) -> Self { Self { output, gas_inspector: GasInspector::default(), - print_summary, + print_summary: true, + include_memory: false, stack: Default::default(), + memory: Default::default(), pc: 0, opcode: 0, gas: 0, @@ -113,11 +144,45 @@ impl TracerEip3155 { } } + /// Don't include a summary at the end of the trace + pub fn without_summary(mut self) -> Self { + self.print_summary = false; + self + } + + /// Include a memory field for each step. This significantly increases processing time and output size. + pub fn with_memory(mut self) -> Self { + self.include_memory = true; + self + } + fn write_value(&mut self, value: &impl serde::Serialize) -> std::io::Result<()> { serde_json::to_writer(&mut *self.output, value)?; self.output.write_all(b"\n")?; self.output.flush() } + + fn print_summary( + &mut self, + result: &InterpreterResult, + context: &mut EvmContext, + ) { + if self.print_summary { + let spec_name: &str = context.spec_id().into(); + let value = Summary { + state_root: B256::ZERO.to_string(), + output: result.output.to_string(), + gas_used: hex_number( + context.inner.env().tx.gas_limit - self.gas_inspector.gas_remaining(), + ), + pass: result.is_ok(), + + time: None, + fork: Some(spec_name.to_string()), + }; + let _ = self.write_value(&value); + } + } } impl Inspector for TracerEip3155 { @@ -128,6 +193,11 @@ impl Inspector for TracerEip3155 { fn step(&mut self, interp: &mut Interpreter, context: &mut EvmContext) { self.gas_inspector.step(interp, context); self.stack = interp.stack.data().clone(); + self.memory = if self.include_memory { + Some(hex::encode_prefixed(interp.shared_memory.context_memory())) + } else { + None + }; self.pc = interp.program_counter(); self.opcode = interp.current_opcode(); self.mem_size = interp.shared_memory.len(); @@ -159,7 +229,7 @@ impl Inspector for TracerEip3155 { } else { None }, - memory: None, + memory: self.memory.take(), storage: None, return_stack: None, }; @@ -173,19 +243,31 @@ impl Inspector for TracerEip3155 { outcome: CallOutcome, ) -> CallOutcome { let outcome = self.gas_inspector.call_end(context, inputs, outcome); - if self.print_summary && context.journaled_state.depth() == 0 { - let spec_name: &str = context.spec_id().into(); - let value = Summary { - state_root: B256::ZERO.to_string(), - output: outcome.result.output.to_string(), - gas_used: hex_number(inputs.gas_limit - self.gas_inspector.gas_remaining()), - pass: outcome.result.is_ok(), - time: None, - fork: Some(spec_name.to_string()), - }; - let _ = self.write_value(&value); + if context.journaled_state.depth() == 0 { + self.print_summary(&outcome.result, context); + // clear the state if we are at the top level + self.clear(); + } + + outcome + } + + fn create_end( + &mut self, + context: &mut EvmContext, + inputs: &CreateInputs, + outcome: CreateOutcome, + ) -> CreateOutcome { + let outcome = self.gas_inspector.create_end(context, inputs, outcome); + + if context.journaled_state.depth() == 0 { + self.print_summary(&outcome.result, context); + + // clear the state if we are at the top level + self.clear(); } + outcome } } diff --git a/crates/revm/src/inspector/gas.rs b/crates/revm/src/inspector/gas.rs index d22ae0451e..dc98bcaa95 100644 --- a/crates/revm/src/inspector/gas.rs +++ b/crates/revm/src/inspector/gas.rs @@ -35,14 +35,22 @@ impl Inspector for GasInspector { self.gas_remaining = interp.gas.limit(); } + fn step( + &mut self, + interp: &mut crate::interpreter::Interpreter, + _context: &mut EvmContext, + ) { + self.gas_remaining = interp.gas.remaining(); + } + fn step_end( &mut self, interp: &mut crate::interpreter::Interpreter, _context: &mut EvmContext, ) { - let last_gas_remaining = - core::mem::replace(&mut self.gas_remaining, interp.gas.remaining()); - self.last_gas_cost = last_gas_remaining.saturating_sub(self.gas_remaining); + let remaining = interp.gas.remaining(); + self.last_gas_cost = self.gas_remaining.saturating_sub(remaining); + self.gas_remaining = remaining; } fn call_end( @@ -65,8 +73,15 @@ impl Inspector for GasInspector { &mut self, _context: &mut EvmContext, _inputs: &CreateInputs, - outcome: CreateOutcome, + mut outcome: CreateOutcome, ) -> CreateOutcome { + if outcome.result.result.is_error() { + outcome + .result + .gas + .record_cost(outcome.result.gas.remaining()); + self.gas_remaining = 0; + } outcome } } diff --git a/crates/revm/src/inspector/handler_register.rs b/crates/revm/src/inspector/handler_register.rs index 0598c4f829..0cf496a480 100644 --- a/crates/revm/src/inspector/handler_register.rs +++ b/crates/revm/src/inspector/handler_register.rs @@ -133,7 +133,7 @@ pub fn inspector_handle_register<'a, DB: Database, EXT: GetInspector>( let call_input_stack = Rc::>>::new(RefCell::new(Vec::new())); let create_input_stack = Rc::>>::new(RefCell::new(Vec::new())); - // Create handle + // Create handler let create_input_stack_inner = create_input_stack.clone(); let old_handle = handler.execution.create.clone(); handler.execution.create = Arc::new( @@ -260,26 +260,23 @@ pub fn inspector_instruction< #[cfg(test)] mod tests { - use super::*; use crate::{ db::EmptyDB, inspectors::NoOpInspector, - interpreter::{opcode::*, CallInputs, CreateInputs, Interpreter}, + interpreter::{opcode::*, CallInputs, CallOutcome, CreateInputs, CreateOutcome}, primitives::BerlinSpec, - Database, Evm, EvmContext, Inspector, + EvmContext, }; - use revm_interpreter::{CallOutcome, CreateOutcome}; - + // Test that this pattern builds. #[test] fn test_make_boxed_instruction_table() { - // test that this pattern builds. - let inst: InstructionTable> = - make_instruction_table::, BerlinSpec>(); - let _test: BoxedInstructionTable<'_, Evm<'_, _, _>> = - make_boxed_instruction_table::<'_, Evm<'_, NoOpInspector, EmptyDB>, BerlinSpec, _>( - inst, + type MyEvm<'a> = Evm<'a, NoOpInspector, EmptyDB>; + let table: InstructionTable> = make_instruction_table::, BerlinSpec>(); + let _boxed_table: BoxedInstructionTable<'_, MyEvm<'_>> = + make_boxed_instruction_table::<'_, MyEvm<'_>, BerlinSpec, _>( + table, inspector_instruction, ); } diff --git a/crates/revm/src/optimism/handler_register.rs b/crates/revm/src/optimism/handler_register.rs index 0bc348dc9e..600d6709d0 100644 --- a/crates/revm/src/optimism/handler_register.rs +++ b/crates/revm/src/optimism/handler_register.rs @@ -133,7 +133,7 @@ pub fn last_frame_return( // Prior to Regolith, deposit transactions did not receive gas refunds. let is_gas_refund_disabled = env.cfg.is_gas_refund_disabled() || (is_deposit && !is_regolith); if !is_gas_refund_disabled { - gas.set_final_refund::(); + gas.set_final_refund(SPEC::SPEC_ID.is_enabled_in(SpecId::LONDON)); } Ok(()) } @@ -272,7 +272,7 @@ pub fn reward_beneficiary( .env .block .basefee - .mul(U256::from(gas.spend() - gas.refunded() as u64)); + .mul(U256::from(gas.spent() - gas.refunded() as u64)); } Ok(()) } @@ -410,7 +410,7 @@ mod tests { let gas = call_last_frame_return::(env, InstructionResult::Revert, Gas::new(90)); assert_eq!(gas.remaining(), 90); - assert_eq!(gas.spend(), 10); + assert_eq!(gas.spent(), 10); assert_eq!(gas.refunded(), 0); } @@ -423,7 +423,7 @@ mod tests { let gas = call_last_frame_return::(env, InstructionResult::Stop, Gas::new(90)); assert_eq!(gas.remaining(), 90); - assert_eq!(gas.spend(), 10); + assert_eq!(gas.spent(), 10); assert_eq!(gas.refunded(), 0); } @@ -439,12 +439,12 @@ mod tests { let gas = call_last_frame_return::(env.clone(), InstructionResult::Stop, ret_gas); assert_eq!(gas.remaining(), 90); - assert_eq!(gas.spend(), 10); + assert_eq!(gas.spent(), 10); assert_eq!(gas.refunded(), 2); // min(20, 10/5) let gas = call_last_frame_return::(env, InstructionResult::Revert, ret_gas); assert_eq!(gas.remaining(), 90); - assert_eq!(gas.spend(), 10); + assert_eq!(gas.spent(), 10); assert_eq!(gas.refunded(), 0); } @@ -456,7 +456,7 @@ mod tests { let gas = call_last_frame_return::(env, InstructionResult::Stop, Gas::new(90)); assert_eq!(gas.remaining(), 0); - assert_eq!(gas.spend(), 100); + assert_eq!(gas.spent(), 100); assert_eq!(gas.refunded(), 0); } diff --git a/documentation/src/SUMMARY.md b/documentation/src/SUMMARY.md index a4c9db1a25..05a9255851 100644 --- a/documentation/src/SUMMARY.md +++ b/documentation/src/SUMMARY.md @@ -27,6 +27,7 @@ - [precompile](./crates/primitives/precompile.md) - [state](./crates/primitives/state.md) - [utils](./crates/primitives/utils.md) + - [kzg](./crates/primitives/kzg.md) - [Precompile](./crates/precompile.md) - [blake2](./crates/precompile/blake2.md) - [bn128 curve](./crates/precompile/bn128.md) diff --git a/documentation/src/crates/interpreter/instructions.md b/documentation/src/crates/interpreter/instructions.md index 7835718131..84b5b8a857 100644 --- a/documentation/src/crates/interpreter/instructions.md +++ b/documentation/src/crates/interpreter/instructions.md @@ -10,6 +10,6 @@ The `Opcode` enum represents the opcodes that are available in the Ethereum Virt The `Instruction` struct represents a single instruction in the EVM. It contains the opcode, which is the operation to be performed, and a list of bytes representing the operands for the instruction. -## `execute` Function +## `step` Function -The `execute` function interprets an instruction. It uses the opcode to determine what operation to perform and then performs the operation using the operands in the instruction. \ No newline at end of file +The `step` function interprets an instruction. It uses the opcode to determine what operation to perform and then performs the operation using the operands in the instruction. \ No newline at end of file diff --git a/documentation/src/crates/precompile.md b/documentation/src/crates/precompile.md index e4f82c73ae..643ba75942 100644 --- a/documentation/src/crates/precompile.md +++ b/documentation/src/crates/precompile.md @@ -11,6 +11,7 @@ There are 6 precompiles implemented in REVM, and they are: `blake2`, `bn128` cur - [bn128](./precompile/bn128.md): Implements precompiled contracts for addition, scalar multiplication, and optimal ate pairing check on the `alt_bn128` elliptic curve. - [hash](./precompile/hash.md): Implements the `SHA256` and `RIPEMD160` hash functions. - [identity](./precompile/identity.md): Implements the `Identity` precompile, which returns the input data unchanged. +- [point_evaluation](./precompile/point_evaluation.md): Implements the point evaluation precompile for [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844). - [modexp](./precompile/modexp.md): Implements the big integer modular exponentiation precompile. - [secp256k1](./precompile/secp256k1.md): Implements the ECDSA public key recovery precompile, based on `secp256k1` curves. @@ -42,5 +43,5 @@ There are 6 precompiles implemented in REVM, and they are: `blake2`, `bn128` cur ### Re-exported Functionality: -- `Precompiles` provides a static method for each Ethereum hard fork specification (e.g., `homestead`, `byzantium`, `istanbul`, `berlin`, and `latest`), each returning a set of precompiles for that specification. +- `Precompiles` provides a static method for each Ethereum hard fork specification (e.g., `homestead`, `byzantium`, `istanbul`, `berlin`, `cancun`, and `latest`), each returning a set of precompiles for that specification. - `Precompiles` also provides methods to retrieve the list of precompile addresses (`addresses`), to check if a given address is a precompile (`contains`), to get the precompile at a given address (`get`), to check if there are no precompiles (`is_empty`), and to get the number of precompiles (`len`). diff --git a/documentation/src/crates/precompile/point_evaluation.md b/documentation/src/crates/precompile/point_evaluation.md index 9356a89a9f..df982cfe43 100644 --- a/documentation/src/crates/precompile/point_evaluation.md +++ b/documentation/src/crates/precompile/point_evaluation.md @@ -1,6 +1,5 @@ # Point Evaluation Precompile -This precompile is introduced in [EIP4844](https://eips.ethereum.org/EIPS/eip-4844) and is used to verify KZG commitments of blobspace. The precompile allows for efficient verification of commitments to blog transactions. The blob-space transaction contains a large amount of data that cannot be accessed by EVM execution, but has a commitment that can be accessed and verified. The EIP is designed to be forward compatible with danksharding architecture while giving L2s access to cheaper L1 commitments. This precompiled contract resides at the hardcoded Ethereum address `0x000000000000000000000000000000000000000A`. +This precompile is introduced in [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844) and is used to verify KZG commitments of blobs. The precompile allows for efficient verification of commitments to blob transactions. Blob transactions contain a large amount of data that cannot be accessed by EVM execution, but has a commitment that can be accessed and verified. The EIP is designed to be forward compatible with [Danksharding](https://ethereum.org/en/roadmap/danksharding/) architecture while giving L2s access to cheaper L1 commitments. This precompiled contract resides at the hardcoded Ethereum address `0x000000000000000000000000000000000000000A`. - -A useful resource is the python reference implementation for the precompile, which can be found [here](https://github.com/ethereum/consensus-specs/blob/86fb82b221474cc89387fa6436806507b3849d88/specs/deneb/polynomial-commitments.md). This implementation uses the [c-kzg](https://github.com/ethereum/c-kzg-4844) audited foreign function interface bindings from the Ethereum Foundation. \ No newline at end of file +A useful resource is the Python reference implementation for the precompile, which can be found [here](https://github.com/ethereum/consensus-specs/blob/86fb82b221474cc89387fa6436806507b3849d88/specs/deneb/polynomial-commitments.md). The implementation in REVM uses [c-kzg-4844](https://github.com/ethereum/c-kzg-4844), via its [foreign function interface](https://en.wikipedia.org/wiki/Foreign_function_interface) bindings, from the Ethereum Foundation. \ No newline at end of file diff --git a/documentation/src/crates/precompile/secp256k1.md b/documentation/src/crates/precompile/secp256k1.md index 757fa577a1..4146448c1e 100644 --- a/documentation/src/crates/precompile/secp256k1.md +++ b/documentation/src/crates/precompile/secp256k1.md @@ -1,6 +1,6 @@ # Secp256k1 -This implementation Ethereum's precompiled contract `ECRECOVER`, an elliptic curve digital signature algorithm (ECDSA) recovery function that recovers the Ethereum address (public key hash) associated with a given signature. The implementation features two versions, each contingent on whether the secp256k1 cryptographic library is enabled, which depends on the build configuration. +This implements Ethereum's precompiled contract `ECRECOVER`, an elliptic curve digital signature algorithm (ECDSA) recovery function that recovers the Ethereum address (public key hash) associated with a given signature. The implementation features two versions, each contingent on whether the secp256k1 cryptographic library is enabled, which depends on the build configuration. Both versions define a `secp256k1` module that includes an `ecrecover` function. This function takes a digital signature and a message as input, both represented as byte arrays, and returns the recovered Ethereum address. It performs this operation by using the signature to recover the original public key used for signing, then hashing this public key with `Keccak256`, Ethereum's chosen hash function. The hash is then truncated to match Ethereum's 20-byte address size. diff --git a/documentation/src/crates/primitives.md b/documentation/src/crates/primitives.md index 013458daa0..bc058e5a1d 100644 --- a/documentation/src/crates/primitives.md +++ b/documentation/src/crates/primitives.md @@ -17,6 +17,7 @@ It is set up to be compatible with environments that do not include Rust's stand - [specification](./primitives/specifications.md): This module defines types related to Ethereum specifications (also known as hard forks). - [state](./primitives/state.md): This module provides types and functions for managing Ethereum state, including accounts and storage. - [utilities](./primitives/utils.md): This module provides utility functions used in multiple places across the EVM implementation. +- [kzg](./primitives/kzg.md): This module provides types and functions related to KZG commitment, it is empolyed visibly in the Point Evalution Precompile. ### External Crates: @@ -27,6 +28,7 @@ It is set up to be compatible with environments that do not include Rust's stand - `hex_literal`: The hex_literal crate provides a macro for including hexadecimal data directly in the source code. - `hashbrown`: The hashbrown crate provides high-performance hash map and hash set data structures. - `ruint`: The ruint crate provides types and functions for big unsigned integer arithmetic. +- `c-kzg`: A minimal implementation of the Polynomial Commitments API for EIP-4844, written in C. (With rust bindings) ### Type Aliases: @@ -40,5 +42,5 @@ It is set up to be compatible with environments that do not include Rust's stand - `U256`: A 256-bit unsigned integer type from the `ruint` crate. - `HashMap` and `HashSet`: High-performance hash map and hash set data structures from the hashbrown crate. -### Re-exported Modules: -All types, constants, and functions from the `bytecode`, `constants`, `env`, `log`, `precompile`, `result`, `specification`, `state`, and `utilities` modules are re-exported, allowing users to import these items directly from the `primitives` crate. +Re-exported Modules: +All types, constants, and functions from the `bytecode`, `constants`, `env`, `log`, `precompile`, `result`, `specification`, `state`, `utilities`, `KzgSettings`, `EnvKzgSettings`, `trusted_setup_points` types and methods were all re-exported, allowing users to import these items directly from the `primitives` crate. diff --git a/documentation/src/crates/primitives/kzg.md b/documentation/src/crates/primitives/kzg.md new file mode 100644 index 0000000000..7e7e6316d3 --- /dev/null +++ b/documentation/src/crates/primitives/kzg.md @@ -0,0 +1,12 @@ +# KZG + +With the introduction of [EIP4844](https://eips.ethereum.org/EIPS/eip-4844), this use of blobs for a more efficent short term storage is employed, the validity of this blob stored in the consensus layer is verified using the `Point Evaluation` pre-compile, a fancy way of verifing that and evaluation at a given point of a commited polynomial is vaild, in a much more bigger scale, implies that `Data is Available`. + +This module houses; + +1. `KzgSettings`: Stores the setup and parameters needed for computing and verify KZG proofs. + + The `KZG` premitive provides a default `KZGSettings` obtained from [this]( https://ceremony.ethereum.org/) trusted setup ceremony, a provision is also made for using a custom `KZGSettings` if need be, this is available in the `env.cfg`. + + +2. `trusted_setup_points`: This module contains functions and types used for parsing and utilizing the [Trusted Setup]( https://ceremony.ethereum.org/) for the `KzgSettings`. \ No newline at end of file diff --git a/documentation/src/crates/revm.md b/documentation/src/crates/revm.md index ed17b8d7d5..2ad609f40a 100644 --- a/documentation/src/crates/revm.md +++ b/documentation/src/crates/revm.md @@ -4,7 +4,7 @@ The `evm` crate is focused on the implementation of Ethereum Virtual Machine (EV This crate pulls Primitives, Interpreter and Precompiles together to deliver the rust evm. The starting point for reading the documentation is [`Evm`](./revm/evm.md), that is main structure of EVM. -Then, I read about the [`EvmBuilder`](./revm/builder.md) that is used to create the `Evm` and modify it. +Then, you can read about the [`EvmBuilder`](./revm/builder.md) that is used to create the `Evm` and modify it. After, you can read about the [`Handler`](./revm/handler.md) that is used to modify the logic of the Evm, and it will tie with how Evm introspection can be done. Finally, you can read about the [`Inspector`](./revm/inspector.md), a legacy interface for inspecting execution that is now repurposed as a handler register example. @@ -34,6 +34,6 @@ Finally, you can read about the [`Inspector`](./revm/inspector.md), a legacy int - `Database`, `DatabaseCommit`, `InMemoryDB`: These types from the `db` module are re-exported for handling the database operations. - `EVM`: The `EVM` struct from the `evm` module is re-exported, serving as the main interface to the EVM implementation. -- `EvmContext`: The `EvmContext` struct from the `evm_impl` module is re-exported, providing data structures to encapsulate EVM execution data. +- `EvmContext`: The `EvmContext` struct from the `context` module is re-exported, providing data structures to encapsulate EVM execution data. - `JournalEntry`, `JournaledState`: These types from the `journaled_state` module are re-exported, providing the journaling system for the EVM state. - `inspectors`, `Inspector`: The `Inspector` trait and its implementations from the `inspector` module are re-exported for observing the EVM execution. diff --git a/documentation/src/crates/revm/handler.md b/documentation/src/crates/revm/handler.md index 7980f087a0..5e9c14fb98 100644 --- a/documentation/src/crates/revm/handler.md +++ b/documentation/src/crates/revm/handler.md @@ -33,7 +33,7 @@ They are called in the following order: * `validate_env`: Verifies if all data is set in `Environment` and if valid, for example if `gas_limit` is smaller than block `gas_limit`. * `validate_initial_tx_gas`: - Calculates initial gas needed for the transaction to be executed and checks if it is less them the transaction gas_limit. + Calculates initial gas needed for the transaction to be executed and checks if it is less than the transaction gas_limit. Note that this does not touch the `Database` or state. * `validate_tx_against_state`: Loads the caller account and checks their information. diff --git a/documentation/src/crates/revm/state.md b/documentation/src/crates/revm/state.md index ebeafb20a1..5951f3cdd7 100644 --- a/documentation/src/crates/revm/state.md +++ b/documentation/src/crates/revm/state.md @@ -14,7 +14,7 @@ You can implement the traits `Database`, `DatabaseRef` or `Database + DatabaseCo - `DatabaseRef`: Takes a reference on the object. It is useful if you only have a reference on the state and don't want to update anything on it. - It enables `previerify_transaction`, `transact_preverified_ref`, `transact_ref` and `inspect_ref` functions. + It enables `preverify_transaction`, `transact_preverified_ref`, `transact_ref` and `inspect_ref` functions. - `Database + DatabaseCommit`: Allows directly committing changes of a transaction. It enables `transact_commit` and `inspect_commit` functions. diff --git a/examples/db_by_ref.rs b/examples/db_by_ref.rs index c9094a905b..9e3615400c 100644 --- a/examples/db_by_ref.rs +++ b/examples/db_by_ref.rs @@ -72,7 +72,7 @@ fn run_transaction_and_commit(db: &mut CacheDB) -> anyhow::Result<()> { fn main() -> anyhow::Result<()> { let mut cache_db = CacheDB::new(EmptyDB::default()); - let mut tracer = TracerEip3155::new(Box::new(std::io::stdout()), true); + let mut tracer = TracerEip3155::new(Box::new(std::io::stdout())); run_transaction_and_commit_with_ext(&mut cache_db, &mut tracer, inspector_handle_register)?; run_transaction_and_commit(&mut cache_db)?; diff --git a/examples/generate_block_traces.rs b/examples/generate_block_traces.rs index 37a1550778..cfd8f030c1 100644 --- a/examples/generate_block_traces.rs +++ b/examples/generate_block_traces.rs @@ -13,6 +13,7 @@ use std::io::BufWriter; use std::io::Write; use std::sync::Arc; use std::sync::Mutex; +use std::time::Instant; macro_rules! local_fill { ($left:expr, $right:expr, $fun:expr) => { @@ -76,7 +77,7 @@ async fn main() -> anyhow::Result<()> { let mut state = StateBuilder::new_with_database(cache_db).build(); let mut evm = Evm::builder() .with_db(&mut state) - .with_external_context(TracerEip3155::new(Box::new(std::io::stdout()), true)) + .with_external_context(TracerEip3155::new(Box::new(std::io::stdout()))) .modify_block_env(|b| { if let Some(number) = block.number { let nn = number.0[0]; @@ -100,7 +101,7 @@ async fn main() -> anyhow::Result<()> { println!("Found {txs} transactions."); let console_bar = Arc::new(ProgressBar::new(txs as u64)); - let elapsed = std::time::Duration::ZERO; + let start = Instant::now(); // Create the traces directory if it doesn't exist std::fs::create_dir_all("traces").expect("Failed to create traces directory"); @@ -176,6 +177,8 @@ async fn main() -> anyhow::Result<()> { } console_bar.finish_with_message("Finished all transactions."); + + let elapsed = start.elapsed(); println!( "Finished execution. Total CPU time: {:.6}s", elapsed.as_secs_f64() diff --git a/publish.sh b/publish.sh new file mode 100755 index 0000000000..b6944ae0f1 --- /dev/null +++ b/publish.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +# stop on error +set -e + +cargo publish --package revm-primitives +cargo publish --package revm-precompile +cargo publish --package revm-interpreter +cargo publish --package revm +cargo publish --package revme + +echo "All crates published"