From 330c682122bbac815d400e7a36b9ecb3d2287486 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 10 Feb 2026 14:12:05 +0100 Subject: [PATCH 001/189] Brutally copy the `sp1-crates` directory from wakabat fork --- sp1-crates/.cargo/config.toml | 2 + sp1-crates/.gitignore | 1 + sp1-crates/Cargo.lock | 7363 +++++++++++++++++ sp1-crates/Cargo.toml | 84 + sp1-crates/README.md | 79 + sp1-crates/build.sh | 36 + sp1-crates/builder/Cargo.toml | 17 + sp1-crates/builder/build.rs | 4 + sp1-crates/builder/src/main.rs | 136 + sp1-crates/program/Cargo.toml | 30 + sp1-crates/program/src/imports/arbcompress.rs | 87 + sp1-crates/program/src/imports/debug.rs | 43 + sp1-crates/program/src/imports/mod.rs | 13 + sp1-crates/program/src/imports/precompiles.rs | 61 + sp1-crates/program/src/imports/programs.rs | 293 + sp1-crates/program/src/imports/vm_hooks.rs | 734 ++ sp1-crates/program/src/imports/wasi_stub.rs | 339 + sp1-crates/program/src/imports/wavmio.rs | 303 + sp1-crates/program/src/lib.rs | 157 + sp1-crates/program/src/main.rs | 27 + sp1-crates/program/src/platform.rs | 19 + sp1-crates/program/src/replay.rs | 403 + sp1-crates/program/src/stylus.rs | 687 ++ sp1-crates/prover/Cargo.toml | 33 + sp1-crates/prover/src/binary_input.rs | 111 + sp1-crates/prover/src/lib.rs | 25 + sp1-crates/runner/Cargo.toml | 17 + sp1-crates/runner/src/main.rs | 181 + sp1-crates/rust-toolchain.toml | 2 + sp1-crates/stylus-compiler-program/Cargo.toml | 10 + .../stylus-compiler-program/src/main.rs | 60 + 31 files changed, 11357 insertions(+) create mode 100644 sp1-crates/.cargo/config.toml create mode 100644 sp1-crates/.gitignore create mode 100644 sp1-crates/Cargo.lock create mode 100644 sp1-crates/Cargo.toml create mode 100644 sp1-crates/README.md create mode 100755 sp1-crates/build.sh create mode 100644 sp1-crates/builder/Cargo.toml create mode 100644 sp1-crates/builder/build.rs create mode 100644 sp1-crates/builder/src/main.rs create mode 100644 sp1-crates/program/Cargo.toml create mode 100644 sp1-crates/program/src/imports/arbcompress.rs create mode 100644 sp1-crates/program/src/imports/debug.rs create mode 100644 sp1-crates/program/src/imports/mod.rs create mode 100644 sp1-crates/program/src/imports/precompiles.rs create mode 100644 sp1-crates/program/src/imports/programs.rs create mode 100644 sp1-crates/program/src/imports/vm_hooks.rs create mode 100644 sp1-crates/program/src/imports/wasi_stub.rs create mode 100644 sp1-crates/program/src/imports/wavmio.rs create mode 100644 sp1-crates/program/src/lib.rs create mode 100644 sp1-crates/program/src/main.rs create mode 100644 sp1-crates/program/src/platform.rs create mode 100644 sp1-crates/program/src/replay.rs create mode 100644 sp1-crates/program/src/stylus.rs create mode 100644 sp1-crates/prover/Cargo.toml create mode 100644 sp1-crates/prover/src/binary_input.rs create mode 100644 sp1-crates/prover/src/lib.rs create mode 100644 sp1-crates/runner/Cargo.toml create mode 100644 sp1-crates/runner/src/main.rs create mode 100644 sp1-crates/rust-toolchain.toml create mode 100644 sp1-crates/stylus-compiler-program/Cargo.toml create mode 100644 sp1-crates/stylus-compiler-program/src/main.rs diff --git a/sp1-crates/.cargo/config.toml b/sp1-crates/.cargo/config.toml new file mode 100644 index 00000000000..c91c3f38b7b --- /dev/null +++ b/sp1-crates/.cargo/config.toml @@ -0,0 +1,2 @@ +[net] +git-fetch-with-cli = true diff --git a/sp1-crates/.gitignore b/sp1-crates/.gitignore new file mode 100644 index 00000000000..eb5a316cbd1 --- /dev/null +++ b/sp1-crates/.gitignore @@ -0,0 +1 @@ +target diff --git a/sp1-crates/Cargo.lock b/sp1-crates/Cargo.lock new file mode 100644 index 00000000000..019c782a021 --- /dev/null +++ b/sp1-crates/Cargo.lock @@ -0,0 +1,7363 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "addchain" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2e69442aa5628ea6951fa33e24efe8313f4321a91bd729fc2f75bdfc858570" +dependencies = [ + "num-bigint 0.3.3", + "num-integer", + "num-traits", +] + +[[package]] +name = "addr2line" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + +[[package]] +name = "anstream" +version = "0.6.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" + +[[package]] +name = "anstyle-parse" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.61.2", +] + +[[package]] +name = "anyhow" +version = "1.0.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" + +[[package]] +name = "arbutil" +version = "0.1.0" +dependencies = [ + "digest", + "eyre", + "fnv", + "hex", + "num-traits", + "num_enum 0.7.5", + "ruint2", + "serde", + "siphasher 0.3.11", + "tiny-keccak 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmparser 0.121.2", +] + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "derivative", + "digest", + "itertools 0.10.5", + "num-bigint 0.4.6", + "num-traits", + "paste", + "rustc_version", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint 0.4.6", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-std", + "digest", + "num-bigint 0.4.6", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "async-scoped" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4042078ea593edffc452eef14e99fdb2b120caa4ad9618bcdeabc4a023b98740" +dependencies = [ + "futures", + "pin-project", + "tokio", +] + +[[package]] +name = "async-stream" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "async-trait" +version = "0.1.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "atomic" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89cbf775b137e9b968e67227ef7f775587cde3fd31b0d8599dbd0f598a48340" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "axum" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" +dependencies = [ + "async-trait", + "axum-core", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper", + "tower 0.5.2", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "rustversion", + "sync_wrapper", + "tower-layer", + "tower-service", +] + +[[package]] +name = "backtrace" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object 0.37.3", + "rustc-demangle", + "serde", + "windows-link", +] + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "base64ct" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e050f626429857a27ddccb31e0aca21356bfa709c04041aefddac081a8f068a" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bindgen" +version = "0.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" +dependencies = [ + "bitflags 2.10.0", + "cexpr", + "clang-sys", + "itertools 0.13.0", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash 1.1.0", + "shlex", + "syn 2.0.111", +] + +[[package]] +name = "bindgen" +version = "0.72.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" +dependencies = [ + "bitflags 2.10.0", + "cexpr", + "clang-sys", + "itertools 0.13.0", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash 2.1.1", + "shlex", + "syn 2.0.111", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest", +] + +[[package]] +name = "blake2b_simd" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06e903a20b159e944f91ec8499fe1e55651480c541ea0a584f5d967c49ad9d99" +dependencies = [ + "arrayref", + "arrayvec", + "constant_time_eq", +] + +[[package]] +name = "blake3" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "bls12_381" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3c196a77437e7cc2fb515ce413a6401291578b5afc8ecb29a3c7ab957f05941" +dependencies = [ + "ff 0.12.1", + "group 0.12.1", + "pairing", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "brotli" +version = "8.0.1" +source = "git+https://github.com/wakabat/rust-brotli?rev=37b6403#37b6403c1075625e15b9355bcedf8b20232bc6c2" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "bumpalo" +version = "3.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" + +[[package]] +name = "byte-slice-cast" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7575182f7272186991736b70173b0ea045398f984bf5ebbb3804736ce1330c9d" + +[[package]] +name = "bytecheck" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0caa33a2c0edca0419d15ac723dff03f1956f7978329b1e3b5fdaaaed9d3ca8b" +dependencies = [ + "bytecheck_derive", + "ptr_meta", + "rancor", + "simdutf8", +] + +[[package]] +name = "bytecheck_derive" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89385e82b5d1821d2219e0b095efa2cc1f246cbf99080f3be46a1a85c0d392d9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "bytemuck" +version = "1.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" + +[[package]] +name = "camino" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e629a66d692cb9ff1a1c664e41771b3dcaf961985a9774c0eb0bd1b51cf60a48" +dependencies = [ + "serde_core", +] + +[[package]] +name = "cargo-platform" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror 1.0.69", +] + +[[package]] +name = "cc" +version = "1.2.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f50d563227a1c37cc0a263f64eca3334388c01c5e4c4861a9def205c614383c" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "chrono" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" +dependencies = [ + "iana-time-zone", + "num-traits", + "serde", + "windows-link", +] + +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "clap" +version = "4.5.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "clap_lex" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" + +[[package]] +name = "cmake" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d" +dependencies = [ + "cc", +] + +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + +[[package]] +name = "console" +version = "0.15.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" +dependencies = [ + "encode_unicode", + "libc", + "once_cell", + "unicode-width 0.2.2", + "windows-sys 0.59.0", +] + +[[package]] +name = "const-default" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b396d1f76d455557e1218ec8066ae14bba60b4b36ecd55577ba979f5db7ecaa" + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "const_format" +version = "0.2.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7faa7469a93a566e9ccc1c73fe783b4a65c274c5ace346038dca9c39fe0030ad" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "convert_case" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "corosensei" +version = "0.3.2" +source = "git+https://github.com/wakabat/corosensei?branch=patch-v0.3.2#08e582a7492621acb09318eab166a96715f3eebd" +dependencies = [ + "autocfg", + "cfg-if", + "libc", + "scopeguard", + "sp1-primitives 6.0.0", + "sp1-zkvm", + "windows-sys 0.59.0", +] + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" + +[[package]] +name = "crossbeam" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-epoch", + "crossbeam-queue", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array 0.14.7", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array 0.14.7", + "typenum", +] + +[[package]] +name = "darling" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.111", +] + +[[package]] +name = "darling_macro" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "dashmap" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "dashu" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b3e5ac1e23ff1995ef05b912e2b012a8784506987a2651552db2c73fb3d7e0" +dependencies = [ + "dashu-base", + "dashu-float", + "dashu-int", + "dashu-macros", + "dashu-ratio", + "rustversion", +] + +[[package]] +name = "dashu-base" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0b80bf6b85aa68c58ffea2ddb040109943049ce3fbdf4385d0380aef08ef289" + +[[package]] +name = "dashu-float" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85078445a8dbd2e1bd21f04a816f352db8d333643f0c9b78ca7c3d1df71063e7" +dependencies = [ + "dashu-base", + "dashu-int", + "num-modular", + "num-order", + "rustversion", + "static_assertions", +] + +[[package]] +name = "dashu-int" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee99d08031ca34a4d044efbbb21dff9b8c54bb9d8c82a189187c0651ffdb9fbf" +dependencies = [ + "cfg-if", + "dashu-base", + "num-modular", + "num-order", + "rustversion", + "static_assertions", +] + +[[package]] +name = "dashu-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93381c3ef6366766f6e9ed9cf09e4ef9dec69499baf04f0c60e70d653cf0ab10" +dependencies = [ + "dashu-base", + "dashu-float", + "dashu-int", + "dashu-ratio", + "paste", + "proc-macro2", + "quote", + "rustversion", +] + +[[package]] +name = "dashu-ratio" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47e33b04dd7ce1ccf8a02a69d3419e354f2bbfdf4eb911a0b7465487248764c9" +dependencies = [ + "dashu-base", + "dashu-float", + "dashu-int", + "num-modular", + "num-order", + "rustversion", +] + +[[package]] +name = "debugid" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d" +dependencies = [ + "uuid", +] + +[[package]] +name = "deepsize2" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b5184084af9beed35eecbf4c36baf6e26b9dc47b61b74e02f930c72a58e71b" +dependencies = [ + "deepsize_derive2", + "hashbrown 0.14.5", +] + +[[package]] +name = "deepsize_derive2" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0f8817865cacf3b93b943ca06b0fc5fd8e99eabfdb7ea5d296efcbc4afc4f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "deranged" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" +dependencies = [ + "powerfmt", + "serde_core", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive-where" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef941ded77d15ca19b40374869ac6000af1c9f2a4c0f3d4c70926287e6364a8f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "derive_more" +version = "0.99.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" +dependencies = [ + "convert_case 0.4.0", + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.111", +] + +[[package]] +name = "derive_more" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" +dependencies = [ + "derive_more-impl 1.0.0", +] + +[[package]] +name = "derive_more" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10b768e943bed7bf2cab53df09f4bc34bfd217cdb57d971e769874c9a6710618" +dependencies = [ + "derive_more-impl 2.1.0", +] + +[[package]] +name = "derive_more-impl" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "derive_more-impl" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d286bfdaf75e988b4a78e013ecd79c581e06399ab53fbacd2d916c2f904f30b" +dependencies = [ + "convert_case 0.10.0", + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.111", + "unicode-xid", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + +[[package]] +name = "downloader" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ac1e888d6830712d565b2f3a974be3200be9296bc1b03db8251a4cbf18a4a34" +dependencies = [ + "digest", + "futures", + "rand 0.8.5", + "reqwest", + "thiserror 1.0.69", + "tokio", +] + +[[package]] +name = "dyn-clone" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" + +[[package]] +name = "dynasm" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7d4c414c94bc830797115b8e5f434d58e7e80cb42ba88508c14bc6ea270625" +dependencies = [ + "bitflags 2.10.0", + "byteorder", + "lazy_static", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "dynasm" +version = "4.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d36219658beb39702975c707dee7895943ca281ca46eebbc5ea395171b9c182b" +dependencies = [ + "bitflags 2.10.0", + "byteorder", + "lazy_static", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "dynasmrt" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "602f7458a3859195fb840e6e0cce5f4330dd9dfbfece0edaf31fe427af346f55" +dependencies = [ + "byteorder", + "dynasm 3.2.1", + "fnv", + "memmap2 0.9.9", +] + +[[package]] +name = "dynasmrt" +version = "4.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bc32ed2a02b82bc43a7631dd624e8c5731a8377e40a468da28e62fc2e028952" +dependencies = [ + "byteorder", + "dynasm 4.0.2", + "fnv", + "memmap2 0.9.9", +] + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest", + "elliptic-curve", + "rfc6979 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serdect", + "signature", + "spki", +] + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "git+https://github.com/sp1-patches/signatures?tag=sp1-skip-verify-on-recovery#1880299a48fe7ef249edaa616fd411239fb5daf1" +dependencies = [ + "der", + "digest", + "elliptic-curve", + "rfc6979 0.4.0 (git+https://github.com/sp1-patches/signatures?tag=sp1-skip-verify-on-recovery)", + "signature", + "spki", +] + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +dependencies = [ + "serde", +] + +[[package]] +name = "elf" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4445909572dbd556c457c849c4ca58623d84b27c8fff1e74b0b4227d8b90d17b" + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest", + "ff 0.13.1", + "generic-array 0.14.7", + "group 0.13.0", + "hkdf", + "pem-rfc7468", + "pkcs8", + "rand_core 0.6.4", + "sec1", + "serdect", + "subtle", + "zeroize", +] + +[[package]] +name = "embedded-alloc" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f2de9133f68db0d4627ad69db767726c99ff8585272716708227008d3f1bddd" +dependencies = [ + "const-default", + "critical-section", + "linked_list_allocator", + "rlsf", +] + +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" + +[[package]] +name = "enum-iterator" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4549325971814bda7a44061bf3fe7e487d447cba01e4220a4b454d630d7a016" +dependencies = [ + "enum-iterator-derive", +] + +[[package]] +name = "enum-iterator-derive" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "685adfa4d6f3d765a26bc5dbc936577de9abf756c1feeb3089b01dd395034842" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "enum-map" +version = "2.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6866f3bfdf8207509a033af1a75a7b08abda06bbaaeae6669323fd5a097df2e9" +dependencies = [ + "enum-map-derive", + "serde", +] + +[[package]] +name = "enum-map-derive" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "enumset" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25b07a8dfbbbfc0064c0a6bdf9edcf966de6b1c33ce344bdeca3b41615452634" +dependencies = [ + "enumset_derive", +] + +[[package]] +name = "enumset_derive" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43e744e4ea338060faee68ed933e46e722fb7f3617e722a5772d7e856d8b3ce" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "env_home" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f84e12ccf0a7ddc17a6c41c93326024c42920d7ee630d04950e6926645c0fe" + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "eventsource-stream" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74fef4569247a5f429d9156b9d0a2599914385dd189c539334c625d8099d90ab" +dependencies = [ + "futures-core", + "nom", + "pin-project-lite", +] + +[[package]] +name = "eyre" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "fallible-iterator" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "bitvec", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "ff" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +dependencies = [ + "bitvec", + "byteorder", + "ff_derive", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "ff_derive" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f10d12652036b0e99197587c6ba87a8fc3031986499973c030d8b44fcc151b60" +dependencies = [ + "addchain", + "num-bigint 0.3.3", + "num-integer", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "filetime" +version = "0.2.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc0505cd1b6fa6580283f6bdf70a73fcf4aba1184038c90902b92b3dd0df63ed" +dependencies = [ + "cfg-if", + "libc", + "libredox", + "windows-sys 0.60.2", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" + +[[package]] +name = "fixedbitset" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" + +[[package]] +name = "flate2" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "gcd" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a" + +[[package]] +name = "gecko_profile" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "890852c7e1e02bc6758e325d6b1e0236e4fbf21b492f585ce4d4715be54b4c6a" +dependencies = [ + "debugid", + "serde", + "serde_json", +] + +[[package]] +name = "gen_ops" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "304de19db7028420975a296ab0fcbbc8e69438c4ed254a1e41e2a7f37d5f0e0a" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "generic-array" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96512db27971c2c3eece70a1e106fbe6c87760234e31e8f7e5634912fe52794a" +dependencies = [ + "serde", + "typenum", +] + +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "r-efi", + "wasip2", + "wasm-bindgen", +] + +[[package]] +name = "gimli" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" +dependencies = [ + "fallible-iterator", + "indexmap 2.12.1", + "stable_deref_trait", +] + +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff 0.12.1", + "memuse", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff 0.13.1", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "h2" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap 2.12.1", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "halo2" +version = "0.1.0-beta.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a23c779b38253fe1538102da44ad5bd5378495a61d2c4ee18d64eaa61ae5995" +dependencies = [ + "halo2_proofs", +] + +[[package]] +name = "halo2_proofs" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e925780549adee8364c7f2b685c753f6f3df23bde520c67416e93bf615933760" +dependencies = [ + "blake2b_simd", + "ff 0.12.1", + "group 0.12.1", + "pasta_curves 0.4.1", + "rand_core 0.6.4", + "rayon", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", + "serde", +] + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash 0.1.5", + "serde", +] + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "foldhash 0.2.0", +] + +[[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.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "http" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "pin-utils", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", + "webpki-roots", +] + +[[package]] +name = "hyper-timeout" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" +dependencies = [ + "hyper", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2 0.6.1", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core 0.62.2", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "icu_collections" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" + +[[package]] +name = "icu_properties" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +dependencies = [ + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" + +[[package]] +name = "icu_provider" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "indenter" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" +dependencies = [ + "equivalent", + "hashbrown 0.16.1", + "serde", + "serde_core", +] + +[[package]] +name = "indicatif" +version = "0.17.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "183b3088984b400f4cfac3620d5e076c84da5364016b4f49473de574b2586235" +dependencies = [ + "console", + "number_prefix", + "portable-atomic", + "unicode-width 0.2.2", + "web-time", +] + +[[package]] +name = "inkwell" +version = "0.7.1" +source = "git+https://github.com/TheDan64/inkwell.git?rev=b9c53276e30935ccec841d12c9687a17e9199958#b9c53276e30935ccec841d12c9687a17e9199958" +dependencies = [ + "inkwell_internals", + "libc", + "llvm-sys", + "once_cell", + "thiserror 2.0.17", +] + +[[package]] +name = "inkwell_internals" +version = "0.12.0" +source = "git+https://github.com/TheDan64/inkwell.git?rev=b9c53276e30935ccec841d12c9687a17e9199958#b9c53276e30935ccec841d12c9687a17e9199958" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "iri-string" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f867b9d1d896b67beb18518eda36fdb77a32ea590de864f1325b294a6d14397" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +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 = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee5b5339afb4c41626dde77b7a611bd4f2c202b897852b4bcf5d03eddc61010" + +[[package]] +name = "js-sys" +version = "0.3.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "jubjub" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a575df5f985fe1cd5b2b05664ff6accfc46559032b954529fd225a2168d27b0f" +dependencies = [ + "bitvec", + "bls12_381", + "ff 0.12.1", + "group 0.12.1", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "k256" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" +dependencies = [ + "cfg-if", + "ecdsa 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", + "elliptic-curve", + "once_cell", + "serdect", + "sha2", + "signature", +] + +[[package]] +name = "k256" +version = "0.13.4" +source = "git+https://github.com/sp1-patches/elliptic-curves?tag=patch-k256-13.4-sp1-6.0.0#0efe186cee5930a0d23501651c226bd81fcc2c15" +dependencies = [ + "cfg-if", + "ecdsa 0.16.9 (git+https://github.com/sp1-patches/signatures?tag=sp1-skip-verify-on-recovery)", + "elliptic-curve", + "hex", + "once_cell", + "sha2", + "signature", + "sp1-lib 6.0.0", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin", +] + +[[package]] +name = "leb128" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" + +[[package]] +name = "libc" +version = "0.2.178" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" + +[[package]] +name = "libloading" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" +dependencies = [ + "cfg-if", + "windows-link", +] + +[[package]] +name = "libm" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" + +[[package]] +name = "libredox" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df15f6eac291ed1cf25865b1ee60399f57e7c227e7f51bdbd4c5270396a9ed50" +dependencies = [ + "bitflags 2.10.0", + "libc", + "redox_syscall 0.6.0", +] + +[[package]] +name = "libunwind" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c6639b70a7ce854b79c70d7e83f16b5dc0137cc914f3d7d03803b513ecc67ac" + +[[package]] +name = "linked_list_allocator" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afa463f5405ee81cdb9cc2baf37e08ec7e4c8209442b5d72c04cfb2cd6e6286" + +[[package]] +name = "linux-raw-sys" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" + +[[package]] +name = "litemap" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" + +[[package]] +name = "llvm-sys" +version = "211.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "108b3ad2b2eaf2a561fc74196273b20e3436e4a688b8b44e250d83974dc1b2e2" +dependencies = [ + "anyhow", + "cc", + "lazy_static", + "libc", + "regex-lite", + "semver", +] + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + +[[package]] +name = "lru" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" +dependencies = [ + "hashbrown 0.15.5", +] + +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + +[[package]] +name = "mach2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d640282b302c0bb0a2a8e0233ead9035e3bed871f0b7e81fe4a1ec829765db44" +dependencies = [ + "libc", +] + +[[package]] +name = "mach2" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dae608c151f68243f2b000364e1f7b186d9c29845f7d2d85bd31b9ad77ad552b" + +[[package]] +name = "macho-unwind-info" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb4bdc8b0ce69932332cf76d24af69c3a155242af95c226b2ab6c2e371ed1149" +dependencies = [ + "thiserror 2.0.17", + "zerocopy", + "zerocopy-derive", +] + +[[package]] +name = "matchers" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest", +] + +[[package]] +name = "memchr" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" + +[[package]] +name = "memfd" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad38eb12aea514a0466ea40a80fd8cc83637065948eb4a426e4aa46261175227" +dependencies = [ + "rustix", +] + +[[package]] +name = "memmap2" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d28bba84adfe6646737845bc5ebbfa2c08424eb1c37e94a1fd2a82adb56a872" +dependencies = [ + "libc", +] + +[[package]] +name = "memmap2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "744133e4a0e0a658e1374cf3bf8e415c4052a15a111acd372764c55b4177d490" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "memuse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d97bbf43eb4f088f8ca469930cde17fa036207c9a5e02ccc5107c4e8b17c964" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "mio" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.61.2", +] + +[[package]] +name = "more-asserts" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fafa6961cabd9c63bcd77a45d7e3b7f3b552b70417831fb0f56db717e72407e" + +[[package]] +name = "mti" +version = "1.0.7-beta.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73e89058909957124fd8271ac984c38733f080e0f0edd93322f82d7bd6a0010a" +dependencies = [ + "typeid_prefix", + "typeid_suffix", +] + +[[package]] +name = "multimap" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084" + +[[package]] +name = "munge" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e17401f259eba956ca16491461b6e8f72913a0a114e39736ce404410f915a0c" +dependencies = [ + "munge_macro", +] + +[[package]] +name = "munge_macro" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4568f25ccbd45ab5d5603dc34318c1ec56b117531781260002151b8530a9f931" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "ntapi" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c70f219e21142367c70c0b30c6a9e3a14d55b4d12a204d897fbec83a0363f081" +dependencies = [ + "winapi", +] + +[[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "num" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" +dependencies = [ + "num-bigint 0.4.6", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6f7833f2cbf2360a6cfd58cd41a53aa7a90bd4c202f5b1c7dd2ed73c57b2c3" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-modular" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17bb261bf36fa7d83f4c294f834e91256769097b3cb505d44831e0a179ac647f" + +[[package]] +name = "num-order" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "537b596b97c40fcf8056d153049eb22f481c17ebce72a513ec9286e4986d1bb6" +dependencies = [ + "num-modular", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint 0.4.6", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +dependencies = [ + "num_enum_derive 0.5.11", +] + +[[package]] +name = "num_enum" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c" +dependencies = [ + "num_enum_derive 0.7.5", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" +dependencies = [ + "proc-macro-crate 3.4.0", + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + +[[package]] +name = "object" +version = "0.37.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" +dependencies = [ + "crc32fast", + "flate2", + "hashbrown 0.15.5", + "indexmap 2.12.1", + "memchr", + "ruzstd", +] + +[[package]] +name = "object" +version = "0.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8b28f24bd43920cd8e0bc4f9c6553e8b93221c512cb9a1014987fc89d36f830" +dependencies = [ + "crc32fast", + "flate2", + "hashbrown 0.16.1", + "indexmap 2.12.1", + "memchr", + "ruzstd", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" + +[[package]] +name = "opentelemetry" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b69a91d4893e713e06f724597ad630f1fa76057a5e1026c0ca67054a9032a76" +dependencies = [ + "futures-core", + "futures-sink", + "js-sys", + "once_cell", + "pin-project-lite", + "thiserror 1.0.69", +] + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", + "elliptic-curve", + "primeorder", + "sha2", +] + +[[package]] +name = "p3-air" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" +dependencies = [ + "p3-field 0.1.0", + "p3-matrix 0.1.0", + "serde", +] + +[[package]] +name = "p3-baby-bear" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" +dependencies = [ + "num-bigint 0.4.6", + "p3-field 0.1.0", + "p3-mds 0.1.0", + "p3-poseidon2 0.1.0", + "p3-symmetric 0.1.0", + "rand 0.8.5", + "serde", +] + +[[package]] +name = "p3-baby-bear" +version = "0.2.3-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7521838ecab2ddf4f7bc4ceebad06ec02414729598485c1ada516c39900820e8" +dependencies = [ + "num-bigint 0.4.6", + "p3-field 0.2.3-succinct", + "p3-mds 0.2.3-succinct", + "p3-poseidon2 0.2.3-succinct", + "p3-symmetric 0.2.3-succinct", + "rand 0.8.5", + "serde", +] + +[[package]] +name = "p3-bn254-fr" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" +dependencies = [ + "ff 0.13.1", + "num-bigint 0.4.6", + "p3-field 0.1.0", + "p3-poseidon2 0.1.0", + "p3-symmetric 0.1.0", + "rand 0.8.5", + "serde", +] + +[[package]] +name = "p3-challenger" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" +dependencies = [ + "p3-field 0.1.0", + "p3-maybe-rayon 0.1.0", + "p3-symmetric 0.1.0", + "p3-util 0.1.0", + "serde", + "tracing", +] + +[[package]] +name = "p3-commit" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" +dependencies = [ + "itertools 0.12.1", + "p3-challenger", + "p3-field 0.1.0", + "p3-matrix 0.1.0", + "p3-util 0.1.0", + "serde", +] + +[[package]] +name = "p3-dft" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" +dependencies = [ + "p3-field 0.1.0", + "p3-matrix 0.1.0", + "p3-maybe-rayon 0.1.0", + "p3-util 0.1.0", + "tracing", +] + +[[package]] +name = "p3-dft" +version = "0.2.3-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46414daedd796f1eefcdc1811c0484e4bced5729486b6eaba9521c572c76761a" +dependencies = [ + "p3-field 0.2.3-succinct", + "p3-matrix 0.2.3-succinct", + "p3-maybe-rayon 0.2.3-succinct", + "p3-util 0.2.3-succinct", + "tracing", +] + +[[package]] +name = "p3-field" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" +dependencies = [ + "itertools 0.12.1", + "num-bigint 0.4.6", + "num-traits", + "p3-util 0.1.0", + "rand 0.8.5", + "serde", +] + +[[package]] +name = "p3-field" +version = "0.2.3-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48948a0516b349e9d1cdb95e7236a6ee010c44e68c5cc78b4b92bf1c4022a0d9" +dependencies = [ + "itertools 0.12.1", + "num-bigint 0.4.6", + "num-traits", + "p3-util 0.2.3-succinct", + "rand 0.8.5", + "serde", +] + +[[package]] +name = "p3-fri" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" +dependencies = [ + "itertools 0.12.1", + "p3-challenger", + "p3-commit", + "p3-dft 0.1.0", + "p3-field 0.1.0", + "p3-interpolation", + "p3-matrix 0.1.0", + "p3-maybe-rayon 0.1.0", + "p3-util 0.1.0", + "serde", + "tracing", +] + +[[package]] +name = "p3-interpolation" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" +dependencies = [ + "p3-field 0.1.0", + "p3-matrix 0.1.0", + "p3-util 0.1.0", +] + +[[package]] +name = "p3-keccak-air" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" +dependencies = [ + "p3-air", + "p3-field 0.1.0", + "p3-matrix 0.1.0", + "p3-maybe-rayon 0.1.0", + "p3-util 0.1.0", + "tracing", +] + +[[package]] +name = "p3-koala-bear" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" +dependencies = [ + "num-bigint 0.4.6", + "p3-field 0.1.0", + "p3-mds 0.1.0", + "p3-poseidon2 0.1.0", + "p3-symmetric 0.1.0", + "rand 0.8.5", + "serde", +] + +[[package]] +name = "p3-matrix" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" +dependencies = [ + "itertools 0.12.1", + "p3-field 0.1.0", + "p3-maybe-rayon 0.1.0", + "p3-util 0.1.0", + "rand 0.8.5", + "serde", + "tracing", +] + +[[package]] +name = "p3-matrix" +version = "0.2.3-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e4de3f373589477cb735ea58e125898ed20935e03664b4614c7fac258b3c42f" +dependencies = [ + "itertools 0.12.1", + "p3-field 0.2.3-succinct", + "p3-maybe-rayon 0.2.3-succinct", + "p3-util 0.2.3-succinct", + "rand 0.8.5", + "serde", + "tracing", +] + +[[package]] +name = "p3-maybe-rayon" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" +dependencies = [ + "rayon", +] + +[[package]] +name = "p3-maybe-rayon" +version = "0.2.3-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3968ad1160310296eb04f91a5f4edfa38fe1d6b2b8cd6b5c64e6f9b7370979e" + +[[package]] +name = "p3-mds" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" +dependencies = [ + "itertools 0.12.1", + "p3-dft 0.1.0", + "p3-field 0.1.0", + "p3-matrix 0.1.0", + "p3-symmetric 0.1.0", + "p3-util 0.1.0", + "rand 0.8.5", +] + +[[package]] +name = "p3-mds" +version = "0.2.3-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2356b1ed0add6d5dfbf7a338ce534a6fde827374394a52cec16a0840af6e97c9" +dependencies = [ + "itertools 0.12.1", + "p3-dft 0.2.3-succinct", + "p3-field 0.2.3-succinct", + "p3-matrix 0.2.3-succinct", + "p3-symmetric 0.2.3-succinct", + "p3-util 0.2.3-succinct", + "rand 0.8.5", +] + +[[package]] +name = "p3-merkle-tree" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" +dependencies = [ + "itertools 0.12.1", + "p3-commit", + "p3-field 0.1.0", + "p3-matrix 0.1.0", + "p3-maybe-rayon 0.1.0", + "p3-symmetric 0.1.0", + "p3-util 0.1.0", + "serde", + "tracing", +] + +[[package]] +name = "p3-poseidon2" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" +dependencies = [ + "gcd", + "p3-field 0.1.0", + "p3-mds 0.1.0", + "p3-symmetric 0.1.0", + "rand 0.8.5", + "serde", +] + +[[package]] +name = "p3-poseidon2" +version = "0.2.3-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da1eec7e1b6900581bedd95e76e1ef4975608dd55be9872c9d257a8a9651c3a" +dependencies = [ + "gcd", + "p3-field 0.2.3-succinct", + "p3-mds 0.2.3-succinct", + "p3-symmetric 0.2.3-succinct", + "rand 0.8.5", + "serde", +] + +[[package]] +name = "p3-symmetric" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" +dependencies = [ + "itertools 0.12.1", + "p3-field 0.1.0", + "serde", +] + +[[package]] +name = "p3-symmetric" +version = "0.2.3-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edb439bea1d822623b41ff4b51e3309e80d13cadf8b86d16ffd5e6efb9fdc360" +dependencies = [ + "itertools 0.12.1", + "p3-field 0.2.3-succinct", + "serde", +] + +[[package]] +name = "p3-uni-stark" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" +dependencies = [ + "itertools 0.12.1", + "p3-air", + "p3-challenger", + "p3-commit", + "p3-dft 0.1.0", + "p3-field 0.1.0", + "p3-matrix 0.1.0", + "p3-maybe-rayon 0.1.0", + "p3-util 0.1.0", + "serde", + "tracing", +] + +[[package]] +name = "p3-util" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" +dependencies = [ + "serde", +] + +[[package]] +name = "p3-util" +version = "0.2.3-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c2c2010678b9332b563eaa38364915b585c1a94b5ca61e2c7541c087ddda5c" +dependencies = [ + "serde", +] + +[[package]] +name = "pairing" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "135590d8bdba2b31346f9cd1fb2a912329f5135e832a4f422942eb6ead8b6b3b" +dependencies = [ + "group 0.12.1", +] + +[[package]] +name = "parity-scale-codec" +version = "3.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799781ae679d79a948e13d4824a40970bfa500058d245760dd857301059810fa" +dependencies = [ + "arrayvec", + "byte-slice-cast", + "const_format", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "rustversion", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34b4653168b563151153c9e4c08ebed57fb8262bebfa79711552fa983c623e7a" +dependencies = [ + "proc-macro-crate 3.4.0", + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.5.18", + "smallvec", + "windows-link", +] + +[[package]] +name = "pasta_curves" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc65faf8e7313b4b1fbaa9f7ca917a0eed499a9663be71477f87993604341d8" +dependencies = [ + "blake2b_simd", + "ff 0.12.1", + "group 0.12.1", + "lazy_static", + "rand 0.8.5", + "static_assertions", + "subtle", +] + +[[package]] +name = "pasta_curves" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e57598f73cc7e1b2ac63c79c517b31a0877cd7c402cdcaa311b5208de7a095" +dependencies = [ + "blake2b_simd", + "ff 0.13.1", + "group 0.13.0", + "lazy_static", + "rand 0.8.5", + "static_assertions", + "subtle", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "petgraph" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" +dependencies = [ + "fixedbitset", + "indexmap 2.12.1", +] + +[[package]] +name = "phf" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" +dependencies = [ + "phf_macros", + "phf_shared", + "serde", +] + +[[package]] +name = "phf_generator" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737" +dependencies = [ + "fastrand", + "phf_shared", +] + +[[package]] +name = "phf_macros" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "phf_shared" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266" +dependencies = [ + "siphasher 1.0.1", +] + +[[package]] +name = "pin-project" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "portable-atomic" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f59e70c4aef1e55797c2e8fd94a4f2a973fc972cfde0e0b05f683667b0cd39dd" + +[[package]] +name = "potential_utf" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +dependencies = [ + "zerovec", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn 2.0.111", +] + +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit 0.19.15", +] + +[[package]] +name = "proc-macro-crate" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" +dependencies = [ + "toml_edit 0.23.10+spec-1.0.0", +] + +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "proc-macro2" +version = "1.0.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "program" +version = "0.1.0" +dependencies = [ + "arbutil", + "brotli", + "bytes", + "corosensei", + "eyre", + "hex", + "num-traits", + "num_enum 0.7.5", + "once_cell", + "prover", + "rand 0.8.5", + "rand_pcg", + "ruint2", + "secp256k1", + "serde", + "serde_json", + "sp1-zkvm", + "thiserror 1.0.69", + "tiny-keccak 2.0.2 (git+https://github.com/sp1-patches/tiny-keccak?tag=patch-2.0.2-sp1-6.0.0)", + "wasmer", + "wasmer-types", + "wasmer-vm", +] + +[[package]] +name = "prost" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be769465445e8c1474e9c5dac2018218498557af32d9ed057325ec9a41ae81bf" +dependencies = [ + "heck", + "itertools 0.14.0", + "log", + "multimap", + "once_cell", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "regex", + "syn 2.0.111", + "tempfile", +] + +[[package]] +name = "prost-derive" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" +dependencies = [ + "anyhow", + "itertools 0.14.0", + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "prost-types" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52c2c1bf36ddb1a1c396b3601a3cec27c2462e45f07c386894ec3ccf5332bd16" +dependencies = [ + "prost", +] + +[[package]] +name = "prover" +version = "0.1.0" +dependencies = [ + "arbutil", + "brotli", + "bytes", + "derivative", + "digest", + "eyre", + "fnv", + "hex", + "lazy_static", + "nom", + "num-derive", + "num-traits", + "parking_lot", + "rkyv", + "serde", + "serde_json", + "serde_with", + "sha3", + "wasmer", + "wasmer-types", + "wasmparser 0.224.1", +] + +[[package]] +name = "ptr_meta" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9a0cf95a1196af61d4f1cbdab967179516d9a4a4312af1f31948f8f6224a79" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7347867d0a7e1208d93b46767be83e2b8f978c3dad35f775ac8d8847551d6fe1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "quinn" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +dependencies = [ + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash 2.1.1", + "rustls", + "socket2 0.6.1", + "thiserror 2.0.17", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" +dependencies = [ + "bytes", + "getrandom 0.3.4", + "lru-slab", + "rand 0.9.2", + "ring", + "rustc-hash 2.1.1", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.17", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2 0.6.1", + "tracing", + "windows-sys 0.60.2", +] + +[[package]] +name = "quote" +version = "1.0.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rancor" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a063ea72381527c2a0561da9c80000ef822bdd7c3241b1cc1b12100e3df081ee" +dependencies = [ + "ptr_meta", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.16", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.4", +] + +[[package]] +name = "rand_pcg" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59cad018caf63deb318e5a4586d99a24424a364f40f1e5778c29aca23f4fc73e" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "range-set-blaze" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8421b5d459262eabbe49048d362897ff3e3830b44eac6cfe341d6acb2f0f13d2" +dependencies = [ + "gen_ops", + "itertools 0.12.1", + "num-integer", + "num-traits", +] + +[[package]] +name = "rayon" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "rayon-scan" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f87cc11a0140b4b0da0ffc889885760c61b13672d80a908920b2c0df078fa14" +dependencies = [ + "rayon", +] + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags 2.10.0", +] + +[[package]] +name = "redox_syscall" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec96166dafa0886eb81fe1c0a388bece180fbef2135f97c1e2cf8302e74b43b5" +dependencies = [ + "bitflags 2.10.0", +] + +[[package]] +name = "redox_users" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +dependencies = [ + "getrandom 0.2.16", + "libredox", + "thiserror 1.0.69", +] + +[[package]] +name = "ref-cast" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "regex" +version = "1.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-lite" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d942b98df5e658f56f20d592c7f868833fe38115e65c33003d8cd224b0155da" + +[[package]] +name = "regex-syntax" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" + +[[package]] +name = "region" +version = "3.0.2" +source = "git+https://github.com/wakabat/region-rs?branch=patch-v3.0.2#ae1c35abce8fbe14deeb7844f95f6b9468bf3fb7" +dependencies = [ + "bitflags 1.3.2", + "libc", + "mach2 0.4.3", + "sp1-primitives 6.0.0", + "sp1-zkvm", + "windows-sys 0.52.0", +] + +[[package]] +name = "rend" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cadadef317c2f20755a64d7fdc48f9e7178ee6b0e1f7fce33fa60f1d68a276e6" +dependencies = [ + "bytecheck", +] + +[[package]] +name = "reqwest" +version = "0.12.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b4c14b2d9afca6a60277086b0cc6a6ae0b568f6f7916c943a8cdc79f8be240f" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-rustls", + "tokio-util", + "tower 0.5.2", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "webpki-roots", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "git+https://github.com/sp1-patches/signatures?tag=sp1-skip-verify-on-recovery#1880299a48fe7ef249edaa616fd411239fb5daf1" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.16", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rkyv" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35a640b26f007713818e9a9b65d34da1cf58538207b052916a83d80e43f3ffa4" +dependencies = [ + "bytecheck", + "bytes", + "hashbrown 0.15.5", + "indexmap 2.12.1", + "munge", + "ptr_meta", + "rancor", + "rend", + "rkyv_derive", + "tinyvec", + "uuid", +] + +[[package]] +name = "rkyv_derive" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd83f5f173ff41e00337d97f6572e416d022ef8a19f371817259ae960324c482" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "rlsf" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "222fb240c3286247ecdee6fa5341e7cdad0ffdf8e7e401d9937f2d58482a20bf" +dependencies = [ + "cfg-if", + "const-default", + "libc", + "svgbobdoc", +] + +[[package]] +name = "rrs-lib" +version = "0.1.0" +source = "git+https://github.com/succinctlabs/rrs-succinct.git?branch=gautham%2Frv64executor-2#eaca3e8e1785f5b4cf55edfe670c1bf2f52eca77" +dependencies = [ + "downcast-rs", + "num_enum 0.5.11", + "paste", +] + +[[package]] +name = "ruint2" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b066b8e4fcea7fae86b6932d2449670b6b5545b7e8407841b2d3a916ff2a9f86" +dependencies = [ + "derive_more 0.99.20", + "ruint2-macro", + "rustc_version", + "thiserror 1.0.69", +] + +[[package]] +name = "ruint2-macro" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89dc553bc0cf4512a8b96caa2e21ed5f6e4b66bf28a1bd08fd9eb07c0b39b28c" + +[[package]] +name = "rustc-demangle" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" +dependencies = [ + "bitflags 2.10.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls" +version = "0.23.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "533f54bc6a7d4f647e46ad909549eda97bf5afc1585190ef692b4286b198bd8f" +dependencies = [ + "log", + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21e6f2ab2928ca4291b86736a8bd920a277a399bba1589409d72154ff87c1282" +dependencies = [ + "web-time", + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "ruzstd" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ff0cc5e135c8870a775d3320910cd9b564ec036b4dc0b8741629020be63f01" +dependencies = [ + "twox-hash", +] + +[[package]] +name = "ryu" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62049b2877bf12821e8f9ad256ee38fdc31db7387ec2d3b3f403024de2034aea" + +[[package]] +name = "scale-info" +version = "2.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "346a3b32eba2640d17a9cb5927056b08f3de90f65b72fe09402c2ad07d684d0b" +dependencies = [ + "cfg-if", + "derive_more 1.0.0", + "parity-scale-codec", + "scale-info-derive", +] + +[[package]] +name = "scale-info-derive" +version = "2.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6630024bf739e2179b91fb424b28898baf819414262c5d376677dbff1fe7ebf" +dependencies = [ + "proc-macro-crate 3.4.0", + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "scc" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46e6f046b7fef48e2660c57ed794263155d713de679057f2d0c169bfc6e756cc" +dependencies = [ + "sdd", +] + +[[package]] +name = "schemars" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9558e172d4e8533736ba97870c4b2cd63f84b382a3d6eb063da41b91cce17289" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sdd" +version = "3.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490dcfcbfef26be6800d11870ff2df8774fa6e86d047e3e8c8a76b25655e41ca" + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array 0.14.7", + "pkcs8", + "serdect", + "subtle", + "zeroize", +] + +[[package]] +name = "secp256k1" +version = "0.29.1" +source = "git+https://github.com/sp1-patches/rust-secp256k1?tag=patch-0.29.1-sp1-6.0.0#5daf12595f56cb549d1516d8139cb7935d79de7a" +dependencies = [ + "cfg-if", + "k256 0.13.4 (git+https://github.com/sp1-patches/elliptic-curves?tag=patch-k256-13.4-sp1-6.0.0)", + "secp256k1-sys", +] + +[[package]] +name = "secp256k1-sys" +version = "0.10.0" +source = "git+https://github.com/sp1-patches/rust-secp256k1?tag=patch-0.29.1-sp1-6.0.0#5daf12595f56cb549d1516d8139cb7935d79de7a" +dependencies = [ + "cc", +] + +[[package]] +name = "self_cell" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16c2f82143577edb4921b71ede051dac62ca3c16084e918bf7b40c96ae10eb33" + +[[package]] +name = "semver" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +dependencies = [ + "serde", + "serde_core", +] + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde-wasm-bindgen" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "serde_arrays" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94a16b99c5ea4fe3daccd14853ad260ec00ea043b2708d1fd1da3106dcd8d9df" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "serde_json" +version = "1.0.145" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", + "serde_core", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_with" +version = "3.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fa237f2807440d238e0364a218270b98f767a00d3dada77b1c53ae88940e2e7" +dependencies = [ + "base64 0.22.1", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.12.1", + "schemars 0.9.0", + "schemars 1.1.0", + "serde_core", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52a8e3ca0ca629121f70ab50f95249e5a6f925cc0f6ffe8256c45b728875706c" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "serdect" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" +dependencies = [ + "base16ct", + "serde", +] + +[[package]] +name = "serial_test" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b258109f244e1d6891bf1053a55d63a5cd4f8f4c30cf9a1280989f80e7a1fa9" +dependencies = [ + "futures", + "log", + "once_cell", + "parking_lot", + "scc", + "serial_test_derive", +] + +[[package]] +name = "serial_test_derive" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d69265a08751de7844521fd15003ae0a888e035773ba05695c5c759a6f89eef" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "sha1_smol" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest", + "keccak", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shared-buffer" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6c99835bad52957e7aa241d3975ed17c1e5f8c92026377d117a606f36b84b16" +dependencies = [ + "bytes", + "memmap2 0.6.2", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7664a098b8e616bdfcc2dc0e9ac44eb231eedf41db4e9fe95d8d32ec728dedad" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core 0.6.4", +] + +[[package]] +name = "simd-adler32" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" + +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "siphasher" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" + +[[package]] +name = "slab" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" + +[[package]] +name = "slop-air" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "p3-air", +] + +[[package]] +name = "slop-algebra" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "itertools 0.13.0", + "p3-field 0.1.0", + "serde", +] + +[[package]] +name = "slop-alloc" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "serde", + "slop-algebra", + "thiserror 1.0.69", +] + +[[package]] +name = "slop-baby-bear" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "lazy_static", + "p3-baby-bear 0.1.0", + "serde", + "slop-algebra", + "slop-challenger", + "slop-poseidon2", + "slop-symmetric", +] + +[[package]] +name = "slop-basefold" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "derive-where", + "itertools 0.13.0", + "serde", + "slop-algebra", + "slop-alloc", + "slop-baby-bear", + "slop-bn254", + "slop-challenger", + "slop-koala-bear", + "slop-merkle-tree", + "slop-multilinear", + "slop-primitives", + "slop-tensor", + "slop-utils", + "thiserror 1.0.69", +] + +[[package]] +name = "slop-basefold-prover" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "derive-where", + "itertools 0.13.0", + "rand 0.8.5", + "serde", + "slop-algebra", + "slop-alloc", + "slop-baby-bear", + "slop-basefold", + "slop-bn254", + "slop-challenger", + "slop-commit", + "slop-dft", + "slop-fri", + "slop-futures", + "slop-koala-bear", + "slop-merkle-tree", + "slop-multilinear", + "slop-tensor", + "thiserror 1.0.69", + "tokio", +] + +[[package]] +name = "slop-bn254" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "ff 0.13.1", + "p3-bn254-fr", + "serde", + "slop-algebra", + "slop-challenger", + "slop-poseidon2", + "slop-symmetric", + "zkhash", +] + +[[package]] +name = "slop-challenger" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "futures", + "p3-challenger", + "serde", + "slop-algebra", + "slop-symmetric", +] + +[[package]] +name = "slop-commit" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "p3-commit", + "serde", + "slop-alloc", +] + +[[package]] +name = "slop-dft" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "p3-dft 0.1.0", + "serde", + "slop-algebra", + "slop-alloc", + "slop-matrix", + "slop-tensor", +] + +[[package]] +name = "slop-fri" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "p3-fri", +] + +[[package]] +name = "slop-futures" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "crossbeam", + "futures", + "pin-project", + "rayon", + "thiserror 1.0.69", + "tokio", + "tracing", +] + +[[package]] +name = "slop-jagged" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "derive-where", + "futures", + "itertools 0.13.0", + "num_cpus", + "rand 0.8.5", + "rayon", + "serde", + "slop-algebra", + "slop-alloc", + "slop-baby-bear", + "slop-basefold", + "slop-basefold-prover", + "slop-bn254", + "slop-challenger", + "slop-commit", + "slop-futures", + "slop-koala-bear", + "slop-merkle-tree", + "slop-multilinear", + "slop-stacked", + "slop-sumcheck", + "slop-symmetric", + "slop-tensor", + "slop-utils", + "thiserror 1.0.69", + "tokio", + "tracing", +] + +[[package]] +name = "slop-keccak-air" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "p3-keccak-air", +] + +[[package]] +name = "slop-koala-bear" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "lazy_static", + "p3-koala-bear", + "serde", + "slop-algebra", + "slop-challenger", + "slop-poseidon2", + "slop-symmetric", +] + +[[package]] +name = "slop-matrix" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "p3-matrix 0.1.0", +] + +[[package]] +name = "slop-maybe-rayon" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "p3-maybe-rayon 0.1.0", +] + +[[package]] +name = "slop-merkle-tree" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "derive-where", + "ff 0.13.1", + "itertools 0.13.0", + "p3-merkle-tree", + "serde", + "slop-algebra", + "slop-alloc", + "slop-baby-bear", + "slop-bn254", + "slop-challenger", + "slop-commit", + "slop-futures", + "slop-koala-bear", + "slop-matrix", + "slop-poseidon2", + "slop-symmetric", + "slop-tensor", + "thiserror 1.0.69", + "tokio", + "zkhash", +] + +[[package]] +name = "slop-multilinear" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "derive-where", + "futures", + "num_cpus", + "rand 0.8.5", + "rayon", + "serde", + "slop-algebra", + "slop-alloc", + "slop-challenger", + "slop-commit", + "slop-futures", + "slop-matrix", + "slop-tensor", + "tokio", +] + +[[package]] +name = "slop-poseidon2" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "p3-poseidon2 0.1.0", +] + +[[package]] +name = "slop-primitives" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "slop-algebra", +] + +[[package]] +name = "slop-stacked" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "derive-where", + "futures", + "itertools 0.13.0", + "serde", + "slop-algebra", + "slop-alloc", + "slop-basefold", + "slop-basefold-prover", + "slop-challenger", + "slop-commit", + "slop-futures", + "slop-merkle-tree", + "slop-multilinear", + "slop-tensor", + "thiserror 1.0.69", + "tokio", +] + +[[package]] +name = "slop-sumcheck" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "futures", + "itertools 0.13.0", + "rayon", + "serde", + "slop-algebra", + "slop-alloc", + "slop-baby-bear", + "slop-challenger", + "slop-multilinear", + "thiserror 1.0.69", +] + +[[package]] +name = "slop-symmetric" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "p3-symmetric 0.1.0", +] + +[[package]] +name = "slop-tensor" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "arrayvec", + "derive-where", + "itertools 0.13.0", + "rand 0.8.5", + "rayon", + "serde", + "slop-algebra", + "slop-alloc", + "slop-futures", + "slop-matrix", + "thiserror 1.0.69", + "tokio", + "transpose", +] + +[[package]] +name = "slop-uni-stark" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "p3-uni-stark", +] + +[[package]] +name = "slop-utils" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "p3-util 0.1.0", + "tracing-forest", + "tracing-subscriber", +] + +[[package]] +name = "slop-whir" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "derive-where", + "futures", + "itertools 0.13.0", + "rand 0.8.5", + "rayon", + "serde", + "slop-algebra", + "slop-alloc", + "slop-baby-bear", + "slop-basefold", + "slop-challenger", + "slop-commit", + "slop-dft", + "slop-jagged", + "slop-koala-bear", + "slop-matrix", + "slop-merkle-tree", + "slop-multilinear", + "slop-stacked", + "slop-tensor", + "slop-utils", + "thiserror 1.0.69", +] + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +dependencies = [ + "serde", +] + +[[package]] +name = "snowbridge-amcl" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460a9ed63cdf03c1b9847e8a12a5f5ba19c4efd5869e4a737e05be25d7c427e5" +dependencies = [ + "parity-scale-codec", + "scale-info", +] + +[[package]] +name = "socket2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "socket2" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +dependencies = [ + "libc", + "windows-sys 0.60.2", +] + +[[package]] +name = "sp1-build" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "anyhow", + "cargo_metadata", + "chrono", + "clap", + "dirs", + "sp1-primitives 6.0.0", +] + +[[package]] +name = "sp1-builder" +version = "0.1.0" +dependencies = [ + "clap", + "serde_json", + "sp1-build", + "sp1-core-executor", + "sp1-sdk", + "wasmer", + "wasmparser 0.224.1", +] + +[[package]] +name = "sp1-core-executor" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "bincode", + "bytemuck", + "cfg-if", + "clap", + "deepsize2", + "elf", + "enum-map", + "eyre", + "gecko_profile", + "hashbrown 0.14.5", + "hex", + "indicatif", + "itertools 0.13.0", + "memmap2 0.9.9", + "num", + "object 0.37.3", + "rrs-lib", + "rustc-demangle", + "serde", + "serde_arrays", + "serde_json", + "slop-air", + "slop-algebra", + "slop-maybe-rayon", + "slop-symmetric", + "sp1-curves", + "sp1-hypercube", + "sp1-jit", + "sp1-primitives 6.0.0", + "strum", + "subenum", + "thiserror 1.0.69", + "tiny-keccak 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tracing", + "typenum", + "vec_map", +] + +[[package]] +name = "sp1-core-machine" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "bincode", + "cfg-if", + "enum-map", + "futures", + "generic-array 1.1.0", + "hashbrown 0.14.5", + "itertools 0.13.0", + "num", + "num_cpus", + "rayon", + "rayon-scan", + "rrs-lib", + "serde", + "serde_json", + "slop-air", + "slop-algebra", + "slop-challenger", + "slop-futures", + "slop-keccak-air", + "slop-matrix", + "slop-maybe-rayon", + "slop-uni-stark", + "snowbridge-amcl", + "sp1-core-executor", + "sp1-curves", + "sp1-derive", + "sp1-hypercube", + "sp1-jit", + "sp1-primitives 6.0.0", + "static_assertions", + "strum", + "sysinfo", + "tempfile", + "thiserror 1.0.69", + "tokio", + "tracing", + "tracing-forest", + "tracing-subscriber", + "typenum", +] + +[[package]] +name = "sp1-cuda" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "bincode", + "bytes", + "reqwest", + "semver", + "serde", + "serde_json", + "sp1-core-executor", + "sp1-core-machine", + "sp1-primitives 6.0.0", + "sp1-prover", + "sp1-prover-types", + "thiserror 1.0.69", + "tokio", + "tracing", +] + +[[package]] +name = "sp1-curves" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "cfg-if", + "dashu", + "elliptic-curve", + "generic-array 1.1.0", + "itertools 0.13.0", + "k256 0.13.4 (registry+https://github.com/rust-lang/crates.io-index)", + "num", + "p256", + "serde", + "slop-algebra", + "snowbridge-amcl", + "sp1-primitives 6.0.0", + "typenum", +] + +[[package]] +name = "sp1-derive" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "sp1-hypercube" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "arrayref", + "deepsize2", + "derive-where", + "futures", + "hashbrown 0.14.5", + "itertools 0.13.0", + "num-bigint 0.4.6", + "num-traits", + "num_cpus", + "rayon", + "rayon-scan", + "serde", + "slop-air", + "slop-algebra", + "slop-alloc", + "slop-basefold", + "slop-basefold-prover", + "slop-challenger", + "slop-commit", + "slop-futures", + "slop-jagged", + "slop-koala-bear", + "slop-matrix", + "slop-merkle-tree", + "slop-multilinear", + "slop-poseidon2", + "slop-stacked", + "slop-sumcheck", + "slop-symmetric", + "slop-tensor", + "slop-uni-stark", + "slop-whir", + "sp1-derive", + "sp1-primitives 6.0.0", + "strum", + "thiserror 1.0.69", + "thousands", + "tokio", + "tracing", +] + +[[package]] +name = "sp1-jit" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "dynasmrt 3.2.1", + "hashbrown 0.14.5", + "memfd", + "memmap2 0.9.9", + "serde", + "sp1-primitives 6.0.0", + "tracing", + "uuid", +] + +[[package]] +name = "sp1-lib" +version = "5.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b73b8ff343f2405d5935440e56b7aba5cee6d87303f0051974cbd6f5de502f57" +dependencies = [ + "bincode", + "elliptic-curve", + "serde", + "sp1-primitives 5.2.4", +] + +[[package]] +name = "sp1-lib" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "bincode", + "elliptic-curve", + "serde", + "sp1-primitives 6.0.0", +] + +[[package]] +name = "sp1-primitives" +version = "5.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e69a03098f827102c54c31a5e57280eb45b2c085de433b3f702e4f9e3ec1641" +dependencies = [ + "bincode", + "blake3", + "cfg-if", + "hex", + "lazy_static", + "num-bigint 0.4.6", + "p3-baby-bear 0.2.3-succinct", + "p3-field 0.2.3-succinct", + "p3-poseidon2 0.2.3-succinct", + "p3-symmetric 0.2.3-succinct", + "serde", + "sha2", +] + +[[package]] +name = "sp1-primitives" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "bincode", + "blake3", + "elf", + "hex", + "itertools 0.13.0", + "lazy_static", + "num-bigint 0.4.6", + "serde", + "sha2", + "slop-algebra", + "slop-bn254", + "slop-challenger", + "slop-koala-bear", + "slop-poseidon2", + "slop-primitives", + "slop-symmetric", +] + +[[package]] +name = "sp1-prover" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "anyhow", + "bincode", + "clap", + "dirs", + "downloader", + "either", + "enum-map", + "eyre", + "futures", + "hashbrown 0.14.5", + "hex", + "indicatif", + "itertools 0.13.0", + "lru", + "mti", + "num-bigint 0.4.6", + "opentelemetry", + "pin-project", + "rand 0.8.5", + "reqwest", + "serde", + "serde_json", + "serial_test", + "sha2", + "slop-air", + "slop-algebra", + "slop-basefold", + "slop-bn254", + "slop-challenger", + "slop-futures", + "slop-jagged", + "slop-multilinear", + "slop-stacked", + "slop-symmetric", + "sp1-core-executor", + "sp1-core-machine", + "sp1-derive", + "sp1-hypercube", + "sp1-jit", + "sp1-primitives 6.0.0", + "sp1-prover-types", + "sp1-recursion-circuit", + "sp1-recursion-compiler", + "sp1-recursion-executor", + "sp1-recursion-gnark-ffi", + "sp1-recursion-machine", + "sp1-verifier", + "static_assertions", + "sysinfo", + "tempfile", + "thiserror 1.0.69", + "tokio", + "tonic", + "tracing", + "tracing-appender", + "tracing-subscriber", +] + +[[package]] +name = "sp1-prover-types" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "anyhow", + "async-scoped", + "bincode", + "chrono", + "futures-util", + "hashbrown 0.14.5", + "mti", + "prost", + "serde", + "tokio", + "tonic", + "tonic-build", + "tracing", +] + +[[package]] +name = "sp1-recursion-circuit" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "itertools 0.13.0", + "rand 0.8.5", + "rayon", + "serde", + "slop-air", + "slop-algebra", + "slop-alloc", + "slop-basefold", + "slop-basefold-prover", + "slop-bn254", + "slop-challenger", + "slop-commit", + "slop-jagged", + "slop-koala-bear", + "slop-matrix", + "slop-merkle-tree", + "slop-multilinear", + "slop-stacked", + "slop-sumcheck", + "slop-symmetric", + "slop-tensor", + "slop-whir", + "sp1-core-executor", + "sp1-core-machine", + "sp1-derive", + "sp1-hypercube", + "sp1-primitives 6.0.0", + "sp1-recursion-compiler", + "sp1-recursion-executor", + "sp1-recursion-machine", + "tracing", +] + +[[package]] +name = "sp1-recursion-compiler" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "backtrace", + "cfg-if", + "itertools 0.13.0", + "serde", + "slop-algebra", + "slop-bn254", + "slop-symmetric", + "sp1-core-machine", + "sp1-hypercube", + "sp1-primitives 6.0.0", + "sp1-recursion-executor", + "tracing", + "vec_map", +] + +[[package]] +name = "sp1-recursion-executor" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "backtrace", + "cfg-if", + "hashbrown 0.14.5", + "itertools 0.13.0", + "range-set-blaze", + "serde", + "slop-algebra", + "slop-maybe-rayon", + "slop-poseidon2", + "slop-symmetric", + "smallvec", + "sp1-derive", + "sp1-hypercube", + "static_assertions", + "thiserror 1.0.69", + "tracing", +] + +[[package]] +name = "sp1-recursion-gnark-ffi" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "anyhow", + "bincode", + "bindgen 0.70.1", + "cfg-if", + "hex", + "num-bigint 0.4.6", + "serde", + "serde_json", + "sha2", + "slop-algebra", + "slop-symmetric", + "sp1-hypercube", + "sp1-primitives 6.0.0", + "sp1-recursion-compiler", + "sp1-verifier", + "tempfile", + "tracing", +] + +[[package]] +name = "sp1-recursion-machine" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "itertools 0.13.0", + "rand 0.8.5", + "slop-air", + "slop-algebra", + "slop-basefold", + "slop-matrix", + "slop-maybe-rayon", + "slop-symmetric", + "sp1-derive", + "sp1-hypercube", + "sp1-primitives 6.0.0", + "sp1-recursion-executor", + "strum", + "tracing", + "zkhash", +] + +[[package]] +name = "sp1-runner" +version = "0.1.0" +dependencies = [ + "bincode", + "clap", + "prover", + "rkyv", + "serde_json", + "sp1-core-executor", + "sp1-sdk", + "tokio", + "tracing", +] + +[[package]] +name = "sp1-sdk" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "anyhow", + "async-trait", + "bincode", + "cfg-if", + "dirs", + "eventsource-stream", + "futures", + "hex", + "indicatif", + "itertools 0.13.0", + "k256 0.13.4 (registry+https://github.com/rust-lang/crates.io-index)", + "num-bigint 0.4.6", + "serde", + "slop-algebra", + "sp1-build", + "sp1-core-executor", + "sp1-core-machine", + "sp1-cuda", + "sp1-hypercube", + "sp1-primitives 6.0.0", + "sp1-prover", + "sp1-prover-types", + "sp1-recursion-executor", + "sp1-recursion-gnark-ffi", + "sp1-verifier", + "strum", + "tempfile", + "thiserror 1.0.69", + "tokio", + "tracing", +] + +[[package]] +name = "sp1-verifier" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "bincode", + "blake3", + "cfg-if", + "dirs", + "hex", + "lazy_static", + "serde", + "sha2", + "slop-algebra", + "slop-primitives", + "slop-symmetric", + "sp1-hypercube", + "sp1-primitives 6.0.0", + "sp1-recursion-executor", + "sp1-recursion-machine", + "strum", + "substrate-bn-succinct", + "thiserror 2.0.17", +] + +[[package]] +name = "sp1-zkvm" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "cfg-if", + "critical-section", + "embedded-alloc", + "getrandom 0.2.16", + "getrandom 0.3.4", + "lazy_static", + "libm", + "rand 0.8.5", + "sha2", + "sp1-lib 6.0.0", + "sp1-primitives 6.0.0", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strength_reduce" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe895eb47f22e2ddd4dabc02bce419d2e643c8e3b585c78158b349195bc24d82" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "stylus-compiler-program" +version = "0.1.0" +dependencies = [ + "prover", + "sp1-zkvm", + "wasmer", +] + +[[package]] +name = "subenum" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3d08fe7078c57309d5c3d938e50eba95ba1d33b9c3a101a8465fc6861a5416" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "substrate-bn-succinct" +version = "0.6.0-v5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ba32f1b74728f92887c3ad17c42bf82998eb52c9091018f35294e9cd388b0c8" +dependencies = [ + "bytemuck", + "byteorder", + "cfg-if", + "crunchy", + "lazy_static", + "num-bigint 0.4.6", + "rand 0.8.5", + "rustc-hex", + "sp1-lib 5.2.4", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "svgbobdoc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2c04b93fc15d79b39c63218f15e3fdffaa4c227830686e3b7c5f41244eb3e50" +dependencies = [ + "base64 0.13.1", + "proc-macro2", + "quote", + "syn 1.0.109", + "unicode-width 0.1.14", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.111" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "sysinfo" +version = "0.30.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a5b4ddaee55fb2bea2bf0e5000747e5f5c0de765e5a5ff87f4cd106439f4bb3" +dependencies = [ + "cfg-if", + "core-foundation-sys", + "libc", + "ntapi", + "once_cell", + "rayon", + "windows", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tar" +version = "0.4.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "target-lexicon" +version = "0.13.3" +source = "git+https://github.com/wakabat/target-lexicon?branch=patch-v0.13.3#de11745aa0f7a24c39f2b7faa5d5283825310ae3" + +[[package]] +name = "tempfile" +version = "3.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" +dependencies = [ + "fastrand", + "getrandom 0.3.4", + "once_cell", + "rustix", + "windows-sys 0.61.2", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" +dependencies = [ + "thiserror-impl 2.0.17", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "thousands" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bf63baf9f5039dadc247375c29eb13706706cfde997d0330d05aa63a77d8820" + +[[package]] +name = "thread_local" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "time" +version = "0.3.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" + +[[package]] +name = "time-macros" +version = "0.2.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "git+https://github.com/sp1-patches/tiny-keccak?tag=patch-2.0.2-sp1-6.0.0#957430a459f7a2332ab5bab4a12f9b473bb95c87" +dependencies = [ + "cfg-if", + "crunchy", + "sp1-lib 6.0.0", +] + +[[package]] +name = "tinystr" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tinyvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" +dependencies = [ + "bytes", + "libc", + "mio", + "pin-project-lite", + "signal-hook-registry", + "socket2 0.6.1", + "tokio-macros", + "windows-sys 0.61.2", +] + +[[package]] +name = "tokio-macros" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml_datetime" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" + +[[package]] +name = "toml_datetime" +version = "0.7.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.12.1", + "toml_datetime 0.6.11", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.23.10+spec-1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" +dependencies = [ + "indexmap 2.12.1", + "toml_datetime 0.7.5+spec-1.1.0", + "toml_parser", + "winnow 0.7.14", +] + +[[package]] +name = "toml_parser" +version = "1.0.6+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" +dependencies = [ + "winnow 0.7.14", +] + +[[package]] +name = "tonic" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64 0.22.1", + "bytes", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-timeout", + "hyper-util", + "percent-encoding", + "pin-project", + "prost", + "rustls-pemfile", + "socket2 0.5.10", + "tokio", + "tokio-rustls", + "tokio-stream", + "tower 0.4.13", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tonic-build" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9557ce109ea773b399c9b9e5dca39294110b74f1f342cb347a80d1fce8c26a11" +dependencies = [ + "prettyplease", + "proc-macro2", + "prost-build", + "prost-types", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "indexmap 1.9.3", + "pin-project", + "pin-project-lite", + "rand 0.8.5", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +dependencies = [ + "bitflags 2.10.0", + "bytes", + "futures-util", + "http", + "http-body", + "iri-string", + "pin-project-lite", + "tower 0.5.2", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-appender" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "786d480bce6247ab75f005b14ae1624ad978d3029d9113f0a22fa1ac773faeaf" +dependencies = [ + "crossbeam-channel", + "thiserror 2.0.17", + "time", + "tracing-subscriber", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-forest" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee40835db14ddd1e3ba414292272eddde9dad04d3d4b65509656414d1c42592f" +dependencies = [ + "ansi_term", + "smallvec", + "thiserror 1.0.69", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex-automata", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "transpose" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad61aed86bc3faea4300c7aee358b4c6d0c8d6ccc36524c96e4c92ccf26e77e" +dependencies = [ + "num-integer", + "strength_reduce", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "twox-hash" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea3136b675547379c4bd395ca6b938e5ad3c3d20fad76e7fe85f9e0d011419c" + +[[package]] +name = "typeid_prefix" +version = "1.1.1-beta.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "257608c6fd0cbb5a8e00fe11ef14e9c285eb02f9e29624aaaba79e59a829a9e2" + +[[package]] +name = "typeid_suffix" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d46b723d74f5ede0160048deba99670a898b7905682a7a77be7cf8e8b75df50" +dependencies = [ + "uuid", +] + +[[package]] +name = "typenum" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" + +[[package]] +name = "unicode-ident" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" + +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + +[[package]] +name = "unicode-width" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "uuid" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" +dependencies = [ + "atomic", + "getrandom 0.3.4", + "js-sys", + "md-5", + "sha1_smol", + "wasm-bindgen", +] + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" +dependencies = [ + "serde", +] + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasip2" +version = "1.0.1+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c" +dependencies = [ + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 2.0.111", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "wasm-streams" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "wasmer" +version = "6.1.0" +source = "git+https://github.com/wakabat/official-wasmer?rev=e065880#e065880e79728b4d15ffc9d4eccd5153d249de2c" +dependencies = [ + "bindgen 0.72.1", + "bytes", + "cfg-if", + "cmake", + "derive_more 2.1.0", + "indexmap 2.12.1", + "js-sys", + "more-asserts", + "paste", + "rustc-demangle", + "serde", + "serde-wasm-bindgen", + "shared-buffer", + "tar", + "target-lexicon", + "thiserror 2.0.17", + "tracing", + "wasm-bindgen", + "wasmer-compiler", + "wasmer-compiler-llvm", + "wasmer-compiler-singlepass", + "wasmer-derive", + "wasmer-types", + "wasmer-vm", + "wasmparser 0.224.1", + "windows-sys 0.61.2", +] + +[[package]] +name = "wasmer-compiler" +version = "6.1.0" +source = "git+https://github.com/wakabat/official-wasmer?rev=e065880#e065880e79728b4d15ffc9d4eccd5153d249de2c" +dependencies = [ + "backtrace", + "bytes", + "cfg-if", + "enum-iterator", + "enumset", + "itertools 0.14.0", + "leb128", + "libc", + "macho-unwind-info", + "memmap2 0.9.9", + "more-asserts", + "object 0.38.0", + "region", + "rkyv", + "self_cell", + "shared-buffer", + "smallvec", + "target-lexicon", + "tempfile", + "thiserror 2.0.17", + "wasmer-types", + "wasmer-vm", + "wasmparser 0.224.1", + "which", + "windows-sys 0.61.2", + "xxhash-rust", +] + +[[package]] +name = "wasmer-compiler-llvm" +version = "6.1.0" +source = "git+https://github.com/wakabat/official-wasmer?rev=e065880#e065880e79728b4d15ffc9d4eccd5153d249de2c" +dependencies = [ + "byteorder", + "cc", + "inkwell", + "itertools 0.14.0", + "libc", + "object 0.38.0", + "phf", + "rayon", + "regex", + "rustc_version", + "semver", + "smallvec", + "target-lexicon", + "tracing", + "wasmer-compiler", + "wasmer-types", + "wasmer-vm", +] + +[[package]] +name = "wasmer-compiler-singlepass" +version = "6.1.0" +source = "git+https://github.com/wakabat/official-wasmer?rev=e065880#e065880e79728b4d15ffc9d4eccd5153d249de2c" +dependencies = [ + "byteorder", + "dynasm 4.0.2", + "dynasmrt 4.0.2", + "enumset", + "gimli", + "itertools 0.14.0", + "more-asserts", + "rayon", + "smallvec", + "target-lexicon", + "tempfile", + "wasmer-compiler", + "wasmer-types", +] + +[[package]] +name = "wasmer-derive" +version = "6.1.0" +source = "git+https://github.com/wakabat/official-wasmer?rev=e065880#e065880e79728b4d15ffc9d4eccd5153d249de2c" +dependencies = [ + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "wasmer-types" +version = "6.1.0" +source = "git+https://github.com/wakabat/official-wasmer?rev=e065880#e065880e79728b4d15ffc9d4eccd5153d249de2c" +dependencies = [ + "bytecheck", + "enum-iterator", + "enumset", + "getrandom 0.2.16", + "hex", + "indexmap 2.12.1", + "more-asserts", + "rkyv", + "sha2", + "target-lexicon", + "thiserror 2.0.17", + "xxhash-rust", +] + +[[package]] +name = "wasmer-vm" +version = "6.1.0" +source = "git+https://github.com/wakabat/official-wasmer?rev=e065880#e065880e79728b4d15ffc9d4eccd5153d249de2c" +dependencies = [ + "backtrace", + "cc", + "cfg-if", + "corosensei", + "crossbeam-queue", + "dashmap", + "enum-iterator", + "fnv", + "indexmap 2.12.1", + "libc", + "libunwind", + "mach2 0.6.0", + "memoffset", + "more-asserts", + "parking_lot", + "region", + "rustversion", + "scopeguard", + "thiserror 2.0.17", + "wasmer-types", + "windows-sys 0.61.2", +] + +[[package]] +name = "wasmparser" +version = "0.121.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dbe55c8f9d0dbd25d9447a5a889ff90c0cc3feaa7395310d3d826b2c703eaab" +dependencies = [ + "bitflags 2.10.0", + "indexmap 2.12.1", + "semver", +] + +[[package]] +name = "wasmparser" +version = "0.224.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04f17a5917c2ddd3819e84c661fae0d6ba29d7b9c1f0e96c708c65a9c4188e11" +dependencies = [ + "bitflags 2.10.0", + "hashbrown 0.15.5", + "indexmap 2.12.1", + "semver", + "serde", +] + +[[package]] +name = "web-sys" +version = "0.3.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2878ef029c47c6e8cf779119f20fcf52bde7ad42a731b2a304bc221df17571e" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "which" +version = "8.0.0" +source = "git+https://github.com/wakabat/which-rs?branch=patch-v8.0.0#9a426008c3d86d89425f6f8644700aa2d4b0a739" +dependencies = [ + "env_home", + "rustix", + "winsafe", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core 0.52.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.5", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "winnow" +version = "0.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +dependencies = [ + "memchr", +] + +[[package]] +name = "winsafe" +version = "0.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" + +[[package]] +name = "wit-bindgen" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" + +[[package]] +name = "writeable" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "xattr" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156" +dependencies = [ + "libc", + "rustix", +] + +[[package]] +name = "xxhash-rust" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdd20c5420375476fbd4394763288da7eb0cc0b8c11deed431a91562af7335d3" + +[[package]] +name = "yoke" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.8.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "zerotrie" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "zkhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4352d1081da6922701401cdd4cbf29a2723feb4cfabb5771f6fee8e9276da1c7" +dependencies = [ + "ark-ff", + "ark-std", + "bitvec", + "blake2", + "bls12_381", + "byteorder", + "cfg-if", + "group 0.12.1", + "group 0.13.0", + "halo2", + "hex", + "jubjub", + "lazy_static", + "pasta_curves 0.5.1", + "rand 0.8.5", + "serde", + "sha2", + "sha3", + "subtle", +] diff --git a/sp1-crates/Cargo.toml b/sp1-crates/Cargo.toml new file mode 100644 index 00000000000..154ef53fd14 --- /dev/null +++ b/sp1-crates/Cargo.toml @@ -0,0 +1,84 @@ +[workspace] +resolver = "3" + +members = ["program", "builder", "stylus-compiler-program", "prover", "runner"] + +[workspace.dependencies] +sp1-build = { version = "6.0.0", features = ["may_dump_elf"] } +sp1-core-executor = "6.0.0" +sp1-lib = "6.0.0" +sp1-primitives = "6.0.0" +sp1-sdk = { version = "6.0.0", features = ["profiling"] } +sp1-zkvm = { version = "6.0.0", features = ["untrusted_programs", "may_dump_elf"] } + +arbutil = { path = "../arbitrator/arbutil" } +prover = { path = "prover", default-features = false, features = ["sp1"] } + +bincode = "1.3.3" +bytes = "1" +clap = { version = "4.5.53", features = ["cargo", "derive"] } +corosensei = "0.3.0" +derivative = "2.2.0" +digest = "0.10.7" +eyre = "0.6.5" +fnv = "1.0.7" +hex = "0.4.3" +lazy_static = "1.4.0" +nom = "7.0.0" +num-derive = "0.4.1" +num-traits = "0.2.17" +num_enum = "0.7.1" +once_cell = "1.21.3" +parking_lot = "0.12.1" +rand_pcg = { version = "0.3.1", default-features = false } +rand = { version = "0.8.4", default-features = false } +rkyv = { version = "0.8.8", features = ["indexmap-2", "bytes-1"] } +ruint2 = "1.9.0" +tracing = "0.1.40" +tokio = "1.42.0" +serde = "1.0.130" +serde_json = "1.0.67" +serde_with = "3.8.1" +sha3 = "0.10.8" +thiserror = "1.0.33" +wasmparser = "0.224.0" + +brotli = { git = "https://github.com/wakabat/rust-brotli", rev = "37b6403" } + +[workspace.dependencies.secp256k1] +git = "https://github.com/sp1-patches/rust-secp256k1" +tag = "patch-0.29.1-sp1-6.0.0" +features = [ "recovery", "global-context" ] + +[workspace.dependencies.tiny-keccak] +git = "https://github.com/sp1-patches/tiny-keccak" +tag = "patch-2.0.2-sp1-6.0.0" +features = ["keccak"] + +[workspace.dependencies.wasmer] +git = "https://github.com/wakabat/official-wasmer" +rev = "e065880" +default-features = false +features = ["sys", "compiler", "singlepass", "wasmparser"] + +[workspace.dependencies.wasmer-types] +git = "https://github.com/wakabat/official-wasmer" +rev = "e065880" + +[workspace.dependencies.wasmer-vm] +git = "https://github.com/wakabat/official-wasmer" +rev = "e065880" +features = ["force-baremetal"] + +[patch.crates-io] +target-lexicon = { git = "https://github.com/wakabat/target-lexicon", branch = "patch-v0.13.3" } +region = { git = "https://github.com/wakabat/region-rs", branch = "patch-v3.0.2" } +corosensei = { git = "https://github.com/wakabat/corosensei", branch = "patch-v0.3.2" } +which = { git = "https://github.com/wakabat/which-rs", branch = "patch-v8.0.0" } + +sp1-build = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe" } +sp1-core-executor = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe" } +sp1-lib = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe" } +sp1-primitives = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe" } +sp1-sdk = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe" } +sp1-zkvm = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe" } diff --git a/sp1-crates/README.md b/sp1-crates/README.md new file mode 100644 index 00000000000..472a5e3f5c4 --- /dev/null +++ b/sp1-crates/README.md @@ -0,0 +1,79 @@ +This folder adds a new Arbitrum block runner(like `jit` and `prover` in `arbitrator` folder), powered by [Succinct SP1](https://github.com/succinctlabs/sp1). For now we are only showcasing the executor powered by SP1, but the same code should be able to generate zero knowledge proofs for validating an Arbitrum block. + +Ideally, the crates in this folder shall be merged into `arbitrator`. But for now, the differences in wasmer and Rust versions prevent us from doing this. Later when all the issues have been tackled we will likely merge both Rust workspaces. + +## Usage + +To build this runner, of course you must be able to build a significant part of nitro. Please refer to [this document](https://docs.arbitrum.io/run-arbitrum-node/nitro/build-nitro-locally) on setting up the computer to build nitro. + +One major dependency wasmer also requires you to have LLVM 21 installed. Please note that you must have LLVM 21.x.y installed. Wasmer requires this major version. + +The code included here requires a SP1 Rust toolchain with riscv64 support. You can use the following commands: + +```bash +$ curl -L https://sp1up.succinct.xyz | bash +$ sp1up -v v6.0.0-beta.1 +``` + +To verify that correct toolchain have been installed, you can run the following 2 commands, and compare output: + +```bash +$ rustc +succinct --version +rustc 1.93.0-dev +$ rustc +succinct --print target-list | grep succinct +riscv32im-succinct-zkvm-elf +riscv64im-succinct-zkvm-elf +``` + +Now you can start the build process: + +```bash +$ git clone https://github.com/OffchainLabs/nitro +$ # Checkout current PR +$ ./sp1-crates/build.sh +``` + +To make things easier to understand, for now we are using a simple bash script. As the code grow more mature, we would merge the bash script into the top-level makefile. + +After the build process, all the files required by SP1 runner can be found in `target/sp1` folder. Some important files are: + +* `replay.wasm`: this is Arbitrum's STF built with `sp1` tag enabled, so it contains SP1 specific optimizations +* `dumped_replay_wasm.elf`: this is the SP1 version of `replay.wasm`. The 2 fulfill the same task. It's just that `dumped_replay_wasm.elf` is in RISC-V architecture accepted by SP1, following SP1's ABIs. +* `stylus-compiler-program`: this is a SP1 program wrapping wasmer's singlepass compiler. It can compile an Arbitrum stylus program into RISC-V format accepted by SP1. +* `sp1-runner`: this is the SP1 runner that can execute / validate an Arbitrum block. One can see it as SP1 version of `jit` or `prover` in `arbitrator` workspace. +* `*.json`: sample Arbitrum test blocks you can use for testing. In my run, `block_inputs_7.json` was generated. + +There are also other files in the folder, but you can safely ignore them. They are kept now for debugging purposes. + +Now you can use the following command to execute an Arbitrum block using SP1 runner: + +```bash +$ ./target/sp1/sp1-runner \ + --program target/sp1/dumped_replay_wasm.elf \ + --stylus-compiler-program target/sp1/stylus-compiler-program \ + --block-file target/sp1/block_inputs_7.json +stderr: WARNING: Using insecure random number generator. +stdout: Validation succeeds with hash 624b2d504238ba9fe94ad3e19d1036a51894bc209b7f0ead1331d22005d40178 +``` + +You can tweak `RUST_LOG` for more logs(e.g., running cycles and running time): + +```bash +$ RUST_LOG=info ./target/sp1/sp1-runner \ + --program target/sp1/dumped_replay_wasm.elf \ + --stylus-compiler-program target/sp1/stylus-compiler-program \ + --block-file target/sp1/block_inputs_7.json +``` + +You can also compare the result hash with Arbitrum's own JIT engine: + +```bash +$ ./target/bin/jit \ + --debug --cranelift \ + --binary target/machines/latest/replay.wasm \ + --json-inputs=target/sp1/block_inputs_7.json +Created the machine in 4081ms. +Completed in 19ms with hash 624b2d504238ba9fe94ad3e19d1036a51894bc209b7f0ead1331d22005d40178. +``` + +You can also generate other Arbitrum blocks to test. There is one caveat: for any stylus programs that might be executed, you must include the original wasm source in the block JSON file as well. SP1 runner works either with the original WASM source files(it will invoke stylus compiler program automatically), or the `rv64` target binary after compilation. You can also refer to [this commit](https://github.com/wakabat/nitro/commit/d924d4907ace4bd329b27dacd31ebad832b6eb90) where we patch nitro's tests to dump as many acceptable test blocks as possible. diff --git a/sp1-crates/build.sh b/sp1-crates/build.sh new file mode 100755 index 00000000000..d02b78dc0e1 --- /dev/null +++ b/sp1-crates/build.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash + +set -ex + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +export TOP=$SCRIPT_DIR/.. + +cd $TOP +# Build nitro dependencies +make build-replay-env test-go-deps +rm -rf target/sp1 +mkdir -p target/sp1 +export OUTPUT_DIR=$TOP/target/sp1 +# Build replay.wasm, but with SP1 optimizations +GOOS=wasip1 GOARCH=wasm go build -tags sp1 -o $OUTPUT_DIR/replay.wasm $TOP/cmd/replay/... +# Build a sample Arbitrum test block +rm -rf system_tests/test-data +go test -run TestProgramStorage ./system_tests/ -- \ + -recordBlockInputs.WithBaseDir=`pwd`/system_tests/test-data \ + -recordBlockInputs.WithTimestampDirEnabled=false \ + -recordBlockInputs.enable=true +cp system_tests/test-data/TestProgramStorage/*.json target/sp1/ + +cd $SCRIPT_DIR +# Bump SP1's maximum heap memory size +export SP1_ZKVM_MAX_MEMORY=1099511627776 +# Build SP1 program and run bootloading process +cargo run --release -p sp1-builder -- --replay-wasm $OUTPUT_DIR/replay.wasm --output-folder $OUTPUT_DIR +# Build the SP1 runner +cargo build --release -p sp1-runner + +# Copy relavant files to target folder +cp target/elf-compilation/riscv64im-succinct-zkvm-elf/release/stylus-compiler-program $OUTPUT_DIR +cp target/release/sp1-runner $OUTPUT_DIR + +echo "SP1 runner is successfully built!" diff --git a/sp1-crates/builder/Cargo.toml b/sp1-crates/builder/Cargo.toml new file mode 100644 index 00000000000..d1ce116a97e --- /dev/null +++ b/sp1-crates/builder/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "sp1-builder" +description = "A builder crate that builds SP1 programs, necessary metadata, then run bootloader to generated bootloaded SP1 program" +version = "0.1.0" +edition = "2024" + +[dependencies] +sp1-core-executor = { workspace = true } +sp1-sdk = { workspace = true } + +clap = { workspace = true } +serde_json = { workspace = true } +wasmer = { workspace = true, features = ["llvm"] } +wasmparser = { workspace = true } + +[build-dependencies] +sp1-build = { workspace = true } diff --git a/sp1-crates/builder/build.rs b/sp1-crates/builder/build.rs new file mode 100644 index 00000000000..b838b9c2bb1 --- /dev/null +++ b/sp1-crates/builder/build.rs @@ -0,0 +1,4 @@ +fn main() { + sp1_build::build_program("../stylus-compiler-program"); + sp1_build::build_program("../program"); +} diff --git a/sp1-crates/builder/src/main.rs b/sp1-crates/builder/src/main.rs new file mode 100644 index 00000000000..78216c7b4e2 --- /dev/null +++ b/sp1-crates/builder/src/main.rs @@ -0,0 +1,136 @@ +use clap::Parser; +use sp1_core_executor::{MinimalExecutor, Program}; +use sp1_sdk::{Elf, include_elf}; +use std::collections::HashMap; +use std::path::PathBuf; +use std::str::FromStr; +use std::sync::Arc; +use wasmer::{ + Module, Store, + sys::{CpuFeature, EngineBuilder, LLVM, Target, Triple}, +}; + +pub const PROGRAM_ELF: Elf = include_elf!("program"); + +#[derive(Debug, Parser)] +#[command(version, about, long_about = None)] +struct Cli { + /// Path to replay.wasm file + #[arg(long)] + replay_wasm: String, + + /// Output folder for generated artifacts + #[arg(long)] + output_folder: PathBuf, +} + +fn main() { + let cli = Cli::parse(); + let wasm = std::fs::read(&cli.replay_wasm).expect("read replay.wasm"); + + // Step 1: given wasm file, extract the original function names. + // This information is lost in wasmer's generated binary, but the + // function names can be very useful in debugging & profiling. + let function_names_json = { + use wasmparser::{BinaryReader, Name, NameSectionReader, Parser, Payload}; + + let mut name_mapping = HashMap::new(); + for payload in Parser::new(0).parse_all(&wasm) { + match payload { + Ok(Payload::CustomSection(s)) if s.name() == "name" => { + let name_reader = + NameSectionReader::new(BinaryReader::new(s.data(), s.data_offset())); + for name in name_reader { + match name.expect("name") { + Name::Function(name_map) => { + for naming in name_map { + let naming = naming.expect("naming"); + name_mapping.insert(naming.index, naming.name.to_string()); + } + } + _ => (), + } + } + } + _ => (), + } + } + + // names might be sparse, we need more processing work here. + let min_index = name_mapping.iter().map(|(index, _)| *index).min().unwrap(); + let name_mapping: Vec<(usize, String)> = name_mapping + .into_iter() + .map(|(index, name)| ((index - min_index) as usize, name)) + .collect(); + let mut names = vec![None; name_mapping.iter().max_by_key(|(i, _)| i).unwrap().0 + 1]; + for (i, name) in name_mapping { + names[i] = Some(name); + } + + let names_json = serde_json::to_string_pretty(&names).expect("serde_json"); + + let output = cli.output_folder.join("function_names.json"); + println!("Write wasm function names to {}", output.display()); + std::fs::write(output, &names_json).expect("write function_names.json"); + + names_json + }; + + // Step 2: build wasmu (riscv64 target) file from replay.wasm, + // using wasmer's LLVM compiler. + let wasmu_binary = { + let target = Target::new(Triple::from_str("riscv64").unwrap(), CpuFeature::set()); + let config = LLVM::new(); + let engine = EngineBuilder::new(config).set_target(Some(target)).engine(); + + let store = Store::new(engine); + let module = Module::new(&store, wasm).expect("wasm compilation"); + let wasmu_binary = module.serialize().expect("serialize module"); + + let output = cli.output_folder.join("replay.wasmu"); + println!("Compile {} to {}", cli.replay_wasm, output.display()); + std::fs::write(output, &wasmu_binary).expect("write replay.wasmu"); + + wasmu_binary + }; + + // Step 3: use generated data from previous steps to bootload SP1 program. + { + sp1_sdk::utils::setup_logger(); + + let output = match std::env::var("DUMP_ELF_OUTPUT") { + Ok(s) => s, + Err(_) => { + let output = cli.output_folder.join("dumped_replay_wasm.elf"); + unsafe { std::env::set_var("DUMP_ELF_OUTPUT", &output) }; + output.display().to_string() + } + }; + let _ = std::fs::remove_file(&output); + assert!(!std::fs::exists(&output).unwrap()); + + let program = Arc::new(Program::from(&PROGRAM_ELF).expect("parse elf")); + let mut executor = MinimalExecutor::simple(program); + executor.with_input(&wasmu_binary); + executor.with_input(function_names_json.as_bytes()); + // The executed program expects an Arbitrum block, sending it an + // empty buffer would fail. However, it does not matter here, since + // all we need to do is the bootloading process, which should finish + // before reading this input. + executor.with_input(&[]); + + assert!(executor.execute_chunk().is_none()); + + if let Ok(true) = std::fs::exists(&output) { + println!( + "SP1 bootloading process completes. It's fine if you are seeing some errors, please ignore them" + ); + } else { + panic!("Something is wrong with SP1 bootloading process, please check the logs."); + } + + println!("Bootloaded program is written to {}", output); + } + + println!("All build processes are completed!"); +} diff --git a/sp1-crates/program/Cargo.toml b/sp1-crates/program/Cargo.toml new file mode 100644 index 00000000000..6ba6bc52096 --- /dev/null +++ b/sp1-crates/program/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "program" +description = "Initial SP1 program for validating Arbitrum blocks, it will be bootloaded for optimizations." +version = "0.1.0" +edition = "2024" + +[dependencies] +sp1-zkvm = { workspace = true } +wasmer = { workspace = true } +wasmer-types = { workspace = true } +wasmer-vm = { workspace = true } +prover = { workspace = true, features = ["native"] } +arbutil = { workspace = true } + +brotli = { workspace = true } +bytes = { workspace = true } +corosensei = { workspace = true } +eyre = { workspace = true } +hex = { workspace = true } +num_enum = { workspace = true } +num-traits = { workspace = true } +once_cell = { workspace = true } +rand_pcg = { workspace = true } +rand = { workspace = true } +ruint2 = { workspace = true } +secp256k1 = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } +thiserror = { workspace = true } +tiny-keccak = { workspace = true } diff --git a/sp1-crates/program/src/imports/arbcompress.rs b/sp1-crates/program/src/imports/arbcompress.rs new file mode 100644 index 00000000000..988a6676106 --- /dev/null +++ b/sp1-crates/program/src/imports/arbcompress.rs @@ -0,0 +1,87 @@ +//! This module implements arbcompression functions required by Arbitrum. +//! It is based on: +//! https://github.com/OffchainLabs/nitro/blob/d2dba175c037c47e68cf3038f0d4b06b54983644/arbitrator/caller-env/src/brotli/mod.rs +//! But a pure Rust brotli implementation is used instead of the C++ FFI one. +//! We have verified (in a small scale) that the 2 brotli implementations generate +//! the same bytes in both compression and decompression. + +use crate::{Escape, Ptr, read_slice, replay::CustomEnvData}; +use brotli::{Allocator, CompressorWriter, Decompressor, HeapAlloc, SliceWrapperMut}; +use std::io::{Cursor, Read, Write}; +use wasmer::FunctionEnvMut; + +const STYLUS_DICTIONARY: &[u8] = + include_bytes!("../../../../arbitrator/brotli/src/dicts/stylus-program-11.lz"); + +// Following Arbitrum's convention +pub const BROTLI_SUCCESS: u32 = 1; + +pub fn brotli_compress( + mut ctx: FunctionEnvMut, + in_buf_ptr: Ptr, + in_buf_len: u32, + out_buf_ptr: Ptr, + out_len_ptr: Ptr, + level: u32, + window_size: u32, + dictionary: u8, +) -> Result { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + let input = read_slice(in_buf_ptr, in_buf_len as usize, &memory)?; + let mut output = vec![]; + { + let mut writer = CompressorWriter::new(&mut output, 4096, level, window_size); + match dictionary { + 0 => (), // Empty dictionary + 1 => writer.set_custom_dictionary(STYLUS_DICTIONARY), + _ => panic!("Unknown dictionary value: {dictionary}"), + } + writer.write_all(&input)?; + } + let out_len = out_len_ptr.read(&memory)?; + assert!(output.len() <= out_len as usize); + + memory.write(out_buf_ptr.offset() as u64, &output)?; + out_len_ptr.write(&memory, output.len() as u32)?; + + Ok(BROTLI_SUCCESS) +} + +pub fn brotli_decompress( + mut ctx: FunctionEnvMut, + in_buf_ptr: Ptr, + in_buf_len: u32, + out_buf_ptr: Ptr, + out_len_ptr: Ptr, + dictionary: u8, +) -> Result { + // Keep the allocator alive for the duration of this method + let mut allocator = HeapAlloc::default(); + + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + let input = read_slice(in_buf_ptr, in_buf_len as usize, &memory)?; + let mut decompressor = match dictionary { + 0 => Decompressor::new(Cursor::new(input), 4096), + 1 => { + // This is slow(requires copying for every operation), but it might work now. + let mut buffer = allocator.alloc_cell(STYLUS_DICTIONARY.len()); + buffer.slice_mut().copy_from_slice(STYLUS_DICTIONARY); + Decompressor::new_with_custom_dict(Cursor::new(input), 4096, buffer) + } + _ => panic!("Unknown dictionary value: {dictionary}"), + }; + let mut output = vec![]; + decompressor.read_to_end(&mut output)?; + + let out_len = out_len_ptr.read(&memory)?; + assert!(output.len() <= out_len as usize); + + memory.write(out_buf_ptr.offset() as u64, &output)?; + out_len_ptr.write(&memory, output.len() as u32)?; + + Ok(BROTLI_SUCCESS) +} diff --git a/sp1-crates/program/src/imports/debug.rs b/sp1-crates/program/src/imports/debug.rs new file mode 100644 index 00000000000..2aa32a27001 --- /dev/null +++ b/sp1-crates/program/src/imports/debug.rs @@ -0,0 +1,43 @@ +use crate::{Escape, MaybeEscape, Ptr, read_slice, stylus::StylusCustomEnvData}; +use prover::value::Value; +use wasmer::FunctionEnvMut; + +pub fn console_log_text( + mut ctx: FunctionEnvMut, + ptr: Ptr, + len: u32, +) -> MaybeEscape { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + let text = read_slice(ptr, len as usize, &memory)?; + println!("Stylus says: {}", String::from_utf8_lossy(&text)); + Ok(()) +} + +pub fn console_log>( + _ctx: FunctionEnvMut, + value: T, +) -> MaybeEscape { + let value = value.into(); + println!("Stylus says: {}", value); + Ok(()) +} + +pub fn console_tee + Copy>( + _ctx: FunctionEnvMut, + value: T, +) -> Result { + println!("Stylus says: {}", value.into()); + Ok(value) +} + +pub fn null_host(_ctx: FunctionEnvMut) {} + +pub fn start_benchmark(_ctx: FunctionEnvMut) -> MaybeEscape { + unimplemented!() +} + +pub fn end_benchmark(_ctx: FunctionEnvMut) -> MaybeEscape { + unimplemented!() +} diff --git a/sp1-crates/program/src/imports/mod.rs b/sp1-crates/program/src/imports/mod.rs new file mode 100644 index 00000000000..49e7245f595 --- /dev/null +++ b/sp1-crates/program/src/imports/mod.rs @@ -0,0 +1,13 @@ +//! All wasmer import functions +//! +//! TODO: many of the implementations here, are reimplementing the same +//! functions from jit & prover modules. Maybe we should revisit the code +//! and see if we can merge multiple implementations into one. + +pub mod arbcompress; +pub mod debug; +pub mod precompiles; +pub mod programs; +pub mod vm_hooks; +pub mod wasi_stub; +pub mod wavmio; diff --git a/sp1-crates/program/src/imports/precompiles.rs b/sp1-crates/program/src/imports/precompiles.rs new file mode 100644 index 00000000000..597cef826cb --- /dev/null +++ b/sp1-crates/program/src/imports/precompiles.rs @@ -0,0 +1,61 @@ +use crate::{Escape, MaybeEscape, Ptr, keccak, platform, read_slice, replay::CustomEnvData}; +use wasmer::FunctionEnvMut; + +use secp256k1::{ + Message, + ecdsa::{RecoverableSignature, RecoveryId}, +}; + +pub fn ecrecover( + mut ctx: FunctionEnvMut, + hash: Ptr, + sig: Ptr, + output: Ptr, +) -> Result { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + let hash = read_slice(hash, 32, &memory)?; + let sig = read_slice(sig, 65, &memory)?; + + let message = Message::from_digest(hash.try_into().unwrap()); + let Ok(recovery_id) = RecoveryId::from_i32(sig[64] as i32) else { + return Ok(1); + }; + let Ok(signature) = RecoverableSignature::from_compact(&sig[0..64], recovery_id) else { + return Ok(2); + }; + + let Ok(public_key) = signature.recover(&message) else { + return Ok(3); + }; + let serialized_pub_key = public_key.serialize_uncompressed(); + + memory.write(output.offset() as u64, &serialized_pub_key)?; + Ok(0) +} + +pub fn keccak256( + mut ctx: FunctionEnvMut, + input: Ptr, + input_length: u32, + output: Ptr, +) -> MaybeEscape { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + let input = read_slice(input, input_length as usize, &memory)?; + let hash = keccak(input); + memory.write(output.offset() as u64, &hash)?; + + Ok(()) +} + +pub fn dump_elf(mut ctx: FunctionEnvMut) -> MaybeEscape { + let data = ctx.data_mut(); + assert!(!data.input_initialized()); + + platform::dump_elf(); + + Ok(()) +} diff --git a/sp1-crates/program/src/imports/programs.rs b/sp1-crates/program/src/imports/programs.rs new file mode 100644 index 00000000000..ab1a65d477f --- /dev/null +++ b/sp1-crates/program/src/imports/programs.rs @@ -0,0 +1,293 @@ +//! This module should implement programs related APIs, mainly for +//! launching stylus programs. +//! TODO: for now, we are focusing on getting replay.wasm to run first, +//! so this module only contains dummy impls that serve as a placeholder, +//! and will throw errors when called. +//! They are expected to follow implementations in: +//! https://github.com/OffchainLabs/nitro/blob/d2dba175c037c47e68cf3038f0d4b06b54983644/arbitrator/jit/src/program.rs + +use crate::{ + Escape, JitConfig, MaybeEscape, Ptr, read_bytes20, read_bytes32, read_slice, + replay::CustomEnvData, stylus::MessageToCothread, +}; +use arbutil::evm::{EvmData, api::Gas}; +use prover::programs::config::{CompileConfig, PricingParams, StylusConfig}; +use wasmer::{FunctionEnvMut, WasmPtr}; + +pub fn new_program( + mut ctx: FunctionEnvMut, + compiled_hash_ptr: Ptr, + calldata_ptr: Ptr, + calldata_size: u32, + stylus_config_handler: u64, + evm_data_handler: u64, + gas: u64, +) -> Result { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + let compiled_hash = read_bytes32(compiled_hash_ptr, &memory)?; + let calldata = read_slice(calldata_ptr, calldata_size as usize, &memory)?; + let evm_data: EvmData = unsafe { *Box::from_raw(evm_data_handler as *mut EvmData) }; + let config: JitConfig = unsafe { *Box::from_raw(stylus_config_handler as *mut JitConfig) }; + + data.launch_program(&compiled_hash, calldata, config, evm_data, gas) +} + +pub fn pop(mut ctx: FunctionEnvMut) { + let data = ctx.data_mut(); + + // FIXME: this is wrong, when poping, we should yield from replay.wasm coroutine, and keep running the poped program till it sends the last message and terminates. + data.pop_last_program(); +} + +pub fn set_response( + mut ctx: FunctionEnvMut, + id: u32, + gas: u64, + result_ptr: Ptr, + result_len: u32, + raw_data_ptr: Ptr, + raw_data_len: u32, +) -> MaybeEscape { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + // Arbitrator for now only uses hardcoded id, we can ignore + // ids safely. + assert_eq!(id, 0x33333333); + + let result = read_slice(result_ptr, result_len as usize, &memory)?; + let raw_data = read_slice(raw_data_ptr, raw_data_len as usize, &memory)?; + + data.send_to_cothread(MessageToCothread { + result, + raw_data, + cost: Gas(gas), + }); + + Ok(()) +} + +pub fn get_request( + mut ctx: FunctionEnvMut, + id: u32, + len_ptr: Ptr, +) -> Result { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + // Arbitrator for now only uses hardcoded id, we can ignore + // ids safely. + assert_eq!(id, 0x33333333); + + let msg = data.get_last_msg(); + len_ptr.write(&memory, msg.req_data.len() as u32)?; + + Ok(msg.req_type) +} + +pub fn get_request_data( + mut ctx: FunctionEnvMut, + id: u32, + data_ptr: Ptr, +) -> MaybeEscape { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + // Arbitrator for now only uses hardcoded id, we can ignore + // ids safely. + assert_eq!(id, 0x33333333); + + let msg = data.get_last_msg(); + memory.write(data_ptr.offset() as u64, &msg.req_data)?; + + Ok(()) +} + +pub fn start_program(mut ctx: FunctionEnvMut, module: u32) -> u32 { + let data = ctx.data_mut(); + + data.wait_next_message(Some(module)); + let _ = data.get_last_msg(); + + // Arbitrator for now only uses hardcoded id, we can ignore + // ids safely. + 0x33333333 +} + +pub fn send_response(mut ctx: FunctionEnvMut, req_id: u32) -> u32 { + let data = ctx.data_mut(); + + // Arbitrator for now only uses hardcoded id, we can ignore + // ids safely. + assert_eq!(req_id, 0x33333333); + + data.wait_next_message(None); + let _ = data.get_last_msg(); + + 0x33333333 +} + +pub fn create_stylus_config( + _ctx: FunctionEnvMut, + version: u16, + max_depth: u32, + ink_price: u32, + debug: u32, +) -> u64 { + let stylus = StylusConfig { + version, + max_depth, + pricing: PricingParams { ink_price }, + }; + let compile = CompileConfig::version(version, debug != 0); + let res = heapify(JitConfig { stylus, compile }); + res as u64 +} + +const DEFAULT_STYLUS_ARBOS_VERSION: u64 = 31; + +pub fn create_evm_data( + ctx: FunctionEnvMut, + block_basefee_ptr: Ptr, + chainid: u64, + block_coinbase_ptr: Ptr, + block_gas_limit: u64, + block_number: u64, + block_timestamp: u64, + contract_address_ptr: Ptr, + module_hash_ptr: Ptr, + msg_sender_ptr: Ptr, + msg_value_ptr: Ptr, + tx_gas_price_ptr: Ptr, + tx_origin_ptr: Ptr, + cached: u32, + reentrant: u32, +) -> Result { + create_evm_data_v2( + ctx, + DEFAULT_STYLUS_ARBOS_VERSION, + block_basefee_ptr, + chainid, + block_coinbase_ptr, + block_gas_limit, + block_number, + block_timestamp, + contract_address_ptr, + module_hash_ptr, + msg_sender_ptr, + msg_value_ptr, + tx_gas_price_ptr, + tx_origin_ptr, + cached, + reentrant, + ) +} + +pub fn create_evm_data_v2( + mut ctx: FunctionEnvMut, + arbos_version: u64, + block_basefee_ptr: Ptr, + chainid: u64, + block_coinbase_ptr: Ptr, + block_gas_limit: u64, + block_number: u64, + block_timestamp: u64, + contract_address_ptr: Ptr, + module_hash_ptr: Ptr, + msg_sender_ptr: Ptr, + msg_value_ptr: Ptr, + tx_gas_price_ptr: Ptr, + tx_origin_ptr: Ptr, + cached: u32, + reentrant: u32, +) -> Result { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + let evm_data = EvmData { + arbos_version, + block_basefee: read_bytes32(block_basefee_ptr, &memory)?, + cached: cached != 0, + chainid, + block_coinbase: read_bytes20(block_coinbase_ptr, &memory)?, + block_gas_limit, + block_number, + block_timestamp, + contract_address: read_bytes20(contract_address_ptr, &memory)?, + module_hash: read_bytes32(module_hash_ptr, &memory)?, + msg_sender: read_bytes20(msg_sender_ptr, &memory)?, + msg_value: read_bytes32(msg_value_ptr, &memory)?, + tx_gas_price: read_bytes32(tx_gas_price_ptr, &memory)?, + tx_origin: read_bytes20(tx_origin_ptr, &memory)?, + reentrant, + return_data_len: 0, + tracing: false, + }; + + let res = heapify(evm_data); + Ok(res as u64) +} + +pub fn activate( + ctx: FunctionEnvMut, + wasm_ptr: Ptr, + wasm_size: u32, + pages_ptr: WasmPtr, + asm_estimate_ptr: Ptr, + init_cost_ptr: WasmPtr, + cached_init_cost_ptr: WasmPtr, + stylus_version: u16, + debug: u32, + codehash: Ptr, + module_hash_ptr: Ptr, + gas_ptr: WasmPtr, + err_buf: Ptr, + err_buf_len: u32, +) -> Result { + activate_v2( + ctx, + wasm_ptr, + wasm_size, + pages_ptr, + asm_estimate_ptr, + init_cost_ptr, + cached_init_cost_ptr, + stylus_version, + DEFAULT_STYLUS_ARBOS_VERSION, + debug, + codehash, + module_hash_ptr, + gas_ptr, + err_buf, + err_buf_len, + ) +} + +pub fn activate_v2( + _ctx: FunctionEnvMut, + _wasm_ptr: Ptr, + _wasm_size: u32, + _pages_ptr: WasmPtr, + _asm_estimate_ptr: Ptr, + _init_cost_ptr: WasmPtr, + _cached_init_cost_ptr: WasmPtr, + _stylus_version: u16, + _arbos_version_for_gas: u64, + _debug: u32, + _codehash: Ptr, + _module_hash_ptr: Ptr, + _gas_ptr: WasmPtr, + _err_buf: Ptr, + _err_buf_len: u32, +) -> Result { + // TODO: per offline discussion with the Arbitrum team, we will call + // into a separate WASM module to calculate WAVM hash for each stylus + // program. We won't aim to pull in WAVM logic here. + todo!("Implement activate_v2!"); +} + +fn heapify(value: T) -> *mut T { + Box::into_raw(Box::new(value)) +} diff --git a/sp1-crates/program/src/imports/vm_hooks.rs b/sp1-crates/program/src/imports/vm_hooks.rs new file mode 100644 index 00000000000..419eebebdb9 --- /dev/null +++ b/sp1-crates/program/src/imports/vm_hooks.rs @@ -0,0 +1,734 @@ +use crate::{ + CallInputs, Escape, MaybeEscape, Ptr, keccak, read_bytes20, read_bytes32, read_slice, + stylus::StylusCustomEnvData, +}; +use arbutil::{ + Bytes32, + evm::{ + ARBOS_VERSION_STYLUS_CHARGING_FIXES, COLD_ACCOUNT_GAS, COLD_SLOAD_GAS, SSTORE_SENTRY_GAS, + TLOAD_GAS, TSTORE_GAS, api::Gas, storage::StorageCache, user::UserOutcomeKind, + }, + pricing::{EVM_API_INK, hostio}, +}; +use eyre::eyre; +use prover::programs::meter::{GasMeteredMachine, MeteredMachine}; +use wasmer::{FunctionEnvMut, MemoryView}; + +pub fn msg_reentrant(mut ctx: FunctionEnvMut) -> u32 { + let data = ctx.data_mut(); + data.buy_ink(hostio::MSG_REENTRANT_BASE_INK) + .expect("buy ink"); + + data.evm_data.reentrant +} + +pub fn read_args(mut ctx: FunctionEnvMut, ptr: Ptr) -> MaybeEscape { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + data.buy_ink(hostio::READ_ARGS_BASE_INK)?; + data.pay_for_write(data.calldata.len() as u32)?; + + memory.write(ptr.offset() as u64, &data.calldata)?; + + Ok(()) +} + +pub fn storage_load_bytes32( + mut ctx: FunctionEnvMut, + key: Ptr, + dest: Ptr, +) -> MaybeEscape { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + data.buy_ink(hostio::STORAGE_LOAD_BASE_INK)?; + + let arbos_version = data.evm_data.arbos_version; + let evm_api_gas_to_use = if arbos_version < ARBOS_VERSION_STYLUS_CHARGING_FIXES { + Gas(EVM_API_INK.0) + } else { + data.pricing().ink_to_gas(EVM_API_INK) + }; + data.require_gas(COLD_SLOAD_GAS + StorageCache::REQUIRED_ACCESS_GAS + evm_api_gas_to_use)?; + + let key = read_bytes32(key, &memory)?; + + let (value, gas_cost) = data.get_bytes32(key, evm_api_gas_to_use); + data.buy_gas(gas_cost)?; + memory.write(dest.offset() as u64, value.as_slice())?; + + Ok(()) +} + +pub fn transient_load_bytes32( + mut ctx: FunctionEnvMut, + key: Ptr, + dest: Ptr, +) -> MaybeEscape { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + data.buy_ink(hostio::TRANSIENT_LOAD_BASE_INK)?; + data.buy_gas(TLOAD_GAS)?; + + let key = read_bytes32(key, &memory)?; + let value = data.get_transient_bytes32(key); + memory.write(dest.offset() as u64, value.as_slice())?; + + Ok(()) +} + +pub fn storage_cache_bytes32( + mut ctx: FunctionEnvMut, + key: Ptr, + value: Ptr, +) -> MaybeEscape { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + data.buy_ink(hostio::STORAGE_CACHE_BASE_INK)?; + data.require_gas(SSTORE_SENTRY_GAS + StorageCache::REQUIRED_ACCESS_GAS)?; + + let key = read_bytes32(key, &memory)?; + let value = read_bytes32(value, &memory)?; + + let gas_cost = data.cache_bytes32(key, value); + data.buy_gas(gas_cost)?; + + Ok(()) +} + +pub fn transient_store_bytes32( + mut ctx: FunctionEnvMut, + key: Ptr, + value: Ptr, +) -> MaybeEscape { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + data.buy_ink(hostio::TRANSIENT_STORE_BASE_INK)?; + data.buy_gas(TSTORE_GAS)?; + + let key = read_bytes32(key, &memory)?; + let value = read_bytes32(value, &memory)?; + + data.set_transient_bytes32(key, value)?; + + Ok(()) +} + +pub fn storage_flush_cache( + mut ctx: FunctionEnvMut, + clear: u32, +) -> MaybeEscape { + let data = ctx.data_mut(); + + data.buy_ink(hostio::STORAGE_FLUSH_BASE_INK)?; + data.require_gas(SSTORE_SENTRY_GAS)?; + + let gas_left = data.gas_left()?; + let (gas_cost, outcome) = data.flush_storage_cache(clear != 0, gas_left)?; + if data.evm_data.arbos_version >= ARBOS_VERSION_STYLUS_CHARGING_FIXES { + data.buy_gas(gas_cost)?; + } + if outcome != UserOutcomeKind::Success { + return Err(eyre!("outcome {outcome:?}").into()); + } + + Ok(()) +} + +pub fn write_result( + mut ctx: FunctionEnvMut, + ptr: Ptr, + len: u32, +) -> MaybeEscape { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + data.buy_ink(hostio::WRITE_RESULT_BASE_INK)?; + data.pay_for_read(len)?; + data.pay_for_read(len)?; + + data.outs = read_slice(ptr, len as usize, &memory)?; + + Ok(()) +} + +pub fn pay_for_memory_grow( + mut ctx: FunctionEnvMut, + pages: u16, +) -> MaybeEscape { + let data = ctx.data_mut(); + + if pages == 0 { + data.buy_ink(hostio::PAY_FOR_MEMORY_GROW_BASE_INK)?; + return Ok(()); + } + let gas_cost = data.add_pages(pages); + data.buy_gas(gas_cost)?; + + Ok(()) +} + +pub fn exit_early(_ctx: FunctionEnvMut, status: u32) -> MaybeEscape { + Err(Escape::Exit(status)) +} + +pub fn call_contract( + mut ctx: FunctionEnvMut, + contract: Ptr, + data: Ptr, + data_len: u32, + value: Ptr, + gas: u64, + ret_len: Ptr, +) -> Result { + let (ctx_data, store) = ctx.data_and_store_mut(); + let memory = ctx_data.memory.clone().unwrap().view(&store); + + ctx_data.buy_ink(hostio::CALL_CONTRACT_BASE_INK)?; + ctx_data.pay_for_read(data_len)?; + ctx_data.pay_for_read(data_len)?; + + let CallInputs { + contract, + input, + gas_left, + gas_req, + value, + } = ctx_data.parse_call_inputs(&memory, contract, data, Gas(gas), data_len, Some(value))?; + + let (outs_len, gas_cost, status) = + ctx_data.contract_call(contract, &input, gas_left, gas_req, value.unwrap()); + + ctx_data.buy_gas(gas_cost)?; + ctx_data.evm_data.return_data_len = outs_len; + ret_len.write(&memory, outs_len)?; + + Ok(status as u8) +} + +pub fn delegate_call_contract( + mut ctx: FunctionEnvMut, + contract: Ptr, + data: Ptr, + data_len: u32, + gas: u64, + ret_len: Ptr, +) -> Result { + let (ctx_data, store) = ctx.data_and_store_mut(); + let memory = ctx_data.memory.clone().unwrap().view(&store); + + ctx_data.buy_ink(hostio::CALL_CONTRACT_BASE_INK)?; + ctx_data.pay_for_read(data_len)?; + ctx_data.pay_for_read(data_len)?; + + let CallInputs { + contract, + input, + gas_left, + gas_req, + .. + } = ctx_data.parse_call_inputs(&memory, contract, data, Gas(gas), data_len, None)?; + + let (outs_len, gas_cost, status) = ctx_data.delegate_call(contract, &input, gas_left, gas_req); + + ctx_data.buy_gas(gas_cost)?; + ctx_data.evm_data.return_data_len = outs_len; + ret_len.write(&memory, outs_len)?; + + Ok(status as u8) +} + +pub fn static_call_contract( + mut ctx: FunctionEnvMut, + contract: Ptr, + data: Ptr, + data_len: u32, + gas: u64, + ret_len: Ptr, +) -> Result { + let (ctx_data, store) = ctx.data_and_store_mut(); + let memory = ctx_data.memory.clone().unwrap().view(&store); + + ctx_data.buy_ink(hostio::CALL_CONTRACT_BASE_INK)?; + ctx_data.pay_for_read(data_len)?; + ctx_data.pay_for_read(data_len)?; + + let CallInputs { + contract, + input, + gas_left, + gas_req, + .. + } = ctx_data.parse_call_inputs(&memory, contract, data, Gas(gas), data_len, None)?; + + let (outs_len, gas_cost, status) = ctx_data.static_call(contract, &input, gas_left, gas_req); + + ctx_data.buy_gas(gas_cost)?; + ctx_data.evm_data.return_data_len = outs_len; + ret_len.write(&memory, outs_len)?; + + Ok(status as u8) +} + +pub fn create1( + mut ctx: FunctionEnvMut, + code: Ptr, + code_len: u32, + endowment: Ptr, + contract: Ptr, + revert_data_len: Ptr, +) -> MaybeEscape { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + data.buy_ink(hostio::CREATE1_BASE_INK)?; + data.pay_for_read(code_len)?; + data.pay_for_read(code_len)?; + + let code = read_slice(code, code_len as usize, &memory)?; + let endowment = read_bytes32(endowment, &memory)?; + let gas = data.gas_left()?; + + let (result, ret_len, gas_cost) = data.create1(code, endowment, gas); + let result = result?; + + data.buy_gas(gas_cost)?; + data.evm_data.return_data_len = ret_len; + revert_data_len.write(&memory, ret_len)?; + memory.write(contract.offset() as u64, result.as_slice())?; + + Ok(()) +} + +pub fn create2( + mut ctx: FunctionEnvMut, + code: Ptr, + code_len: u32, + endowment: Ptr, + salt: Ptr, + contract: Ptr, + revert_data_len: Ptr, +) -> MaybeEscape { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + data.buy_ink(hostio::CREATE2_BASE_INK)?; + data.pay_for_read(code_len)?; + data.pay_for_read(code_len)?; + + let code = read_slice(code, code_len as usize, &memory)?; + let endowment = read_bytes32(endowment, &memory)?; + let salt = read_bytes32(salt, &memory)?; + let gas = data.gas_left()?; + + let (result, ret_len, gas_cost) = data.create2(code, endowment, salt, gas); + let result = result?; + + data.buy_gas(gas_cost)?; + data.evm_data.return_data_len = ret_len; + revert_data_len.write(&memory, ret_len)?; + memory.write(contract.offset() as u64, result.as_slice())?; + + Ok(()) +} + +pub fn read_return_data( + mut ctx: FunctionEnvMut, + dest: Ptr, + offset: u32, + size: u32, +) -> Result { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + data.buy_ink(hostio::READ_RETURN_DATA_BASE_INK)?; + + let max = data.evm_data.return_data_len.saturating_sub(offset); + data.pay_for_write(size.min(max))?; + if max == 0 { + return Ok(0); + } + + let ret_data = data.get_return_data(); + let out_slice = slice_with_runoff(&ret_data, offset, offset.saturating_add(size)); + + let out_len = out_slice.len() as u32; + if out_len > 0 { + memory.write(dest.offset() as u64, out_slice)?; + } + Ok(out_len) +} + +pub fn return_data_size(mut ctx: FunctionEnvMut) -> Result { + let data = ctx.data_mut(); + + data.buy_ink(hostio::RETURN_DATA_SIZE_BASE_INK)?; + Ok(data.evm_data.return_data_len) +} + +pub fn emit_log( + mut ctx: FunctionEnvMut, + log_data: Ptr, + len: u32, + topics: u32, +) -> MaybeEscape { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + data.buy_ink(hostio::EMIT_LOG_BASE_INK)?; + if topics > 4 || len < topics * 32 { + return Err("bad topic data".to_string().into()); + } + data.pay_for_read(len)?; + data.pay_for_evm_log(topics, len - topics * 32)?; + + let log_data = read_slice(log_data, len as usize, &memory)?; + data.emit_log(log_data, topics) +} + +pub fn account_balance( + mut ctx: FunctionEnvMut, + address: Ptr, + ptr: Ptr, +) -> MaybeEscape { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + data.buy_ink(hostio::ACCOUNT_BALANCE_BASE_INK)?; + data.require_gas(COLD_ACCOUNT_GAS)?; + let address = read_bytes20(address, &memory)?; + + let (balance, gas_cost) = data.account_balance(address); + data.buy_gas(gas_cost)?; + memory.write(ptr.offset() as u64, balance.as_slice())?; + + Ok(()) +} + +pub fn account_code( + mut ctx: FunctionEnvMut, + address: Ptr, + offset: u32, + size: u32, + dest: Ptr, +) -> Result { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + data.buy_ink(hostio::ACCOUNT_CODE_BASE_INK)?; + data.require_gas(COLD_ACCOUNT_GAS)?; + let address = read_bytes20(address, &memory)?; + let gas = data.gas_left()?; + + let arbos_version = data.evm_data.arbos_version; + + let (code, gas_cost) = data.account_code(arbos_version, address, gas); + data.buy_gas(gas_cost)?; + + data.pay_for_write(code.len() as u32)?; + + let out_slice = slice_with_runoff(&code, offset, offset.saturating_add(size)); + let out_len = out_slice.len() as u32; + memory.write(dest.offset() as u64, out_slice)?; + + Ok(out_len) +} + +pub fn account_codehash( + mut ctx: FunctionEnvMut, + address: Ptr, + ptr: Ptr, +) -> MaybeEscape { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + data.buy_ink(hostio::ACCOUNT_CODE_HASH_BASE_INK)?; + data.require_gas(COLD_ACCOUNT_GAS)?; + let address = read_bytes20(address, &memory)?; + + let (hash, gas_cost) = data.account_codehash(address); + data.buy_gas(gas_cost)?; + memory.write(ptr.offset() as u64, hash.as_slice())?; + + Ok(()) +} + +pub fn account_code_size( + mut ctx: FunctionEnvMut, + address: Ptr, +) -> Result { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + data.buy_ink(hostio::ACCOUNT_CODE_SIZE_BASE_INK)?; + data.require_gas(COLD_ACCOUNT_GAS)?; + let address = read_bytes20(address, &memory)?; + let gas = data.gas_left()?; + + let arbos_version = data.evm_data.arbos_version; + + let (code, gas_cost) = data.account_code(arbos_version, address, gas); + data.buy_gas(gas_cost)?; + + Ok(code.len() as u32) +} + +pub fn evm_gas_left(mut ctx: FunctionEnvMut) -> Result { + let data = ctx.data_mut(); + + data.buy_ink(hostio::EVM_GAS_LEFT_BASE_INK)?; + Ok(data.gas_left()?.0) +} + +pub fn evm_ink_left(mut ctx: FunctionEnvMut) -> Result { + let data = ctx.data_mut(); + + data.buy_ink(hostio::EVM_INK_LEFT_BASE_INK)?; + Ok(data.ink_ready()?.0) +} + +pub fn block_basefee(mut ctx: FunctionEnvMut, ptr: Ptr) -> MaybeEscape { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + data.buy_ink(hostio::BLOCK_BASEFEE_BASE_INK)?; + memory.write(ptr.offset() as u64, data.evm_data.block_basefee.as_slice())?; + + Ok(()) +} + +pub fn chainid(mut ctx: FunctionEnvMut) -> Result { + let data = ctx.data_mut(); + + data.buy_ink(hostio::CHAIN_ID_BASE_INK)?; + Ok(data.evm_data.chainid) +} + +pub fn block_coinbase(mut ctx: FunctionEnvMut, ptr: Ptr) -> MaybeEscape { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + data.buy_ink(hostio::BLOCK_COINBASE_BASE_INK)?; + memory.write(ptr.offset() as u64, data.evm_data.block_coinbase.as_slice())?; + + Ok(()) +} + +pub fn block_gas_limit(mut ctx: FunctionEnvMut) -> Result { + let data = ctx.data_mut(); + + data.buy_ink(hostio::BLOCK_GAS_LIMIT_BASE_INK)?; + Ok(data.evm_data.block_gas_limit) +} + +pub fn block_number(mut ctx: FunctionEnvMut) -> Result { + let data = ctx.data_mut(); + + data.buy_ink(hostio::BLOCK_NUMBER_BASE_INK)?; + Ok(data.evm_data.block_number) +} + +pub fn block_timestamp(mut ctx: FunctionEnvMut) -> Result { + let data = ctx.data_mut(); + + data.buy_ink(hostio::BLOCK_TIMESTAMP_BASE_INK)?; + Ok(data.evm_data.block_timestamp) +} + +pub fn contract_address(mut ctx: FunctionEnvMut, ptr: Ptr) -> MaybeEscape { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + data.buy_ink(hostio::ADDRESS_BASE_INK)?; + memory.write( + ptr.offset() as u64, + data.evm_data.contract_address.as_slice(), + )?; + + Ok(()) +} + +type U256 = ruint2::Uint<256, 4>; + +fn read_u256(ptr: Ptr, memory: &MemoryView) -> Result<(U256, Bytes32), Escape> { + let bytes = read_bytes32(ptr, memory)?; + Ok((bytes.clone().into(), bytes)) +} + +pub fn math_div( + mut ctx: FunctionEnvMut, + value: Ptr, + divisor: Ptr, +) -> MaybeEscape { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + data.buy_ink(hostio::MATH_DIV_BASE_INK)?; + let (a, _) = read_u256(value, &memory)?; + let (b, _) = read_u256(divisor, &memory)?; + + let result: Bytes32 = a.checked_div(b).unwrap_or_default().into(); + memory.write(value.offset() as u64, result.as_slice())?; + + Ok(()) +} + +pub fn math_mod( + mut ctx: FunctionEnvMut, + value: Ptr, + modulus: Ptr, +) -> MaybeEscape { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + data.buy_ink(hostio::MATH_MOD_BASE_INK)?; + let (a, _) = read_u256(value, &memory)?; + let (b, _) = read_u256(modulus, &memory)?; + + let result: Bytes32 = a.checked_rem(b).unwrap_or_default().into(); + memory.write(value.offset() as u64, result.as_slice())?; + + Ok(()) +} + +pub fn math_pow( + mut ctx: FunctionEnvMut, + value: Ptr, + exponent: Ptr, +) -> MaybeEscape { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + data.buy_ink(hostio::MATH_POW_BASE_INK)?; + let (a, _) = read_u256(value, &memory)?; + let (b, b32) = read_u256(exponent, &memory)?; + + data.pay_for_pow(&b32)?; + let result: Bytes32 = a.wrapping_pow(b).into(); + memory.write(value.offset() as u64, result.as_slice())?; + + Ok(()) +} + +pub fn math_add_mod( + mut ctx: FunctionEnvMut, + value: Ptr, + addend: Ptr, + modulus: Ptr, +) -> MaybeEscape { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + data.buy_ink(hostio::MATH_ADD_MOD_BASE_INK)?; + let (a, _) = read_u256(value, &memory)?; + let (b, _) = read_u256(addend, &memory)?; + let (c, _) = read_u256(modulus, &memory)?; + + let result: Bytes32 = a.add_mod(b, c).into(); + memory.write(value.offset() as u64, result.as_slice())?; + + Ok(()) +} + +pub fn math_mul_mod( + mut ctx: FunctionEnvMut, + value: Ptr, + multiplier: Ptr, + modulus: Ptr, +) -> MaybeEscape { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + data.buy_ink(hostio::MATH_MUL_MOD_BASE_INK)?; + let (a, _) = read_u256(value, &memory)?; + let (b, _) = read_u256(multiplier, &memory)?; + let (c, _) = read_u256(modulus, &memory)?; + + let result: Bytes32 = a.mul_mod(b, c).into(); + memory.write(value.offset() as u64, result.as_slice())?; + + Ok(()) +} + +pub fn msg_sender(mut ctx: FunctionEnvMut, ptr: Ptr) -> MaybeEscape { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + data.buy_ink(hostio::MSG_SENDER_BASE_INK)?; + memory.write(ptr.offset() as u64, data.evm_data.msg_sender.as_slice())?; + + Ok(()) +} + +pub fn msg_value(mut ctx: FunctionEnvMut, ptr: Ptr) -> MaybeEscape { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + data.buy_ink(hostio::MSG_VALUE_BASE_INK)?; + memory.write(ptr.offset() as u64, data.evm_data.msg_value.as_slice())?; + + Ok(()) +} + +pub fn tx_gas_price(mut ctx: FunctionEnvMut, ptr: Ptr) -> MaybeEscape { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + data.buy_ink(hostio::TX_GAS_PRICE_BASE_INK)?; + memory.write(ptr.offset() as u64, data.evm_data.tx_gas_price.as_slice())?; + + Ok(()) +} + +pub fn tx_ink_price(mut ctx: FunctionEnvMut) -> Result { + let data = ctx.data_mut(); + + data.buy_ink(hostio::TX_INK_PRICE_BASE_INK)?; + Ok(data.pricing().ink_price) +} + +pub fn tx_origin(mut ctx: FunctionEnvMut, ptr: Ptr) -> MaybeEscape { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + data.buy_ink(hostio::TX_ORIGIN_BASE_INK)?; + memory.write(ptr.offset() as u64, data.evm_data.tx_origin.as_slice())?; + + Ok(()) +} + +pub fn native_keccak256( + mut ctx: FunctionEnvMut, + input: Ptr, + len: u32, + output: Ptr, +) -> MaybeEscape { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + data.pay_for_keccak(len)?; + let preimage = read_slice(input, len as usize, &memory)?; + let digest = keccak(&preimage); + memory.write(output.offset() as u64, &digest)?; + + Ok(()) +} + +use num_traits::Unsigned; +fn slice_with_runoff(data: &impl AsRef<[T]>, start: I, end: I) -> &[T] +where + I: TryInto + Unsigned, +{ + let start = start.try_into().unwrap_or(usize::MAX); + let end = end.try_into().unwrap_or(usize::MAX); + + let data = data.as_ref(); + if start >= data.len() || end < start { + return &[]; + } + &data[start..end.min(data.len())] +} diff --git a/sp1-crates/program/src/imports/wasi_stub.rs b/sp1-crates/program/src/imports/wasi_stub.rs new file mode 100644 index 00000000000..18af7ff4c56 --- /dev/null +++ b/sp1-crates/program/src/imports/wasi_stub.rs @@ -0,0 +1,339 @@ +//! WASI stubs +//! +//! The code used here is heavily borrowed from nitro's own WASI stubs: +//! https://github.com/OffchainLabs/nitro/blob/c858ed93a5a4fd81908277d94fb72974058a3615/arbitrator/caller-env/src/wasip1_stub.rs + +use crate::{Escape, Ptr, platform, read_slice, replay::CustomEnvData}; +use rand::RngCore; +use wasmer::FunctionEnvMut; + +pub type Errno = u16; + +pub const ERRNO_SUCCESS: Errno = 0; +pub const ERRNO_BADF: Errno = 8; +pub const ERRNO_INVAL: Errno = 28; + +pub fn proc_exit(mut ctx: FunctionEnvMut, code: u32) { + let (data, _store) = ctx.data_and_store_mut(); + + if code == 0 { + platform::print_string( + 1, + format!( + "Validation succeeds with hash {}", + hex::encode(data.input().large_globals[0]) + ) + .as_bytes(), + ); + } + + platform::exit(code); +} + +pub fn args_sizes_get( + mut ctx: FunctionEnvMut, + argc: Ptr, + argv_buf_size: Ptr, +) -> Result { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + argc.write(&memory, 1)?; + argv_buf_size.write(&memory, 4)?; + + Ok(ERRNO_SUCCESS) +} + +pub fn args_get( + mut ctx: FunctionEnvMut, + argv_buf: Ptr, + data_buf: Ptr, +) -> Result { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + let data_buf = data_buf.deref(&memory); + + argv_buf.write(&memory, data_buf.offset() as u32)?; + data_buf.write(0x6E6962)?; // "bin\0" + + Ok(ERRNO_SUCCESS) +} + +pub fn environ_sizes_get( + mut ctx: FunctionEnvMut, + length_ptr: Ptr, + data_size_ptr: Ptr, +) -> Result { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + length_ptr.write(&memory, 0)?; + data_size_ptr.write(&memory, 0)?; + + Ok(ERRNO_SUCCESS) +} + +pub fn environ_get(_ctx: FunctionEnvMut, _: Ptr, _: Ptr) -> Errno { + ERRNO_SUCCESS +} + +pub fn fd_write( + mut ctx: FunctionEnvMut, + fd: u32, + iovecs_ptr: Ptr, + iovecs_len: u32, + ret_ptr: Ptr, +) -> Result { + if fd != 1 && fd != 2 { + return Ok(ERRNO_BADF); + } + + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + let mut size = 0; + for i in 0..iovecs_len { + let ptr = iovecs_ptr.add_offset((i * 2).into()).unwrap(); + let len = ptr.add_offset(1).unwrap().read(&memory)?; + let ptr = Ptr::new(ptr.read(&memory)?); + let data = read_slice(ptr, len as usize, &memory)?; + + platform::print_string(fd, &data); + + size += len; + } + + ret_ptr.write(&memory, size)?; + Ok(ERRNO_SUCCESS) +} + +pub fn fd_close(_ctx: FunctionEnvMut, _fd: u32) -> Errno { + ERRNO_BADF +} + +pub fn fd_read(_ctx: FunctionEnvMut, _: u32, _: u32, _: u32, _: u32) -> Errno { + ERRNO_BADF +} + +pub fn fd_readdir( + _ctx: FunctionEnvMut, + _fd: u32, + _: u32, + _: u32, + _: u64, + _: u32, +) -> Errno { + ERRNO_BADF +} + +pub fn fd_sync(_ctx: FunctionEnvMut, _: u32) -> Errno { + ERRNO_SUCCESS +} + +pub fn fd_seek(_ctx: FunctionEnvMut, _: u32, _: u64, _: u32, _: u32) -> Errno { + ERRNO_BADF +} + +pub fn fd_datasync(_ctx: FunctionEnvMut, _: u32) -> Errno { + ERRNO_BADF +} + +pub fn fd_prestat_get(_ctx: FunctionEnvMut, _: u32, _: u32) -> Errno { + ERRNO_BADF +} + +pub fn fd_prestat_dir_name(_ctx: FunctionEnvMut, _: u32, _: u32, _: u32) -> Errno { + ERRNO_BADF +} + +pub fn fd_filestat_get(_ctx: FunctionEnvMut, _: u32, _: u32) -> Errno { + ERRNO_BADF +} + +pub fn fd_filestat_set_size(_ctx: FunctionEnvMut, _: u32, _: u64) -> Errno { + ERRNO_BADF +} + +pub fn fd_pread( + _ctx: FunctionEnvMut, + _fd: u32, + _: u32, + _: u32, + _: u64, + _: u32, +) -> Errno { + ERRNO_BADF +} + +pub fn fd_pwrite( + _ctx: FunctionEnvMut, + _fd: u32, + _: u32, + _: u32, + _: u64, + _: u32, +) -> Errno { + ERRNO_BADF +} + +pub fn fd_fdstat_get(_ctx: FunctionEnvMut, _: u32, _: u32) -> Errno { + ERRNO_INVAL +} + +pub fn fd_fdstat_set_flags(_ctx: FunctionEnvMut, _: u32, _: u32) -> Errno { + ERRNO_INVAL +} + +const TIME_INTERVAL: u64 = 10_000_000; + +pub fn clock_time_get( + mut ctx: FunctionEnvMut, + _clock_id: u32, + _precision: u64, + time_ptr: Ptr, +) -> Result { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + data.time += TIME_INTERVAL; + time_ptr.cast::().write(&memory, data.time)?; + + Ok(ERRNO_SUCCESS) +} + +pub fn random_get( + mut ctx: FunctionEnvMut, + mut buf: Ptr, + mut len: u32, +) -> Result { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + while len >= 4 { + let next_rand = data.pcg.next_u32(); + buf.write(&memory, next_rand)?; + buf = buf.add_offset(1).unwrap(); + len -= 4; + } + if len > 0 { + let mut rem = data.pcg.next_u32(); + let mut buf = buf.cast::(); + + for _ in 0..len { + buf.write(&memory, rem as u8)?; + buf = buf.add_offset(1).unwrap(); + rem >>= 8; + } + } + Ok(ERRNO_SUCCESS) +} + +pub fn poll_oneoff( + mut ctx: FunctionEnvMut, + in_subs: Ptr, + out_evt: Ptr, + num_subscriptions: u32, + num_events_ptr: Ptr, +) -> Result { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + data.time += TIME_INTERVAL; + + const SUBSCRIPTION_SIZE: u32 = 48; + for index in 0..num_subscriptions { + let subs_base = in_subs + .cast::() + .add_offset(SUBSCRIPTION_SIZE * index) + .unwrap(); + let subs_type = subs_base + .add_offset(8) + .unwrap() + .cast::() + .read(&memory)?; + if subs_type != 0 { + continue; + } + let user_data = subs_base.cast::().read(&memory)?; + out_evt.write(&memory, user_data)?; + out_evt.add_offset(2).unwrap().write(&memory, subs_type)?; + num_events_ptr.write(&memory, 1)?; + return Ok(ERRNO_SUCCESS); + } + Ok(ERRNO_INVAL) +} + +pub fn sched_yield(_ctx: FunctionEnvMut) -> Errno { + ERRNO_SUCCESS +} + +pub fn path_open( + _ctx: FunctionEnvMut, + _: u32, + _: u32, + _: u32, + _: u32, + _: u32, + _: u64, + _: u64, + _: u32, + _: u32, +) -> Errno { + ERRNO_BADF +} + +pub fn path_create_directory(_ctx: FunctionEnvMut, _: u32, _: u32, _: u32) -> Errno { + ERRNO_BADF +} + +pub fn path_remove_directory(_ctx: FunctionEnvMut, _: u32, _: u32, _: u32) -> Errno { + ERRNO_BADF +} + +pub fn path_readlink( + _ctx: FunctionEnvMut, + _: u32, + _: u32, + _: u32, + _: u32, + _: u32, + _: u32, +) -> Errno { + ERRNO_BADF +} + +pub fn path_rename( + _ctx: FunctionEnvMut, + _: u32, + _: u32, + _: u32, + _: u32, + _: u32, + _: u32, +) -> Errno { + ERRNO_BADF +} + +pub fn path_filestat_get( + _ctx: FunctionEnvMut, + _: u32, + _: u32, + _: u32, + _: u32, + _: u32, +) -> Errno { + ERRNO_BADF +} + +pub fn path_unlink_file(_ctx: FunctionEnvMut, _: u32, _: u32, _: u32) -> Errno { + ERRNO_BADF +} + +pub fn sock_accept(_ctx: FunctionEnvMut, _: u32, _: u32, _: u32) -> Errno { + ERRNO_BADF +} + +pub fn sock_shutdown(_ctx: FunctionEnvMut, _: u32, _: u32) -> Errno { + ERRNO_BADF +} diff --git a/sp1-crates/program/src/imports/wavmio.rs b/sp1-crates/program/src/imports/wavmio.rs new file mode 100644 index 00000000000..1714a9ecf0b --- /dev/null +++ b/sp1-crates/program/src/imports/wavmio.rs @@ -0,0 +1,303 @@ +//! wavmio functions +//! +//! The code here is heavily borrowed from nitro's own implementation: +//! https://github.com/OffchainLabs/nitro/blob/3710544c6b36a8927a8dab26d928ad553f08175d/arbitrator/jit/src/wavmio.rs + +use crate::{Escape, MaybeEscape, Ptr, read_bytes32, replay::CustomEnvData}; +use std::ops::Deref; +use wasmer::{FunctionEnvMut, MemoryView}; + +pub fn get_global_state_bytes32( + mut ctx: FunctionEnvMut, + idx: u32, + out_ptr: Ptr, +) -> MaybeEscape { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + let Some(global) = data.input().large_globals.get(idx as usize) else { + return Escape::logical("global read out of bounds in wavmio.getGlobalStateBytes32"); + }; + + memory.write(out_ptr.offset() as u64, &global[..32])?; + + Ok(()) +} + +pub fn set_global_state_bytes32( + mut ctx: FunctionEnvMut, + idx: u32, + src_ptr: Ptr, +) -> MaybeEscape { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + let slice = read_bytes32(src_ptr, &memory)?; + match data.input_mut().large_globals.get_mut(idx as usize) { + Some(global) => *global = *slice, + None => return Escape::logical("global write oob in wavmio.setGlobalStateBytes32"), + } + Ok(()) +} + +pub fn get_global_state_u64( + mut ctx: FunctionEnvMut, + idx: u32, +) -> Result { + let (data, _store) = ctx.data_and_store_mut(); + + Ok(match data.input().small_globals.get(idx as usize) { + Some(global) => *global, + None => return Escape::logical("global read out of bounds in wavmio.getGlobalStateU64"), + }) +} + +pub fn set_global_state_u64( + mut ctx: FunctionEnvMut, + idx: u32, + val: u64, +) -> MaybeEscape { + let (data, _store) = ctx.data_and_store_mut(); + + match data.input_mut().small_globals.get_mut(idx as usize) { + Some(global) => *global = val, + None => return Escape::logical("global write out of bounds in wavmio.setGlobalStateU64"), + } + Ok(()) +} + +pub fn read_inbox_message( + mut ctx: FunctionEnvMut, + msg_num: u64, + offset: u32, + out_ptr: Ptr, +) -> Result { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + let message = match data.input().sequencer_messages.get(&msg_num) { + Some(message) => message, + None => return Escape::logical("missing sequencer inbox message {msg_num}"), + }; + let offset = offset as usize; + let len = std::cmp::min(32, message.len().saturating_sub(offset)); + let read = message.get(offset..(offset + len)).unwrap_or_default(); + memory.write(out_ptr.offset() as u64, read)?; + + Ok(read.len() as u32) +} + +pub fn read_delayed_inbox_message( + mut ctx: FunctionEnvMut, + msg_num: u64, + offset: u32, + out_ptr: Ptr, +) -> Result { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + let message = match data.input().delayed_messages.get(&msg_num) { + Some(message) => message, + None => return Escape::logical("missing delayed inbox message {msg_num}"), + }; + let offset = offset as usize; + let len = std::cmp::min(32, message.len().saturating_sub(offset)); + let read = message.get(offset..(offset + len)).unwrap_or_default(); + memory.write(out_ptr.offset() as u64, read)?; + + Ok(read.len() as u32) +} + +pub fn resolve_keccak_preimage( + ctx: FunctionEnvMut, + hash_ptr: Ptr, + offset: u32, + out_ptr: Ptr, +) -> Result { + resolve_preimage_impl(ctx, 0, hash_ptr, offset, out_ptr, "wavmio.ResolvePreImage") +} + +pub fn validate_certificate( + mut ctx: FunctionEnvMut, + preimage_type: u8, + hash_ptr: Ptr, +) -> Result { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + let hash = read_bytes32(hash_ptr, &memory)?; + + // Check if preimage exists + let exists = data + .input() + .preimages + .get(&preimage_type) + .and_then(|m| m.get(hash.deref())) + .is_some(); + + Ok(if exists { 1 } else { 0 }) +} + +pub fn resolve_typed_preimage( + ctx: FunctionEnvMut, + preimage_type: u8, + hash_ptr: Ptr, + offset: u32, + out_ptr: Ptr, +) -> Result { + resolve_preimage_impl( + ctx, + preimage_type, + hash_ptr, + offset, + out_ptr, + "wavmio.ResolveTypedPreimage", + ) +} + +pub fn greedy_resolve_typed_preimage( + ctx: FunctionEnvMut, + preimage_type: u8, + hash_ptr: Ptr, + offset: u32, + available: u32, + out_ptr: Ptr, +) -> Result { + greedy_resolve_typed_preimage_impl( + ctx, + preimage_type, + hash_ptr, + offset, + available, + out_ptr, + "wavmio.ResolveTypedPreimage2", + ) +} + +fn resolve_preimage_impl( + mut ctx: FunctionEnvMut, + preimage_type: u8, + hash_ptr: Ptr, + offset: u32, + out_ptr: Ptr, + name: &str, +) -> Result { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + let offset = offset as usize; + + let hash = read_bytes32(hash_ptr, &memory)?; + + let Some(preimage) = data + .input() + .preimages + .get(&preimage_type) + .and_then(|m| m.get(hash.deref())) + else { + let hash_hex = hex::encode(hash); + return Escape::logical(format!( + "Missing requested preimage for hash {hash_hex} in {name}" + )); + }; + + #[cfg(debug_assertions)] + { + use crate::input_types::PreimageType; + use sha2::Sha256; + use sha3::{Digest, Keccak256}; + + // Check if preimage rehashes to the provided hash. Exclude blob preimages + let calculated_hash: [u8; 32] = match preimage_type { + PreimageType::Keccak256 => Keccak256::digest(preimage).into(), + PreimageType::Sha2_256 => Sha256::digest(preimage).into(), + PreimageType::EthVersionedHash => *hash, + }; + if calculated_hash != *hash { + panic!( + "Calculated hash {} of preimage {} does not match provided hash {}", + hex::encode(calculated_hash), + hex::encode(preimage), + hex::encode(*hash) + ); + } + } + + if offset % 32 != 0 { + return Escape::logical(format!("bad offset {offset} in {name}")); + } + + let len = std::cmp::min(32, preimage.len().saturating_sub(offset)); + let read = preimage.get(offset..(offset + len)).unwrap_or_default(); + memory.write(out_ptr.offset() as u64, read)?; + + Ok(read.len() as u32) +} + +fn greedy_read( + data: &[u8], + memory: &MemoryView, + offset: usize, + available: u32, + out_ptr: Ptr, +) -> Result { + let full_len = data.len().saturating_sub(offset) as u32; + let len = std::cmp::min(available, full_len); + let read = data + .get(offset..(offset + len as usize)) + .unwrap_or_default(); + memory.write(out_ptr.offset() as u64, read)?; + + Ok(full_len) +} + +fn greedy_resolve_typed_preimage_impl( + mut ctx: FunctionEnvMut, + preimage_type: u8, + hash_ptr: Ptr, + offset: u32, + available: u32, + out_ptr: Ptr, + name: &str, +) -> Result { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + let offset = offset as usize; + + let hash = read_bytes32(hash_ptr, &memory)?; + + let Some(preimage) = data + .input() + .preimages + .get(&preimage_type) + .and_then(|m| m.get(hash.deref())) + else { + let hash_hex = hex::encode(hash); + return Escape::logical(format!( + "Missing requested preimage for hash {hash_hex} in {name}" + )); + }; + + #[cfg(debug_assertions)] + { + use crate::input_types::PreimageType; + use sha2::Sha256; + use sha3::{Digest, Keccak256}; + + // Check if preimage rehashes to the provided hash. Exclude blob preimages + let calculated_hash: [u8; 32] = match preimage_type { + PreimageType::Keccak256 => Keccak256::digest(preimage).into(), + PreimageType::Sha2_256 => Sha256::digest(preimage).into(), + PreimageType::EthVersionedHash => *hash, + }; + if calculated_hash != *hash { + panic!( + "Calculated hash {} of preimage {} does not match provided hash {}", + hex::encode(calculated_hash), + hex::encode(preimage), + hex::encode(*hash) + ); + } + } + + greedy_read(&preimage, &memory, offset, available, out_ptr) +} diff --git a/sp1-crates/program/src/lib.rs b/sp1-crates/program/src/lib.rs new file mode 100644 index 00000000000..d6eeccf0ce5 --- /dev/null +++ b/sp1-crates/program/src/lib.rs @@ -0,0 +1,157 @@ +pub mod imports; +pub mod platform; +pub mod replay; +pub mod stylus; + +use arbutil::{ + Bytes20, Bytes32, + evm::api::{Gas, Ink}, +}; +use prover::programs::config::{CompileConfig, StylusConfig}; +use std::io; +use std::mem::{self, MaybeUninit}; +use std::ptr::NonNull; +use thiserror::Error; +use wasmer::{MemoryAccessError, MemoryView, WasmPtr}; +use wasmer_types::RawValue; +use wasmer_vm::VMGlobalDefinition; + +pub use crate::replay::run; + +pub const STACK_SIZE: usize = 1024 * 1024; + +// nitro uses 32-bit memory space +pub(crate) type Ptr = WasmPtr; + +pub(crate) fn read_slice(ptr: Ptr, len: usize, memory: &MemoryView) -> Result, Escape> { + let mut data: Vec> = Vec::with_capacity(len); + // SAFETY: read_uninit fills all available space + Ok(unsafe { + data.set_len(len); + memory.read_uninit(ptr.offset() as u64, &mut data)?; + mem::transmute::>, Vec>(data) + }) +} + +pub(crate) fn read_bytes20(ptr: Ptr, memory: &MemoryView) -> Result { + read_slice(ptr, 20, memory).map(|data| data.try_into().unwrap()) +} + +pub(crate) fn read_bytes32(ptr: Ptr, memory: &MemoryView) -> Result { + read_slice(ptr, 32, memory).map(|data| data.try_into().unwrap()) +} + +fn keccak>(preimage: T) -> [u8; 32] { + use std::mem::MaybeUninit; + use tiny_keccak::{Hasher, Keccak}; + + let mut output = MaybeUninit::<[u8; 32]>::uninit(); + let mut hasher = Keccak::v256(); + hasher.update(preimage.as_ref()); + + // SAFETY: finalize() writes 32 bytes + unsafe { + hasher.finalize(&mut *output.as_mut_ptr()); + output.assume_init() + } +} + +pub type MaybeEscape = Result<(), Escape>; + +#[derive(Error, Debug)] +pub enum Escape { + #[error("failed to access memory: `{0}`")] + Memory(MemoryAccessError), + #[error("internal error: `{0}`")] + Internal(String), + #[error("logic error: `{0}`")] + Logical(String), + #[error("out of ink")] + OutOfInk, + #[error("exit early: `{0}`")] + Exit(u32), +} + +impl Escape { + pub fn logical>(message: S) -> Result { + Err(Self::Logical(message.as_ref().to_string())) + } +} + +impl From for Escape { + fn from(err: String) -> Self { + Self::Internal(err) + } +} + +impl From for Escape { + fn from(err: eyre::ErrReport) -> Self { + Self::Internal(err.to_string()) + } +} + +impl From for Escape { + fn from(err: io::Error) -> Self { + Self::Internal(format!("[io error]: {err:?}")) + } +} + +impl From for Escape { + fn from(_: prover::programs::meter::OutOfInkError) -> Self { + Self::OutOfInk + } +} + +impl From for Escape { + fn from(err: MemoryAccessError) -> Self { + Self::Memory(err) + } +} + +// Below are some data structures that do not belong to prover / arbutil, +// but we don't want to pull in full crate anyway. As a result, they are +// for now copied over. + +pub struct JitConfig { + pub stylus: StylusConfig, + pub compile: CompileConfig, +} + +pub struct CallInputs { + pub contract: Bytes20, + pub input: Vec, + pub gas_left: Gas, + pub gas_req: Gas, + pub value: Option, +} + +#[derive(Clone, Copy, Debug)] +pub struct MeterData { + /// The amount of ink left + pub ink_left: NonNull, + /// Whether the instance has run out of ink + pub ink_status: NonNull, +} + +impl MeterData { + pub fn ink(&self) -> Ink { + Ink(unsafe { self.ink_left.as_ref().val.u64 }) + } + + pub fn status(&self) -> u32 { + unsafe { self.ink_status.as_ref().val.u32 } + } + + pub fn set_ink(&mut self, ink: Ink) { + unsafe { self.ink_left.as_mut().val = RawValue { u64: ink.0 } } + } + + pub fn set_status(&mut self, status: u32) { + unsafe { self.ink_status.as_mut().val = RawValue { u32: status } } + } +} + +/// The data we're pointing to is owned by the `NativeInstance`. +/// These are simple integers whose lifetime is that of the instance. +/// Stylus is also single-threaded. +unsafe impl Send for MeterData {} diff --git a/sp1-crates/program/src/main.rs b/sp1-crates/program/src/main.rs new file mode 100644 index 00000000000..90ee5171dc9 --- /dev/null +++ b/sp1-crates/program/src/main.rs @@ -0,0 +1,27 @@ +#![cfg_attr(target_os = "zkvm", no_main)] + +#[cfg(target_os = "zkvm")] +sp1_zkvm::entrypoint!(main); + +fn main() { + // We are loading replay.wasmu object here. After initializing, it is + // not needed. + let sp1_zkvm::ReadVecResult { ptr, len, .. } = sp1_zkvm::read_vec_raw(); + assert!(!ptr.is_null()); + // SAFETY: ptr must not be deallocated + let s: &'static [u8] = unsafe { std::slice::from_raw_parts(ptr, len) }; + let metadata = bytes::Bytes::from_static(s); + + program::run(metadata); +} + +// Those are referenced by wasmer runtimes, but are never invoked +#[unsafe(no_mangle)] +pub extern "C" fn __negdf2(_x: f64) -> f64 { + todo!() +} + +#[unsafe(no_mangle)] +pub extern "C" fn __negsf2(_x: f32) -> f32 { + todo!() +} diff --git a/sp1-crates/program/src/platform.rs b/sp1-crates/program/src/platform.rs new file mode 100644 index 00000000000..98e5aa7117f --- /dev/null +++ b/sp1-crates/program/src/platform.rs @@ -0,0 +1,19 @@ +use prover::binary_input::Input; +use sp1_zkvm::{io, syscalls}; + +pub fn print_string(fd: u32, bytes: &[u8]) { + syscalls::syscall_write(fd, bytes.as_ptr(), bytes.len()); +} + +pub fn read_input() -> Input { + let s = io::read::>(); + Input::from_reader(std::io::Cursor::new(s)).expect("parse input file") +} + +pub fn exit(code: u32) -> ! { + syscalls::syscall_halt(code as u8) +} + +pub fn dump_elf() { + syscalls::syscall_dump_elf(); +} diff --git a/sp1-crates/program/src/replay.rs b/sp1-crates/program/src/replay.rs new file mode 100644 index 00000000000..6683e862c7e --- /dev/null +++ b/sp1-crates/program/src/replay.rs @@ -0,0 +1,403 @@ +//! Runtime code for replay.wasm + +use crate::{ + Escape, JitConfig, STACK_SIZE, + imports::{arbcompress, precompiles, programs, wasi_stub, wavmio}, + platform::{exit, read_input}, + stylus::{Cothread, MessageFromCothread, MessageToCothread}, +}; +use arbutil::{Bytes32, evm::EvmData}; +use bytes::Bytes; +use corosensei::{Coroutine, CoroutineResult, Yielder, stack::DefaultStack}; +use once_cell::unsync::Lazy; +use prover::{binary_input::Input, programs::meter::MeteredMachine}; +use rand_pcg::Pcg32; +use std::marker::PhantomData; +use std::ops::{Deref, DerefMut}; +use wasmer::{ + Engine, Function, FunctionEnv, Imports, Instance, Memory, Module, RuntimeError, Store, Value, + imports, sys::NativeEngineExt, +}; +use wasmer_vm::install_unwinder; + +// Coroutine is not Send, so we cannot keep it in CustomEnvData. +// As SP1 is single-threaded, it won't hurt if we use a few static variables. +// Another way of doing this is to build a wrapper similar to SendYielder, we +// will leave it to another time to debate which is a better option. +static mut COTHREADS: Vec = Vec::new(); +fn cothreads_mut() -> &'static mut Vec { + unsafe { &mut *&raw mut COTHREADS } +} +fn cothreads() -> &'static [Cothread] { + unsafe { &*&raw const COTHREADS } +} + +/// This provides a single-threaded Send yielder since corosensei's +/// own Yielder does not implement Send +pub struct SendYielder { + yielder: u64, + _input: PhantomData, + _yield: PhantomData, +} + +impl Clone for SendYielder { + fn clone(&self) -> Self { + Self { + yielder: self.yielder, + _input: PhantomData, + _yield: PhantomData, + } + } +} + +impl std::ops::Deref for SendYielder { + type Target = Yielder; + + fn deref(&self) -> &Self::Target { + self.yielder() + } +} + +impl SendYielder { + pub fn new(yielder: &Yielder) -> Self { + Self { + yielder: yielder as *const _ as u64, + _input: PhantomData, + _yield: PhantomData, + } + } + + pub fn yielder(&self) -> &Yielder { + unsafe { &*(self.yielder as *const _) } + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum MainYieldMessage { + RunLastChild, +} + +pub struct CustomEnvData { + /// Note this is an option, since memory is not available when building + /// imports. A multi-step solution is required for initialization: + /// + /// * Build imports with memory set to None + /// * Use imports to initialize Instance + /// * Extract memory from instance's exports + /// * Set the memory back in CustomEnvData. + pub memory: Option, + pub time: u64, + pub pcg: Pcg32, + + input: Lazy, + yielder: SendYielder<(), MainYieldMessage>, +} + +impl CustomEnvData { + pub fn new(yielder: &Yielder<(), MainYieldMessage>) -> Self { + // See https://github.com/OffchainLabs/nitro/blob/7e5c0bb3cfd55ef2d99abff8b3875c97f85eb1c8/arbitrator/caller-env/src/lib.rs#L27-L31 + const PCG_INIT_STATE: u64 = 0xcafef00dd15ea5e5; + const PCG_INIT_STREAM: u64 = 0xa02bdbf7bb3c0a7; + let pcg = Pcg32::new(PCG_INIT_STATE, PCG_INIT_STREAM); + + Self { + memory: None, + time: 0, + pcg, + input: Lazy::new(|| read_input()), + yielder: SendYielder::new(yielder), + } + } + + pub fn input(&self) -> &Input { + self.input.deref() + } + + pub fn input_mut(&mut self) -> &mut Input { + self.input.deref_mut() + } + + pub fn input_initialized(&self) -> bool { + Lazy::get(&self.input).is_some() + } + + pub fn launch_program( + &mut self, + module_hash: &Bytes32, + calldata: Vec, + config: JitConfig, + evm_data: EvmData, + gas: u64, + ) -> Result { + let Some(module) = self.input.module_asms.get(module_hash.deref()) else { + return Escape::logical(format!("Unable to locate module: {module_hash}")); + }; + let cothread = Cothread::new(module.clone(), calldata, config, evm_data, gas); + + cothreads_mut().push(cothread); + Ok(cothreads().len().try_into().unwrap()) + } + + pub fn send_to_cothread(&mut self, msg: MessageToCothread) { + let queue = &cothreads().last().unwrap().queue; + queue.lock().expect("lock").send_to_cothread(msg); + } + + pub fn wait_next_message(&mut self, module: Option) { + if let Some(module) = module { + assert_ne!(module, 0); + assert_eq!(module, cothreads().len() as u32); + } + + let queue = &cothreads().last().unwrap().queue; + queue.lock().expect("lock").mark_read_from_cothread(); + + // Bound the number of loops for ease of debuging + for _ in 0..10 { + if queue.lock().expect("lock").peek_from_cothread().is_some() { + return; + } + + self.yielder.suspend(MainYieldMessage::RunLastChild); + } + panic!("did not receive message"); + } + + // For now, message id in arbitrator is hardcoded to 0x33333333, + // we are safely ignoring it + pub fn get_last_msg(&self) -> MessageFromCothread { + let queue = &cothreads().last().unwrap().queue; + queue + .lock() + .expect("lock") + .peek_from_cothread() + .expect("no message waiting") + } + + pub fn pop_last_program(&mut self) { + cothreads_mut().pop(); + } +} + +/// Given replay.wasm's serialized module(or serialized object), this method starts the main +/// event loop. +pub fn run(m: Bytes) -> ! { + // Runs the wasmer module in a coroutine, so we can multiplex between different + // modules without threads. + let mut coro = Coroutine::with_stack( + DefaultStack::new(STACK_SIZE).expect("create default stack"), + |yielder: &Yielder<(), MainYieldMessage>, ()| { + let mut store = Store::new(Engine::headless()); + let module = unsafe { Module::deserialize(&store, m) }.expect("creating module"); + + // Setup replay.wasm function symbols for profiling & debugging + #[cfg(target_os = "zkvm")] + { + let sp1_zkvm::ReadVecResult { ptr, len, .. } = sp1_zkvm::read_vec_raw(); + assert!(!ptr.is_null()); + let mapping_bytes = unsafe { std::slice::from_raw_parts(ptr, len) }; + let mapping: Vec> = + serde_json::from_slice(&mapping_bytes[..]).expect("parse mapping"); + let infos = module.as_sys().local_function_infos(); + // ptr => (function name, size), for precision, all usizes are casted to string + let mut profiler_data: std::collections::HashMap = + std::collections::HashMap::default(); + for (index, ptr, size) in infos { + if let Some(Some(name)) = mapping.get(index as usize) { + profiler_data.insert(ptr.to_string(), (name.clone(), size.to_string())); + } + } + let profiler_data_str = + serde_json::to_string(&profiler_data).expect("profiler data to json"); + sp1_zkvm::syscalls::syscall_insert_profiler_symbols( + profiler_data_str.as_str().as_ptr(), + profiler_data_str.as_str().len() as u64, + ); + } + + let (imports, function_env) = build_imports(&mut store, yielder); + let instance = + Instance::new(&mut store, &module, &imports).expect("instantiating module"); + + let memory = instance + .exports + .get_memory("memory") + .expect("fetching memory"); + function_env.as_mut(&mut store).memory = Some(memory.clone()); + + let start = instance + .exports + .get_function("_start") + .expect("fetching start function!"); + + start.call(&mut store, &[]) + }, + ); + + let result = loop { + install_unwinder(None); + match coro.resume(()) { + CoroutineResult::Yield(msg) => match msg { + MainYieldMessage::RunLastChild => { + let cothread = cothreads_mut().last_mut().unwrap(); + let input = cothread.input(); + let store = input.store_mut(); + let function_env = input.function_env_mut(); + let env = function_env.as_mut(store); + { + if let Some(yielder) = &env.yielder { + let yielder = yielder.clone(); + install_unwinder(Some(Box::new(move |reason| { + yielder.suspend(Some(reason)); + }))); + } + } + store.force_create(); + let exit = match cothread.coroutine.resume(input.clone()) { + CoroutineResult::Yield(y) => match y { + Some(unwind_reason) => { + unsafe { + cothread.coroutine.force_reset(); + } + Some(Err(unwind_reason.into_trap().into())) + } + None => None, + }, + CoroutineResult::Return(r) => Some(r), + }; + store.force_clean(); + if let Some(result) = exit { + let env = function_env.as_mut(store); + let (req_type, req_data) = { + let (req_type, data) = match result { + // Success + Ok(0) => (0, env.outs.clone()), + // Revert + Ok(_) => (1, env.outs.clone()), + // Failure + Err(e) => match e.downcast::() { + Ok(escape) => match escape { + Escape::Exit(0) => (0, env.outs.clone()), + Escape::Exit(_) => (1, env.outs.clone()), + _ => (2, format!("{escape:?}").as_bytes().to_vec()), + }, + Err(e) => (2, format!("{e:?}").as_bytes().to_vec()), + }, + }; + let mut output = Vec::with_capacity(8 + data.len()); + let ink_left = env.ink_left().into(); + let gas_left = env.config.stylus.pricing.ink_to_gas(ink_left); + output.extend(gas_left.to_be_bytes()); + output.extend(data); + (req_type, output) + }; + let msg = MessageFromCothread { req_data, req_type }; + env.send_from_cothread(msg); + } + } + }, + CoroutineResult::Return(result) => break result, + } + }; + handle_result(result); +} + +fn build_imports( + store: &mut Store, + yielder: &Yielder<(), MainYieldMessage>, +) -> (Imports, FunctionEnv) { + let func_env = FunctionEnv::new(store, CustomEnvData::new(yielder)); + macro_rules! func { + ($func:expr) => { + Function::new_typed_with_env(store, &func_env, $func) + }; + } + + ( + imports! { + "arbcompress" => { + "brotli_compress" => func!(arbcompress::brotli_compress), + "brotli_decompress" => func!(arbcompress::brotli_decompress), + }, + "wasi_snapshot_preview1" => { + "proc_exit" => func!(wasi_stub::proc_exit), + "sched_yield" => func!(wasi_stub::sched_yield), + "clock_time_get" => func!(wasi_stub::clock_time_get), + "random_get" => func!(wasi_stub::random_get), + "poll_oneoff" => func!(wasi_stub::poll_oneoff), + "args_sizes_get" => func!(wasi_stub::args_sizes_get), + "args_get" => func!(wasi_stub::args_get), + "environ_sizes_get" => func!(wasi_stub::environ_sizes_get), + "environ_get" => func!(wasi_stub::environ_get), + "fd_write" => func!(wasi_stub::fd_write), + "fd_close" => func!(wasi_stub::fd_close), + "fd_read" => func!(wasi_stub::fd_read), + "fd_readdir" => func!(wasi_stub::fd_readdir), + "fd_sync" => func!(wasi_stub::fd_sync), + "fd_seek" => func!(wasi_stub::fd_seek), + "fd_datasync" => func!(wasi_stub::fd_datasync), + "fd_prestat_get" => func!(wasi_stub::fd_prestat_get), + "fd_prestat_dir_name" => func!(wasi_stub::fd_prestat_dir_name), + "fd_filestat_get" => func!(wasi_stub::fd_filestat_get), + "fd_filestat_set_size" => func!(wasi_stub::fd_filestat_set_size), + "fd_pread" => func!(wasi_stub::fd_pread), + "fd_pwrite" => func!(wasi_stub::fd_pwrite), + "fd_fdstat_get" => func!(wasi_stub::fd_fdstat_get), + "fd_fdstat_set_flags" => func!(wasi_stub::fd_fdstat_set_flags), + "path_open" => func!(wasi_stub::path_open), + "path_create_directory" => func!(wasi_stub::path_create_directory), + "path_remove_directory" => func!(wasi_stub::path_remove_directory), + "path_readlink" => func!(wasi_stub::path_readlink), + "path_rename" => func!(wasi_stub::path_rename), + "path_filestat_get" => func!(wasi_stub::path_filestat_get), + "path_unlink_file" => func!(wasi_stub::path_unlink_file), + "sock_accept" => func!(wasi_stub::sock_accept), + "sock_shutdown" => func!(wasi_stub::sock_shutdown), + }, + "wavmio" => { + "getGlobalStateBytes32" => func!(wavmio::get_global_state_bytes32), + "setGlobalStateBytes32" => func!(wavmio::set_global_state_bytes32), + "getGlobalStateU64" => func!(wavmio::get_global_state_u64), + "setGlobalStateU64" => func!(wavmio::set_global_state_u64), + "readInboxMessage" => func!(wavmio::read_inbox_message), + "readDelayedInboxMessage" => func!(wavmio::read_delayed_inbox_message), + "resolvePreImage" => func!(wavmio::resolve_keccak_preimage), + "resolveTypedPreimage" => func!(wavmio::resolve_typed_preimage), + "greedyResolveTypedPreimage" => func!(wavmio::greedy_resolve_typed_preimage), + "validateCertificate" => func!(wavmio::validate_certificate), + }, + "programs" => { + "new_program" => func!(programs::new_program), + "pop" => func!(programs::pop), + "set_response" => func!(programs::set_response), + "get_request" => func!(programs::get_request), + "get_request_data" => func!(programs::get_request_data), + "start_program" => func!(programs::start_program), + "send_response" => func!(programs::send_response), + "create_stylus_config" => func!(programs::create_stylus_config), + "create_evm_data" => func!(programs::create_evm_data), + "create_evm_data_v2" => func!(programs::create_evm_data_v2), + "activate" => func!(programs::activate), + "activate_v2" => func!(programs::activate_v2), + }, + "sp1" => { + "dump_elf" => func!(precompiles::dump_elf), + "ecrecover" => func!(precompiles::ecrecover), + "keccak256" => func!(precompiles::keccak256), + }, + }, + func_env, + ) +} + +pub(crate) fn handle_result(result: Result, RuntimeError>) -> ! { + let message = match result { + Ok(value) => format!("Machine exited prematurely with: {:?}", value), + Err(e) => format!("Runtime error: {}", e), + }; + + if !message.is_empty() { + println!("{message}"); + } + exit(1); +} diff --git a/sp1-crates/program/src/stylus.rs b/sp1-crates/program/src/stylus.rs new file mode 100644 index 00000000000..f5e952e6a21 --- /dev/null +++ b/sp1-crates/program/src/stylus.rs @@ -0,0 +1,687 @@ +//! Stylus runtime. In this module we keep data structures & code +//! required to interface with wasmer. Nitro's definitions are mostly +//! kept in `nitro` sub-module. + +use crate::{ + CallInputs, Escape, JitConfig, MeterData, Ptr, STACK_SIZE, + imports::{debug, vm_hooks}, + read_bytes20, read_bytes32, read_slice, + replay::SendYielder, +}; +use arbutil::{ + Bytes20, Bytes32, + evm::{ + ARBOS_VERSION_STYLUS_LAST_CODE_CACHE_FIX, EvmData, + api::{EVM_API_METHOD_REQ_OFFSET, EvmApiMethod, EvmApiStatus, Gas}, + storage::{StorageCache, StorageWord}, + user::UserOutcomeKind, + }, +}; +use bytes::Bytes; +use corosensei::{Coroutine, Yielder, stack::DefaultStack}; +use eyre::{bail, eyre}; +use prover::programs::{ + STYLUS_ENTRY_POINT, + config::PricingParams, + depth::STYLUS_STACK_LEFT, + meter::{GasMeteredMachine, MachineMeter, MeteredMachine, STYLUS_INK_LEFT, STYLUS_INK_STATUS}, +}; +use std::collections::{VecDeque, hash_map::Entry}; +use std::ops::DerefMut; +use std::sync::{Arc, Mutex}; +use wasmer::{ + AsStoreMut, Engine, Function, FunctionEnv, Imports, Instance, Memory, MemoryView, Module, + RuntimeError, Store, StoreObjects, imports, sys::NativeEngineExt, +}; +use wasmer_vm::{UnwindReason, VMExtern, install_unwinder}; + +/// A cothread wraps a stylus program. Actually we run the stylus +/// program via a coroutine, it is just so named following existing +/// structure in arbitrator +pub struct Cothread { + pub queue: Arc>, + pub coroutine: Coroutine, + + store: Store, + instance: Instance, + function_env: FunctionEnv, +} + +/// This way we can workaround Rust limitations. All variables will +/// be alive for the entire duration of Cothread, so there is no use +/// after free situation. +#[derive(Clone)] +pub struct CothreadInput { + store: usize, + instance: usize, + function_env: usize, +} + +pub type CothreadYield = Option; +pub type CothreadReturn = Result; + +impl Cothread { + pub fn new( + program: Bytes, + calldata: Vec, + config: JitConfig, + evm_data: EvmData, + gas: u64, + ) -> Self { + let queue = MessageQueue::new(); + let args_len = calldata.len(); + let mut store = Store::new(Engine::headless()); + let module = unsafe { Module::deserialize(&store, program) }.expect("creating module"); + let (imports, function_env) = + build_imports(&mut store, calldata, config, evm_data, queue.clone()); + let instance = Instance::new(&mut store, &module, &imports).expect("instantiating module"); + + let memory = instance + .exports + .get_memory("memory") + .expect("fetching memory"); + function_env.as_mut(&mut store).memory = Some(memory.clone()); + + // Setup ink variables + let (ink_left, ink_status) = { + let mut expect_global = |name| { + let VMExtern::Global(sh) = instance + .exports + .get_extern(name) + .unwrap() + .to_vm_extern() + .into_sys() + else { + panic!("name not found global"); + }; + let StoreObjects::Sys(objects) = store.objects_mut(); + sh.get(&objects).vmglobal() + }; + ( + expect_global(STYLUS_INK_LEFT), + expect_global(STYLUS_INK_STATUS), + ) + }; + { + let env = function_env.as_mut(&mut store); + + env.meter = Some(MeterData { + ink_left, + ink_status, + }); + let ink = env.config.stylus.pricing.gas_to_ink(Gas(gas)); + env.set_ink(ink); + } + + // Set stack left + { + let max_depth = { + let env = function_env.as_mut(&mut store); + env.config.stylus.max_depth + }; + let Ok(global) = instance.exports.get_global(STYLUS_STACK_LEFT) else { + panic!("global {} does not exist", STYLUS_STACK_LEFT); + }; + global + .set(&mut store, max_depth.into()) + .expect("set stack left") + } + + let coroutine = Coroutine::with_stack( + DefaultStack::new(STACK_SIZE).expect("create stylus default stack"), + move |yielder: &Yielder, input: CothreadInput| { + let store = input.store_mut(); + let function_env = input.function_env_mut(); + let instance = input.instance(); + + let send_yielder = SendYielder::new(yielder); + { + let env = function_env.as_mut(store); + env.yielder = Some(send_yielder.clone()); + } + install_unwinder(Some(Box::new(move |reason| { + send_yielder.suspend(Some(reason)); + }))); + + let start = instance + .exports + .get_typed_function::(&store, STYLUS_ENTRY_POINT) + .expect("fetching stylus entrypoint function!"); + + start.call(store, args_len as u32) + }, + ); + Self { + queue, + coroutine, + store, + instance, + function_env, + } + } + + pub fn input(&self) -> CothreadInput { + CothreadInput { + store: (&self.store) as *const _ as usize, + instance: (&self.instance) as *const _ as usize, + function_env: (&self.function_env) as *const _ as usize, + } + } +} + +impl CothreadInput { + pub fn store_mut(&self) -> &mut Store { + unsafe { &mut *(self.store as *mut _) } + } + + pub fn function_env_mut(&self) -> &mut FunctionEnv { + unsafe { &mut *(self.function_env as *mut _) } + } + + pub fn instance(&self) -> &Instance { + unsafe { &*(self.instance as *const _) } + } +} + +#[derive(Default)] +pub struct MessageQueue { + tx: VecDeque, + rx: VecDeque, +} + +impl MessageQueue { + pub fn new() -> Arc> { + Arc::new(Mutex::new(Self::default())) + } + + pub fn send_from_cothread(&mut self, msg: MessageFromCothread) { + self.rx.push_back(msg); + } + + pub fn peek_from_cothread(&self) -> Option { + self.rx.front().cloned() + } + + pub fn mark_read_from_cothread(&mut self) { + self.rx.pop_front(); + // For now nitro uses rendezvous channel, this assertion will + // hold. + assert!(self.rx.is_empty()); + } + + pub fn send_to_cothread(&mut self, msg: MessageToCothread) { + self.tx.push_back(msg); + } + + pub fn read_to_cothread(&mut self) -> Option { + self.tx.pop_front() + } +} + +/// Wasmer custom env data for stylus programs +pub struct StylusCustomEnvData { + pub memory: Option, + pub meter: Option, + + pub calldata: Vec, + pub config: JitConfig, + pub evm_data: EvmData, + pub outs: Vec, + pub storage_cache: StorageCache, + + last_return_data: Option>, + last_code: Option<(Bytes20, Vec)>, + + queue: Arc>, + /// Value will be set every time current coroutine is invoked. + pub yielder: Option>, +} + +impl StylusCustomEnvData { + pub fn send_from_cothread(&mut self, msg: MessageFromCothread) { + self.queue.lock().expect("lock").send_from_cothread(msg); + } + + fn wait_next_message(&mut self) -> MessageToCothread { + for _ in 0..10 { + if let Some(msg) = self.queue.lock().expect("lock").read_to_cothread() { + return msg; + } + self.yielder.as_ref().unwrap().suspend(None); + } + panic!("did not receive message to cothread"); + } + + pub fn request( + &mut self, + req_type: EvmApiMethod, + req_data: Vec, + ) -> (Vec, Vec, Gas) { + let msg = MessageFromCothread { + req_type: req_type as u32 + EVM_API_METHOD_REQ_OFFSET, + req_data, + }; + self.send_from_cothread(msg); + + let res = self.wait_next_message(); + (res.result, res.raw_data, res.cost) + } + + pub fn get_bytes32(&mut self, key: Bytes32, evm_api_gas_to_use: Gas) -> (Bytes32, Gas) { + let mut cost = self.storage_cache.read_gas(); + + if !self.storage_cache.contains_key(&key) { + let (res, _, gas) = self.request(EvmApiMethod::GetBytes32, key.to_vec()); + cost = cost.saturating_add(gas).saturating_add(evm_api_gas_to_use); + self.storage_cache + .insert(key, StorageWord::known(res.try_into().unwrap())); + } + + (self.storage_cache[&key].value, cost) + } + + pub fn cache_bytes32(&mut self, key: Bytes32, value: Bytes32) -> Gas { + let cost = self.storage_cache.write_gas(); + match self.storage_cache.entry(key) { + Entry::Occupied(mut key) => key.get_mut().value = value, + Entry::Vacant(slot) => drop(slot.insert(StorageWord::unknown(value))), + }; + cost + } + + pub fn flush_storage_cache( + &mut self, + clear: bool, + gas_left: Gas, + ) -> eyre::Result<(Gas, UserOutcomeKind)> { + let mut data = Vec::with_capacity(64 * self.storage_cache.len() + 8); + data.extend(gas_left.to_be_bytes()); + + for (key, value) in self.storage_cache.deref_mut() { + if value.dirty() { + data.extend(*key); + data.extend(*value.value); + value.known = Some(value.value); + } + } + if clear { + self.storage_cache.clear(); + } + if data.len() == 8 { + return Ok((Gas(0), UserOutcomeKind::Success)); // no need to make request + } + + let (res, _, cost) = self.request(EvmApiMethod::SetTrieSlots, data); + let status = res.first().copied().ok_or(eyre!("empty result!"))?; + let outcome = match status.try_into()? { + EvmApiStatus::Success => UserOutcomeKind::Success, + EvmApiStatus::WriteProtection => UserOutcomeKind::Revert, + EvmApiStatus::OutOfGas => UserOutcomeKind::OutOfInk, + _ => bail!("unexpect outcome"), + }; + Ok((cost, outcome)) + } + + pub fn get_transient_bytes32(&mut self, key: Bytes32) -> Bytes32 { + let (res, ..) = self.request(EvmApiMethod::GetTransientBytes32, key.to_vec()); + res.try_into().unwrap() + } + + pub fn set_transient_bytes32( + &mut self, + key: Bytes32, + value: Bytes32, + ) -> eyre::Result { + let mut data = Vec::with_capacity(64); + data.extend(key); + data.extend(value); + let (res, ..) = self.request(EvmApiMethod::SetTransientBytes32, data); + let status = res.first().copied().ok_or(eyre!("empty result!"))?; + let outcome = match status.try_into()? { + EvmApiStatus::Success => UserOutcomeKind::Success, + EvmApiStatus::WriteProtection => UserOutcomeKind::Revert, + _ => bail!("unexpect outcome"), + }; + + Ok(outcome) + } + + pub fn emit_log(&mut self, data: Vec, topics: u32) -> Result<(), Escape> { + let mut request = Vec::with_capacity(4 + data.len()); + request.extend(topics.to_be_bytes()); + request.extend(data); + + let (res, _, _) = self.request(EvmApiMethod::EmitLog, request); + if !res.is_empty() { + return Err(String::from_utf8(res) + .unwrap_or("malformed emit-log response".into()) + .into()); + } + Ok(()) + } + + pub fn account_balance(&mut self, address: Bytes20) -> (Bytes32, Gas) { + let (res, _, cost) = self.request(EvmApiMethod::AccountBalance, address.to_vec()); + (res.try_into().unwrap(), cost) + } + + pub fn account_code( + &mut self, + arbos_version: u64, + address: Bytes20, + gas_left: Gas, + ) -> (Vec, Gas) { + if let Some((stored_address, data)) = self.last_code.as_ref() { + if address == *stored_address { + return (data.clone(), Gas(0)); + } + } + let mut req = Vec::with_capacity(20 + 8); + req.extend(address); + req.extend(gas_left.to_be_bytes()); + + let (_, data, cost) = self.request(EvmApiMethod::AccountCode, req); + if !data.is_empty() || arbos_version < ARBOS_VERSION_STYLUS_LAST_CODE_CACHE_FIX { + self.last_code = Some((address, data.clone())); + } + (data, cost) + } + + pub fn account_codehash(&mut self, address: Bytes20) -> (Bytes32, Gas) { + let (res, _, cost) = self.request(EvmApiMethod::AccountCodeHash, address.to_vec()); + (res.try_into().unwrap(), cost) + } + + pub fn get_return_data(&self) -> Vec { + self.last_return_data.clone().expect("missing return data") + } + + fn create_request( + &mut self, + create_type: EvmApiMethod, + code: Vec, + endowment: Bytes32, + salt: Option, + gas: Gas, + ) -> (Result, u32, Gas) { + let mut request = Vec::with_capacity(8 + 2 * 32 + code.len()); + request.extend(gas.to_be_bytes()); + request.extend(endowment); + if let Some(salt) = salt { + request.extend(salt); + } + request.extend(code); + + let (mut res, data, cost) = self.request(create_type, request); + if res.len() != 21 || res[0] == 0 { + if !res.is_empty() { + res.remove(0); + } + let err_string = String::from_utf8(res).unwrap_or("create_response_malformed".into()); + return (Err(err_string), 0, cost); + } + res.remove(0); + let address = res.try_into().unwrap(); + let data_len = data.len() as u32; + self.last_return_data = Some(data); + (Ok(address), data_len, cost) + } + + pub fn create1( + &mut self, + code: Vec, + endowment: Bytes32, + gas: Gas, + ) -> (Result, u32, Gas) { + self.create_request(EvmApiMethod::Create1, code, endowment, None, gas) + } + + pub fn create2( + &mut self, + code: Vec, + endowment: Bytes32, + salt: Bytes32, + gas: Gas, + ) -> (Result, u32, Gas) { + self.create_request(EvmApiMethod::Create2, code, endowment, Some(salt), gas) + } + + pub fn parse_call_inputs( + &mut self, + memory: &MemoryView, + contract: Ptr, + data: Ptr, + gas: Gas, + data_len: u32, + value: Option, + ) -> Result { + let gas_left = self.gas_left()?; + let gas_req = gas.min(gas_left); + let contract = read_bytes20(contract, memory)?; + let input = read_slice(data, data_len as usize, memory)?; + let value = value.map(|x| read_bytes32(x, memory)).transpose()?; + Ok(CallInputs { + contract, + input, + gas_left, + gas_req, + value, + }) + } + + fn call_request( + &mut self, + call_type: EvmApiMethod, + contract: Bytes20, + input: &[u8], + gas_left: Gas, + gas_req: Gas, + value: Bytes32, + ) -> (u32, Gas, UserOutcomeKind) { + let mut request = Vec::with_capacity(20 + 32 + 8 + 8 + input.len()); + request.extend(contract); + request.extend(value); + request.extend(gas_left.to_be_bytes()); + request.extend(gas_req.to_be_bytes()); + request.extend(input); + + let (res, data, cost) = self.request(call_type, request); + let status: UserOutcomeKind = res[0].try_into().expect("unknown outcome"); + let data_len = data.len() as u32; + self.last_return_data = Some(data); + (data_len, cost, status) + } + + pub fn contract_call( + &mut self, + contract: Bytes20, + input: &[u8], + gas_left: Gas, + gas_req: Gas, + value: Bytes32, + ) -> (u32, Gas, UserOutcomeKind) { + self.call_request( + EvmApiMethod::ContractCall, + contract, + input, + gas_left, + gas_req, + value, + ) + } + + pub fn delegate_call( + &mut self, + contract: Bytes20, + input: &[u8], + gas_left: Gas, + gas_req: Gas, + ) -> (u32, Gas, UserOutcomeKind) { + self.call_request( + EvmApiMethod::DelegateCall, + contract, + input, + gas_left, + gas_req, + Bytes32::default(), + ) + } + + pub fn static_call( + &mut self, + contract: Bytes20, + input: &[u8], + gas_left: Gas, + gas_req: Gas, + ) -> (u32, Gas, UserOutcomeKind) { + self.call_request( + EvmApiMethod::StaticCall, + contract, + input, + gas_left, + gas_req, + Bytes32::default(), + ) + } + + pub fn add_pages(&mut self, pages: u16) -> Gas { + self.request(EvmApiMethod::AddPages, pages.to_be_bytes().to_vec()) + .2 + } + + pub fn meter_mut(&mut self) -> &mut MeterData { + self.meter.as_mut().expect("not metered") + } + + pub fn meter(&self) -> &MeterData { + self.meter.as_ref().expect("not metered") + } +} + +impl MeteredMachine for StylusCustomEnvData { + fn ink_left(&self) -> MachineMeter { + let vm = self.meter(); + match vm.status() { + 0 => MachineMeter::Ready(vm.ink()), + _ => MachineMeter::Exhausted, + } + } + + fn set_meter(&mut self, meter: MachineMeter) { + let vm = self.meter_mut(); + vm.set_ink(meter.ink()); + vm.set_status(meter.status()); + } +} + +impl GasMeteredMachine for StylusCustomEnvData { + fn pricing(&self) -> PricingParams { + self.config.stylus.pricing + } +} + +fn build_imports( + store: &mut Store, + calldata: Vec, + config: JitConfig, + evm_data: EvmData, + queue: Arc>, +) -> (Imports, FunctionEnv) { + let debug_funcs = config.compile.debug.debug_funcs; + + let env = StylusCustomEnvData { + memory: None, + meter: None, + calldata, + config, + evm_data, + outs: Vec::new(), + storage_cache: StorageCache::default(), + queue, + yielder: None, + last_code: None, + last_return_data: None, + }; + let func_env = FunctionEnv::new(store, env); + macro_rules! func { + ($func:expr) => { + Function::new_typed_with_env(store, &func_env, $func) + }; + } + + // TODO: this is not yet a complete list of hook APIs + let mut imports = imports! { + "vm_hooks" => { + "read_args" => func!(vm_hooks::read_args), + "write_result" => func!(vm_hooks::write_result), + "exit_early" => func!(vm_hooks::exit_early), + "storage_load_bytes32" => func!(vm_hooks::storage_load_bytes32), + "storage_cache_bytes32" => func!(vm_hooks::storage_cache_bytes32), + "storage_flush_cache" => func!(vm_hooks::storage_flush_cache), + "transient_load_bytes32" => func!(vm_hooks::transient_load_bytes32), + "transient_store_bytes32" => func!(vm_hooks::transient_store_bytes32), + "call_contract" => func!(vm_hooks::call_contract), + "delegate_call_contract" => func!(vm_hooks::delegate_call_contract), + "static_call_contract" => func!(vm_hooks::static_call_contract), + "create1" => func!(vm_hooks::create1), + "create2" => func!(vm_hooks::create2), + "read_return_data" => func!(vm_hooks::read_return_data), + "return_data_size" => func!(vm_hooks::return_data_size), + "emit_log" => func!(vm_hooks::emit_log), + "account_balance" => func!(vm_hooks::account_balance), + "account_code" => func!(vm_hooks::account_code), + "account_codehash" => func!(vm_hooks::account_codehash), + "account_code_size" => func!(vm_hooks::account_code_size), + "evm_gas_left" => func!(vm_hooks::evm_gas_left), + "evm_ink_left" => func!(vm_hooks::evm_ink_left), + "block_basefee" => func!(vm_hooks::block_basefee), + "chainid" => func!(vm_hooks::chainid), + "block_coinbase" => func!(vm_hooks::block_coinbase), + "block_gas_limit" => func!(vm_hooks::block_gas_limit), + "block_number" => func!(vm_hooks::block_number), + "block_timestamp" => func!(vm_hooks::block_timestamp), + "contract_address" => func!(vm_hooks::contract_address), + "math_div" => func!(vm_hooks::math_div), + "math_mod" => func!(vm_hooks::math_mod), + "math_pow" => func!(vm_hooks::math_pow), + "math_add_mod" => func!(vm_hooks::math_add_mod), + "math_mul_mod" => func!(vm_hooks::math_mul_mod), + "msg_reentrant" => func!(vm_hooks::msg_reentrant), + "msg_sender" => func!(vm_hooks::msg_sender), + "msg_value" => func!(vm_hooks::msg_value), + "tx_gas_price" => func!(vm_hooks::tx_gas_price), + "tx_ink_price" => func!(vm_hooks::tx_ink_price), + "tx_origin" => func!(vm_hooks::tx_origin), + "pay_for_memory_grow" => func!(vm_hooks::pay_for_memory_grow), + "native_keccak256" => func!(vm_hooks::native_keccak256), + } + }; + if debug_funcs { + imports.define("console", "log_txt", func!(debug::console_log_text)); + imports.define("console", "log_i32", func!(debug::console_log::)); + imports.define("console", "log_i64", func!(debug::console_log::)); + imports.define("console", "log_f32", func!(debug::console_log::)); + imports.define("console", "log_f64", func!(debug::console_log::)); + imports.define("console", "tee_i32", func!(debug::console_tee::)); + imports.define("console", "tee_i64", func!(debug::console_tee::)); + imports.define("console", "tee_f32", func!(debug::console_tee::)); + imports.define("console", "tee_f64", func!(debug::console_tee::)); + imports.define("debug", "null_host", func!(debug::null_host)); + imports.define("debug", "start_benchmark", func!(debug::start_benchmark)); + imports.define("debug", "end_benchmark", func!(debug::end_benchmark)); + } + (imports, func_env) +} + +#[derive(Clone)] +pub struct MessageToCothread { + pub result: Vec, + pub raw_data: Vec, + pub cost: Gas, +} + +#[derive(Clone)] +pub struct MessageFromCothread { + pub req_type: u32, + pub req_data: Vec, +} diff --git a/sp1-crates/prover/Cargo.toml b/sp1-crates/prover/Cargo.toml new file mode 100644 index 00000000000..d922538f659 --- /dev/null +++ b/sp1-crates/prover/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "prover" +version = "0.1.0" +edition = "2024" + +[dependencies] +arbutil = { workspace = true } +brotli = { workspace = true } +bytes = { workspace = true } +derivative = { workspace = true } +digest = { workspace = true } +eyre = { workspace = true } +fnv = { workspace = true } +hex = { workspace = true } +lazy_static = { workspace = true } +nom = { workspace = true } +num-derive = { workspace = true } +num-traits = { workspace = true } +parking_lot = { workspace = true } +serde = { workspace = true, features = ["derive", "rc"] } +serde_json = { workspace = true } +serde_with = { workspace = true, features = ["base64"] } +sha3 = { workspace = true } +rkyv = { workspace = true } + +wasmer = { workspace = true, optional = true } +wasmer-types = { workspace = true, optional = true } +wasmparser = { workspace = true, optional = true } + +[features] +default = ["native", "sp1"] +sp1 = [] +native = ["dep:wasmer", "dep:wasmer-types", "dep:wasmparser"] diff --git a/sp1-crates/prover/src/binary_input.rs b/sp1-crates/prover/src/binary_input.rs new file mode 100644 index 00000000000..3330b3e1eea --- /dev/null +++ b/sp1-crates/prover/src/binary_input.rs @@ -0,0 +1,111 @@ +use crate::parse_input::{FileData, UserWasm}; +use bytes::{Bytes, BytesMut}; +use std::{ + collections::{BTreeMap, HashMap}, + io::Read, +}; + +/// This groups components in Arbitrum's WasmEnv that come from FileData. +/// It helps us maintain a clear separation between Arbitrum inputs, and other +/// WASM required data. +/// For details of each field other than FileData, please refer to: +/// https://github.com/OffchainLabs/nitro/blob/11255c6177d50c1ebc43dbcd4bb5f6e9fae5383a/arbitrator/jit/src/machine.rs#L193-L214 +#[derive(rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)] +pub struct Input { + pub small_globals: [u64; 2], + pub large_globals: [[u8; 32]; 2], + pub preimages: Preimages, + pub module_asms: HashMap<[u8; 32], ModuleAsm>, + pub sequencer_messages: Inbox, + pub delayed_messages: Inbox, +} + +// SP1 has additional alignment requirements, we have to decompress the data +// into aligned bytes +pub fn decompress_aligned(user_wasm: &UserWasm) -> ModuleAsm { + let data = { + let mut decompressor = + brotli::Decompressor::new(std::io::Cursor::new(user_wasm.as_vec()), 4096); + let mut result = vec![]; + decompressor + .read_to_end(&mut result) + .expect("decompressing"); + result + }; + // This is less ideal but until one of the following happens, we + // will have to stick with it: + // * Allocator allocates aligned memory + // * Bytes add alignment options + // * Wasmer's Module does not simply accept `IntoBytes` trait. + let mut buffer = BytesMut::zeroed(data.len() + 7); + let p = buffer.as_ptr() as usize; + let aligned_p = (p + 7) / 8 * 8; + let offset = aligned_p - p; + buffer[offset..offset + data.len()].copy_from_slice(&data); + let bytes = buffer.freeze(); + bytes.slice(offset..offset + data.len()) +} + +impl Input { + /// This takes hint from `arbitrator/jit/src/prepare.rs` + pub fn from_file_data(data: FileData) -> eyre::Result { + let block_hash: [u8; 32] = data.start_state.block_hash.try_into().unwrap(); + let send_root: [u8; 32] = data.start_state.send_root.try_into().unwrap(); + let bytes32_vals: [[u8; 32]; 2] = [block_hash, send_root]; + let u64_vals: [u64; 2] = [data.start_state.batch, data.start_state.pos_in_batch]; + + let mut sequencer_messages = Inbox::default(); + for batch_info in data.batch_info.iter() { + sequencer_messages.insert(batch_info.number, batch_info.data_b64.clone()); + } + + let mut delayed_messages = Inbox::default(); + if data.delayed_msg_nr != 0 && !data.delayed_msg_b64.is_empty() { + delayed_messages.insert(data.delayed_msg_nr, data.delayed_msg_b64.clone()); + } + + let mut preimages = Preimages::default(); + for (preimage_ty, inner_map) in data.preimages_b64 { + let map = preimages.entry(preimage_ty as u8).or_default(); + for (hash, preimage) in inner_map { + map.insert(*hash, preimage); + } + } + + let mut module_asms = HashMap::default(); + if let Some(user_wasms) = data.user_wasms.get(&local_target()) { + for (module_hash, module_asm) in user_wasms.iter() { + module_asms.insert(**module_hash, decompress_aligned(&module_asm)); + } + } + + Ok(Self { + small_globals: u64_vals, + large_globals: bytes32_vals, + preimages, + module_asms, + sequencer_messages, + delayed_messages, + }) + } + + // This utilizes binary format from rykv + pub fn from_reader(mut reader: R) -> Result { + let mut s = Vec::new(); + reader + .read_to_end(&mut s) + .map_err(|e| format!("IO Error: {e:?}"))?; + let archived = rkyv::access::(&s[..]) + .map_err(|e| format!("rkyv access error: {e:?}"))?; + rkyv::deserialize::(archived) + .map_err(|e| format!("rkyv deserialize error: {e:?}")) + } +} + +fn local_target() -> String { + "rv64".to_string() +} + +pub type Inbox = BTreeMap>; +pub type Preimages = BTreeMap>>; +pub type ModuleAsm = Bytes; diff --git a/sp1-crates/prover/src/lib.rs b/sp1-crates/prover/src/lib.rs new file mode 100644 index 00000000000..63a98634204 --- /dev/null +++ b/sp1-crates/prover/src/lib.rs @@ -0,0 +1,25 @@ +//! Ideally, we should just use arbitrator/prover. This crate has no +//! reason to exist. But at the moment, nitro uses wasmer 4.x, while SP1 +//! requires wasmer 6.1.x. The 2 wasmer versions are hardly compatible. +//! On the other hand, we would want to borrow common definitions in +//! arbitrator/prover so we don't have to define them twice. +//! This crate serves as a workaround till we can upgrade wasmer in nitro. +#![allow(unexpected_cfgs)] + +#[cfg(feature = "native")] +#[path = "../../../arbitrator/prover/src/binary.rs"] +pub mod binary; +#[path = "../../../arbitrator/prover/src/parse_input.rs"] +pub mod parse_input; +#[cfg(feature = "native")] +#[path = "../../../arbitrator/prover/src/programs/mod.rs"] +pub mod programs; +#[cfg(feature = "native")] +#[path = "../../../arbitrator/prover/src/value.rs"] +pub mod value; + +#[cfg(feature = "native")] +#[path = "../../../arbitrator/arbutil/src/operator.rs"] +pub mod operator; + +pub mod binary_input; diff --git a/sp1-crates/runner/Cargo.toml b/sp1-crates/runner/Cargo.toml new file mode 100644 index 00000000000..1cd82f767f8 --- /dev/null +++ b/sp1-crates/runner/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "sp1-runner" +description = "Runner utility for validating Arbitrum blocks in SP1" +version = "0.1.0" +edition = "2024" + +[dependencies] +sp1-core-executor = { workspace = true } +sp1-sdk = { workspace = true } +prover = { workspace = true } + +bincode = { workspace = true } +clap = { workspace = true } +rkyv = { workspace = true } +serde_json = { workspace = true } +tracing = { workspace = true } +tokio = { workspace = true } diff --git a/sp1-crates/runner/src/main.rs b/sp1-crates/runner/src/main.rs new file mode 100644 index 00000000000..6ce0fc22f71 --- /dev/null +++ b/sp1-crates/runner/src/main.rs @@ -0,0 +1,181 @@ +use clap::{ArgAction, Parser, ValueEnum}; +use prover::{ + binary_input::{Input, decompress_aligned}, + parse_input::FileData, +}; +use sp1_core_executor::{MinimalExecutor, Program}; +use sp1_sdk::{Elf, Prover, ProverClient, SP1Stdin}; +use std::collections::HashMap; +use std::ops::Deref; +use std::sync::Arc; +use std::time::SystemTime; + +#[derive(Debug, Parser)] +#[command(version, about, long_about = None)] +struct Cli { + /// Path to SP1 validation program, could be bootloaded one or the initial one. + #[arg(long)] + program: String, + + /// Path to SP1 stylus compiler program + #[arg(long)] + stylus_compiler_program: String, + + /// Arbitrum version. Used by the stylus compiler. + #[arg(long, default_value_t = 2)] + version: u16, + + /// Debug flag, by default it is true, when set in arguments this + /// flag will become false. Used by the stylus compiler. + #[arg(long, action = ArgAction::SetFalse, default_value_t = true)] + debug: bool, + + /// Block file + #[arg(long)] + block_file: String, + + /// Execution mode, fast is, well, faster, but normal mode provides + /// more diagnosis information, at the expense of longer running time + /// and more memory. + #[arg(value_enum, long, default_value_t = Mode::Fast)] + mode: Mode, +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, ValueEnum)] +enum Mode { + /// Fast mode without detailed opcode statistics + Fast, + + /// Normal mode + Normal, +} + +#[tokio::main] +async fn main() { + sp1_sdk::utils::setup_logger(); + + let cli = Cli::parse(); + + let input_data = build_input(&cli); + let stdin: SP1Stdin = bincode::deserialize(&input_data).expect("deserializing stdin"); + + let program_elf = Elf::from(std::fs::read(&cli.program).expect("read program")); + + let exit_code = match cli.mode { + Mode::Fast => { + let program = Arc::new(Program::from(&program_elf).expect("parse elf")); + + let mut executor = MinimalExecutor::simple(program); + for buf in stdin.buffer { + executor.with_input(&buf); + } + + let a = SystemTime::now(); + assert!(executor.execute_chunk().is_none()); + let b = SystemTime::now(); + tracing::info!( + "Exit code: {}, cycles: {}, execution time: {:?}", + executor.exit_code(), + executor.global_clk(), + b.duration_since(a).unwrap(), + ); + + executor.exit_code() as i32 + } + Mode::Normal => { + let client = ProverClient::builder().cpu().build().await; + + let a = SystemTime::now(); + let (_output, report) = client.execute(program_elf, stdin).await.expect("run"); + let b = SystemTime::now(); + + tracing::info!( + "Completed execution, cycles: {}, execution time: {:?}", + report.total_instruction_count(), + b.duration_since(a).unwrap(), + ); + + tracing::info!("Syscalls:"); + for (code, count) in report.syscall_counts.iter() { + if *count > 0 { + tracing::info!(" {}: {}", code, count); + } + } + + tracing::info!("Cycle trackers:"); + for (entry, cycles) in &report.cycle_tracker { + tracing::info!(" {} consumed cycles: {}", entry, cycles); + } + + report.exit_code as i32 + } + }; + + std::process::exit(exit_code); +} + +// Build SP1 input from Arbitrum block. It is serialized to Vec, so +// we can easily inject debugging code to dump stdin when needed. +fn build_input(cli: &Cli) -> Vec { + let file_data: FileData = + serde_json::from_slice(&std::fs::read(&cli.block_file).expect("read input block")) + .expect("parse input block"); + + let mut module_asms = HashMap::default(); + if let Some(binaries) = file_data.user_wasms.get("rv64") { + for (module_hash, binary) in binaries.iter() { + module_asms.insert(**module_hash, decompress_aligned(binary)); + } + } + if let Some(wasms) = file_data.user_wasms.get("wasm") { + for (module_hash, wasm) in wasms.iter() { + // rv64 binaries take precedence. This way when nitro introduces + // caching for rv64 binaries, no changes will be needed for runner. + if module_asms.contains_key(module_hash.deref()) { + continue; + } + let decompressed = decompress_aligned(wasm); + let binary = run_in_sp1(&cli, &decompressed); + module_asms.insert(**module_hash, binary.into()); + } + } + + let mut input = Input::from_file_data(file_data).expect("create input"); + input.module_asms = module_asms; + + let binary_input = rkyv::to_bytes::(&input) + .expect("to bytes") + .to_vec(); + let mut stdin = SP1Stdin::new(); + stdin.write(&binary_input); + bincode::serialize(&stdin).expect("serialize with bincode") +} + +fn run_in_sp1(cli: &Cli, wasm: &[u8]) -> Vec { + let mut stdin = SP1Stdin::new(); + stdin.write(&cli.version); + stdin.write(&cli.debug); + stdin.write(&wasm); + + let compiler_elf = std::fs::read(&cli.stylus_compiler_program).expect("read stylus program"); + let program = Arc::new(Program::from(&compiler_elf).expect("parse elf")); + + let mut executor = MinimalExecutor::simple(program); + for buf in stdin.buffer { + executor.with_input(&buf); + } + + let a = SystemTime::now(); + assert!(executor.execute_chunk().is_none()); + let b = SystemTime::now(); + + assert_eq!(executor.exit_code(), 0); + tracing::info!( + "Completed stylus compilation in SP1, cycles: {}, execution time: {:?}", + executor.global_clk(), + b.duration_since(a).unwrap(), + ); + + let public_value_stream = executor.into_public_values_stream(); + bincode::deserialize(&public_value_stream).expect("deserialize") +} diff --git a/sp1-crates/rust-toolchain.toml b/sp1-crates/rust-toolchain.toml new file mode 100644 index 00000000000..73328e053b3 --- /dev/null +++ b/sp1-crates/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "1.90" diff --git a/sp1-crates/stylus-compiler-program/Cargo.toml b/sp1-crates/stylus-compiler-program/Cargo.toml new file mode 100644 index 00000000000..525f5196d78 --- /dev/null +++ b/sp1-crates/stylus-compiler-program/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "stylus-compiler-program" +description = "SP1 program wrapping wasmer singlepass compiler for provable compilation" +version = "0.1.0" +edition = "2024" + +[dependencies] +sp1-zkvm = { workspace = true } +wasmer = { workspace = true } +prover = { workspace = true, features = ["native"] } diff --git a/sp1-crates/stylus-compiler-program/src/main.rs b/sp1-crates/stylus-compiler-program/src/main.rs new file mode 100644 index 00000000000..a47f7d2c26e --- /dev/null +++ b/sp1-crates/stylus-compiler-program/src/main.rs @@ -0,0 +1,60 @@ +#![cfg_attr(target_os = "zkvm", no_main)] + +#[cfg(target_os = "zkvm")] +sp1_zkvm::entrypoint!(main); + +use prover::programs::{ + MiddlewareWrapper, config::CompileConfig, depth::DepthChecker, dynamic::DynamicMeter, + heap::HeapBound, meter::Meter, start::StartMover, +}; +use std::str::FromStr; +use std::sync::Arc; +use wasmer::{ + Module, Store, + sys::{CompilerConfig, CpuFeature, EngineBuilder, Singlepass, Target, Triple}, +}; + +fn main() { + let version = sp1_zkvm::io::read::(); + let debug = sp1_zkvm::io::read::(); + let wasm = sp1_zkvm::io::read::>(); + + let compile_config = CompileConfig::version(version, debug); + let mut config = Singlepass::new(); + config.canonicalize_nans(true); + config.enable_verifier(); + + let start = MiddlewareWrapper::new(StartMover::new(compile_config.debug.debug_info)); + let meter = MiddlewareWrapper::new(Meter::new(&compile_config.pricing)); + let dygas = MiddlewareWrapper::new(DynamicMeter::new(&compile_config.pricing)); + let depth = MiddlewareWrapper::new(DepthChecker::new(compile_config.bounds)); + let bound = MiddlewareWrapper::new(HeapBound::new(compile_config.bounds)); + + config.push_middleware(Arc::new(start)); + config.push_middleware(Arc::new(meter)); + config.push_middleware(Arc::new(dygas)); + config.push_middleware(Arc::new(depth)); + config.push_middleware(Arc::new(bound)); + + let triple = Triple::from_str("riscv64").expect("target triple"); + let engine = EngineBuilder::new(config) + .set_target(Some(Target::new(triple, CpuFeature::set()))) + .engine(); + + let store = Store::new(engine); + let module = Module::new(&store, wasm).expect("compilation failed"); + let rv64_binary = module.serialize().expect("serialize module"); + + sp1_zkvm::io::commit(&rv64_binary.to_vec()); +} + +// Those are referenced by wasmer runtimes, but are never invoked +#[unsafe(no_mangle)] +pub extern "C" fn __negdf2(_x: f64) -> f64 { + todo!() +} + +#[unsafe(no_mangle)] +pub extern "C" fn __negsf2(_x: f32) -> f32 { + todo!() +} From 8e582102df3ee875cde9c67713992d3273919697 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 10 Feb 2026 14:15:28 +0100 Subject: [PATCH 002/189] Update paths referring to arbitrator/ directory, to point to crates/ --- sp1-crates/Cargo.toml | 2 +- sp1-crates/program/src/imports/arbcompress.rs | 2 +- sp1-crates/prover/src/lib.rs | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/sp1-crates/Cargo.toml b/sp1-crates/Cargo.toml index 154ef53fd14..cd7210acd4e 100644 --- a/sp1-crates/Cargo.toml +++ b/sp1-crates/Cargo.toml @@ -11,7 +11,7 @@ sp1-primitives = "6.0.0" sp1-sdk = { version = "6.0.0", features = ["profiling"] } sp1-zkvm = { version = "6.0.0", features = ["untrusted_programs", "may_dump_elf"] } -arbutil = { path = "../arbitrator/arbutil" } +arbutil = { path = "../crates/arbutil" } prover = { path = "prover", default-features = false, features = ["sp1"] } bincode = "1.3.3" diff --git a/sp1-crates/program/src/imports/arbcompress.rs b/sp1-crates/program/src/imports/arbcompress.rs index 988a6676106..e81d5bc5696 100644 --- a/sp1-crates/program/src/imports/arbcompress.rs +++ b/sp1-crates/program/src/imports/arbcompress.rs @@ -11,7 +11,7 @@ use std::io::{Cursor, Read, Write}; use wasmer::FunctionEnvMut; const STYLUS_DICTIONARY: &[u8] = - include_bytes!("../../../../arbitrator/brotli/src/dicts/stylus-program-11.lz"); + include_bytes!("../../../../crates/brotli/src/dicts/stylus-program-11.lz"); // Following Arbitrum's convention pub const BROTLI_SUCCESS: u32 = 1; diff --git a/sp1-crates/prover/src/lib.rs b/sp1-crates/prover/src/lib.rs index 63a98634204..09ccc90f0d8 100644 --- a/sp1-crates/prover/src/lib.rs +++ b/sp1-crates/prover/src/lib.rs @@ -7,19 +7,19 @@ #![allow(unexpected_cfgs)] #[cfg(feature = "native")] -#[path = "../../../arbitrator/prover/src/binary.rs"] +#[path = "../../../crates/prover/src/binary.rs"] pub mod binary; -#[path = "../../../arbitrator/prover/src/parse_input.rs"] +#[path = "../../../crates/prover/src/parse_input.rs"] pub mod parse_input; #[cfg(feature = "native")] -#[path = "../../../arbitrator/prover/src/programs/mod.rs"] +#[path = "../../../crates/prover/src/programs/mod.rs"] pub mod programs; #[cfg(feature = "native")] -#[path = "../../../arbitrator/prover/src/value.rs"] +#[path = "../../../crates/prover/src/value.rs"] pub mod value; #[cfg(feature = "native")] -#[path = "../../../arbitrator/arbutil/src/operator.rs"] +#[path = "../../../crates/arbutil/src/operator.rs"] pub mod operator; pub mod binary_input; From 2c1110304ace307b651a60aa03bd02e961dbd5a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 10 Feb 2026 14:22:34 +0100 Subject: [PATCH 003/189] Inline the old parse_input module from the old prover (to ensure the code here works exactly the same as on the wakabat branch) --- sp1-crates/prover/src/lib.rs | 1 - sp1-crates/prover/src/parse_input.rs | 121 +++++++++++++++++++++++++++ 2 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 sp1-crates/prover/src/parse_input.rs diff --git a/sp1-crates/prover/src/lib.rs b/sp1-crates/prover/src/lib.rs index 09ccc90f0d8..99bd2bb6c9a 100644 --- a/sp1-crates/prover/src/lib.rs +++ b/sp1-crates/prover/src/lib.rs @@ -9,7 +9,6 @@ #[cfg(feature = "native")] #[path = "../../../crates/prover/src/binary.rs"] pub mod binary; -#[path = "../../../crates/prover/src/parse_input.rs"] pub mod parse_input; #[cfg(feature = "native")] #[path = "../../../crates/prover/src/programs/mod.rs"] diff --git a/sp1-crates/prover/src/parse_input.rs b/sp1-crates/prover/src/parse_input.rs new file mode 100644 index 00000000000..334f0864b53 --- /dev/null +++ b/sp1-crates/prover/src/parse_input.rs @@ -0,0 +1,121 @@ +use arbutil::Bytes32; +use serde::Deserialize; +use serde_json; +use serde_with::As; +use serde_with::DisplayFromStr; +use serde_with::base64::Base64; +use std::{ + collections::HashMap, + io::{self, BufRead}, +}; + +/// prefixed_hex deserializes hex strings which are prefixed with `0x` +/// +/// The default hex deserializer does not support prefixed hex strings. +/// +/// It is an error to use this deserializer on a string that does not +/// begin with `0x`. +mod prefixed_hex { + use serde::{self, Deserialize, Deserializer}; + + pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> + where + D: Deserializer<'de>, + { + let s = String::deserialize(deserializer)?; + if let Some(s) = s.strip_prefix("0x") { + hex::decode(s).map_err(serde::de::Error::custom) + } else { + Err(serde::de::Error::custom("missing 0x prefix")) + } + } +} + +#[derive(Debug)] +pub struct UserWasm(Vec); + +/// UserWasm is a wrapper around Vec +/// +/// It is useful for decompressing a brotli-compressed wasm module. +/// +/// Note: The wrapped Vec is already Base64 decoded before +/// from(Vec) is called by serde. +impl UserWasm { + /// as_vec returns the decompressed wasm module as a Vec + pub fn as_vec(&self) -> Vec { + self.0.clone() + } +} + +impl AsRef<[u8]> for UserWasm { + fn as_ref(&self) -> &[u8] { + &self.0 + } +} + +/// The Vec is compressed using brotli, and must be decompressed before use. +#[cfg(not(feature = "sp1"))] +impl From> for UserWasm { + fn from(data: Vec) -> Self { + let decompressed = brotli::decompress(&data, brotli::Dictionary::Empty).unwrap(); + Self(decompressed) + } +} + +/// Due to alignment reason, we will do the decompression elsewhere in SP1. +#[cfg(feature = "sp1")] +impl From> for UserWasm { + fn from(data: Vec) -> Self { + Self(data) + } +} + +#[derive(Debug, Clone, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct BatchInfo { + pub number: u64, + #[serde(with = "As::")] + pub data_b64: Vec, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct StartState { + #[serde(with = "prefixed_hex")] + pub block_hash: Vec, + #[serde(with = "prefixed_hex")] + pub send_root: Vec, + pub batch: u64, + pub pos_in_batch: u64, +} + +/// FileData is the deserialized form of the input JSON file. +/// +/// The go JSON library in json.go uses some custom serialization and +/// compression logic that needs to be reversed when deserializing the +/// JSON in rust. +/// +/// Note: It is important to change this file whenever the go JSON +/// serialization changes. +#[derive(Debug, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct FileData { + pub id: u64, + pub has_delayed_msg: bool, + pub delayed_msg_nr: u64, + #[serde(with = "As::>>")] + pub preimages_b64: HashMap>>, + pub batch_info: Vec, + #[serde(with = "As::")] + pub delayed_msg_b64: Vec, + pub start_state: StartState, + #[serde(with = "As::>>")] + pub user_wasms: HashMap>, +} + +impl FileData { + pub fn from_reader(mut reader: R) -> io::Result { + let data = serde_json::from_reader(&mut reader)?; + Ok(data) + } +} From b2d2a2ab5cd190020acc4f6e91f43b5dbca97d1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 10 Feb 2026 14:47:15 +0100 Subject: [PATCH 004/189] It will be MUCH easier to just leave the old modules --- arbitrator/arbutil/src/operator.rs | 1211 +++++++++++++++++ arbitrator/prover/src/binary.rs | 750 ++++++++++ .../prover/src/parse_input.rs | 0 arbitrator/prover/src/programs/config.rs | 234 ++++ arbitrator/prover/src/programs/counter.rs | 158 +++ arbitrator/prover/src/programs/depth.rs | 545 ++++++++ arbitrator/prover/src/programs/dynamic.rs | 154 +++ arbitrator/prover/src/programs/heap.rs | 117 ++ arbitrator/prover/src/programs/memory.rs | 127 ++ arbitrator/prover/src/programs/meter.rs | 528 +++++++ arbitrator/prover/src/programs/mod.rs | 486 +++++++ arbitrator/prover/src/programs/prelude.rs | 12 + arbitrator/prover/src/programs/start.rs | 67 + arbitrator/prover/src/value.rs | 572 ++++++++ sp1-crates/prover/src/lib.rs | 9 +- 15 files changed, 4966 insertions(+), 4 deletions(-) create mode 100644 arbitrator/arbutil/src/operator.rs create mode 100644 arbitrator/prover/src/binary.rs rename {sp1-crates => arbitrator}/prover/src/parse_input.rs (100%) create mode 100644 arbitrator/prover/src/programs/config.rs create mode 100644 arbitrator/prover/src/programs/counter.rs create mode 100644 arbitrator/prover/src/programs/depth.rs create mode 100644 arbitrator/prover/src/programs/dynamic.rs create mode 100644 arbitrator/prover/src/programs/heap.rs create mode 100644 arbitrator/prover/src/programs/memory.rs create mode 100644 arbitrator/prover/src/programs/meter.rs create mode 100644 arbitrator/prover/src/programs/mod.rs create mode 100644 arbitrator/prover/src/programs/prelude.rs create mode 100644 arbitrator/prover/src/programs/start.rs create mode 100644 arbitrator/prover/src/value.rs diff --git a/arbitrator/arbutil/src/operator.rs b/arbitrator/arbutil/src/operator.rs new file mode 100644 index 00000000000..fad90d22703 --- /dev/null +++ b/arbitrator/arbutil/src/operator.rs @@ -0,0 +1,1211 @@ +// Copyright 2021-2023, Offchain Labs, Inc. +// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md + +use std::fmt; +use std::fmt::{Debug, Display, Formatter}; +use std::hash::Hash; +use wasmparser::Operator; + +#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct OperatorCode(usize); + +impl OperatorCode { + // TODO: use std::mem::variant_count when it's stabilized + pub const OPERATOR_COUNT: usize = 529; +} + +impl Display for OperatorCode { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + let name = match self.0 { + 0x00 => "Unreachable", + 0x01 => "Nop", + 0x02 => "Block", + 0x03 => "Loop", + 0x04 => "If", + 0x05 => "Else", + 0x06 => "Try", + 0x07 => "Catch", + 0x08 => "Throw", + 0x09 => "Rethrow", + 0x0a => "ThrowRef", + 0x0b => "End", + 0x0c => "Br", + 0x0d => "BrIf", + 0x0e => "BrTable", + 0x0f => "Return", + 0x10 => "Call", + 0x11 => "CallIndirect", + 0x12 => "ReturnCall", + 0x13 => "ReturnCallIndirect", + 0x14 => "CallRef", + 0x15 => "ReturnCallRef", + 0x18 => "Delegate", + 0x19 => "CatchAll", + 0x1a => "Drop", + 0x1b => "Select", + 0x1c => "TypedSelect", + 0x1f => "TryTable", + 0x20 => "LocalGet", + 0x21 => "LocalSet", + 0x22 => "LocalTee", + 0x23 => "GlobalGet", + 0x24 => "GlobalSet", + 0x25 => "TableGet", + 0x26 => "TableSet", + 0x28 => "I32Load", + 0x29 => "I64Load", + 0x2a => "F32Load", + 0x2b => "F64Load", + 0x2c => "I32Load8S", + 0x2d => "I32Load8U", + 0x2e => "I32Load16S", + 0x2f => "I32Load16U", + 0x30 => "I64Load8S", + 0x31 => "I64Load8U", + 0x32 => "I64Load16S", + 0x33 => "I64Load16U", + 0x34 => "I64Load32S", + 0x35 => "I64Load32U", + 0x36 => "I32Store", + 0x37 => "I64Store", + 0x38 => "F32Store", + 0x39 => "F64Store", + 0x3a => "I32Store8", + 0x3b => "I32Store16", + 0x3c => "I64Store8", + 0x3d => "I64Store16", + 0x3e => "I64Store32", + 0x3f => "MemorySize", + 0x40 => "MemoryGrow", + 0x41 => "I32Const", + 0x42 => "I64Const", + 0x43 => "F32Const", + 0x44 => "F64Const", + 0x45 => "I32Eqz", + 0x46 => "I32Eq", + 0x47 => "I32Ne", + 0x48 => "I32LtS", + 0x49 => "I32LtU", + 0x4a => "I32GtS", + 0x4b => "I32GtU", + 0x4c => "I32LeS", + 0x4d => "I32LeU", + 0x4e => "I32GeS", + 0x4f => "I32GeU", + 0x50 => "I64Eqz", + 0x51 => "I64Eq", + 0x52 => "I64Ne", + 0x53 => "I64LtS", + 0x54 => "I64LtU", + 0x55 => "I64GtS", + 0x56 => "I64GtU", + 0x57 => "I64LeS", + 0x58 => "I64LeU", + 0x59 => "I64GeS", + 0x5a => "I64GeU", + 0x5b => "F32Eq", + 0x5c => "F32Ne", + 0x5d => "F32Lt", + 0x5e => "F32Gt", + 0x5f => "F32Le", + 0x60 => "F32Ge", + 0x61 => "F64Eq", + 0x62 => "F64Ne", + 0x63 => "F64Lt", + 0x64 => "F64Gt", + 0x65 => "F64Le", + 0x66 => "F64Ge", + 0x67 => "I32Clz", + 0x68 => "I32Ctz", + 0x69 => "I32Popcnt", + 0x6a => "I32Add", + 0x6b => "I32Sub", + 0x6c => "I32Mul", + 0x6d => "I32DivS", + 0x6e => "I32DivU", + 0x6f => "I32RemS", + 0x70 => "I32RemU", + 0x71 => "I32And", + 0x72 => "I32Or", + 0x73 => "I32Xor", + 0x74 => "I32Shl", + 0x75 => "I32ShrS", + 0x76 => "I32ShrU", + 0x77 => "I32Rotl", + 0x78 => "I32Rotr", + 0x79 => "I64Clz", + 0x7a => "I64Ctz", + 0x7b => "I64Popcnt", + 0x7c => "I64Add", + 0x7d => "I64Sub", + 0x7e => "I64Mul", + 0x7f => "I64DivS", + 0x80 => "I64DivU", + 0x81 => "I64RemS", + 0x82 => "I64RemU", + 0x83 => "I64And", + 0x84 => "I64Or", + 0x85 => "I64Xor", + 0x86 => "I64Shl", + 0x87 => "I64ShrS", + 0x88 => "I64ShrU", + 0x89 => "I64Rotl", + 0x8a => "I64Rotr", + 0x8b => "F32Abs", + 0x8c => "F32Neg", + 0x8d => "F32Ceil", + 0x8e => "F32Floor", + 0x8f => "F32Trunc", + 0x90 => "F32Nearest", + 0x91 => "F32Sqrt", + 0x92 => "F32Add", + 0x93 => "F32Sub", + 0x94 => "F32Mul", + 0x95 => "F32Div", + 0x96 => "F32Min", + 0x97 => "F32Max", + 0x98 => "F32Copysign", + 0x99 => "F64Abs", + 0x9a => "F64Neg", + 0x9b => "F64Ceil", + 0x9c => "F64Floor", + 0x9d => "F64Trunc", + 0x9e => "F64Nearest", + 0x9f => "F64Sqrt", + 0xa0 => "F64Add", + 0xa1 => "F64Sub", + 0xa2 => "F64Mul", + 0xa3 => "F64Div", + 0xa4 => "F64Min", + 0xa5 => "F64Max", + 0xa6 => "F64Copysign", + 0xa7 => "I32WrapI64", + 0xa8 => "I32TruncF32S", + 0xa9 => "I32TruncF32U", + 0xaa => "I32TruncF64S", + 0xab => "I32TruncF64U", + 0xac => "I64ExtendI32S", + 0xad => "I64ExtendI32U", + 0xae => "I64TruncF32S", + 0xaf => "I64TruncF32U", + 0xb0 => "I64TruncF64S", + 0xb1 => "I64TruncF64U", + 0xb2 => "F32ConvertI32S", + 0xb3 => "F32ConvertI32U", + 0xb4 => "F32ConvertI64S", + 0xb5 => "F32ConvertI64U", + 0xb6 => "F32DemoteF64", + 0xb7 => "F64ConvertI32S", + 0xb8 => "F64ConvertI32U", + 0xb9 => "F64ConvertI64S", + 0xba => "F64ConvertI64U", + 0xbb => "F64PromoteF32", + 0xbc => "I32ReinterpretF32", + 0xbd => "I64ReinterpretF64", + 0xbe => "F32ReinterpretI32", + 0xbf => "F64ReinterpretI64", + 0xc0 => "I32Extend8S", + 0xc1 => "I32Extend16S", + 0xc2 => "I64Extend8S", + 0xc3 => "I64Extend16S", + 0xc4 => "I64Extend32S", + 0xd0 => "RefNull", + 0xd1 => "RefIsNull", + 0xd2 => "RefFunc", + 0xd3 => "RefAsNonNull", + 0xd4 => "BrOnNull", + 0xd5 => "RefEq", + 0xd6 => "BrOnNonNull", + 0xfb00 => "StructNew", + 0xfb01 => "StructNewDefault", + 0xfb02 => "StructGet", + 0xfb03 => "StructGetS", + 0xfb04 => "StructGetU", + 0xfb05 => "StructSet", + 0xfb06 => "ArrayNew", + 0xfb07 => "ArrayNewDefault", + 0xfb08 => "ArrayNewFixed", + 0xfb09 => "ArrayNewData", + 0xfb0a => "ArrayNewElem", + 0xfb0b => "ArrayGet", + 0xfb0c => "ArrayGetS", + 0xfb0d => "ArrayGetU", + 0xfb0e => "ArraySet", + 0xfb0f => "ArrayLen", + 0xfb10 => "ArrayFill", + 0xfb11 => "ArrayCopy", + 0xfb12 => "ArrayInitData", + 0xfb13 => "ArrayInitElem", + 0xfb14 => "RefTestNonNull", + 0xfb15 => "RefTestNullable", + 0xfb16 => "RefCastNonNull", + 0xfb17 => "RefCastNullable", + 0xfb18 => "BrOnCast", + 0xfb19 => "BrOnCastFail", + 0xfb1a => "AnyConvertExtern", + 0xfb1b => "ExternConvertAny", + 0xfb1c => "RefI31", + 0xfb1d => "I31GetS", + 0xfb1e => "I31GetU", + 0xfc00 => "I32TruncSatF32S", + 0xfc01 => "I32TruncSatF32U", + 0xfc02 => "I32TruncSatF64S", + 0xfc03 => "I32TruncSatF64U", + 0xfc04 => "I64TruncSatF32S", + 0xfc05 => "I64TruncSatF32U", + 0xfc06 => "I64TruncSatF64S", + 0xfc07 => "I64TruncSatF64U", + 0xfc08 => "MemoryInit", + 0xfc09 => "DataDrop", + 0xfc0a => "MemoryCopy", + 0xfc0b => "MemoryFill", + 0xfc0c => "TableInit", + 0xfc0d => "ElemDrop", + 0xfc0e => "TableCopy", + 0xfc0f => "TableGrow", + 0xfc10 => "TableSize", + 0xfc11 => "TableFill", + 0xfc12 => "MemoryDiscard", + 0xfd00 => "V128Load", + 0xfd01 => "V128Load8x8S", + 0xfd02 => "V128Load8x8U", + 0xfd03 => "V128Load16x4S", + 0xfd04 => "V128Load16x4U", + 0xfd05 => "V128Load32x2S", + 0xfd06 => "V128Load32x2U", + 0xfd07 => "V128Load8Splat", + 0xfd08 => "V128Load16Splat", + 0xfd09 => "V128Load32Splat", + 0xfd0a => "V128Load64Splat", + 0xfd0b => "V128Store", + 0xfd0c => "V128Const", + 0xfd0d => "I8x16Shuffle", + 0xfd0e => "I8x16Swizzle", + 0xfd0f => "I8x16Splat", + 0xfd10 => "I16x8Splat", + 0xfd11 => "I32x4Splat", + 0xfd12 => "I64x2Splat", + 0xfd13 => "F32x4Splat", + 0xfd14 => "F64x2Splat", + 0xfd15 => "I8x16ExtractLaneS", + 0xfd16 => "I8x16ExtractLaneU", + 0xfd17 => "I8x16ReplaceLane", + 0xfd18 => "I16x8ExtractLaneS", + 0xfd19 => "I16x8ExtractLaneU", + 0xfd1a => "I16x8ReplaceLane", + 0xfd1b => "I32x4ExtractLane", + 0xfd1c => "I32x4ReplaceLane", + 0xfd1d => "I64x2ExtractLane", + 0xfd1e => "I64x2ReplaceLane", + 0xfd1f => "F32x4ExtractLane", + 0xfd20 => "F32x4ReplaceLane", + 0xfd21 => "F64x2ExtractLane", + 0xfd22 => "F64x2ReplaceLane", + 0xfd23 => "I8x16Eq", + 0xfd24 => "I8x16Ne", + 0xfd25 => "I8x16LtS", + 0xfd26 => "I8x16LtU", + 0xfd27 => "I8x16GtS", + 0xfd28 => "I8x16GtU", + 0xfd29 => "I8x16LeS", + 0xfd2a => "I8x16LeU", + 0xfd2b => "I8x16GeS", + 0xfd2c => "I8x16GeU", + 0xfd2d => "I16x8Eq", + 0xfd2e => "I16x8Ne", + 0xfd2f => "I16x8LtS", + 0xfd30 => "I16x8LtU", + 0xfd31 => "I16x8GtS", + 0xfd32 => "I16x8GtU", + 0xfd33 => "I16x8LeS", + 0xfd34 => "I16x8LeU", + 0xfd35 => "I16x8GeS", + 0xfd36 => "I16x8GeU", + 0xfd37 => "I32x4Eq", + 0xfd38 => "I32x4Ne", + 0xfd39 => "I32x4LtS", + 0xfd3a => "I32x4LtU", + 0xfd3b => "I32x4GtS", + 0xfd3c => "I32x4GtU", + 0xfd3d => "I32x4LeS", + 0xfd3e => "I32x4LeU", + 0xfd3f => "I32x4GeS", + 0xfd40 => "I32x4GeU", + 0xfd41 => "F32x4Eq", + 0xfd42 => "F32x4Ne", + 0xfd43 => "F32x4Lt", + 0xfd44 => "F32x4Gt", + 0xfd45 => "F32x4Le", + 0xfd46 => "F32x4Ge", + 0xfd47 => "F64x2Eq", + 0xfd48 => "F64x2Ne", + 0xfd49 => "F64x2Lt", + 0xfd4a => "F64x2Gt", + 0xfd4b => "F64x2Le", + 0xfd4c => "F64x2Ge", + 0xfd4d => "V128Not", + 0xfd4e => "V128And", + 0xfd4f => "V128AndNot", + 0xfd50 => "V128Or", + 0xfd51 => "V128Xor", + 0xfd52 => "V128Bitselect", + 0xfd53 => "V128AnyTrue", + 0xfd54 => "V128Load8Lane", + 0xfd55 => "V128Load16Lane", + 0xfd56 => "V128Load32Lane", + 0xfd57 => "V128Load64Lane", + 0xfd58 => "V128Store8Lane", + 0xfd59 => "V128Store16Lane", + 0xfd5a => "V128Store32Lane", + 0xfd5b => "V128Store64Lane", + 0xfd5c => "V128Load32Zero", + 0xfd5d => "V128Load64Zero", + 0xfd5e => "F32x4DemoteF64x2Zero", + 0xfd5f => "F64x2PromoteLowF32x4", + 0xfd60 => "I8x16Abs", + 0xfd61 => "I8x16Neg", + 0xfd62 => "I8x16Popcnt", + 0xfd63 => "I8x16AllTrue", + 0xfd64 => "I8x16Bitmask", + 0xfd65 => "I8x16NarrowI16x8S", + 0xfd66 => "I8x16NarrowI16x8U", + 0xfd67 => "F32x4Ceil", + 0xfd68 => "F32x4Floor", + 0xfd69 => "F32x4Trunc", + 0xfd6a => "F32x4Nearest", + 0xfd6b => "I8x16Shl", + 0xfd6c => "I8x16ShrS", + 0xfd6d => "I8x16ShrU", + 0xfd6e => "I8x16Add", + 0xfd6f => "I8x16AddSatS", + 0xfd70 => "I8x16AddSatU", + 0xfd71 => "I8x16Sub", + 0xfd72 => "I8x16SubSatS", + 0xfd73 => "I8x16SubSatU", + 0xfd74 => "F64x2Ceil", + 0xfd75 => "F64x2Floor", + 0xfd76 => "I8x16MinS", + 0xfd77 => "I8x16MinU", + 0xfd78 => "I8x16MaxS", + 0xfd79 => "I8x16MaxU", + 0xfd7a => "F64x2Trunc", + 0xfd7b => "I8x16AvgrU", + 0xfd7c => "I16x8ExtAddPairwiseI8x16S", + 0xfd7d => "I16x8ExtAddPairwiseI8x16U", + 0xfd7e => "I32x4ExtAddPairwiseI16x8S", + 0xfd7f => "I32x4ExtAddPairwiseI16x8U", + 0xfd80 => "I16x8Abs", + 0xfd81 => "I16x8Neg", + 0xfd82 => "I16x8Q15MulrSatS", + 0xfd83 => "I16x8AllTrue", + 0xfd84 => "I16x8Bitmask", + 0xfd85 => "I16x8NarrowI32x4S", + 0xfd86 => "I16x8NarrowI32x4U", + 0xfd87 => "I16x8ExtendLowI8x16S", + 0xfd88 => "I16x8ExtendHighI8x16S", + 0xfd89 => "I16x8ExtendLowI8x16U", + 0xfd8a => "I16x8ExtendHighI8x16U", + 0xfd8b => "I16x8Shl", + 0xfd8c => "I16x8ShrS", + 0xfd8d => "I16x8ShrU", + 0xfd8e => "I16x8Add", + 0xfd8f => "I16x8AddSatS", + 0xfd90 => "I16x8AddSatU", + 0xfd91 => "I16x8Sub", + 0xfd92 => "I16x8SubSatS", + 0xfd93 => "I16x8SubSatU", + 0xfd94 => "F64x2Nearest", + 0xfd95 => "I16x8Mul", + 0xfd96 => "I16x8MinS", + 0xfd97 => "I16x8MinU", + 0xfd98 => "I16x8MaxS", + 0xfd99 => "I16x8MaxU", + 0xfd9b => "I16x8AvgrU", + 0xfd9c => "I16x8ExtMulLowI8x16S", + 0xfd9d => "I16x8ExtMulHighI8x16S", + 0xfd9e => "I16x8ExtMulLowI8x16U", + 0xfd9f => "I16x8ExtMulHighI8x16U", + 0xfda0 => "I32x4Abs", + 0xfda2 => "I8x16RelaxedSwizzle", + 0xfda1 => "I32x4Neg", + 0xfda3 => "I32x4AllTrue", + 0xfda4 => "I32x4Bitmask", + 0xfda5 => "I32x4RelaxedTruncF32x4S", + 0xfda6 => "I32x4RelaxedTruncF32x4U", + 0xfda7 => "I32x4ExtendLowI16x8S", + 0xfda8 => "I32x4ExtendHighI16x8S", + 0xfda9 => "I32x4ExtendLowI16x8U", + 0xfdaa => "I32x4ExtendHighI16x8U", + 0xfdab => "I32x4Shl", + 0xfdac => "I32x4ShrS", + 0xfdad => "I32x4ShrU", + 0xfdae => "I32x4Add", + 0xfdaf => "F32x4RelaxedMadd", + 0xfdb0 => "F32x4RelaxedNmadd", + 0xfdb1 => "I32x4Sub", + 0xfdb2 => "I8x16RelaxedLaneselect", + 0xfdb3 => "I16x8RelaxedLaneselect", + 0xfdb4 => "F32x4RelaxedMin", + 0xfdb5 => "I32x4Mul", + 0xfdb6 => "I32x4MinS", + 0xfdb7 => "I32x4MinU", + 0xfdb8 => "I32x4MaxS", + 0xfdb9 => "I32x4MaxU", + 0xfdba => "I32x4DotI16x8S", + 0xfdbc => "I32x4ExtMulLowI16x8S", + 0xfdbd => "I32x4ExtMulHighI16x8S", + 0xfdbe => "I32x4ExtMulLowI16x8U", + 0xfdbf => "I32x4ExtMulHighI16x8U", + 0xfdc0 => "I64x2Abs", + 0xfdc1 => "I64x2Neg", + 0xfdc3 => "I64x2AllTrue", + 0xfdc4 => "I64x2Bitmask", + 0xfdc5 => "I32x4RelaxedTruncF64x2SZero", + 0xfdc6 => "I32x4RelaxedTruncF64x2UZero", + 0xfdc7 => "I64x2ExtendLowI32x4S", + 0xfdc8 => "I64x2ExtendHighI32x4S", + 0xfdc9 => "I64x2ExtendLowI32x4U", + 0xfdca => "I64x2ExtendHighI32x4U", + 0xfdcb => "I64x2Shl", + 0xfdcc => "I64x2ShrS", + 0xfdcd => "I64x2ShrU", + 0xfdce => "I64x2Add", + 0xfdcf => "F64x2RelaxedMadd", + 0xfdd0 => "F64x2RelaxedNmadd", + 0xfdd1 => "I64x2Sub", + 0xfdd2 => "I32x4RelaxedLaneselect", + 0xfdd3 => "I64x2RelaxedLaneselect", + 0xfdd4 => "F64x2RelaxedMin", + 0xfdd5 => "I64x2Mul", + 0xfdd6 => "I64x2Eq", + 0xfdd7 => "I64x2Ne", + 0xfdd8 => "I64x2LtS", + 0xfdd9 => "I64x2GtS", + 0xfdda => "I64x2LeS", + 0xfddb => "I64x2GeS", + 0xfddc => "I64x2ExtMulLowI32x4S", + 0xfddd => "I64x2ExtMulHighI32x4S", + 0xfdde => "I64x2ExtMulLowI32x4U", + 0xfddf => "I64x2ExtMulHighI32x4U", + 0xfde0 => "F32x4Abs", + 0xfde1 => "F32x4Neg", + 0xfde2 => "F32x4RelaxedMax", + 0xfde3 => "F32x4Sqrt", + 0xfde4 => "F32x4Add", + 0xfde5 => "F32x4Sub", + 0xfde6 => "F32x4Mul", + 0xfde7 => "F32x4Div", + 0xfde8 => "F32x4Min", + 0xfde9 => "F32x4Max", + 0xfdea => "F32x4PMin", + 0xfdeb => "F32x4PMax", + 0xfdec => "F64x2Abs", + 0xfded => "F64x2Neg", + 0xfdee => "F64x2RelaxedMax", + 0xfdef => "F64x2Sqrt", + 0xfdf0 => "F64x2Add", + 0xfdf1 => "F64x2Sub", + 0xfdf2 => "F64x2Mul", + 0xfdf3 => "F64x2Div", + 0xfdf4 => "F64x2Min", + 0xfdf5 => "F64x2Max", + 0xfdf6 => "F64x2PMin", + 0xfdf7 => "F64x2PMax", + 0xfdf8 => "I32x4TruncSatF32x4S", + 0xfdf9 => "I32x4TruncSatF32x4U", + 0xfdfa => "F32x4ConvertI32x4S", + 0xfdfb => "F32x4ConvertI32x4U", + 0xfdfc => "I32x4TruncSatF64x2SZero", + 0xfdfd => "I32x4TruncSatF64x2UZero", + 0xfdfe => "F64x2ConvertLowI32x4S", + 0xfdff => "F64x2ConvertLowI32x4U", + 0xfe00 => "MemoryAtomicNotify", + 0xfe01 => "MemoryAtomicWait32", + 0xfe02 => "MemoryAtomicWait64", + 0xfe03 => "AtomicFence", + 0xfe10 => "I32AtomicLoad", + 0xfe11 => "I64AtomicLoad", + 0xfe12 => "I32AtomicLoad8U", + 0xfe13 => "I32AtomicLoad16U", + 0xfe14 => "I64AtomicLoad8U", + 0xfe15 => "I64AtomicLoad16U", + 0xfe16 => "I64AtomicLoad32U", + 0xfe17 => "I32AtomicStore", + 0xfe18 => "I64AtomicStore", + 0xfe19 => "I32AtomicStore8", + 0xfe1a => "I32AtomicStore16", + 0xfe1b => "I64AtomicStore8", + 0xfe1c => "I64AtomicStore16", + 0xfe1d => "I64AtomicStore32", + 0xfe1e => "I32AtomicRmwAdd", + 0xfe1f => "I64AtomicRmwAdd", + 0xfe20 => "I32AtomicRmw8AddU", + 0xfe21 => "I32AtomicRmw16AddU", + 0xfe22 => "I64AtomicRmw8AddU", + 0xfe23 => "I64AtomicRmw16AddU", + 0xfe24 => "I64AtomicRmw32AddU", + 0xfe25 => "I32AtomicRmwSub", + 0xfe26 => "I64AtomicRmwSub", + 0xfe27 => "I32AtomicRmw8SubU", + 0xfe28 => "I32AtomicRmw16SubU", + 0xfe29 => "I64AtomicRmw8SubU", + 0xfe2a => "I64AtomicRmw16SubU", + 0xfe2b => "I64AtomicRmw32SubU", + 0xfe2c => "I32AtomicRmwAnd", + 0xfe2d => "I64AtomicRmwAnd", + 0xfe2e => "I32AtomicRmw8AndU", + 0xfe2f => "I32AtomicRmw16AndU", + 0xfe30 => "I64AtomicRmw8AndU", + 0xfe31 => "I64AtomicRmw16AndU", + 0xfe32 => "I64AtomicRmw32AndU", + 0xfe33 => "I32AtomicRmwOr", + 0xfe34 => "I64AtomicRmwOr", + 0xfe35 => "I32AtomicRmw8OrU", + 0xfe36 => "I32AtomicRmw16OrU", + 0xfe37 => "I64AtomicRmw8OrU", + 0xfe38 => "I64AtomicRmw16OrU", + 0xfe39 => "I64AtomicRmw32OrU", + 0xfe3a => "I32AtomicRmwXor", + 0xfe3b => "I64AtomicRmwXor", + 0xfe3c => "I32AtomicRmw8XorU", + 0xfe3d => "I32AtomicRmw16XorU", + 0xfe3e => "I64AtomicRmw8XorU", + 0xfe3f => "I64AtomicRmw16XorU", + 0xfe40 => "I64AtomicRmw32XorU", + 0xfe41 => "I32AtomicRmwXchg", + 0xfe42 => "I64AtomicRmwXchg", + 0xfe43 => "I32AtomicRmw8XchgU", + 0xfe44 => "I32AtomicRmw16XchgU", + 0xfe45 => "I64AtomicRmw8XchgU", + 0xfe46 => "I64AtomicRmw16XchgU", + 0xfe47 => "I64AtomicRmw32XchgU", + 0xfe48 => "I32AtomicRmwCmpxchg", + 0xfe49 => "I64AtomicRmwCmpxchg", + 0xfe4a => "I32AtomicRmw8CmpxchgU", + 0xfe4b => "I32AtomicRmw16CmpxchgU", + 0xfe4c => "I64AtomicRmw8CmpxchgU", + 0xfe4d => "I64AtomicRmw16CmpxchgU", + 0xfe4e => "I64AtomicRmw32CmpxchgU", + 0xfd111 => "I16x8RelaxedQ15mulrS", + 0xfd112 => "I16x8RelaxedDotI8x16I7x16S", + 0xfd113 => "I32x4RelaxedDotI8x16I7x16AddS", + _ => "UNKNOWN", + }; + write!(f, "{name}") + } +} + +impl From> for OperatorCode { + fn from(op: Operator) -> Self { + OperatorCode::from(&op) + } +} + +impl From<&Operator<'_>> for OperatorCode { + fn from(op: &Operator) -> Self { + use Operator as O; + + OperatorCode(match op { + O::Unreachable => 0x00, + O::Nop => 0x01, + O::Block { .. } => 0x02, + O::Loop { .. } => 0x03, + O::If { .. } => 0x04, + O::Else => 0x05, + O::Try { .. } => 0x06, + O::Catch { .. } => 0x07, + O::Throw { .. } => 0x08, + O::Rethrow { .. } => 0x09, + O::ThrowRef { .. } => 0x0A, + O::End => 0x0b, + O::Br { .. } => 0x0c, + O::BrIf { .. } => 0x0d, + O::BrTable { .. } => 0x0e, + O::Return => 0x0f, + O::Call { .. } => 0x10, + O::CallIndirect { .. } => 0x11, + O::ReturnCall { .. } => 0x12, + O::ReturnCallIndirect { .. } => 0x13, + O::CallRef { .. } => 0x14, + O::ReturnCallRef { .. } => 0x15, + O::Delegate { .. } => 0x18, + O::CatchAll => 0x19, + O::Drop => 0x1a, + O::Select => 0x1b, + O::TypedSelect { .. } => 0x1c, + O::TryTable { .. } => 0x1f, + O::LocalGet { .. } => 0x20, + O::LocalSet { .. } => 0x21, + O::LocalTee { .. } => 0x22, + O::GlobalGet { .. } => 0x23, + O::GlobalSet { .. } => 0x24, + O::TableGet { .. } => 0x25, + O::TableSet { .. } => 0x26, + O::I32Load { .. } => 0x28, + O::I64Load { .. } => 0x29, + O::F32Load { .. } => 0x2a, + O::F64Load { .. } => 0x2b, + O::I32Load8S { .. } => 0x2c, + O::I32Load8U { .. } => 0x2d, + O::I32Load16S { .. } => 0x2e, + O::I32Load16U { .. } => 0x2f, + O::I64Load8S { .. } => 0x30, + O::I64Load8U { .. } => 0x31, + O::I64Load16S { .. } => 0x32, + O::I64Load16U { .. } => 0x33, + O::I64Load32S { .. } => 0x34, + O::I64Load32U { .. } => 0x35, + O::I32Store { .. } => 0x36, + O::I64Store { .. } => 0x37, + O::F32Store { .. } => 0x38, + O::F64Store { .. } => 0x39, + O::I32Store8 { .. } => 0x3a, + O::I32Store16 { .. } => 0x3b, + O::I64Store8 { .. } => 0x3c, + O::I64Store16 { .. } => 0x3d, + O::I64Store32 { .. } => 0x3e, + O::MemorySize { .. } => 0x3f, + O::MemoryGrow { .. } => 0x40, + O::I32Const { .. } => 0x41, + O::I64Const { .. } => 0x42, + O::F32Const { .. } => 0x43, + O::F64Const { .. } => 0x44, + O::I32Eqz => 0x45, + O::I32Eq => 0x46, + O::I32Ne => 0x47, + O::I32LtS => 0x48, + O::I32LtU => 0x49, + O::I32GtS => 0x4a, + O::I32GtU => 0x4b, + O::I32LeS => 0x4c, + O::I32LeU => 0x4d, + O::I32GeS => 0x4e, + O::I32GeU => 0x4f, + O::I64Eqz => 0x50, + O::I64Eq => 0x51, + O::I64Ne => 0x52, + O::I64LtS => 0x53, + O::I64LtU => 0x54, + O::I64GtS => 0x55, + O::I64GtU => 0x56, + O::I64LeS => 0x57, + O::I64LeU => 0x58, + O::I64GeS => 0x59, + O::I64GeU => 0x5a, + O::F32Eq => 0x5b, + O::F32Ne => 0x5c, + O::F32Lt => 0x5d, + O::F32Gt => 0x5e, + O::F32Le => 0x5f, + O::F32Ge => 0x60, + O::F64Eq => 0x61, + O::F64Ne => 0x62, + O::F64Lt => 0x63, + O::F64Gt => 0x64, + O::F64Le => 0x65, + O::F64Ge => 0x66, + O::I32Clz => 0x67, + O::I32Ctz => 0x68, + O::I32Popcnt => 0x69, + O::I32Add => 0x6a, + O::I32Sub => 0x6b, + O::I32Mul => 0x6c, + O::I32DivS => 0x6d, + O::I32DivU => 0x6e, + O::I32RemS => 0x6f, + O::I32RemU => 0x70, + O::I32And => 0x71, + O::I32Or => 0x72, + O::I32Xor => 0x73, + O::I32Shl => 0x74, + O::I32ShrS => 0x75, + O::I32ShrU => 0x76, + O::I32Rotl => 0x77, + O::I32Rotr => 0x78, + O::I64Clz => 0x79, + O::I64Ctz => 0x7a, + O::I64Popcnt => 0x7b, + O::I64Add => 0x7c, + O::I64Sub => 0x7d, + O::I64Mul => 0x7e, + O::I64DivS => 0x7f, + O::I64DivU => 0x80, + O::I64RemS => 0x81, + O::I64RemU => 0x82, + O::I64And => 0x83, + O::I64Or => 0x84, + O::I64Xor => 0x85, + O::I64Shl => 0x86, + O::I64ShrS => 0x87, + O::I64ShrU => 0x88, + O::I64Rotl => 0x89, + O::I64Rotr => 0x8a, + O::F32Abs => 0x8b, + O::F32Neg => 0x8c, + O::F32Ceil => 0x8d, + O::F32Floor => 0x8e, + O::F32Trunc => 0x8f, + O::F32Nearest => 0x90, + O::F32Sqrt => 0x91, + O::F32Add => 0x92, + O::F32Sub => 0x93, + O::F32Mul => 0x94, + O::F32Div => 0x95, + O::F32Min => 0x96, + O::F32Max => 0x97, + O::F32Copysign => 0x98, + O::F64Abs => 0x99, + O::F64Neg => 0x9a, + O::F64Ceil => 0x9b, + O::F64Floor => 0x9c, + O::F64Trunc => 0x9d, + O::F64Nearest => 0x9e, + O::F64Sqrt => 0x9f, + O::F64Add => 0xa0, + O::F64Sub => 0xa1, + O::F64Mul => 0xa2, + O::F64Div => 0xa3, + O::F64Min => 0xa4, + O::F64Max => 0xa5, + O::F64Copysign => 0xa6, + O::I32WrapI64 => 0xa7, + O::I32TruncF32S => 0xa8, + O::I32TruncF32U => 0xa9, + O::I32TruncF64S => 0xaa, + O::I32TruncF64U => 0xab, + O::I64ExtendI32S => 0xac, + O::I64ExtendI32U => 0xad, + O::I64TruncF32S => 0xae, + O::I64TruncF32U => 0xaf, + O::I64TruncF64S => 0xb0, + O::I64TruncF64U => 0xb1, + O::F32ConvertI32S => 0xb2, + O::F32ConvertI32U => 0xb3, + O::F32ConvertI64S => 0xb4, + O::F32ConvertI64U => 0xb5, + O::F32DemoteF64 => 0xb6, + O::F64ConvertI32S => 0xb7, + O::F64ConvertI32U => 0xb8, + O::F64ConvertI64S => 0xb9, + O::F64ConvertI64U => 0xba, + O::F64PromoteF32 => 0xbb, + O::I32ReinterpretF32 => 0xbc, + O::I64ReinterpretF64 => 0xbd, + O::F32ReinterpretI32 => 0xbe, + O::F64ReinterpretI64 => 0xbf, + O::I32Extend8S => 0xc0, + O::I32Extend16S => 0xc1, + O::I64Extend8S => 0xc2, + O::I64Extend16S => 0xc3, + O::I64Extend32S => 0xc4, + O::RefNull { .. } => 0xd0, + O::RefIsNull => 0xd1, + O::RefFunc { .. } => 0xd2, + O::RefAsNonNull => 0xd3, + O::BrOnNull { .. } => 0xd4, + O::RefEq { .. } => 0xd5, + O::BrOnNonNull { .. } => 0xd6, + O::StructNew { .. } => 0xfb00, + O::StructNewDefault { .. } => 0xfb01, + O::StructGet { .. } => 0xfb02, + O::StructGetS { .. } => 0xfb03, + O::StructGetU { .. } => 0xfb04, + O::StructSet { .. } => 0xfb05, + O::ArrayNew { .. } => 0xfb06, + O::ArrayNewDefault { .. } => 0xfb07, + O::ArrayNewFixed { .. } => 0xfb08, + O::ArrayNewData { .. } => 0xfb09, + O::ArrayNewElem { .. } => 0xfb0a, + O::ArrayGet { .. } => 0xfb0b, + O::ArrayGetS { .. } => 0xfb0c, + O::ArrayGetU { .. } => 0xfb0d, + O::ArraySet { .. } => 0xfb0e, + O::ArrayLen { .. } => 0xfb0f, + O::ArrayFill { .. } => 0xfb10, + O::ArrayCopy { .. } => 0xfb11, + O::ArrayInitData { .. } => 0xfb12, + O::ArrayInitElem { .. } => 0xfb13, + O::RefTestNonNull { .. } => 0xfb14, + O::RefTestNullable { .. } => 0xfb15, + O::RefCastNonNull { .. } => 0xfb16, + O::RefCastNullable { .. } => 0xfb17, + O::BrOnCast { .. } => 0xfb18, + O::BrOnCastFail { .. } => 0xfb19, + O::AnyConvertExtern => 0xfb1a, + O::ExternConvertAny => 0xfb1b, + O::RefI31 { .. } => 0xfb1c, + O::I31GetS => 0xfb1d, + O::I31GetU => 0xfb1e, + O::I32TruncSatF32S => 0xfc00, + O::I32TruncSatF32U => 0xfc01, + O::I32TruncSatF64S => 0xfc02, + O::I32TruncSatF64U => 0xfc03, + O::I64TruncSatF32S => 0xfc04, + O::I64TruncSatF32U => 0xfc05, + O::I64TruncSatF64S => 0xfc06, + O::I64TruncSatF64U => 0xfc07, + O::MemoryInit { .. } => 0xfc08, + O::DataDrop { .. } => 0xfc09, + O::MemoryCopy { .. } => 0xfc0a, + O::MemoryFill { .. } => 0xfc0b, + O::TableInit { .. } => 0xfc0c, + O::ElemDrop { .. } => 0xfc0d, + O::TableCopy { .. } => 0xfc0e, + O::TableGrow { .. } => 0xfc0f, + O::TableSize { .. } => 0xfc10, + O::TableFill { .. } => 0xfc11, + O::MemoryDiscard { .. } => 0xfc12, + O::V128Load { .. } => 0xfd00, + O::V128Load8x8S { .. } => 0xfd01, + O::V128Load8x8U { .. } => 0xfd02, + O::V128Load16x4S { .. } => 0xfd03, + O::V128Load16x4U { .. } => 0xfd04, + O::V128Load32x2S { .. } => 0xfd05, + O::V128Load32x2U { .. } => 0xfd06, + O::V128Load8Splat { .. } => 0xfd07, + O::V128Load16Splat { .. } => 0xfd08, + O::V128Load32Splat { .. } => 0xfd09, + O::V128Load64Splat { .. } => 0xfd0a, + O::V128Store { .. } => 0xfd0b, + O::V128Const { .. } => 0xfd0c, + O::I8x16Shuffle { .. } => 0xfd0d, + O::I8x16Swizzle => 0xfd0e, + O::I8x16Splat => 0xfd0f, + O::I16x8Splat => 0xfd10, + O::I32x4Splat => 0xfd11, + O::I64x2Splat => 0xfd12, + O::F32x4Splat => 0xfd13, + O::F64x2Splat => 0xfd14, + O::I8x16ExtractLaneS { .. } => 0xfd15, + O::I8x16ExtractLaneU { .. } => 0xfd16, + O::I8x16ReplaceLane { .. } => 0xfd17, + O::I16x8ExtractLaneS { .. } => 0xfd18, + O::I16x8ExtractLaneU { .. } => 0xfd19, + O::I16x8ReplaceLane { .. } => 0xfd1a, + O::I32x4ExtractLane { .. } => 0xfd1b, + O::I32x4ReplaceLane { .. } => 0xfd1c, + O::I64x2ExtractLane { .. } => 0xfd1d, + O::I64x2ReplaceLane { .. } => 0xfd1e, + O::F32x4ExtractLane { .. } => 0xfd1f, + O::F32x4ReplaceLane { .. } => 0xfd20, + O::F64x2ExtractLane { .. } => 0xfd21, + O::F64x2ReplaceLane { .. } => 0xfd22, + O::I8x16Eq => 0xfd23, + O::I8x16Ne => 0xfd24, + O::I8x16LtS => 0xfd25, + O::I8x16LtU => 0xfd26, + O::I8x16GtS => 0xfd27, + O::I8x16GtU => 0xfd28, + O::I8x16LeS => 0xfd29, + O::I8x16LeU => 0xfd2a, + O::I8x16GeS => 0xfd2b, + O::I8x16GeU => 0xfd2c, + O::I16x8Eq => 0xfd2d, + O::I16x8Ne => 0xfd2e, + O::I16x8LtS => 0xfd2f, + O::I16x8LtU => 0xfd30, + O::I16x8GtS => 0xfd31, + O::I16x8GtU => 0xfd32, + O::I16x8LeS => 0xfd33, + O::I16x8LeU => 0xfd34, + O::I16x8GeS => 0xfd35, + O::I16x8GeU => 0xfd36, + O::I32x4Eq => 0xfd37, + O::I32x4Ne => 0xfd38, + O::I32x4LtS => 0xfd39, + O::I32x4LtU => 0xfd3a, + O::I32x4GtS => 0xfd3b, + O::I32x4GtU => 0xfd3c, + O::I32x4LeS => 0xfd3d, + O::I32x4LeU => 0xfd3e, + O::I32x4GeS => 0xfd3f, + O::I32x4GeU => 0xfd40, + O::F32x4Eq => 0xfd41, + O::F32x4Ne => 0xfd42, + O::F32x4Lt => 0xfd43, + O::F32x4Gt => 0xfd44, + O::F32x4Le => 0xfd45, + O::F32x4Ge => 0xfd46, + O::F64x2Eq => 0xfd47, + O::F64x2Ne => 0xfd48, + O::F64x2Lt => 0xfd49, + O::F64x2Gt => 0xfd4a, + O::F64x2Le => 0xfd4b, + O::F64x2Ge => 0xfd4c, + O::V128Not => 0xfd4d, + O::V128And => 0xfd4e, + O::V128AndNot => 0xfd4f, + O::V128Or => 0xfd50, + O::V128Xor => 0xfd51, + O::V128Bitselect => 0xfd52, + O::V128AnyTrue => 0xfd53, + O::V128Load8Lane { .. } => 0xfd54, + O::V128Load16Lane { .. } => 0xfd55, + O::V128Load32Lane { .. } => 0xfd56, + O::V128Load64Lane { .. } => 0xfd57, + O::V128Store8Lane { .. } => 0xfd58, + O::V128Store16Lane { .. } => 0xfd59, + O::V128Store32Lane { .. } => 0xfd5a, + O::V128Store64Lane { .. } => 0xfd5b, + O::V128Load32Zero { .. } => 0xfd5c, + O::V128Load64Zero { .. } => 0xfd5d, + O::F32x4DemoteF64x2Zero => 0xfd5e, + O::F64x2PromoteLowF32x4 => 0xfd5f, + O::I8x16Abs => 0xfd60, + O::I8x16Neg => 0xfd61, + O::I8x16Popcnt => 0xfd62, + O::I8x16AllTrue => 0xfd63, + O::I8x16Bitmask => 0xfd64, + O::I8x16NarrowI16x8S => 0xfd65, + O::I8x16NarrowI16x8U => 0xfd66, + O::F32x4Ceil => 0xfd67, + O::F32x4Floor => 0xfd68, + O::F32x4Trunc => 0xfd69, + O::F32x4Nearest => 0xfd6a, + O::I8x16Shl => 0xfd6b, + O::I8x16ShrS => 0xfd6c, + O::I8x16ShrU => 0xfd6d, + O::I8x16Add => 0xfd6e, + O::I8x16AddSatS => 0xfd6f, + O::I8x16AddSatU => 0xfd70, + O::I8x16Sub => 0xfd71, + O::I8x16SubSatS => 0xfd72, + O::I8x16SubSatU => 0xfd73, + O::F64x2Ceil => 0xfd74, + O::F64x2Floor => 0xfd75, + O::I8x16MinS => 0xfd76, + O::I8x16MinU => 0xfd77, + O::I8x16MaxS => 0xfd78, + O::I8x16MaxU => 0xfd79, + O::F64x2Trunc => 0xfd7a, + O::I8x16AvgrU => 0xfd7b, + O::I16x8ExtAddPairwiseI8x16S => 0xfd7c, + O::I16x8ExtAddPairwiseI8x16U => 0xfd7d, + O::I32x4ExtAddPairwiseI16x8S => 0xfd7e, + O::I32x4ExtAddPairwiseI16x8U => 0xfd7f, + O::I16x8Abs => 0xfd80, + O::I16x8Neg => 0xfd81, + O::I16x8Q15MulrSatS => 0xfd82, + O::I16x8AllTrue => 0xfd83, + O::I16x8Bitmask => 0xfd84, + O::I16x8NarrowI32x4S => 0xfd85, + O::I16x8NarrowI32x4U => 0xfd86, + O::I16x8ExtendLowI8x16S => 0xfd87, + O::I16x8ExtendHighI8x16S => 0xfd88, + O::I16x8ExtendLowI8x16U => 0xfd89, + O::I16x8ExtendHighI8x16U => 0xfd8a, + O::I16x8Shl => 0xfd8b, + O::I16x8ShrS => 0xfd8c, + O::I16x8ShrU => 0xfd8d, + O::I16x8Add => 0xfd8e, + O::I16x8AddSatS => 0xfd8f, + O::I16x8AddSatU => 0xfd90, + O::I16x8Sub => 0xfd91, + O::I16x8SubSatS => 0xfd92, + O::I16x8SubSatU => 0xfd93, + O::F64x2Nearest => 0xfd94, + O::I16x8Mul => 0xfd95, + O::I16x8MinS => 0xfd96, + O::I16x8MinU => 0xfd97, + O::I16x8MaxS => 0xfd98, + O::I16x8MaxU => 0xfd99, + O::I16x8AvgrU => 0xfd9b, + O::I16x8ExtMulLowI8x16S => 0xfd9c, + O::I16x8ExtMulHighI8x16S => 0xfd9d, + O::I16x8ExtMulLowI8x16U => 0xfd9e, + O::I16x8ExtMulHighI8x16U => 0xfd9f, + O::I32x4Abs => 0xfda0, + O::I8x16RelaxedSwizzle => 0xfda2, + O::I32x4Neg => 0xfda1, + O::I32x4AllTrue => 0xfda3, + O::I32x4Bitmask => 0xfda4, + O::I32x4RelaxedTruncF32x4S => 0xfda5, + O::I32x4RelaxedTruncF32x4U => 0xfda6, + O::I32x4ExtendLowI16x8S => 0xfda7, + O::I32x4ExtendHighI16x8S => 0xfda8, + O::I32x4ExtendLowI16x8U => 0xfda9, + O::I32x4ExtendHighI16x8U => 0xfdaa, + O::I32x4Shl => 0xfdab, + O::I32x4ShrS => 0xfdac, + O::I32x4ShrU => 0xfdad, + O::I32x4Add => 0xfdae, + O::F32x4RelaxedMadd => 0xfdaf, + O::F32x4RelaxedNmadd => 0xfdb0, + O::I32x4Sub => 0xfdb1, + O::I8x16RelaxedLaneselect => 0xfdb2, + O::I16x8RelaxedLaneselect => 0xfdb3, + O::F32x4RelaxedMin => 0xfdb4, + O::I32x4Mul => 0xfdb5, + O::I32x4MinS => 0xfdb6, + O::I32x4MinU => 0xfdb7, + O::I32x4MaxS => 0xfdb8, + O::I32x4MaxU => 0xfdb9, + O::I32x4DotI16x8S => 0xfdba, + O::I32x4ExtMulLowI16x8S => 0xfdbc, + O::I32x4ExtMulHighI16x8S => 0xfdbd, + O::I32x4ExtMulLowI16x8U => 0xfdbe, + O::I32x4ExtMulHighI16x8U => 0xfdbf, + O::I64x2Abs => 0xfdc0, + O::I64x2Neg => 0xfdc1, + O::I64x2AllTrue => 0xfdc3, + O::I64x2Bitmask => 0xfdc4, + O::I32x4RelaxedTruncF64x2SZero => 0xfdc5, + O::I32x4RelaxedTruncF64x2UZero => 0xfdc6, + O::I64x2ExtendLowI32x4S => 0xfdc7, + O::I64x2ExtendHighI32x4S => 0xfdc8, + O::I64x2ExtendLowI32x4U => 0xfdc9, + O::I64x2ExtendHighI32x4U => 0xfdca, + O::I64x2Shl => 0xfdcb, + O::I64x2ShrS => 0xfdcc, + O::I64x2ShrU => 0xfdcd, + O::I64x2Add => 0xfdce, + O::F64x2RelaxedMadd => 0xfdcf, + O::F64x2RelaxedNmadd => 0xfdd0, + O::I64x2Sub => 0xfdd1, + O::I32x4RelaxedLaneselect => 0xfdd2, + O::I64x2RelaxedLaneselect => 0xfdd3, + O::F64x2RelaxedMin => 0xfdd4, + O::I64x2Mul => 0xfdd5, + O::I64x2Eq => 0xfdd6, + O::I64x2Ne => 0xfdd7, + O::I64x2LtS => 0xfdd8, + O::I64x2GtS => 0xfdd9, + O::I64x2LeS => 0xfdda, + O::I64x2GeS => 0xfddb, + O::I64x2ExtMulLowI32x4S => 0xfddc, + O::I64x2ExtMulHighI32x4S => 0xfddd, + O::I64x2ExtMulLowI32x4U => 0xfdde, + O::I64x2ExtMulHighI32x4U => 0xfddf, + O::F32x4Abs => 0xfde0, + O::F32x4Neg => 0xfde1, + O::F32x4RelaxedMax => 0xfde2, + O::F32x4Sqrt => 0xfde3, + O::F32x4Add => 0xfde4, + O::F32x4Sub => 0xfde5, + O::F32x4Mul => 0xfde6, + O::F32x4Div => 0xfde7, + O::F32x4Min => 0xfde8, + O::F32x4Max => 0xfde9, + O::F32x4PMin => 0xfdea, + O::F32x4PMax => 0xfdeb, + O::F64x2Abs => 0xfdec, + O::F64x2Neg => 0xfded, + O::F64x2RelaxedMax => 0xfdee, + O::F64x2Sqrt => 0xfdef, + O::F64x2Add => 0xfdf0, + O::F64x2Sub => 0xfdf1, + O::F64x2Mul => 0xfdf2, + O::F64x2Div => 0xfdf3, + O::F64x2Min => 0xfdf4, + O::F64x2Max => 0xfdf5, + O::F64x2PMin => 0xfdf6, + O::F64x2PMax => 0xfdf7, + O::I32x4TruncSatF32x4S => 0xfdf8, + O::I32x4TruncSatF32x4U => 0xfdf9, + O::F32x4ConvertI32x4S => 0xfdfa, + O::F32x4ConvertI32x4U => 0xfdfb, + O::I32x4TruncSatF64x2SZero => 0xfdfc, + O::I32x4TruncSatF64x2UZero => 0xfdfd, + O::F64x2ConvertLowI32x4S => 0xfdfe, + O::F64x2ConvertLowI32x4U => 0xfdff, + O::MemoryAtomicNotify { .. } => 0xfe00, + O::MemoryAtomicWait32 { .. } => 0xfe01, + O::MemoryAtomicWait64 { .. } => 0xfe02, + O::AtomicFence { .. } => 0xfe03, + O::I32AtomicLoad { .. } => 0xfe10, + O::I64AtomicLoad { .. } => 0xfe11, + O::I32AtomicLoad8U { .. } => 0xfe12, + O::I32AtomicLoad16U { .. } => 0xfe13, + O::I64AtomicLoad8U { .. } => 0xfe14, + O::I64AtomicLoad16U { .. } => 0xfe15, + O::I64AtomicLoad32U { .. } => 0xfe16, + O::I32AtomicStore { .. } => 0xfe17, + O::I64AtomicStore { .. } => 0xfe18, + O::I32AtomicStore8 { .. } => 0xfe19, + O::I32AtomicStore16 { .. } => 0xfe1a, + O::I64AtomicStore8 { .. } => 0xfe1b, + O::I64AtomicStore16 { .. } => 0xfe1c, + O::I64AtomicStore32 { .. } => 0xfe1d, + O::I32AtomicRmwAdd { .. } => 0xfe1e, + O::I64AtomicRmwAdd { .. } => 0xfe1f, + O::I32AtomicRmw8AddU { .. } => 0xfe20, + O::I32AtomicRmw16AddU { .. } => 0xfe21, + O::I64AtomicRmw8AddU { .. } => 0xfe22, + O::I64AtomicRmw16AddU { .. } => 0xfe23, + O::I64AtomicRmw32AddU { .. } => 0xfe24, + O::I32AtomicRmwSub { .. } => 0xfe25, + O::I64AtomicRmwSub { .. } => 0xfe26, + O::I32AtomicRmw8SubU { .. } => 0xfe27, + O::I32AtomicRmw16SubU { .. } => 0xfe28, + O::I64AtomicRmw8SubU { .. } => 0xfe29, + O::I64AtomicRmw16SubU { .. } => 0xfe2a, + O::I64AtomicRmw32SubU { .. } => 0xfe2b, + O::I32AtomicRmwAnd { .. } => 0xfe2c, + O::I64AtomicRmwAnd { .. } => 0xfe2d, + O::I32AtomicRmw8AndU { .. } => 0xfe2e, + O::I32AtomicRmw16AndU { .. } => 0xfe2f, + O::I64AtomicRmw8AndU { .. } => 0xfe30, + O::I64AtomicRmw16AndU { .. } => 0xfe31, + O::I64AtomicRmw32AndU { .. } => 0xfe32, + O::I32AtomicRmwOr { .. } => 0xfe33, + O::I64AtomicRmwOr { .. } => 0xfe34, + O::I32AtomicRmw8OrU { .. } => 0xfe35, + O::I32AtomicRmw16OrU { .. } => 0xfe36, + O::I64AtomicRmw8OrU { .. } => 0xfe37, + O::I64AtomicRmw16OrU { .. } => 0xfe38, + O::I64AtomicRmw32OrU { .. } => 0xfe39, + O::I32AtomicRmwXor { .. } => 0xfe3a, + O::I64AtomicRmwXor { .. } => 0xfe3b, + O::I32AtomicRmw8XorU { .. } => 0xfe3c, + O::I32AtomicRmw16XorU { .. } => 0xfe3d, + O::I64AtomicRmw8XorU { .. } => 0xfe3e, + O::I64AtomicRmw16XorU { .. } => 0xfe3f, + O::I64AtomicRmw32XorU { .. } => 0xfe40, + O::I32AtomicRmwXchg { .. } => 0xfe41, + O::I64AtomicRmwXchg { .. } => 0xfe42, + O::I32AtomicRmw8XchgU { .. } => 0xfe43, + O::I32AtomicRmw16XchgU { .. } => 0xfe44, + O::I64AtomicRmw8XchgU { .. } => 0xfe45, + O::I64AtomicRmw16XchgU { .. } => 0xfe46, + O::I64AtomicRmw32XchgU { .. } => 0xfe47, + O::I32AtomicRmwCmpxchg { .. } => 0xfe48, + O::I64AtomicRmwCmpxchg { .. } => 0xfe49, + O::I32AtomicRmw8CmpxchgU { .. } => 0xfe4a, + O::I32AtomicRmw16CmpxchgU { .. } => 0xfe4b, + O::I64AtomicRmw8CmpxchgU { .. } => 0xfe4c, + O::I64AtomicRmw16CmpxchgU { .. } => 0xfe4d, + O::I64AtomicRmw32CmpxchgU { .. } => 0xfe4e, + O::I16x8RelaxedQ15mulrS { .. } => 0xfd111, + O::I16x8RelaxedDotI8x16I7x16S { .. } => 0xfd112, + O::I32x4RelaxedDotI8x16I7x16AddS { .. } => 0xfd113, + #[cfg(feature = "sp1")] + _ => todo!(), + }) + } +} + +pub trait OperatorInfo { + fn ends_basic_block(&self) -> bool; + fn code(&self) -> OperatorCode; +} + +impl OperatorInfo for Operator<'_> { + fn ends_basic_block(&self) -> bool { + use Operator::*; + + macro_rules! dot { + ($first:ident $(,$opcode:ident)*) => { + $first { .. } $(| $opcode { .. })* + }; + } + + matches!( + self, + End | Else | Return | dot!(Loop, Br, BrTable, BrIf, If, Call, CallIndirect) + ) + } + + fn code(&self) -> OperatorCode { + self.into() + } +} diff --git a/arbitrator/prover/src/binary.rs b/arbitrator/prover/src/binary.rs new file mode 100644 index 00000000000..2dd269371fc --- /dev/null +++ b/arbitrator/prover/src/binary.rs @@ -0,0 +1,750 @@ +// Copyright 2021-2024, Offchain Labs, Inc. +// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md + +use crate::{ + programs::{ + FuncMiddleware, Middleware, ModuleMod, STYLUS_ENTRY_POINT, StylusData, + config::CompileConfig, counter::Counter, depth::DepthChecker, dynamic::DynamicMeter, + heap::HeapBound, meter::Meter, start::StartMover, + }, + value::{ArbValueType, FunctionType, IntegerValType, Value}, +}; +use arbutil::{ + Bytes32, Color, DebugColor, evm::ARBOS_VERSION_STYLUS_CHARGING_FIXES, math::SaturatingSum, +}; +use eyre::{Result, WrapErr, bail, ensure, eyre}; +use fnv::{FnvHashMap as HashMap, FnvHashSet as HashSet}; +use nom::{ + branch::alt, + bytes::complete::tag, + combinator::{all_consuming, map, value}, + sequence::{preceded, tuple}, +}; +use serde::{Deserialize, Serialize}; +use std::{convert::TryInto, fmt::Debug, hash::Hash, mem, path::Path, str::FromStr}; +use wasmer_types::{ExportIndex, FunctionIndex, LocalFunctionIndex, entity::EntityRef}; +use wasmparser::{ + Data, Element, ExternalKind, MemoryType, Name, NameSectionReader, Naming, Operator, Parser, + Payload, TableType, TypeRef, ValType, Validator, WasmFeatures, +}; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub enum FloatType { + F32, + F64, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub enum FloatUnOp { + Abs, + Neg, + Ceil, + Floor, + Trunc, + Nearest, + Sqrt, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub enum FloatBinOp { + Add, + Sub, + Mul, + Div, + Min, + Max, + CopySign, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub enum FloatRelOp { + Eq, + Ne, + Lt, + Gt, + Le, + Ge, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub enum FloatInstruction { + UnOp(FloatType, FloatUnOp), + BinOp(FloatType, FloatBinOp), + RelOp(FloatType, FloatRelOp), + /// The bools represent (saturating, signed) + TruncIntOp(IntegerValType, FloatType, bool, bool), + ConvertIntOp(FloatType, IntegerValType, bool), + F32DemoteF64, + F64PromoteF32, +} + +impl FloatInstruction { + pub fn signature(&self) -> FunctionType { + match *self { + FloatInstruction::UnOp(t, _) => FunctionType::new([t.into()], [t.into()]), + FloatInstruction::BinOp(t, _) => FunctionType::new([t.into(); 2], [t.into()]), + FloatInstruction::RelOp(t, _) => FunctionType::new([t.into(); 2], [ArbValueType::I32]), + FloatInstruction::TruncIntOp(i, f, ..) => FunctionType::new([f.into()], [i.into()]), + FloatInstruction::ConvertIntOp(f, i, _) => FunctionType::new([i.into()], [f.into()]), + FloatInstruction::F32DemoteF64 => { + FunctionType::new([ArbValueType::F64], [ArbValueType::F32]) + } + FloatInstruction::F64PromoteF32 => { + FunctionType::new([ArbValueType::F32], [ArbValueType::F64]) + } + } + } +} + +impl FromStr for FloatInstruction { + type Err = String; + + fn from_str(s: &str) -> Result { + type IResult<'a, T> = nom::IResult<&'a str, T, nom::error::Error<&'a str>>; + + fn parse_fp_type(s: &str) -> IResult<'_, FloatType> { + alt(( + value(FloatType::F32, tag("f32")), + value(FloatType::F64, tag("f64")), + ))(s) + } + + fn parse_signedness(s: &str) -> IResult<'_, bool> { + alt((value(true, tag("s")), value(false, tag("u"))))(s) + } + + fn parse_int_type(s: &str) -> IResult<'_, IntegerValType> { + alt(( + value(IntegerValType::I32, tag("i32")), + value(IntegerValType::I64, tag("i64")), + ))(s) + } + + fn parse_un_op(s: &str) -> IResult<'_, FloatUnOp> { + alt(( + value(FloatUnOp::Abs, tag("abs")), + value(FloatUnOp::Neg, tag("neg")), + value(FloatUnOp::Ceil, tag("ceil")), + value(FloatUnOp::Floor, tag("floor")), + value(FloatUnOp::Trunc, tag("trunc")), + value(FloatUnOp::Nearest, tag("nearest")), + value(FloatUnOp::Sqrt, tag("sqrt")), + ))(s) + } + + fn parse_bin_op(s: &str) -> IResult<'_, FloatBinOp> { + alt(( + value(FloatBinOp::Add, tag("add")), + value(FloatBinOp::Sub, tag("sub")), + value(FloatBinOp::Mul, tag("mul")), + value(FloatBinOp::Div, tag("div")), + value(FloatBinOp::Min, tag("min")), + value(FloatBinOp::Max, tag("max")), + value(FloatBinOp::CopySign, tag("copysign")), + ))(s) + } + + fn parse_rel_op(s: &str) -> IResult<'_, FloatRelOp> { + alt(( + value(FloatRelOp::Eq, tag("eq")), + value(FloatRelOp::Ne, tag("ne")), + value(FloatRelOp::Lt, tag("lt")), + value(FloatRelOp::Gt, tag("gt")), + value(FloatRelOp::Le, tag("le")), + value(FloatRelOp::Ge, tag("ge")), + ))(s) + } + + let inst = alt(( + map( + all_consuming(tuple((parse_fp_type, tag("_"), parse_un_op))), + |(t, _, o)| FloatInstruction::UnOp(t, o), + ), + map( + all_consuming(tuple((parse_fp_type, tag("_"), parse_bin_op))), + |(t, _, o)| FloatInstruction::BinOp(t, o), + ), + map( + all_consuming(tuple((parse_fp_type, tag("_"), parse_rel_op))), + |(t, _, o)| FloatInstruction::RelOp(t, o), + ), + map( + all_consuming(tuple(( + parse_int_type, + alt(( + value(true, tag("_trunc_sat_")), + value(false, tag("_trunc_")), + )), + parse_fp_type, + tag("_"), + parse_signedness, + ))), + |(i, sat, f, _, s)| FloatInstruction::TruncIntOp(i, f, sat, s), + ), + map( + all_consuming(tuple(( + parse_fp_type, + tag("_convert_"), + parse_int_type, + tag("_"), + parse_signedness, + ))), + |(f, _, i, _, s)| FloatInstruction::ConvertIntOp(f, i, s), + ), + value( + FloatInstruction::F32DemoteF64, + all_consuming(tag("f32_demote_f64")), + ), + value( + FloatInstruction::F64PromoteF32, + all_consuming(tag("f64_promote_f32")), + ), + )); + + let res = preceded(tag("wavm__"), inst)(s); + + res.map(|(_, i)| i).map_err(|e| e.to_string()) + } +} + +pub fn op_as_const(op: Operator) -> Result { + match op { + Operator::I32Const { value } => Ok(Value::I32(value as u32)), + Operator::I64Const { value } => Ok(Value::I64(value as u64)), + Operator::F32Const { value } => Ok(Value::F32(f32::from_bits(value.bits()))), + Operator::F64Const { value } => Ok(Value::F64(f64::from_bits(value.bits()))), + _ => bail!("Opcode is not a constant"), + } +} + +#[derive(Clone, Debug, Default)] +pub struct FuncImport<'a> { + pub offset: u32, + pub module: &'a str, + pub name: &'a str, +} + +/// This enum primarily exists because wasmer's ExternalKind doesn't impl these derived functions +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)] +pub enum ExportKind { + Func, + Table, + Memory, + Global, + Tag, +} + +impl From for ExportKind { + fn from(kind: ExternalKind) -> Self { + use ExternalKind as E; + match kind { + E::Func => Self::Func, + E::Table => Self::Table, + E::Memory => Self::Memory, + E::Global => Self::Global, + E::Tag => Self::Tag, + } + } +} + +impl From for ExportKind { + fn from(value: ExportIndex) -> Self { + use ExportIndex as E; + match value { + E::Function(_) => Self::Func, + E::Table(_) => Self::Table, + E::Memory(_) => Self::Memory, + E::Global(_) => Self::Global, + #[cfg(feature = "sp1")] + E::Tag(_) => Self::Tag, + } + } +} + +#[derive(Clone, Debug, Default)] +pub struct Code<'a> { + pub locals: Vec, + pub expr: Vec>, +} + +#[derive(Clone, Debug)] +pub struct Local { + pub index: u32, + pub value: ArbValueType, +} + +#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] +pub struct NameCustomSection { + pub module: String, + pub functions: HashMap, +} + +pub type ExportMap = HashMap; + +#[derive(Clone, Default)] +pub struct WasmBinary<'a> { + pub types: Vec, + pub imports: Vec>, + /// Maps *local* function indices to global type signatures. + pub functions: Vec, + pub tables: Vec, + pub memories: Vec, + pub globals: Vec, + pub exports: ExportMap, + pub start: Option, + pub elements: Vec>, + pub codes: Vec>, + pub datas: Vec>, + pub names: NameCustomSection, + /// The source wasm, if known. + pub wasm: Option<&'a [u8]>, + /// Consensus data used to make module hashes unique. + pub extra_data: Vec, +} + +pub fn parse<'a>(input: &'a [u8], path: &'_ Path) -> Result> { + #[cfg(not(feature = "sp1"))] + let features = WasmFeatures { + mutable_global: true, + saturating_float_to_int: true, + sign_extension: true, + reference_types: false, + multi_value: true, + bulk_memory: true, // not all ops supported yet + simd: false, + relaxed_simd: false, + threads: false, + tail_call: false, + floats: true, + multi_memory: false, + exceptions: false, + memory64: false, + extended_const: false, + component_model: false, + function_references: false, + memory_control: false, + gc: false, + component_model_values: false, + component_model_nested_names: false, + }; + #[cfg(feature = "sp1")] + let features = { + let mut features = WasmFeatures::empty(); + features.set(WasmFeatures::MUTABLE_GLOBAL, true); + features.set(WasmFeatures::SATURATING_FLOAT_TO_INT, true); + features.set(WasmFeatures::SIGN_EXTENSION, true); + features.set(WasmFeatures::MULTI_VALUE, true); + features.set(WasmFeatures::BULK_MEMORY, true); // not all ops supported yet + features.set(WasmFeatures::FLOATS, true); + features + }; + Validator::new_with_features(features) + .validate_all(input) + .wrap_err_with(|| eyre!("failed to validate {}", path.to_string_lossy().red()))?; + + let mut binary = WasmBinary { + wasm: Some(input), + ..Default::default() + }; + let sections: Vec<_> = Parser::new(0).parse_all(input).collect::>()?; + + for section in sections { + use Payload::*; + + macro_rules! process { + ($dest:expr, $source:expr) => {{ + for item in $source.into_iter() { + $dest.push(item?.into()) + } + }}; + } + + match section { + TypeSection(type_section) => { + for func in type_section.into_iter_err_on_gc_types() { + binary.types.push(func?.try_into()?); + } + } + CodeSectionEntry(codes) => { + let mut code = Code::default(); + let mut locals = codes.get_locals_reader()?; + let mut ops = codes.get_operators_reader()?; + let mut index = 0; + + for _ in 0..locals.get_count() { + let (count, value) = locals.read()?; + for _ in 0..count { + code.locals.push(Local { + index, + value: value.try_into()?, + }); + index += 1; + } + } + while !ops.eof() { + code.expr.push(ops.read()?); + } + + binary.codes.push(code); + } + GlobalSection(globals) => { + for global in globals { + let mut init = global?.init_expr.get_operators_reader(); + + let value = match (init.read()?, init.read()?, init.eof()) { + (op, Operator::End, true) => op_as_const(op)?, + _ => bail!("Non-constant global initializer"), + }; + binary.globals.push(value); + } + } + ImportSection(imports) => { + for import in imports { + let import = import?; + let TypeRef::Func(offset) = import.ty else { + bail!("unsupported import kind {:?}", import) + }; + let import = FuncImport { + offset, + module: import.module, + name: import.name, + }; + binary.imports.push(import); + } + } + ExportSection(exports) => { + use ExternalKind as E; + for export in exports { + let export = export?; + let name = export.name.to_owned(); + let kind = export.kind; + if let E::Func = kind { + let index = export.index; + let name = || name.clone(); + binary.names.functions.entry(index).or_insert_with(name); + } + binary.exports.insert(name, (export.index, kind.into())); + } + } + FunctionSection(functions) => process!(binary.functions, functions), + TableSection(tables) => { + for table in tables { + binary.tables.push(table?.ty); + } + } + MemorySection(memories) => process!(binary.memories, memories), + StartSection { func, .. } => binary.start = Some(func), + ElementSection(elements) => process!(binary.elements, elements), + DataSection(datas) => process!(binary.datas, datas), + CodeSectionStart { .. } => {} + CustomSection(reader) => { + if reader.name() != "name" { + continue; + } + + // CHECK: maybe reader.data_offset() + #[cfg(not(feature = "sp1"))] + let name_reader = NameSectionReader::new(reader.data(), 0); + #[cfg(feature = "sp1")] + let name_reader = + NameSectionReader::new(wasmparser::BinaryReader::new(reader.data(), 0)); + + for name in name_reader { + match name? { + Name::Module { name, .. } => binary.names.module = name.to_owned(), + Name::Function(namemap) => { + for naming in namemap { + let Naming { index, name } = naming?; + binary.names.functions.insert(index, name.to_owned()); + } + } + _ => {} + } + } + } + Version { num, .. } => ensure!(num == 1, "wasm format version not supported {num}"), + UnknownSection { id, .. } => bail!("unsupported unknown section type {id}"), + End(_) => {} + x => bail!("unsupported section type {:?}", x), + } + } + + // reject the module if it imports the same func with inconsistent signatures + let mut imports = HashMap::default(); + for import in &binary.imports { + let offset = import.offset; + let module = import.module; + let name = import.name; + + let key = (module, name); + if let Some(prior) = imports.insert(key, offset) { + if prior != offset { + let name = name.debug_red(); + bail!("inconsistent imports for {} {name}", module.red()); + } + } + } + + // reject the module if it re-exports an import with the same name + let mut exports = HashSet::default(); + for export in binary.exports.keys() { + let export = export.rsplit("__").take(1); + exports.extend(export); + } + for import in &binary.imports { + let name = import.name; + if exports.contains(name) { + bail!("binary exports an import with the same name {}", name.red()); + } + } + + // reject the module if it imports or exports reserved symbols + let reserved = |x: &&str| x.starts_with("stylus"); + if let Some(name) = exports.into_iter().find(reserved) { + bail!("binary exports reserved symbol {}", name.red()) + } + if let Some(name) = binary.imports.iter().map(|x| x.name).find(reserved) { + bail!("binary imports reserved symbol {}", name.red()) + } + + // if no module name was given, make a best-effort guess with the file path + if binary.names.module.is_empty() { + binary.names.module = match path.file_name() { + Some(os_str) => os_str.to_string_lossy().into(), + None => path.to_string_lossy().into(), + }; + } + Ok(binary) +} + +impl Debug for WasmBinary<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("WasmBinary") + .field("types", &self.types) + .field("imports", &self.imports) + .field("functions", &self.functions) + .field("tables", &self.tables) + .field("memories", &self.memories) + .field("globals", &self.globals) + .field("exports", &self.exports) + .field("start", &self.start) + .field("elements", &format!("<{} elements>", self.elements.len())) + .field("codes", &self.codes) + .field("datas", &self.datas) + .field("names", &self.names) + .finish() + } +} + +impl<'a> WasmBinary<'a> { + /// Instruments a user wasm, producing a version bounded via configurable instrumentation. + pub fn instrument( + &mut self, + compile: &CompileConfig, + codehash: &Bytes32, + ) -> Result { + let start = StartMover::new(compile.debug.debug_info); + let meter = Meter::new(&compile.pricing); + let dygas = DynamicMeter::new(&compile.pricing); + let depth = DepthChecker::new(compile.bounds); + let bound = HeapBound::new(compile.bounds); + + start.update_module(self)?; + meter.update_module(self)?; + dygas.update_module(self)?; + depth.update_module(self)?; + bound.update_module(self)?; + + let count = compile.debug.count_ops.then(Counter::new); + if let Some(count) = &count { + count.update_module(self)?; + } + + for (index, code) in self.codes.iter_mut().enumerate() { + let index = LocalFunctionIndex::from_u32(index as u32); + let locals: Vec = code.locals.iter().map(|x| x.value.into()).collect(); + + let mut build = mem::take(&mut code.expr); + let mut input = Vec::with_capacity(build.len()); + + /// this macro exists since middlewares aren't sized (can't use a vec without boxes) + macro_rules! apply { + ($middleware:expr) => { + let mut mid = Middleware::::instrument(&$middleware, index)?; + mid.locals_info(&locals); + + mem::swap(&mut build, &mut input); + + for op in input.drain(..) { + mid.feed(op, &mut build) + .wrap_err_with(|| format!("{} failure", mid.name()))? + } + }; + } + + // add the instrumentation in the order of application + // note: this must be consistent with native execution + apply!(start); + apply!(meter); + apply!(dygas); + apply!(depth); + apply!(bound); + + if let Some(count) = &count { + apply!(*count); + } + + code.expr = build; + } + + let wasm = self.wasm.take().unwrap(); + self.extra_data.extend(*codehash); + self.extra_data.extend(compile.version.to_be_bytes()); + + // 4GB maximum implies `footprint` fits in a u16 + let footprint = self.memory_info()?.min.0 as u16; + + // check the entrypoint + let ty = FunctionType::new([ArbValueType::I32], [ArbValueType::I32]); + let user_main = self.check_func(STYLUS_ENTRY_POINT, ty)?; + + // predict costs + let funcs = self.codes.len() as u64; + let globals = self.globals.len() as u64; + let wasm_len = wasm.len() as u64; + + let data_len: u64 = self.datas.iter().map(|x| x.range.len() as u64).sum(); + let elem_len: u64 = self.elements.iter().map(|x| x.range.len() as u64).sum(); + let data_len = data_len + elem_len; + + let mut type_len = 0; + for index in &self.functions { + let ty = &self.types[*index as usize]; + type_len += (ty.inputs.len() + ty.outputs.len()) as u64; + } + + let mut asm_estimate: u64 = 512000; + asm_estimate = asm_estimate.saturating_add(funcs.saturating_mul(996829) / 1000); + asm_estimate = asm_estimate.saturating_add(type_len.saturating_mul(11416) / 1000); + asm_estimate = asm_estimate.saturating_add(wasm_len.saturating_mul(62628) / 10000); + + let mut cached_init: u64 = 0; + cached_init = cached_init.saturating_add(funcs.saturating_mul(13420) / 100_000); + cached_init = cached_init.saturating_add(type_len.saturating_mul(89) / 100_000); + cached_init = cached_init.saturating_add(wasm_len.saturating_mul(122) / 100_000); + cached_init = cached_init.saturating_add(globals.saturating_mul(1628) / 1000); + cached_init = cached_init.saturating_add(data_len.saturating_mul(75244) / 100_000); + cached_init = cached_init.saturating_add(footprint as u64 * 5); + + let mut init: u64 = 0; + if compile.version == 1 { + init = cached_init; // in version 1 cached cost is part of init cost + } + init = init.saturating_add(funcs.saturating_mul(8252) / 1000); + init = init.saturating_add(type_len.saturating_mul(1059) / 1000); + init = init.saturating_add(wasm_len.saturating_mul(1286) / 10_000); + + let [ink_left, ink_status] = meter.globals(); + let depth_left = depth.globals(); + Ok(StylusData { + ink_left: ink_left.as_u32(), + ink_status: ink_status.as_u32(), + depth_left: depth_left.as_u32(), + init_cost: init.try_into().wrap_err("init cost too high")?, + cached_init_cost: cached_init.try_into().wrap_err("cached cost too high")?, + asm_estimate: asm_estimate.try_into().wrap_err("asm estimate too large")?, + footprint, + user_main, + }) + } + + /// Parses and instruments a user wasm + pub fn parse_user( + wasm: &'a [u8], + arbos_version_for_gas: u64, + page_limit: u16, + compile: &CompileConfig, + codehash: &Bytes32, + ) -> Result<(WasmBinary<'a>, StylusData)> { + let mut bin = parse(wasm, Path::new("user"))?; + let stylus_data = bin.instrument(compile, codehash)?; + + let Some(memory) = bin.memories.first() else { + bail!("missing memory with export name \"memory\"") + }; + let pages = memory.initial; + + // ensure the wasm fits within the remaining amount of memory + if pages > page_limit.into() { + let limit = page_limit.red(); + bail!("memory exceeds limit: {} > {limit}", pages.red()); + } + + // not strictly necessary, but anti-DoS limits and extra checks in case of bugs + macro_rules! limit { + ($limit:expr, $count:expr, $name:expr) => { + if $count > $limit { + bail!("too many wasm {}: {} > {}", $name, $count, $limit); + } + }; + } + limit!(1, bin.memories.len(), "memories"); + limit!(128, bin.datas.len(), "datas"); + limit!(128, bin.elements.len(), "elements"); + limit!(1024, bin.exports.len(), "exports"); + limit!(4096, bin.codes.len(), "functions"); + limit!(32768, bin.globals.len(), "globals"); + for code in &bin.codes { + limit!(348, code.locals.len(), "locals"); + limit!(65536, code.expr.len(), "opcodes in func body"); + } + + if arbos_version_for_gas >= ARBOS_VERSION_STYLUS_CHARGING_FIXES { + limit!(513, bin.imports.len(), "imports") + } + + let table_entries = bin.tables.iter().map(|x| x.initial).saturating_sum(); + limit!(4096, table_entries, "table entries"); + + let elem_entries = bin.elements.iter().map(|x| x.range.len()).saturating_sum(); + limit!(4096, elem_entries, "element entries"); + + let max_len = 512; + macro_rules! too_long { + ($name:expr, $len:expr) => { + bail!( + "wasm {} too long: {} > {}", + $name.red(), + $len.red(), + max_len.red() + ) + }; + } + if let Some((name, _)) = bin.exports.iter().find(|(name, _)| name.len() > max_len) { + too_long!("name", name.len()) + } + if bin.names.module.len() > max_len { + too_long!("module name", bin.names.module.len()) + } + if bin.start.is_some() { + bail!("wasm start functions not allowed"); + } + Ok((bin, stylus_data)) + } + + /// Ensures a func exists and has the right type. + fn check_func(&self, name: &str, ty: FunctionType) -> Result { + let Some(&(func, kind)) = self.exports.get(name) else { + bail!("missing export with name {}", name.red()); + }; + if kind != ExportKind::Func { + let kind = kind.debug_red(); + bail!("export {} must be a function but is a {kind}", name.red()); + } + let func_ty = self.get_function(FunctionIndex::new(func.try_into()?))?; + if func_ty != ty { + bail!("wrong type for {}: {}", name.red(), func_ty.red()); + } + Ok(func) + } +} diff --git a/sp1-crates/prover/src/parse_input.rs b/arbitrator/prover/src/parse_input.rs similarity index 100% rename from sp1-crates/prover/src/parse_input.rs rename to arbitrator/prover/src/parse_input.rs diff --git a/arbitrator/prover/src/programs/config.rs b/arbitrator/prover/src/programs/config.rs new file mode 100644 index 00000000000..79df3b605a2 --- /dev/null +++ b/arbitrator/prover/src/programs/config.rs @@ -0,0 +1,234 @@ +// Copyright 2022-2023, Offchain Labs, Inc. +// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md + +#![allow(clippy::field_reassign_with_default)] + +use crate::{programs::meter, value::FunctionType}; +use arbutil::evm::api::{Gas, Ink}; +use derivative::Derivative; +use fnv::FnvHashMap as HashMap; +use std::fmt::Debug; +use wasmer_types::{Pages, SignatureIndex, WASM_PAGE_SIZE}; +use wasmparser::Operator; + +#[cfg(feature = "native")] +use { + super::{ + MiddlewareWrapper, counter::Counter, depth::DepthChecker, dynamic::DynamicMeter, + heap::HeapBound, meter::Meter, start::StartMover, + }, + std::sync::Arc, +}; + +#[derive(Clone, Copy, Debug)] +#[repr(C)] +pub struct StylusConfig { + /// Version the program was compiled against + pub version: u16, + /// The maximum size of the stack, measured in words + pub max_depth: u32, + /// Pricing parameters supplied at runtime + pub pricing: PricingParams, +} + +#[derive(Clone, Copy, Debug)] +#[repr(C)] +pub struct PricingParams { + /// The price of ink, measured in bips of an evm gas + pub ink_price: u32, +} + +impl Default for StylusConfig { + fn default() -> Self { + Self { + version: 0, + max_depth: u32::MAX, + pricing: PricingParams::default(), + } + } +} + +impl Default for PricingParams { + fn default() -> Self { + Self { ink_price: 1 } + } +} + +impl StylusConfig { + pub const fn new(version: u16, max_depth: u32, ink_price: u32) -> Self { + let pricing = PricingParams::new(ink_price); + Self { + version, + max_depth, + pricing, + } + } +} + +#[allow(clippy::inconsistent_digit_grouping)] +impl PricingParams { + pub const fn new(ink_price: u32) -> Self { + Self { ink_price } + } + + pub fn gas_to_ink(&self, gas: Gas) -> Ink { + Ink(gas.0.saturating_mul(self.ink_price.into())) + } + + pub fn ink_to_gas(&self, ink: Ink) -> Gas { + Gas(ink.0 / self.ink_price as u64) // ink_price is never 0 + } +} + +pub type SigMap = HashMap; +pub type OpCosts = fn(&Operator, &SigMap) -> u64; + +#[derive(Clone, Debug, Default)] +pub struct CompileConfig { + /// Version of the compiler to use + pub version: u16, + /// Pricing parameters used for metering + pub pricing: CompilePricingParams, + /// Memory bounds + pub bounds: CompileMemoryParams, + /// Debug parameters for test chains + pub debug: CompileDebugParams, +} + +#[derive(Clone, Copy, Debug)] +pub struct CompileMemoryParams { + /// The maximum number of pages a program may start with + pub heap_bound: Pages, + /// The maximum size of a stack frame, measured in words + pub max_frame_size: u32, + /// The maximum number of overlapping value lifetimes in a frame + pub max_frame_contention: u16, +} + +#[derive(Clone, Derivative)] +#[derivative(Debug)] +pub struct CompilePricingParams { + /// Associates opcodes to their ink costs + #[derivative(Debug = "ignore")] + pub costs: OpCosts, + /// Cost of checking the amount of ink left. + pub ink_header_cost: u64, + /// Per-byte `MemoryFill` cost + pub memory_fill_ink: u64, + /// Per-byte `MemoryCopy` cost + pub memory_copy_ink: u64, +} + +#[derive(Clone, Debug, Default)] +pub struct CompileDebugParams { + /// Allow debug functions + pub debug_funcs: bool, + /// Retain debug info + pub debug_info: bool, + /// Add instrumentation to count the number of times each kind of opcode is executed + pub count_ops: bool, +} + +impl Default for CompilePricingParams { + fn default() -> Self { + Self { + costs: |_, _| 0, + ink_header_cost: 0, + memory_fill_ink: 0, + memory_copy_ink: 0, + } + } +} + +impl Default for CompileMemoryParams { + fn default() -> Self { + Self { + heap_bound: Pages(u32::MAX / WASM_PAGE_SIZE as u32), + max_frame_size: u32::MAX, + max_frame_contention: u16::MAX, + } + } +} + +impl CompileConfig { + pub fn version(version: u16, debug_chain: bool) -> Self { + let mut config = Self::default(); + config.version = version; + config.debug.debug_funcs = debug_chain; + config.debug.debug_info = debug_chain; + + match version { + 0 => {} + 1 | 2 => { + config.bounds.heap_bound = Pages(128); // 8 mb + config.bounds.max_frame_size = 10 * 1024; + config.bounds.max_frame_contention = 4096; + config.pricing = CompilePricingParams { + costs: meter::pricing_v1, + ink_header_cost: 2450, + memory_fill_ink: 800 / 8, + memory_copy_ink: 800 / 8, + }; + } + _ => panic!("no config exists for Stylus version {version}"), + } + + config + } +} + +#[cfg(all(feature = "native", not(feature = "sp1")))] +use { + wasmer::{Cranelift, CraneliftOptLevel, Engine, Store, Target}, + wasmer_compiler_singlepass::Singlepass, +}; + +#[cfg(all(feature = "native", not(feature = "sp1")))] +impl CompileConfig { + fn engine_type(&self, target: Target, cranelift: bool) -> Engine { + use wasmer::sys::EngineBuilder; + + let mut wasmer_config: Box = match cranelift { + true => { + let mut wasmer_config = Cranelift::new(); + wasmer_config.opt_level(CraneliftOptLevel::Speed); + Box::new(wasmer_config) + } + false => Box::new(Singlepass::new()), + }; + wasmer_config.canonicalize_nans(true); + wasmer_config.enable_verifier(); + + let start = MiddlewareWrapper::new(StartMover::new(self.debug.debug_info)); + let meter = MiddlewareWrapper::new(Meter::new(&self.pricing)); + let dygas = MiddlewareWrapper::new(DynamicMeter::new(&self.pricing)); + let depth = MiddlewareWrapper::new(DepthChecker::new(self.bounds)); + let bound = MiddlewareWrapper::new(HeapBound::new(self.bounds)); + + // add the instrumentation in the order of application + // note: this must be consistent with the prover + wasmer_config.push_middleware(Arc::new(start)); + wasmer_config.push_middleware(Arc::new(meter)); + wasmer_config.push_middleware(Arc::new(dygas)); + wasmer_config.push_middleware(Arc::new(depth)); + wasmer_config.push_middleware(Arc::new(bound)); + + if self.debug.count_ops { + let counter = Counter::new(); + wasmer_config.push_middleware(Arc::new(MiddlewareWrapper::new(counter))); + } + + EngineBuilder::new(wasmer_config) + .set_target(Some(target)) + .into() + } + + // cranelift only matters for compilation and not usually needed + pub fn engine(&self, target: Target) -> Engine { + self.engine_type(target, true) + } + + pub fn store(&self, target: Target, cranelift: bool) -> Store { + Store::new(self.engine_type(target, cranelift)) + } +} diff --git a/arbitrator/prover/src/programs/counter.rs b/arbitrator/prover/src/programs/counter.rs new file mode 100644 index 00000000000..95fce3f5e6f --- /dev/null +++ b/arbitrator/prover/src/programs/counter.rs @@ -0,0 +1,158 @@ +// Copyright 2021-2023, Offchain Labs, Inc. +// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md + +use super::{FuncMiddleware, Middleware, ModuleMod}; + +#[cfg(feature = "sp1")] +use crate::operator::{OperatorCode, OperatorInfo}; +#[cfg(not(feature = "sp1"))] +use arbutil::operator::{OperatorCode, OperatorInfo}; +use eyre::{Result, eyre}; +use fnv::FnvHashMap as HashMap; +use lazy_static::lazy_static; +use parking_lot::Mutex; +use std::collections::BTreeMap; +use std::{clone::Clone, fmt::Debug, sync::Arc}; +use wasmer_types::{GlobalIndex, GlobalInit, LocalFunctionIndex, Type}; +use wasmparser::Operator; + +lazy_static! { + /// Assigns each operator a sequential offset + pub static ref OP_OFFSETS: Mutex> = Mutex::new(HashMap::default()); +} + +#[derive(Debug)] +pub struct Counter { + /// Assigns each relative offset a global variable + pub counters: Arc>>, +} + +impl Counter { + pub fn new() -> Self { + let counters = Arc::new(Mutex::new(Vec::with_capacity(OperatorCode::OPERATOR_COUNT))); + Self { counters } + } + + pub fn global_name(index: usize) -> String { + format!("stylus_opcode{index}_count") + } +} + +impl Default for Counter { + fn default() -> Self { + Self::new() + } +} + +impl Middleware for Counter +where + M: ModuleMod, +{ + type FM<'a> = FuncCounter<'a>; + + fn update_module(&self, module: &mut M) -> Result<()> { + let mut counters = self.counters.lock(); + for index in 0..OperatorCode::OPERATOR_COUNT { + let zero_count = GlobalInit::I64Const(0); + let global = module.add_global(&Self::global_name(index), Type::I64, zero_count)?; + counters.push(global); + } + Ok(()) + } + + fn instrument<'a>(&self, _: LocalFunctionIndex) -> Result> { + Ok(FuncCounter::new(self.counters.clone())) + } + + fn name(&self) -> &'static str { + "operator counter" + } +} + +#[derive(Debug)] +pub struct FuncCounter<'a> { + /// Assigns each relative offset a global variable + counters: Arc>>, + /// Instructions of the current basic block + block: Vec>, +} + +impl FuncCounter<'_> { + fn new(counters: Arc>>) -> Self { + let block = vec![]; + Self { counters, block } + } +} + +impl<'a> FuncMiddleware<'a> for FuncCounter<'a> { + fn feed(&mut self, op: Operator<'a>, out: &mut O) -> Result<()> + where + O: Extend>, + { + use Operator::*; + + let end = op.ends_basic_block(); + self.block.push(op); + + if end { + let update = |global_index: u32, value: i64| { + [ + GlobalGet { global_index }, + I64Const { value }, + I64Add, + GlobalSet { global_index }, + ] + }; + + // there's always at least one op, so we chain the instrumentation + let mut increments = HashMap::default(); + for op in self.block.iter().chain(update(0, 0).iter()) { + let count = increments.entry(op.code()).or_default(); + *count += 1; + } + + // add the instrumentation's contribution to the overall counts + let kinds = increments.len() as i64; + for op in update(0, 0) { + let count = increments.get_mut(&op.code()).unwrap(); + *count += kinds - 1; // we included one in the last loop + } + + let counters = self.counters.lock(); + let mut operators = OP_OFFSETS.lock(); + for (op, count) in increments { + let opslen = operators.len(); + let offset = *operators.entry(op).or_insert(opslen); + let global = *counters.get(offset).ok_or_else(|| eyre!("no global"))?; + out.extend(update(global.as_u32(), count)); + } + + out.extend(self.block.drain(..)); + } + Ok(()) + } + + fn name(&self) -> &'static str { + "operator counter" + } +} + +pub trait CountingMachine { + fn operator_counts(&mut self) -> Result>; +} + +#[cfg(not(feature = "sp1"))] +impl CountingMachine for crate::Machine { + fn operator_counts(&mut self) -> Result> { + let mut counts = BTreeMap::new(); + + for (&op, &offset) in OP_OFFSETS.lock().iter() { + let count = self.get_global(&Counter::global_name(offset))?; + let count: u64 = count.try_into()?; + if count != 0 { + counts.insert(op, count); + } + } + Ok(counts) + } +} diff --git a/arbitrator/prover/src/programs/depth.rs b/arbitrator/prover/src/programs/depth.rs new file mode 100644 index 00000000000..6e9c557119e --- /dev/null +++ b/arbitrator/prover/src/programs/depth.rs @@ -0,0 +1,545 @@ +// Copyright 2022-2023, Offchain Labs, Inc. +// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md + +use super::{ + FuncMiddleware, Middleware, ModuleMod, + config::{CompileMemoryParams, SigMap}, +}; +use crate::value::{FunctionType, InternalFunc}; + +use arbutil::Color; +use eyre::{Result, bail}; +use fnv::FnvHashMap as HashMap; +use parking_lot::RwLock; +use std::sync::Arc; +use wasmer_types::{ + FunctionIndex, GlobalIndex, GlobalInit, LocalFunctionIndex, SignatureIndex, Type, +}; +use wasmparser::{BlockType, Operator, ValType}; + +pub const STYLUS_STACK_LEFT: &str = "stylus_stack_left"; + +/// This middleware ensures stack overflows are deterministic across different compilers and targets. +/// The internal notion of "stack space left" that makes this possible is strictly smaller than that of +/// the real stack space consumed on any target platform and is formed by inspecting the contents of each +/// function's frame. +/// Setting a limit smaller than that of any native platform's ensures stack overflows will have the same, +/// logical effect rather than actually exhausting the space provided by the OS. +#[derive(Debug)] +pub struct DepthChecker { + /// The amount of stack space left + global: RwLock>, + /// The maximum size of a stack frame, measured in words + frame_limit: u32, + /// The maximum number of overlapping value lifetimes in a frame + frame_contention: u16, + /// The function types of the module being instrumented + funcs: RwLock>>>, + /// The types of the module being instrumented + sigs: RwLock>>, +} + +impl DepthChecker { + pub fn new(params: CompileMemoryParams) -> Self { + Self { + global: RwLock::default(), + frame_limit: params.max_frame_size, + frame_contention: params.max_frame_contention, + funcs: RwLock::default(), + sigs: RwLock::default(), + } + } + + pub fn globals(&self) -> GlobalIndex { + self.global.read().unwrap() + } +} + +impl Middleware for DepthChecker { + type FM<'a> = FuncDepthChecker<'a>; + + fn update_module(&self, module: &mut M) -> Result<()> { + let limit = GlobalInit::I32Const(0); + let space = module.add_global(STYLUS_STACK_LEFT, Type::I32, limit)?; + *self.global.write() = Some(space); + *self.funcs.write() = Some(Arc::new(module.all_functions()?)); + *self.sigs.write() = Some(Arc::new(module.all_signatures()?)); + Ok(()) + } + + fn instrument<'a>(&self, func: LocalFunctionIndex) -> Result> { + Ok(FuncDepthChecker::new( + self.global.read().expect("no global"), + self.funcs.read().clone().expect("no funcs"), + self.sigs.read().clone().expect("no sigs"), + self.frame_limit, + self.frame_contention, + func, + )) + } + + fn name(&self) -> &'static str { + "depth checker" + } +} + +#[derive(Debug)] +pub struct FuncDepthChecker<'a> { + /// The amount of stack space left + global: GlobalIndex, + /// The function types in this function's module + funcs: Arc>, + /// All the types in this function's modules + sigs: Arc>, + /// The number of local variables this func has + locals: Option, + /// The function being instrumented + func: LocalFunctionIndex, + /// The maximum size of a stack frame, measured in words + frame_limit: u32, + /// The maximum number of overlapping value lifetimes in a frame + frame_contention: u16, + /// The number of open scopes + scopes: isize, + /// The entirety of the func's original instructions + code: Vec>, + /// True once it's statically known feed() won't be called again + done: bool, +} + +impl FuncDepthChecker<'_> { + fn new( + global: GlobalIndex, + funcs: Arc>, + sigs: Arc>, + frame_limit: u32, + frame_contention: u16, + func: LocalFunctionIndex, + ) -> Self { + Self { + global, + funcs, + sigs, + locals: None, + func, + frame_limit, + frame_contention, + scopes: 1, // a function starts with an open scope + code: vec![], + done: false, + } + } +} + +impl<'a> FuncMiddleware<'a> for FuncDepthChecker<'a> { + fn locals_info(&mut self, locals: &[ValType]) { + self.locals = Some(locals.len()); + } + + fn feed(&mut self, op: Operator<'a>, out: &mut O) -> Result<()> + where + O: Extend>, + { + use Operator::*; + + // Knowing when the feed ends requires detecting the final instruction, which is + // guaranteed to be an "End" opcode closing out function's initial opening scope. + if self.done { + bail!("finalized too soon"); + } + + let scopes = &mut self.scopes; + match op { + Block { .. } | Loop { .. } | If { .. } => *scopes += 1, + End => *scopes -= 1, + _ => {} + } + if *scopes < 0 { + bail!("malformed scoping detected"); + } + + let last = *scopes == 0 && matches!(op, End); // true when the feed ends + self.code.push(op); + if !last { + return Ok(()); + } + + // We've reached the final instruction and can instrument the function as follows: + // - When entering, check that the stack has sufficient space and deduct the amount used + // - When returning, credit back the amount used + + let size = self.worst_case_depth()?; + let global_index = self.global.as_u32(); + + if size > self.frame_limit { + let limit = self.frame_limit.red(); + bail!("frame too large: {} > {}-word limit", size.red(), limit); + } + + let blockty = BlockType::Empty; + out.extend([ + // if space <= size => panic with depth = 0 + GlobalGet { global_index }, + I32Const { value: size as i32 }, + I32LeU, + If { blockty }, + I32Const { value: 0 }, + GlobalSet { global_index }, + Unreachable, + End, + // space -= size + GlobalGet { global_index }, + I32Const { value: size as i32 }, + I32Sub, + GlobalSet { global_index }, + ]); + + let reclaim = |out: &mut O| { + out.extend([ + // space += size + GlobalGet { global_index }, + I32Const { value: size as i32 }, + I32Add, + GlobalSet { global_index }, + ]) + }; + + // add an extraneous return instruction to the end to match Arbitrator + let mut code = std::mem::take(&mut self.code); + let last = code.pop().unwrap(); + code.push(Return); + code.push(last); + + for op in code { + let exit = matches!(op, Return); + if exit { + reclaim(out); + } + out.extend([op]); + } + + self.done = true; + Ok(()) + } + + fn name(&self) -> &'static str { + "depth checker" + } +} + +impl FuncDepthChecker<'_> { + fn worst_case_depth(&self) -> Result { + use Operator::*; + + let mut worst: u32 = 0; + let mut stack: u32 = 0; + + macro_rules! push { + ($count:expr) => {{ + stack += $count; + worst = worst.max(stack); + }}; + () => { + push!(1) + }; + } + macro_rules! pop { + ($count:expr) => {{ + stack = stack.saturating_sub($count); + }}; + () => { + pop!(1) + }; + } + macro_rules! ins_and_outs { + ($ty:expr) => {{ + let ins = $ty.inputs.len() as u32; + let outs = $ty.outputs.len() as u32; + push!(outs); + pop!(ins); + }}; + } + macro_rules! op { + ($first:ident $(,$opcode:ident)* $(,)?) => { + $first $(| $opcode)* + }; + } + macro_rules! dot { + ($first:ident $(,$opcode:ident)* $(,)?) => { + $first { .. } $(| $opcode { .. })* + }; + } + #[rustfmt::skip] + macro_rules! block_type { + ($ty:expr) => {{ + match $ty { + BlockType::Empty => {} + BlockType::Type(_) => push!(1), + BlockType::FuncType(id) => { + let index = SignatureIndex::from_u32(*id); + let Some(ty) = self.sigs.get(&index) else { + bail!("missing type for func {}", id.red()) + }; + ins_and_outs!(ty); + } + } + }}; + } + + let mut scopes = vec![stack]; + + for op in &self.code { + #[rustfmt::skip] + match op { + Block { blockty } => { + block_type!(blockty); // we'll say any return slots have been pre-allocated + scopes.push(stack); + } + Loop { blockty } => { + block_type!(blockty); // return slots + scopes.push(stack); + } + If { blockty } => { + pop!(); // pop the conditional + block_type!(blockty); // return slots + scopes.push(stack); + } + Else => { + stack = match scopes.last() { + Some(scope) => *scope, + None => bail!("malformed if-else scope"), + }; + } + End => { + stack = match scopes.pop() { + Some(stack) => stack, + None => bail!("malformed scoping detected at end of block"), + }; + } + + Call { function_index } => { + let index = FunctionIndex::from_u32(*function_index); + let Some(ty) = self.funcs.get(&index) else { + bail!("missing type for func {}", function_index.red()) + }; + ins_and_outs!(ty) + } + CallIndirect { type_index, .. } => { + let index = SignatureIndex::from_u32(*type_index); + let Some(ty) = self.sigs.get(&index) else { + bail!("missing type for signature {}", type_index.red()) + }; + ins_and_outs!(ty); + pop!() // the table index + } + + MemoryFill { .. } => ins_and_outs!(InternalFunc::MemoryFill.ty()), + MemoryCopy { .. } => ins_and_outs!(InternalFunc::MemoryCopy.ty()), + + op!( + Nop, Unreachable, + I32Eqz, I64Eqz, I32Clz, I32Ctz, I32Popcnt, I64Clz, I64Ctz, I64Popcnt, + ) + | dot!( + Br, Return, + LocalTee, MemoryGrow, + I32Load, I64Load, F32Load, F64Load, + I32Load8S, I32Load8U, I32Load16S, I32Load16U, I64Load8S, I64Load8U, + I64Load16S, I64Load16U, I64Load32S, I64Load32U, + I32WrapI64, I64ExtendI32S, I64ExtendI32U, + I32Extend8S, I32Extend16S, I64Extend8S, I64Extend16S, I64Extend32S, + F32Abs, F32Neg, F32Ceil, F32Floor, F32Trunc, F32Nearest, F32Sqrt, + F64Abs, F64Neg, F64Ceil, F64Floor, F64Trunc, F64Nearest, F64Sqrt, + I32TruncF32S, I32TruncF32U, I32TruncF64S, I32TruncF64U, + I64TruncF32S, I64TruncF32U, I64TruncF64S, I64TruncF64U, + F32ConvertI32S, F32ConvertI32U, F32ConvertI64S, F32ConvertI64U, F32DemoteF64, + F64ConvertI32S, F64ConvertI32U, F64ConvertI64S, F64ConvertI64U, F64PromoteF32, + I32ReinterpretF32, I64ReinterpretF64, F32ReinterpretI32, F64ReinterpretI64, + I32TruncSatF32S, I32TruncSatF32U, I32TruncSatF64S, I32TruncSatF64U, + I64TruncSatF32S, I64TruncSatF32U, I64TruncSatF64S, I64TruncSatF64U, + ) => {} + + dot!( + LocalGet, GlobalGet, MemorySize, + I32Const, I64Const, F32Const, F64Const, + ) => push!(), + + op!( + Drop, + I32Eq, I32Ne, I32LtS, I32LtU, I32GtS, I32GtU, I32LeS, I32LeU, I32GeS, I32GeU, + I64Eq, I64Ne, I64LtS, I64LtU, I64GtS, I64GtU, I64LeS, I64LeU, I64GeS, I64GeU, + F32Eq, F32Ne, F32Lt, F32Gt, F32Le, F32Ge, + F64Eq, F64Ne, F64Lt, F64Gt, F64Le, F64Ge, + I32Add, I32Sub, I32Mul, I32DivS, I32DivU, I32RemS, I32RemU, + I64Add, I64Sub, I64Mul, I64DivS, I64DivU, I64RemS, I64RemU, + I32And, I32Or, I32Xor, I32Shl, I32ShrS, I32ShrU, I32Rotl, I32Rotr, + I64And, I64Or, I64Xor, I64Shl, I64ShrS, I64ShrU, I64Rotl, I64Rotr, + F32Add, F32Sub, F32Mul, F32Div, F32Min, F32Max, F32Copysign, + F64Add, F64Sub, F64Mul, F64Div, F64Min, F64Max, F64Copysign, + ) + | dot!(BrIf, BrTable, LocalSet, GlobalSet) => pop!(), + + dot!( + Select, + I32Store, I64Store, F32Store, F64Store, I32Store8, I32Store16, I64Store8, I64Store16, I64Store32, + ) => pop!(2), + + unsupported @ dot!(Try, Catch, Throw, Rethrow, ThrowRef, TryTable) => { + bail!("exception-handling extension not supported {unsupported:?}") + }, + + unsupported @ dot!(ReturnCall, ReturnCallIndirect) => { + bail!("tail-call extension not supported {unsupported:?}") + } + + unsupported @ dot!(CallRef, ReturnCallRef) => { + bail!("typed function references extension not supported {unsupported:?}") + } + + unsupported @ (dot!(Delegate) | op!(CatchAll)) => { + bail!("exception-handling extension not supported {unsupported:?}") + }, + + unsupported @ (op!(RefIsNull) | dot!(TypedSelect, RefNull, RefFunc, RefEq)) => { + bail!("reference-types extension not supported {unsupported:?}") + }, + + unsupported @ dot!(RefAsNonNull, BrOnNull, BrOnNonNull) => { + bail!("typed function references extension not supported {unsupported:?}") + }, + + unsupported @ ( + dot!( + MemoryInit, DataDrop, TableInit, ElemDrop, + TableCopy, TableFill, TableGet, TableSet, TableGrow, TableSize + ) + ) => bail!("bulk-memory-operations extension not fully supported {unsupported:?}"), + + unsupported @ dot!(MemoryDiscard) => { + bail!("typed function references extension not supported {unsupported:?}") + } + + unsupported @ ( + dot!( + StructNew, StructNewDefault, StructGet, StructGetS, StructGetU, StructSet, + ArrayNew, ArrayNewDefault, ArrayNewFixed, ArrayNewData, ArrayNewElem, + ArrayGet, ArrayGetS, ArrayGetU, ArraySet, ArrayLen, ArrayFill, ArrayCopy, + ArrayInitData, ArrayInitElem, + RefTestNonNull, RefTestNullable, RefCastNonNull, RefCastNullable, + BrOnCast, BrOnCastFail, AnyConvertExtern, ExternConvertAny, RefI31, I31GetS, I31GetU + ) + ) => bail!("garbage collection extension not supported {unsupported:?}"), + + unsupported @ ( + dot!( + MemoryAtomicNotify, MemoryAtomicWait32, MemoryAtomicWait64, AtomicFence, I32AtomicLoad, + I64AtomicLoad, I32AtomicLoad8U, I32AtomicLoad16U, I64AtomicLoad8U, I64AtomicLoad16U, + I64AtomicLoad32U, I32AtomicStore, I64AtomicStore, I32AtomicStore8, I32AtomicStore16, + I64AtomicStore8, I64AtomicStore16, I64AtomicStore32, I32AtomicRmwAdd, I64AtomicRmwAdd, + I32AtomicRmw8AddU, I32AtomicRmw16AddU, + I64AtomicRmw8AddU, I64AtomicRmw16AddU, I64AtomicRmw32AddU, + I32AtomicRmwSub, I64AtomicRmwSub, I32AtomicRmw8SubU, I32AtomicRmw16SubU, I64AtomicRmw8SubU, + I64AtomicRmw16SubU, I64AtomicRmw32SubU, I32AtomicRmwAnd, I64AtomicRmwAnd, I32AtomicRmw8AndU, + I32AtomicRmw16AndU, I64AtomicRmw8AndU, I64AtomicRmw16AndU, I64AtomicRmw32AndU, I32AtomicRmwOr, + I64AtomicRmwOr, I32AtomicRmw8OrU, I32AtomicRmw16OrU, I64AtomicRmw8OrU, I64AtomicRmw16OrU, + I64AtomicRmw32OrU, I32AtomicRmwXor, I64AtomicRmwXor, I32AtomicRmw8XorU, I32AtomicRmw16XorU, + I64AtomicRmw8XorU, I64AtomicRmw16XorU, I64AtomicRmw32XorU, I32AtomicRmwXchg, I64AtomicRmwXchg, + I32AtomicRmw8XchgU, I32AtomicRmw16XchgU, I64AtomicRmw8XchgU, I64AtomicRmw16XchgU, + I64AtomicRmw32XchgU, I32AtomicRmwCmpxchg, I64AtomicRmwCmpxchg, I32AtomicRmw8CmpxchgU, + I32AtomicRmw16CmpxchgU, I64AtomicRmw8CmpxchgU, I64AtomicRmw16CmpxchgU, I64AtomicRmw32CmpxchgU + ) + ) => bail!("threads extension not supported {unsupported:?}"), + + unsupported @ ( + dot!( + V128Load, V128Load8x8S, V128Load8x8U, V128Load16x4S, V128Load16x4U, V128Load32x2S, + V128Load8Splat, V128Load16Splat, V128Load32Splat, V128Load64Splat, V128Load32Zero, + V128Load64Zero, V128Load32x2U, + V128Store, V128Load8Lane, V128Load16Lane, V128Load32Lane, V128Load64Lane, V128Store8Lane, + V128Store16Lane, V128Store32Lane, V128Store64Lane, V128Const, + I8x16Shuffle, I8x16ExtractLaneS, I8x16ExtractLaneU, I8x16ReplaceLane, I16x8ExtractLaneS, + I16x8ExtractLaneU, I16x8ReplaceLane, I32x4ExtractLane, I32x4ReplaceLane, I64x2ExtractLane, + I64x2ReplaceLane, F32x4ExtractLane, F32x4ReplaceLane, F64x2ExtractLane, F64x2ReplaceLane, + I8x16Swizzle, I8x16Splat, I16x8Splat, I32x4Splat, I64x2Splat, F32x4Splat, F64x2Splat, I8x16Eq, + I8x16Ne, I8x16LtS, I8x16LtU, I8x16GtS, I8x16GtU, I8x16LeS, I8x16LeU, I8x16GeS, I8x16GeU, + I16x8Eq, I16x8Ne, I16x8LtS, I16x8LtU, I16x8GtS, I16x8GtU, I16x8LeS, I16x8LeU, I16x8GeS, + I16x8GeU, I32x4Eq, I32x4Ne, I32x4LtS, I32x4LtU, I32x4GtS, I32x4GtU, I32x4LeS, I32x4LeU, + I32x4GeS, I32x4GeU, I64x2Eq, I64x2Ne, I64x2LtS, I64x2GtS, I64x2LeS, I64x2GeS, + F32x4Eq, F32x4Ne, F32x4Lt, F32x4Gt, F32x4Le, F32x4Ge, + F64x2Eq, F64x2Ne, F64x2Lt, F64x2Gt, F64x2Le, F64x2Ge, + V128Not, V128And, V128AndNot, V128Or, V128Xor, V128Bitselect, V128AnyTrue, + I8x16Abs, I8x16Neg, I8x16Popcnt, I8x16AllTrue, I8x16Bitmask, + I8x16NarrowI16x8S, I8x16NarrowI16x8U, + I8x16Shl, I8x16ShrS, I8x16ShrU, I8x16Add, I8x16AddSatS, I8x16AddSatU, I8x16Sub, I8x16SubSatS, + I8x16SubSatU, I8x16MinS, I8x16MinU, I8x16MaxS, I8x16MaxU, I8x16AvgrU, + I16x8ExtAddPairwiseI8x16S, I16x8ExtAddPairwiseI8x16U, I16x8Abs, I16x8Neg, I16x8Q15MulrSatS, + I16x8AllTrue, I16x8Bitmask, I16x8NarrowI32x4S, I16x8NarrowI32x4U, I16x8ExtendLowI8x16S, + I16x8ExtendHighI8x16S, I16x8ExtendLowI8x16U, I16x8ExtendHighI8x16U, + I16x8Shl, I16x8ShrS, I16x8ShrU, I16x8Add, I16x8AddSatS, I16x8AddSatU, + I16x8Sub, I16x8SubSatS, I16x8SubSatU, I16x8Mul, I16x8MinS, I16x8MinU, + I16x8MaxS, I16x8MaxU, I16x8AvgrU, I16x8ExtMulLowI8x16S, + I16x8ExtMulHighI8x16S, I16x8ExtMulLowI8x16U, I16x8ExtMulHighI8x16U, + I32x4ExtAddPairwiseI16x8U, I32x4Abs, I32x4Neg, I32x4AllTrue, I32x4Bitmask, + I32x4ExtAddPairwiseI16x8S, I32x4ExtendLowI16x8S, I32x4ExtendHighI16x8S, I32x4ExtendLowI16x8U, + I32x4ExtendHighI16x8U, I32x4Shl, I32x4ShrS, I32x4ShrU, I32x4Add, I32x4Sub, I32x4Mul, + I32x4MinS, I32x4MinU, I32x4MaxS, I32x4MaxU, I32x4DotI16x8S, + I32x4ExtMulLowI16x8S, I32x4ExtMulHighI16x8S, I32x4ExtMulLowI16x8U, I32x4ExtMulHighI16x8U, + I64x2Abs, I64x2Neg, I64x2AllTrue, I64x2Bitmask, I64x2ExtendLowI32x4S, I64x2ExtendHighI32x4S, + I64x2ExtendLowI32x4U, I64x2ExtendHighI32x4U, I64x2Shl, I64x2ShrS, I64x2ShrU, I64x2Add, + I64x2ExtMulLowI32x4S, I64x2ExtMulHighI32x4S, I64x2Sub, I64x2Mul, + I64x2ExtMulLowI32x4U, I64x2ExtMulHighI32x4U, F32x4Ceil, F32x4Floor, F32x4Trunc, + F32x4Nearest, F32x4Abs, F32x4Neg, F32x4Sqrt, F32x4Add, F32x4Sub, F32x4Mul, F32x4Div, + F32x4Min, F32x4Max, F32x4PMin, F32x4PMax, F64x2Ceil, F64x2Floor, F64x2Trunc, + F64x2Nearest, F64x2Abs, F64x2Neg, F64x2Sqrt, F64x2Add, F64x2Sub, F64x2Mul, F64x2Div, F64x2Min, + F64x2Max, F64x2PMin, F64x2PMax, I32x4TruncSatF32x4S, I32x4TruncSatF32x4U, F32x4ConvertI32x4S, + F32x4ConvertI32x4U, I32x4TruncSatF64x2SZero, I32x4TruncSatF64x2UZero, F64x2ConvertLowI32x4S, + F64x2ConvertLowI32x4U, F32x4DemoteF64x2Zero, F64x2PromoteLowF32x4, I8x16RelaxedSwizzle, + I32x4RelaxedTruncF32x4S, I32x4RelaxedTruncF32x4U, I32x4RelaxedTruncF64x2SZero, + I32x4RelaxedTruncF64x2UZero, F32x4RelaxedMadd, F32x4RelaxedNmadd, F64x2RelaxedMadd, + F64x2RelaxedNmadd, I8x16RelaxedLaneselect, I16x8RelaxedLaneselect, I32x4RelaxedLaneselect, + I64x2RelaxedLaneselect, F32x4RelaxedMin, F32x4RelaxedMax, F64x2RelaxedMin, F64x2RelaxedMax, + I16x8RelaxedQ15mulrS, I16x8RelaxedDotI8x16I7x16S, I32x4RelaxedDotI8x16I7x16AddS + ) + ) => bail!("SIMD extension not supported {unsupported:?}"), + + #[cfg(feature = "sp1")] + _ => todo!("New operator not covered yet by nitro!") + }; + } + + if self.locals.is_none() { + bail!("missing locals info for func {}", self.func.as_u32().red()) + } + + let contention = worst; + if contention > self.frame_contention.into() { + bail!( + "too many values on the stack at once in func {}: {} > {}", + self.func.as_u32().red(), + contention.red(), + self.frame_contention.red() + ); + } + + let locals = self.locals.unwrap_or_default(); + Ok(worst + locals as u32 + 4) + } +} + +/// Note: implementers may panic if uninstrumented +pub trait DepthCheckedMachine { + fn stack_left(&mut self) -> u32; + fn set_stack(&mut self, size: u32); +} + +#[cfg(not(feature = "sp1"))] +impl DepthCheckedMachine for crate::Machine { + fn stack_left(&mut self) -> u32 { + let global = self.get_global(STYLUS_STACK_LEFT).unwrap(); + global.try_into().expect("instrumentation type mismatch") + } + + fn set_stack(&mut self, size: u32) { + self.set_global(STYLUS_STACK_LEFT, size.into()).unwrap(); + } +} diff --git a/arbitrator/prover/src/programs/dynamic.rs b/arbitrator/prover/src/programs/dynamic.rs new file mode 100644 index 00000000000..99c35361444 --- /dev/null +++ b/arbitrator/prover/src/programs/dynamic.rs @@ -0,0 +1,154 @@ +// Copyright 2023, Offchain Labs, Inc. +// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md + +use super::{ + FuncMiddleware, Middleware, ModuleMod, + config::CompilePricingParams, + meter::{STYLUS_INK_LEFT, STYLUS_INK_STATUS}, +}; +use eyre::{Result, bail}; +use parking_lot::RwLock; +use wasmer_types::{GlobalIndex, GlobalInit, LocalFunctionIndex, Type}; +use wasmparser::{BlockType, Operator}; + +pub const SCRATCH_GLOBAL: &str = "stylus_scratch_global"; + +#[derive(Debug)] +pub struct DynamicMeter { + memory_fill: u64, + memory_copy: u64, + globals: RwLock>, +} + +impl DynamicMeter { + pub fn new(pricing: &CompilePricingParams) -> Self { + Self { + memory_fill: pricing.memory_fill_ink, + memory_copy: pricing.memory_copy_ink, + globals: RwLock::default(), + } + } +} + +impl Middleware for DynamicMeter { + type FM<'a> = FuncDynamicMeter; + + fn update_module(&self, module: &mut M) -> Result<()> { + let ink = module.get_global(STYLUS_INK_LEFT)?; + let status = module.get_global(STYLUS_INK_STATUS)?; + let scratch = module.add_global(SCRATCH_GLOBAL, Type::I32, GlobalInit::I32Const(0))?; + *self.globals.write() = Some([ink, status, scratch]); + Ok(()) + } + + fn instrument<'a>(&self, _: LocalFunctionIndex) -> Result> { + let globals = self.globals.read().expect("no globals"); + Ok(FuncDynamicMeter::new( + self.memory_fill, + self.memory_copy, + globals, + )) + } + + fn name(&self) -> &'static str { + "dynamic ink meter" + } +} + +#[derive(Debug)] +pub struct FuncDynamicMeter { + memory_fill: u64, + memory_copy: u64, + globals: [GlobalIndex; 3], +} + +impl FuncDynamicMeter { + fn new(memory_fill: u64, memory_copy: u64, globals: [GlobalIndex; 3]) -> Self { + Self { + memory_fill, + memory_copy, + globals, + } + } +} + +impl<'a> FuncMiddleware<'a> for FuncDynamicMeter { + fn feed(&mut self, op: Operator<'a>, out: &mut O) -> Result<()> + where + O: Extend>, + { + use Operator::*; + macro_rules! dot { + ($first:ident $(,$opcode:ident)* $(,)?) => { + $first { .. } $(| $opcode { .. })* + }; + } + macro_rules! get { + ($global:expr) => { + GlobalGet { + global_index: $global, + } + }; + } + macro_rules! set { + ($global:expr) => { + GlobalSet { + global_index: $global, + } + }; + } + + let [ink, status, scratch] = self.globals.map(|x| x.as_u32()); + let blockty = BlockType::Empty; + + #[rustfmt::skip] + let linear = |coefficient| { + [ + // [user] → move user value to scratch + set!(scratch), + get!(ink), + get!(ink), + get!(scratch), + + // [ink ink size] → cost = size * coefficient (can't overflow) + I64ExtendI32U, + I64Const { value: coefficient }, + I64Mul, + + // [ink ink cost] → ink -= cost + I64Sub, + set!(ink), + get!(ink), + + // [old_ink, new_ink] → (old_ink < new_ink) (overflow detected) + I64LtU, + If { blockty }, + I32Const { value: 1 }, + set!(status), + Unreachable, + End, + + // [] → resume since user paid for ink + get!(scratch), + ] + }; + + match op { + dot!(MemoryFill) => out.extend(linear(self.memory_fill as i64)), + dot!(MemoryCopy) => out.extend(linear(self.memory_copy as i64)), + dot!( + MemoryInit, DataDrop, ElemDrop, TableInit, TableCopy, TableFill, TableGet, + TableSet, TableGrow, TableSize + ) => { + bail!("opcode not supported") + } + _ => {} + } + out.extend([op]); + Ok(()) + } + + fn name(&self) -> &'static str { + "dynamic ink meter" + } +} diff --git a/arbitrator/prover/src/programs/heap.rs b/arbitrator/prover/src/programs/heap.rs new file mode 100644 index 00000000000..f9eeb05396f --- /dev/null +++ b/arbitrator/prover/src/programs/heap.rs @@ -0,0 +1,117 @@ +// Copyright 2022-2023, Offchain Labs, Inc. +// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md + +use crate::value::{ArbValueType, FunctionType}; + +use super::{ + FuncMiddleware, Middleware, ModuleMod, config::CompileMemoryParams, dynamic::SCRATCH_GLOBAL, +}; +use arbutil::Color; +use eyre::{Result, bail}; +use parking_lot::RwLock; +use wasmer_types::{FunctionIndex, GlobalIndex, ImportIndex, LocalFunctionIndex, Pages}; +use wasmparser::Operator; + +#[derive(Debug)] +pub struct HeapBound { + /// Upper bounds the amount of heap memory a module may use + limit: Pages, + /// Import called when allocating new pages + pay_func: RwLock>, + /// Scratch global shared among middlewares + scratch: RwLock>, +} + +impl HeapBound { + const PAY_FUNC: &'static str = "pay_for_memory_grow"; + + pub fn new(bounds: CompileMemoryParams) -> Self { + Self { + limit: bounds.heap_bound, + pay_func: RwLock::default(), + scratch: RwLock::default(), + } + } +} + +impl Middleware for HeapBound { + type FM<'a> = FuncHeapBound; + + fn update_module(&self, module: &mut M) -> Result<()> { + let scratch = module.get_global(SCRATCH_GLOBAL)?; + *self.scratch.write() = Some(scratch); + + let memory = module.memory_info()?; + let min = memory.min; + let max = memory.max; + let lim = self.limit; + + if min > lim { + bail!("memory size {} exceeds bound {}", min.0.red(), lim.0.red()); + } + if max == Some(min) { + return Ok(()); + } + + let ImportIndex::Function(import) = module.get_import("vm_hooks", Self::PAY_FUNC)? else { + bail!("wrong import kind for {}", Self::PAY_FUNC.red()); + }; + + let ty = module.get_function(import)?; + if ty != FunctionType::new(vec![ArbValueType::I32], vec![]) { + bail!("wrong type for {}: {}", Self::PAY_FUNC.red(), ty.red()); + } + + *self.pay_func.write() = Some(import); + Ok(()) + } + + fn instrument<'a>(&self, _: LocalFunctionIndex) -> Result> { + Ok(FuncHeapBound { + scratch: self.scratch.read().expect("no scratch global"), + pay_func: *self.pay_func.read(), + }) + } + + fn name(&self) -> &'static str { + "heap bound" + } +} + +#[derive(Debug)] +pub struct FuncHeapBound { + pay_func: Option, + scratch: GlobalIndex, +} + +impl<'a> FuncMiddleware<'a> for FuncHeapBound { + fn feed(&mut self, op: Operator<'a>, out: &mut O) -> Result<()> + where + O: Extend>, + { + use Operator::*; + + let Some(pay_func) = self.pay_func else { + out.extend([op]); + return Ok(()); + }; + + let global_index = self.scratch.as_u32(); + let function_index = pay_func.as_u32(); + + if let MemoryGrow { .. } = op { + out.extend([ + GlobalSet { global_index }, + GlobalGet { global_index }, + GlobalGet { global_index }, + Call { function_index }, + ]); + } + out.extend([op]); + Ok(()) + } + + fn name(&self) -> &'static str { + "heap bound" + } +} diff --git a/arbitrator/prover/src/programs/memory.rs b/arbitrator/prover/src/programs/memory.rs new file mode 100644 index 00000000000..104c08381a8 --- /dev/null +++ b/arbitrator/prover/src/programs/memory.rs @@ -0,0 +1,127 @@ +// Copyright 2023, Offchain Labs, Inc. +// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md + +use arbutil::evm::api::Gas; + +#[derive(Clone, Copy, Debug)] +#[repr(C)] +pub struct MemoryModel { + /// Number of pages a tx gets for free + pub free_pages: u16, + /// Base cost of each additional wasm page + pub page_gas: u16, +} + +impl Default for MemoryModel { + fn default() -> Self { + Self { + free_pages: u16::MAX, + page_gas: 0, + } + } +} + +impl MemoryModel { + pub const fn new(free_pages: u16, page_gas: u16) -> Self { + Self { + free_pages, + page_gas, + } + } + + /// Determines the gas cost of allocating `new` pages given `open` are active and `ever` have ever been. + pub fn gas_cost(&self, new: u16, open: u16, ever: u16) -> Gas { + let new_open = open.saturating_add(new); + let new_ever = ever.max(new_open); + + // free until expansion beyond the first few + if new_ever <= self.free_pages { + return Gas(0); + } + + let credit = |pages: u16| pages.saturating_sub(self.free_pages); + let adding = credit(new_open).saturating_sub(credit(open)) as u64; + let linear = adding.saturating_mul(self.page_gas.into()); + let expand = Self::exp(new_ever) - Self::exp(ever); + Gas(linear.saturating_add(expand)) + } + + fn exp(pages: u16) -> u64 { + MEMORY_EXPONENTS + .get(pages as usize) + .map(|&x| x.into()) + .unwrap_or(u64::MAX) + } +} + +const MEMORY_EXPONENTS: [u32; 129] = [ + 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 14, 17, 19, 22, 25, 29, 33, 38, + 43, 50, 57, 65, 75, 85, 98, 112, 128, 147, 168, 193, 221, 253, 289, 331, 379, 434, 497, 569, + 651, 745, 853, 976, 1117, 1279, 1463, 1675, 1917, 2194, 2511, 2874, 3290, 3765, 4309, 4932, + 5645, 6461, 7395, 8464, 9687, 11087, 12689, 14523, 16621, 19024, 21773, 24919, 28521, 32642, + 37359, 42758, 48938, 56010, 64104, 73368, 83971, 96106, 109994, 125890, 144082, 164904, 188735, + 216010, 247226, 282953, 323844, 370643, 424206, 485509, 555672, 635973, 727880, 833067, 953456, + 1091243, 1248941, 1429429, 1636000, 1872423, 2143012, 2452704, 2807151, 3212820, 3677113, + 4208502, 4816684, 5512756, 6309419, 7221210, 8264766, 9459129, 10826093, 12390601, 14181199, + 16230562, 18576084, 21260563, 24332984, 27849408, 31873999, +]; + +#[test] +fn test_tables() { + let base = f64::exp(31_874_000_f64.ln() / 128.); + + for pages in 0..129 { + let value = base.powi(pages.into()) as u64; + assert_eq!(value, MemoryModel::exp(pages)); + } + assert_eq!(u64::MAX, MemoryModel::exp(129)); + assert_eq!(u64::MAX, MemoryModel::exp(u16::MAX)); +} + +#[test] +fn test_model() { + let model = MemoryModel::new(2, 1000); + + for jump in 1..=128 { + let mut total = Gas(0); + let mut pages = 0; + while pages < 128 { + let jump = jump.min(128 - pages); + total += model.gas_cost(jump, pages, pages); + pages += jump; + } + assert_eq!(total, Gas(31999998)); + } + + for jump in 1..=128 { + let mut total = 0; + let mut open = 0; + let mut ever = 0; + let mut adds = 0; + while ever < 128 { + let jump = jump.min(128 - open); + total += model.gas_cost(jump, open, ever).0; + open += jump; + ever = ever.max(open); + + if ever > model.free_pages { + adds += jump.min(ever - model.free_pages) as u64; + } + + // pretend we've deallocated some pages + open -= jump / 2; + } + let expected = 31873998 + adds * model.page_gas as u64; + assert_eq!(total, expected); + } + + // check saturation + assert_eq!(Gas(u64::MAX), model.gas_cost(129, 0, 0)); + assert_eq!(Gas(u64::MAX), model.gas_cost(u16::MAX, 0, 0)); + + // check free pages + let model = MemoryModel::new(128, 1000); + assert_eq!(Gas(0), model.gas_cost(128, 0, 0)); + assert_eq!(Gas(0), model.gas_cost(128, 0, 128)); + assert_eq!(Gas(u64::MAX), model.gas_cost(129, 0, 0)); +} diff --git a/arbitrator/prover/src/programs/meter.rs b/arbitrator/prover/src/programs/meter.rs new file mode 100644 index 00000000000..e7d3729acf4 --- /dev/null +++ b/arbitrator/prover/src/programs/meter.rs @@ -0,0 +1,528 @@ +// Copyright 2022-2023, Offchain Labs, Inc. +// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md +#![allow(clippy::needless_lifetimes)] + +#[cfg(feature = "sp1")] +use crate::operator::OperatorInfo; +use crate::{ + programs::{ + FuncMiddleware, Middleware, ModuleMod, + config::{CompilePricingParams, PricingParams, SigMap}, + }, + value::FunctionType, +}; +#[cfg(not(feature = "sp1"))] +use arbutil::operator::OperatorInfo; +use arbutil::{ + Bytes32, + evm::{ + self, + api::{Gas, Ink}, + }, + pricing, +}; +use derivative::Derivative; +use eyre::Result; +use fnv::FnvHashMap as HashMap; +use parking_lot::RwLock; +use std::{ + fmt::{Debug, Display}, + sync::Arc, +}; +use wasmer_types::{GlobalIndex, GlobalInit, LocalFunctionIndex, SignatureIndex, Type}; +use wasmparser::{BlockType, Operator}; + +use super::config::OpCosts; + +pub const STYLUS_INK_LEFT: &str = "stylus_ink_left"; +pub const STYLUS_INK_STATUS: &str = "stylus_ink_status"; + +pub trait OpcodePricer: Fn(&Operator, &SigMap) -> u64 + Send + Sync + Clone {} + +impl OpcodePricer for T where T: Fn(&Operator, &SigMap) -> u64 + Send + Sync + Clone {} + +#[derive(Derivative)] +#[derivative(Debug)] +pub struct Meter { + /// Associates opcodes to their ink costs. + #[derivative(Debug = "ignore")] + costs: F, + /// Cost of checking the amount of ink left. + header_cost: u64, + /// Ink and ink status globals. + globals: RwLock>, + /// The types of the module being instrumented + sigs: RwLock>>, +} + +impl Meter { + pub fn new(pricing: &CompilePricingParams) -> Meter { + Self { + costs: pricing.costs, + header_cost: pricing.ink_header_cost, + globals: RwLock::default(), + sigs: RwLock::default(), + } + } +} + +impl Meter { + pub fn globals(&self) -> [GlobalIndex; 2] { + self.globals.read().expect("missing globals") + } +} + +impl Middleware for Meter +where + M: ModuleMod, + F: OpcodePricer + 'static, +{ + type FM<'a> = FuncMeter<'a, F>; + + fn update_module(&self, module: &mut M) -> Result<()> { + let start_status = GlobalInit::I32Const(0); + let ink = module.add_global(STYLUS_INK_LEFT, Type::I64, GlobalInit::I64Const(0))?; + let status = module.add_global(STYLUS_INK_STATUS, Type::I32, start_status)?; + *self.globals.write() = Some([ink, status]); + *self.sigs.write() = Some(Arc::new(module.all_signatures()?)); + Ok(()) + } + + fn instrument<'a>(&self, _: LocalFunctionIndex) -> Result> { + let [ink, status] = self.globals(); + let sigs = self.sigs.read(); + let sigs = sigs.as_ref().expect("no types"); + Ok(FuncMeter::new( + ink, + status, + self.costs.clone(), + self.header_cost, + sigs.clone(), + )) + } + + fn name(&self) -> &'static str { + "ink meter" + } +} + +#[derive(Derivative)] +#[derivative(Debug)] +pub struct FuncMeter<'a, F: OpcodePricer> { + /// Represents the amount of ink left for consumption. + ink_global: GlobalIndex, + /// Represents whether the machine is out of ink. + status_global: GlobalIndex, + /// Instructions of the current basic block. + block: Vec>, + /// The accumulated cost of the current basic block. + block_cost: u64, + /// Cost of checking the amount of ink left. + header_cost: u64, + /// Associates opcodes to their ink costs. + #[derivative(Debug = "ignore")] + costs: F, + /// The types of the module being instrumented. + sigs: Arc, +} + +impl FuncMeter<'_, F> { + fn new( + ink_global: GlobalIndex, + status_global: GlobalIndex, + costs: F, + header_cost: u64, + sigs: Arc, + ) -> Self { + Self { + ink_global, + status_global, + block: vec![], + block_cost: 0, + header_cost, + costs, + sigs, + } + } +} + +impl<'a, F: OpcodePricer> FuncMiddleware<'a> for FuncMeter<'a, F> { + fn feed(&mut self, op: Operator<'a>, out: &mut O) -> Result<()> + where + O: Extend>, + { + use Operator::*; + + let end = op.ends_basic_block(); + + let op_cost = (self.costs)(&op, &self.sigs); + let mut cost = self.block_cost.saturating_add(op_cost); + self.block_cost = cost; + self.block.push(op); + + if end { + let ink = self.ink_global.as_u32(); + let status = self.status_global.as_u32(); + let blockty = BlockType::Empty; + + // include the cost of executing the header + cost = cost.saturating_add(self.header_cost); + + out.extend([ + // if ink < cost => panic with status = 1 + GlobalGet { global_index: ink }, + I64Const { value: cost as i64 }, + I64LtU, + If { blockty }, + I32Const { value: 1 }, + GlobalSet { + global_index: status, + }, + Unreachable, + End, + // ink -= cost + GlobalGet { global_index: ink }, + I64Const { value: cost as i64 }, + I64Sub, + GlobalSet { global_index: ink }, + ]); + out.extend(self.block.drain(..)); + self.block_cost = 0; + } + Ok(()) + } + + fn name(&self) -> &'static str { + "ink meter" + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum MachineMeter { + Ready(Ink), + Exhausted, +} + +impl MachineMeter { + pub fn ink(self) -> Ink { + match self { + Self::Ready(ink) => ink, + Self::Exhausted => Ink(0), + } + } + + pub fn status(self) -> u32 { + match self { + Self::Ready(_) => 0, + Self::Exhausted => 1, + } + } +} + +/// We don't implement `From` since it's unclear what 0 would map to +#[allow(clippy::from_over_into)] +impl Into for MachineMeter { + fn into(self) -> Ink { + self.ink() + } +} + +impl Display for MachineMeter { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Ready(ink) => write!(f, "{} ink", ink.0), + Self::Exhausted => write!(f, "exhausted"), + } + } +} + +#[derive(Debug)] +pub struct OutOfInkError; + +impl std::error::Error for OutOfInkError {} + +impl Display for OutOfInkError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "out of ink") + } +} + +/// Note: implementers may panic if uninstrumented +pub trait MeteredMachine { + fn ink_left(&self) -> MachineMeter; + fn set_meter(&mut self, meter: MachineMeter); + + fn set_ink(&mut self, ink: Ink) { + self.set_meter(MachineMeter::Ready(ink)); + } + + fn out_of_ink(&mut self) -> Result { + self.set_meter(MachineMeter::Exhausted); + Err(OutOfInkError) + } + + fn ink_ready(&mut self) -> Result { + let MachineMeter::Ready(ink_left) = self.ink_left() else { + return self.out_of_ink(); + }; + Ok(ink_left) + } + + fn buy_ink(&mut self, ink: Ink) -> Result<(), OutOfInkError> { + let ink_left = self.ink_ready()?; + if ink_left < ink { + return self.out_of_ink(); + } + self.set_ink(ink_left - ink); + Ok(()) + } + + /// Checks if the user has enough ink, but doesn't burn any + fn require_ink(&mut self, ink: Ink) -> Result<(), OutOfInkError> { + let ink_left = self.ink_ready()?; + if ink_left < ink { + return self.out_of_ink(); + } + Ok(()) + } + + /// Pays for a write into the client. + fn pay_for_write(&mut self, bytes: u32) -> Result<(), OutOfInkError> { + self.buy_ink(pricing::write_price(bytes)) + } + + /// Pays for a read into the host. + fn pay_for_read(&mut self, bytes: u32) -> Result<(), OutOfInkError> { + self.buy_ink(pricing::read_price(bytes)) + } + + /// Pays for both I/O and keccak. + fn pay_for_keccak(&mut self, bytes: u32) -> Result<(), OutOfInkError> { + self.buy_ink(pricing::keccak_price(bytes)) + } + + /// Pays for the variable costs of exponentiation. + fn pay_for_pow(&mut self, exponent: &Bytes32) -> Result<(), OutOfInkError> { + self.buy_ink(pricing::pow_price(exponent)) + } +} + +pub trait GasMeteredMachine: MeteredMachine { + fn pricing(&self) -> PricingParams; + + fn gas_left(&self) -> Result { + let pricing = self.pricing(); + match self.ink_left() { + MachineMeter::Ready(ink) => Ok(pricing.ink_to_gas(ink)), + MachineMeter::Exhausted => Err(OutOfInkError), + } + } + + fn buy_gas(&mut self, gas: Gas) -> Result<(), OutOfInkError> { + let pricing = self.pricing(); + self.buy_ink(pricing.gas_to_ink(gas)) + } + + /// Checks if the user has enough gas, but doesn't burn any + fn require_gas(&mut self, gas: Gas) -> Result<(), OutOfInkError> { + let pricing = self.pricing(); + self.require_ink(pricing.gas_to_ink(gas)) + } + + fn pay_for_evm_log(&mut self, topics: u32, data_len: u32) -> Result<(), OutOfInkError> { + let cost = (1 + topics as u64) * evm::LOG_TOPIC_GAS; + let cost = cost.saturating_add(data_len as u64 * evm::LOG_DATA_GAS); + self.buy_gas(cost) + } +} + +#[cfg(not(feature = "sp1"))] +impl MeteredMachine for crate::Machine { + fn ink_left(&self) -> MachineMeter { + macro_rules! convert { + ($global:expr) => {{ $global.unwrap().try_into().expect("type mismatch") }}; + } + + let ink = || Ink(convert!(self.get_global(STYLUS_INK_LEFT))); + let status: u32 = convert!(self.get_global(STYLUS_INK_STATUS)); + + match status { + 0 => MachineMeter::Ready(ink()), + _ => MachineMeter::Exhausted, + } + } + + fn set_meter(&mut self, meter: MachineMeter) { + let ink = meter.ink(); + let status = meter.status(); + self.set_global(STYLUS_INK_LEFT, ink.0.into()).unwrap(); + self.set_global(STYLUS_INK_STATUS, status.into()).unwrap(); + } +} + +pub fn pricing_v1(op: &Operator, tys: &HashMap) -> u64 { + use Operator::*; + + macro_rules! op { + ($first:ident $(,$opcode:ident)*) => { + $first $(| $opcode)* + }; + } + macro_rules! dot { + ($first:ident $(,$opcode:ident)*) => { + $first { .. } $(| $opcode { .. })* + }; + } + + #[rustfmt::skip] + let ink = match op { + op!(Unreachable, Return) => 1, + op!(Nop) | dot!(I32Const, I64Const) => 1, + + op!(Drop) => 9, // could be 1, but using a higher number helps limit the number of ops in BOLD + + dot!(Block, Loop) | op!(Else, End) => 1, + dot!(Br, BrIf, If) => 765, + dot!(Select) => 1250, // TODO: improve wasmer codegen + dot!(Call) => 3800, + dot!(LocalGet, LocalTee) => 75, + dot!(LocalSet) => 210, + dot!(GlobalGet) => 225, + dot!(GlobalSet) => 575, + dot!(I32Load, I32Load8S, I32Load8U, I32Load16S, I32Load16U) => 670, + dot!(I64Load, I64Load8S, I64Load8U, I64Load16S, I64Load16U, I64Load32S, I64Load32U) => 680, + dot!(I32Store, I32Store8, I32Store16) => 825, + dot!(I64Store, I64Store8, I64Store16, I64Store32) => 950, + dot!(MemorySize) => 3000, + dot!(MemoryGrow) => 8050, // rest of cost handled by memory pricer + + op!(I32Eqz, I32Eq, I32Ne, I32LtS, I32LtU, I32GtS, I32GtU, I32LeS, I32LeU, I32GeS, I32GeU) => 170, + op!(I64Eqz, I64Eq, I64Ne, I64LtS, I64LtU, I64GtS, I64GtU, I64LeS, I64LeU, I64GeS, I64GeU) => 225, + + op!(I32Clz, I32Ctz) => 210, + op!(I32Add, I32Sub) => 70, + op!(I32Mul) => 160, + op!(I32DivS, I32DivU, I32RemS, I32RemU) => 1120, + op!(I32And, I32Or, I32Xor, I32Shl, I32ShrS, I32ShrU, I32Rotl, I32Rotr) => 70, + + op!(I64Clz, I64Ctz) => 210, + op!(I64Add, I64Sub) => 100, + op!(I64Mul) => 160, + op!(I64DivS, I64DivU, I64RemS, I64RemU) => 1270, + op!(I64And, I64Or, I64Xor, I64Shl, I64ShrS, I64ShrU, I64Rotl, I64Rotr) => 100, + + op!(I32Popcnt) => 2650, // slow on ARM, fast on x86 + op!(I64Popcnt) => 6000, // slow on ARM, fast on x86 + + op!(I32WrapI64, I64ExtendI32S, I64ExtendI32U) => 100, + op!(I32Extend8S, I32Extend16S, I64Extend8S, I64Extend16S, I64Extend32S) => 100, + dot!(MemoryCopy) => 950, + dot!(MemoryFill) => 950, + + BrTable { targets } => { + 2400 + 325 * targets.len() as u64 + }, + CallIndirect { type_index, .. } => { + let ty = tys.get(&SignatureIndex::from_u32(*type_index)).expect("no type"); + 13610 + 650 * ty.inputs.len() as u64 + }, + + // we don't support the following, so return u64::MAX + dot!( + Try, Catch, CatchAll, Delegate, Throw, Rethrow, ThrowRef, TryTable, + + RefNull, RefIsNull, RefFunc, RefEq, + + CallRef, ReturnCallRef, RefAsNonNull, BrOnNull, BrOnNonNull, + + TypedSelect, ReturnCall, ReturnCallIndirect, + + MemoryInit, DataDrop, TableInit, ElemDrop, + TableCopy, TableFill, TableGet, TableSet, TableGrow, TableSize, + + MemoryDiscard, + + StructNew, StructNewDefault, StructGet, StructGetS, StructGetU, StructSet, + ArrayNew, ArrayNewDefault, ArrayNewFixed, ArrayNewData, ArrayNewElem, + ArrayGet, ArrayGetS, ArrayGetU, ArraySet, ArrayLen, ArrayFill, ArrayCopy, + ArrayInitData, ArrayInitElem, RefTestNonNull, RefTestNullable, RefCastNonNull, RefCastNullable, + BrOnCast, BrOnCastFail, AnyConvertExtern, ExternConvertAny, RefI31, I31GetS, I31GetU, + + F32Load, F64Load, F32Store, F64Store, F32Const, F64Const, + F32Eq, F32Ne, F32Lt, F32Gt, F32Le, F32Ge, + F64Eq, F64Ne, F64Lt, F64Gt, F64Le, F64Ge, + F32Abs, F32Neg, F32Ceil, F32Floor, F32Trunc, F32Nearest, F32Sqrt, F32Add, F32Sub, F32Mul, + F32Div, F32Min, F32Max, F32Copysign, F64Abs, F64Neg, F64Ceil, F64Floor, F64Trunc, + F64Nearest, F64Sqrt, F64Add, F64Sub, F64Mul, F64Div, F64Min, F64Max, F64Copysign, + I32TruncF32S, I32TruncF32U, I32TruncF64S, I32TruncF64U, + I64TruncF32S, I64TruncF32U, I64TruncF64S, I64TruncF64U, + F32ConvertI32S, F32ConvertI32U, F32ConvertI64S, F32ConvertI64U, F32DemoteF64, + F64ConvertI32S, F64ConvertI32U, F64ConvertI64S, F64ConvertI64U, F64PromoteF32, + I32ReinterpretF32, I64ReinterpretF64, F32ReinterpretI32, F64ReinterpretI64, + I32TruncSatF32S, I32TruncSatF32U, I32TruncSatF64S, I32TruncSatF64U, + I64TruncSatF32S, I64TruncSatF32U, I64TruncSatF64S, I64TruncSatF64U, + + MemoryAtomicNotify, MemoryAtomicWait32, MemoryAtomicWait64, AtomicFence, I32AtomicLoad, + I64AtomicLoad, I32AtomicLoad8U, I32AtomicLoad16U, I64AtomicLoad8U, I64AtomicLoad16U, + I64AtomicLoad32U, I32AtomicStore, I64AtomicStore, I32AtomicStore8, I32AtomicStore16, + I64AtomicStore8, I64AtomicStore16, I64AtomicStore32, I32AtomicRmwAdd, I64AtomicRmwAdd, + I32AtomicRmw8AddU, I32AtomicRmw16AddU, I64AtomicRmw8AddU, I64AtomicRmw16AddU, I64AtomicRmw32AddU, + I32AtomicRmwSub, I64AtomicRmwSub, I32AtomicRmw8SubU, I32AtomicRmw16SubU, I64AtomicRmw8SubU, + I64AtomicRmw16SubU, I64AtomicRmw32SubU, I32AtomicRmwAnd, I64AtomicRmwAnd, I32AtomicRmw8AndU, + I32AtomicRmw16AndU, I64AtomicRmw8AndU, I64AtomicRmw16AndU, I64AtomicRmw32AndU, I32AtomicRmwOr, + I64AtomicRmwOr, I32AtomicRmw8OrU, I32AtomicRmw16OrU, I64AtomicRmw8OrU, I64AtomicRmw16OrU, + I64AtomicRmw32OrU, I32AtomicRmwXor, I64AtomicRmwXor, I32AtomicRmw8XorU, I32AtomicRmw16XorU, + I64AtomicRmw8XorU, I64AtomicRmw16XorU, I64AtomicRmw32XorU, I32AtomicRmwXchg, I64AtomicRmwXchg, + I32AtomicRmw8XchgU, I32AtomicRmw16XchgU, I64AtomicRmw8XchgU, I64AtomicRmw16XchgU, + I64AtomicRmw32XchgU, I32AtomicRmwCmpxchg, I64AtomicRmwCmpxchg, I32AtomicRmw8CmpxchgU, + I32AtomicRmw16CmpxchgU, I64AtomicRmw8CmpxchgU, I64AtomicRmw16CmpxchgU, I64AtomicRmw32CmpxchgU, + + V128Load, V128Load8x8S, V128Load8x8U, V128Load16x4S, V128Load16x4U, V128Load32x2S, V128Load32x2U, + V128Load8Splat, V128Load16Splat, V128Load32Splat, V128Load64Splat, V128Load32Zero, V128Load64Zero, + V128Store, V128Load8Lane, V128Load16Lane, V128Load32Lane, V128Load64Lane, V128Store8Lane, + V128Store16Lane, V128Store32Lane, V128Store64Lane, V128Const, + I8x16Shuffle, I8x16ExtractLaneS, I8x16ExtractLaneU, I8x16ReplaceLane, I16x8ExtractLaneS, + I16x8ExtractLaneU, I16x8ReplaceLane, I32x4ExtractLane, I32x4ReplaceLane, I64x2ExtractLane, + I64x2ReplaceLane, F32x4ExtractLane, F32x4ReplaceLane, F64x2ExtractLane, F64x2ReplaceLane, + I8x16Swizzle, I8x16Splat, I16x8Splat, I32x4Splat, I64x2Splat, F32x4Splat, F64x2Splat, I8x16Eq, + I8x16Ne, I8x16LtS, I8x16LtU, I8x16GtS, I8x16GtU, I8x16LeS, I8x16LeU, I8x16GeS, I8x16GeU, I16x8Eq, + I16x8Ne, I16x8LtS, I16x8LtU, I16x8GtS, I16x8GtU, I16x8LeS, I16x8LeU, I16x8GeS, I16x8GeU, I32x4Eq, + I32x4Ne, I32x4LtS, I32x4LtU, I32x4GtS, I32x4GtU, I32x4LeS, I32x4LeU, I32x4GeS, I32x4GeU, I64x2Eq, + I64x2Ne, I64x2LtS, I64x2GtS, I64x2LeS, I64x2GeS, + F32x4Eq, F32x4Ne, F32x4Lt, F32x4Gt, F32x4Le, F32x4Ge, + F64x2Eq, F64x2Ne, F64x2Lt, F64x2Gt, F64x2Le, F64x2Ge, + V128Not, V128And, V128AndNot, V128Or, V128Xor, V128Bitselect, V128AnyTrue, + I8x16Abs, I8x16Neg, I8x16Popcnt, I8x16AllTrue, I8x16Bitmask, I8x16NarrowI16x8S, I8x16NarrowI16x8U, + I8x16Shl, I8x16ShrS, I8x16ShrU, I8x16Add, I8x16AddSatS, I8x16AddSatU, I8x16Sub, I8x16SubSatS, + I8x16SubSatU, I8x16MinS, I8x16MinU, I8x16MaxS, I8x16MaxU, I8x16AvgrU, + I16x8ExtAddPairwiseI8x16S, I16x8ExtAddPairwiseI8x16U, I16x8Abs, I16x8Neg, I16x8Q15MulrSatS, + I16x8AllTrue, I16x8Bitmask, I16x8NarrowI32x4S, I16x8NarrowI32x4U, I16x8ExtendLowI8x16S, + I16x8ExtendHighI8x16S, I16x8ExtendLowI8x16U, I16x8ExtendHighI8x16U, I16x8Shl, I16x8ShrS, I16x8ShrU, + I16x8Add, I16x8AddSatS, I16x8AddSatU, I16x8Sub, I16x8SubSatS, I16x8SubSatU, I16x8Mul, I16x8MinS, + I16x8MinU, I16x8MaxS, I16x8MaxU, I16x8AvgrU, I16x8ExtMulLowI8x16S, + I16x8ExtMulHighI8x16S, I16x8ExtMulLowI8x16U, I16x8ExtMulHighI8x16U, I32x4ExtAddPairwiseI16x8S, + I32x4ExtAddPairwiseI16x8U, I32x4Abs, I32x4Neg, I32x4AllTrue, I32x4Bitmask, I32x4ExtendLowI16x8S, + I32x4ExtendHighI16x8S, I32x4ExtendLowI16x8U, I32x4ExtendHighI16x8U, I32x4Shl, I32x4ShrS, I32x4ShrU, + I32x4Add, I32x4Sub, I32x4Mul, I32x4MinS, I32x4MinU, I32x4MaxS, I32x4MaxU, I32x4DotI16x8S, + I32x4ExtMulLowI16x8S, I32x4ExtMulHighI16x8S, I32x4ExtMulLowI16x8U, I32x4ExtMulHighI16x8U, I64x2Abs, + I64x2Neg, I64x2AllTrue, I64x2Bitmask, I64x2ExtendLowI32x4S, I64x2ExtendHighI32x4S, + I64x2ExtendLowI32x4U, I64x2ExtendHighI32x4U, I64x2Shl, I64x2ShrS, I64x2ShrU, I64x2Add, I64x2Sub, + I64x2Mul, I64x2ExtMulLowI32x4S, I64x2ExtMulHighI32x4S, I64x2ExtMulLowI32x4U, I64x2ExtMulHighI32x4U, + F32x4Ceil, F32x4Floor, F32x4Trunc, F32x4Nearest, F32x4Abs, F32x4Neg, F32x4Sqrt, F32x4Add, F32x4Sub, + F32x4Mul, F32x4Div, F32x4Min, F32x4Max, F32x4PMin, F32x4PMax, F64x2Ceil, F64x2Floor, F64x2Trunc, + F64x2Nearest, F64x2Abs, F64x2Neg, F64x2Sqrt, F64x2Add, F64x2Sub, F64x2Mul, F64x2Div, F64x2Min, + F64x2Max, F64x2PMin, F64x2PMax, I32x4TruncSatF32x4S, I32x4TruncSatF32x4U, F32x4ConvertI32x4S, + F32x4ConvertI32x4U, I32x4TruncSatF64x2SZero, I32x4TruncSatF64x2UZero, F64x2ConvertLowI32x4S, + F64x2ConvertLowI32x4U, F32x4DemoteF64x2Zero, F64x2PromoteLowF32x4, I8x16RelaxedSwizzle, + I32x4RelaxedTruncF32x4S, I32x4RelaxedTruncF32x4U, I32x4RelaxedTruncF64x2SZero, + I32x4RelaxedTruncF64x2UZero, F32x4RelaxedMadd, F32x4RelaxedNmadd, F64x2RelaxedMadd, + F64x2RelaxedNmadd, I8x16RelaxedLaneselect, I16x8RelaxedLaneselect, I32x4RelaxedLaneselect, + I64x2RelaxedLaneselect, F32x4RelaxedMin, F32x4RelaxedMax, F64x2RelaxedMin, F64x2RelaxedMax, + I16x8RelaxedQ15mulrS, I16x8RelaxedDotI8x16I7x16S, I32x4RelaxedDotI8x16I7x16AddS + ) => u64::MAX, + + #[cfg(feature = "sp1")] + _ => todo!("New operator not covered yet by nitro!") + }; + ink +} diff --git a/arbitrator/prover/src/programs/mod.rs b/arbitrator/prover/src/programs/mod.rs new file mode 100644 index 00000000000..c9fe8387825 --- /dev/null +++ b/arbitrator/prover/src/programs/mod.rs @@ -0,0 +1,486 @@ +// Copyright 2022-2024, Offchain Labs, Inc. +// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md + +use crate::{ + binary::{ExportKind, WasmBinary}, + programs::config::CompileConfig, + value::{FunctionType as ArbFunctionType, MemoryType, Value}, +}; +use arbutil::{Bytes32, Color, evm::ARBOS_VERSION_STYLUS_CHARGING_FIXES, math::SaturatingSum}; +use eyre::{Report, Result, WrapErr, bail, eyre}; +use fnv::FnvHashMap as HashMap; +use std::fmt::Debug; +use wasmer_types::{ + FunctionIndex, GlobalIndex, GlobalInit, ImportIndex, LocalFunctionIndex, SignatureIndex, Type, + entity::EntityRef, +}; +use wasmparser::{Operator, ValType}; + +#[cfg(all(feature = "native", feature = "sp1"))] +use wasmer::sys::{FunctionMiddleware, MiddlewareError, MiddlewareReaderState, ModuleMiddleware}; +#[cfg(all(feature = "native", not(feature = "sp1")))] +use wasmer::{FunctionMiddleware, MiddlewareError, MiddlewareReaderState, ModuleMiddleware}; +#[cfg(feature = "native")] +use { + super::value, + std::marker::PhantomData, + wasmer::{ExportIndex, GlobalType, Mutability}, + wasmer_types::{MemoryIndex, ModuleInfo}, +}; + +pub mod config; +pub mod counter; +pub mod depth; +pub mod dynamic; +pub mod heap; +pub mod memory; +pub mod meter; +pub mod prelude; +pub mod start; + +pub const STYLUS_ENTRY_POINT: &str = "user_entrypoint"; + +pub trait ModuleMod { + fn add_global(&mut self, name: &str, ty: Type, init: GlobalInit) -> Result; + fn get_global(&mut self, name: &str) -> Result; + fn get_signature(&self, sig: SignatureIndex) -> Result; + fn get_function(&self, func: FunctionIndex) -> Result; + fn all_functions(&self) -> Result>; + fn all_signatures(&self) -> Result>; + fn get_import(&self, module: &str, name: &str) -> Result; + /// Moves the start function, returning true if present. + fn move_start_function(&mut self, name: &str) -> Result; + /// Drops debug-only info like export names. + fn drop_exports_and_names(&mut self, keep: &HashMap<&str, ExportKind>); + fn memory_info(&self) -> Result; +} + +pub trait Middleware { + type FM<'a>: FuncMiddleware<'a> + Debug; + + fn update_module(&self, module: &mut M) -> Result<()>; // not mutable due to wasmer + fn instrument<'a>(&self, func_index: LocalFunctionIndex) -> Result>; + fn name(&self) -> &'static str; +} + +pub trait FuncMiddleware<'a> { + /// Provide info on the function's locals. This is called before feed. + fn locals_info(&mut self, _locals: &[ValType]) {} + + /// Processes the given operator. + fn feed(&mut self, op: Operator<'a>, out: &mut O) -> Result<()> + where + O: Extend>; + + /// The name of the middleware + fn name(&self) -> &'static str; +} + +#[derive(Debug)] +pub struct DefaultFuncMiddleware; + +impl<'a> FuncMiddleware<'a> for DefaultFuncMiddleware { + fn feed(&mut self, op: Operator<'a>, out: &mut O) -> Result<()> + where + O: Extend>, + { + out.extend([op]); + Ok(()) + } + + fn name(&self) -> &'static str { + "default middleware" + } +} + +/// This wrapper exists to impl wasmer's `ModuleMiddleware` generically. +/// We can't use `T` directly since we don't define `ModuleMiddleware`, +/// and we need `M` to be part of the type. +#[cfg(feature = "native")] +#[derive(Debug)] +pub struct MiddlewareWrapper(pub T, PhantomData) +where + T: Middleware + Debug + Send + Sync, + M: ModuleMod; + +#[cfg(feature = "native")] +impl MiddlewareWrapper +where + T: Middleware + Debug + Send + Sync, + M: ModuleMod, +{ + pub fn new(middleware: T) -> Self { + Self(middleware, PhantomData) + } +} + +#[cfg(feature = "native")] +impl ModuleMiddleware for MiddlewareWrapper +where + T: Middleware + Debug + Send + Sync + 'static, +{ + fn transform_module_info(&self, module: &mut ModuleInfo) -> Result<(), MiddlewareError> { + let error = |err| MiddlewareError::new(self.0.name().red(), format!("{err:?}")); + self.0.update_module(module).map_err(error) + } + + fn generate_function_middleware<'a>( + &self, + local_function_index: LocalFunctionIndex, + ) -> Box + 'a> { + let worker = self.0.instrument(local_function_index).unwrap(); + Box::new(FuncMiddlewareWrapper(worker, PhantomData)) + } +} + +/// This wrapper exists to impl wasmer's `FunctionMiddleware` generically. +/// The logic is analogous to that of `ModuleMiddleware`, except this time +/// we need a phantom marker to parameterize by `T`'s reference's lifetime. +#[cfg(feature = "native")] +#[derive(Debug)] +pub struct FuncMiddlewareWrapper<'a, T: 'a>(T, PhantomData<&'a T>) +where + T: FuncMiddleware<'a> + Debug; + +#[cfg(feature = "native")] +impl<'a, T> FunctionMiddleware<'a> for FuncMiddlewareWrapper<'a, T> +where + T: FuncMiddleware<'a> + Debug, +{ + fn locals_info(&mut self, locals: &[ValType]) { + self.0.locals_info(locals); + } + + fn feed( + &mut self, + op: Operator<'a>, + out: &mut MiddlewareReaderState<'a>, + ) -> Result<(), MiddlewareError> { + let name = self.0.name().red(); + let error = |err| MiddlewareError::new(name, format!("{err:?}")); + self.0.feed(op, out).map_err(error) + } +} + +#[cfg(feature = "native")] +impl ModuleMod for ModuleInfo { + fn add_global(&mut self, name: &str, ty: Type, init: GlobalInit) -> Result { + let global_type = GlobalType::new(ty, Mutability::Var); + let name = name.to_owned(); + if self.exports.contains_key(&name) { + bail!("wasm already contains {}", name.red()) + } + let index = self.globals.push(global_type); + self.exports.insert(name, ExportIndex::Global(index)); + self.global_initializers.push(init); + Ok(index) + } + + fn get_global(&mut self, name: &str) -> Result { + let Some(ExportIndex::Global(global)) = self.exports.get(name) else { + bail!("missing global {}", name.red()) + }; + Ok(*global) + } + + fn get_signature(&self, sig: SignatureIndex) -> Result { + let error = Report::msg(format!("missing signature {}", sig.as_u32().red())); + let ty = self.signatures.get(sig).cloned().ok_or(error)?; + let ty = value::parser_func_type(ty); + ty.try_into() + } + + fn get_function(&self, func: FunctionIndex) -> Result { + let index = func.as_u32(); + match self.functions.get(func) { + Some(sig) => self.get_signature(*sig), + None => match self.function_names.get(&func) { + Some(name) => bail!("missing func {} @ index {}", name.red(), index.red()), + None => bail!("missing func @ index {}", index.red()), + }, + } + } + + fn all_functions(&self) -> Result> { + let mut funcs = HashMap::default(); + for (func, sig) in &self.functions { + let ty = self.get_signature(*sig)?; + funcs.insert(func, ty); + } + Ok(funcs) + } + + fn all_signatures(&self) -> Result> { + let mut signatures = HashMap::default(); + for (index, _) in &self.signatures { + let ty = self.get_signature(index)?; + signatures.insert(index, ty); + } + Ok(signatures) + } + + fn get_import(&self, module: &str, name: &str) -> Result { + self.imports + .iter() + .find(|(k, _)| k.module == module && k.field == name) + .map(|(_, v)| v.clone()) + .ok_or_else(|| eyre!("missing import {}", name.red())) + } + + fn move_start_function(&mut self, name: &str) -> Result { + if let Some(prior) = self.exports.get(name) { + bail!("function {} already exists @ index {:?}", name.red(), prior) + } + + let start = self.start_function.take(); + if let Some(start) = start { + let export = ExportIndex::Function(start); + self.exports.insert(name.to_owned(), export); + self.function_names.insert(start, name.to_owned()); + } + Ok(start.is_some()) + } + + fn drop_exports_and_names(&mut self, keep: &HashMap<&str, ExportKind>) { + self.exports.retain(|name, export| { + keep.get(name.as_str()) + .is_some_and(|x| *x == (*export).into()) + }); + self.function_names.clear(); + } + + fn memory_info(&self) -> Result { + if self.memories.is_empty() { + bail!("missing memory export with name {}", "memory".red()); + } + if self.memories.len() > 1 { + bail!("only one memory is allowed"); + } + if self.exports.get("memory") != Some(&ExportIndex::Memory(MemoryIndex::from_u32(0))) { + bail!("missing memory with export name {}", "memory".red()); + } + Ok(self.memories.last().unwrap().into()) + } +} + +impl ModuleMod for WasmBinary<'_> { + fn add_global(&mut self, name: &str, _ty: Type, init: GlobalInit) -> Result { + let global = match init { + GlobalInit::I32Const(x) => Value::I32(x as u32), + GlobalInit::I64Const(x) => Value::I64(x as u64), + GlobalInit::F32Const(x) => Value::F32(x), + GlobalInit::F64Const(x) => Value::F64(x), + ty => bail!("cannot add global of type {:?}", ty), + }; + if self.exports.contains_key(name) { + bail!("wasm already contains {}", name.red()) + } + let name = name.to_owned(); + let index = self.globals.len() as u32; + self.exports.insert(name, (index, ExportKind::Global)); + self.globals.push(global); + Ok(GlobalIndex::from_u32(index)) + } + + fn get_global(&mut self, name: &str) -> Result { + let Some((global, ExportKind::Global)) = self.exports.get(name) else { + bail!("missing global {}", name.red()) + }; + Ok(GlobalIndex::from_u32(*global)) + } + + fn get_signature(&self, sig: SignatureIndex) -> Result { + let index = sig.as_u32() as usize; + let error = Report::msg(format!("missing signature {}", index.red())); + self.types.get(index).cloned().ok_or(error) + } + + fn get_function(&self, func: FunctionIndex) -> Result { + let mut index = func.as_u32() as usize; + + let sig = if index < self.imports.len() { + self.imports.get(index).map(|x| &x.offset) + } else { + index -= self.imports.len(); + self.functions.get(index) + }; + + let func = func.as_u32(); + match sig { + Some(sig) => self.get_signature(SignatureIndex::from_u32(*sig)), + None => match self.names.functions.get(&func) { + Some(name) => bail!("missing func {} @ index {}", name.red(), func.red()), + None => bail!("missing func @ index {}", func.red()), + }, + } + } + + fn all_functions(&self) -> Result> { + let mut funcs = HashMap::default(); + let mut index = 0; + for import in &self.imports { + let ty = self.get_signature(SignatureIndex::from_u32(import.offset))?; + funcs.insert(FunctionIndex::new(index), ty); + index += 1; + } + for sig in &self.functions { + let ty = self.get_signature(SignatureIndex::from_u32(*sig))?; + funcs.insert(FunctionIndex::new(index), ty); + index += 1; + } + Ok(funcs) + } + + fn all_signatures(&self) -> Result> { + let mut signatures = HashMap::default(); + for (index, ty) in self.types.iter().enumerate() { + let sig = SignatureIndex::new(index); + signatures.insert(sig, ty.clone()); + } + Ok(signatures) + } + + fn get_import(&self, module: &str, name: &str) -> Result { + self.imports + .iter() + .position(|x| x.module == module && x.name == name) + .map(|x| ImportIndex::Function(FunctionIndex::from_u32(x as u32))) + .ok_or_else(|| eyre!("missing import {}", name.red())) + } + + fn move_start_function(&mut self, name: &str) -> Result { + if let Some(prior) = self.exports.get(name) { + bail!("function {} already exists @ index {:?}", name.red(), prior) + } + + let start = self.start.take(); + if let Some(start) = start { + let name = name.to_owned(); + self.exports.insert(name.clone(), (start, ExportKind::Func)); + self.names.functions.insert(start, name); + } + Ok(start.is_some()) + } + + fn drop_exports_and_names(&mut self, keep: &HashMap<&str, ExportKind>) { + self.exports + .retain(|name, ty| keep.get(name.as_str()).is_some_and(|x| *x == ty.1)); + self.names.functions.clear(); + } + + fn memory_info(&self) -> Result { + if self.memories.is_empty() { + bail!("missing memory export with name {}", "memory".red()); + } + if self.memories.len() > 1 { + bail!("only one memory is allowed"); + } + if self.exports.get("memory") != Some(&(0, ExportKind::Memory)) { + bail!("missing memory with export name {}", "memory".red()); + } + self.memories.last().unwrap().try_into() + } +} + +/// Information about an activated program. +#[derive(Clone, Copy, Debug)] +#[repr(C)] +pub struct StylusData { + /// Global index for the amount of ink left. + pub ink_left: u32, + /// Global index for whether the program is out of ink. + pub ink_status: u32, + /// Global index for the amount of stack space remaining. + pub depth_left: u32, + /// Cost paid to invoke the program. See `programs.go` for the translation to gas. + pub init_cost: u16, + /// Cost paid to invoke the program when stored in the init cache. + pub cached_init_cost: u16, + /// Canonical estimate of the asm length in bytes. + pub asm_estimate: u32, + /// Initial memory size in pages. + pub footprint: u16, + /// Entrypoint offset. + pub user_main: u32, +} + +impl StylusData { + pub fn global_offsets(&self) -> (u64, u64, u64) { + ( + self.ink_left as u64, + self.ink_status as u64, + self.depth_left as u64, + ) + } +} + +#[cfg(not(feature = "sp1"))] +impl crate::machine::Module { + pub fn activate( + wasm: &[u8], + codehash: &Bytes32, + stylus_version: u16, + arbos_version_for_gas: u64, // must only be used for activation gas + page_limit: u16, + debug: bool, + gas: &mut u64, + ) -> Result<(Self, StylusData)> { + let compile = CompileConfig::version(stylus_version, debug); + let (bin, stylus_data) = + WasmBinary::parse_user(wasm, arbos_version_for_gas, page_limit, &compile, codehash) + .wrap_err("failed to parse wasm")?; + + if arbos_version_for_gas > 0 { + // converts a number of microseconds to gas + // TODO: collapse to a single value after finalizing factors + let us_to_gas = |us: u64| { + let fudge = 2; + let sync_rate = 1_000_000 / 2; + let speed = 7_000_000; + us.saturating_mul(fudge * speed) / sync_rate + }; + + macro_rules! pay { + ($us:expr) => { + let amount = us_to_gas($us); + if *gas < amount { + *gas = 0; + bail!("out of gas"); + } + *gas -= amount; + }; + } + + // pay for wasm + if arbos_version_for_gas >= ARBOS_VERSION_STYLUS_CHARGING_FIXES { + let wasm_len = wasm.len() as u64; + pay!(wasm_len.saturating_mul(31_733) / 100_000); + } + + // pay for funcs + let funcs = bin.functions.len() as u64; + pay!(funcs.saturating_mul(17_263) / 100_000); + + // pay for data + let data = bin.datas.iter().map(|x| x.data.len()).saturating_sum() as u64; + pay!(data.saturating_mul(17_376) / 100_000); + + // pay for elements + let elems = bin.elements.iter().map(|x| x.range.len()).saturating_sum() as u64; + pay!(elems.saturating_mul(17_376) / 100_000); + + // pay for memory + let mem = bin.memories.first().map(|x| x.initial).unwrap_or_default(); + pay!(mem.saturating_mul(2217)); + + // pay for code + let code = bin.codes.iter().map(|x| x.expr.len()).saturating_sum() as u64; + pay!(code.saturating_mul(535) / 1_000); + } + + let module = Self::from_user_binary(&bin, compile.debug.debug_funcs, Some(stylus_data)) + .wrap_err("failed to build user module")?; + + Ok((module, stylus_data)) + } +} diff --git a/arbitrator/prover/src/programs/prelude.rs b/arbitrator/prover/src/programs/prelude.rs new file mode 100644 index 00000000000..9fa531d5aaf --- /dev/null +++ b/arbitrator/prover/src/programs/prelude.rs @@ -0,0 +1,12 @@ +// Copyright 2022-2023, Offchain Labs, Inc. +// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md + +pub use super::{ + config::{CompileConfig, StylusConfig}, + counter::CountingMachine, + depth::DepthCheckedMachine, + meter::{GasMeteredMachine, MachineMeter, MeteredMachine}, +}; + +#[cfg(feature = "native")] +pub use super::start::StartlessMachine; diff --git a/arbitrator/prover/src/programs/start.rs b/arbitrator/prover/src/programs/start.rs new file mode 100644 index 00000000000..0d9fa9e004f --- /dev/null +++ b/arbitrator/prover/src/programs/start.rs @@ -0,0 +1,67 @@ +// Copyright 2022-2023, Offchain Labs, Inc. +// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md + +use crate::{ + binary::ExportKind, + programs::{DefaultFuncMiddleware, Middleware, ModuleMod, STYLUS_ENTRY_POINT}, +}; +use eyre::{Result, bail}; +use fnv::FnvHashMap as HashMap; +use lazy_static::lazy_static; +use wasmer_types::LocalFunctionIndex; + +#[cfg(feature = "native")] +use wasmer::TypedFunction; + +lazy_static! { + /// Lists the exports a user program map have + static ref EXPORT_WHITELIST: HashMap<&'static str, ExportKind> = { + let mut map = HashMap::default(); + map.insert(STYLUS_ENTRY_POINT, ExportKind::Func); + map.insert(StartMover::NAME, ExportKind::Func); + map.insert("memory", ExportKind::Memory); + map + }; +} + +#[derive(Debug)] +pub struct StartMover { + /// Whether to keep offchain information. + debug: bool, +} + +impl StartMover { + pub const NAME: &'static str = "stylus_start"; + + pub fn new(debug: bool) -> Self { + Self { debug } + } +} + +impl Middleware for StartMover { + type FM<'a> = DefaultFuncMiddleware; + + fn update_module(&self, module: &mut M) -> Result<()> { + let had_start = module.move_start_function(Self::NAME)?; + if had_start && !self.debug { + bail!("start functions not allowed"); + } + if !self.debug { + module.drop_exports_and_names(&EXPORT_WHITELIST); + } + Ok(()) + } + + fn instrument<'a>(&self, _: LocalFunctionIndex) -> Result> { + Ok(DefaultFuncMiddleware) + } + + fn name(&self) -> &'static str { + "start mover" + } +} + +#[cfg(feature = "native")] +pub trait StartlessMachine { + fn get_start(&self) -> Result>; +} diff --git a/arbitrator/prover/src/value.rs b/arbitrator/prover/src/value.rs new file mode 100644 index 00000000000..6027826b9cc --- /dev/null +++ b/arbitrator/prover/src/value.rs @@ -0,0 +1,572 @@ +// Copyright 2021-2022, Offchain Labs, Inc. +// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md + +use crate::binary::FloatType; +use arbutil::{Bytes32, Color}; +use digest::Digest; +use eyre::{ErrReport, Result, bail}; +use num_derive::FromPrimitive; +use serde::{Deserialize, Serialize}; +use serde_with::{TryFromInto, serde_as}; +use sha3::Keccak256; +use std::{ + convert::{TryFrom, TryInto}, + fmt::Display, + ops::Add, +}; +use wasmer_types::Pages; +use wasmparser::{FuncType, RefType, ValType}; + +#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize, Deserialize)] +#[repr(u8)] +pub enum ArbValueType { + I32, + I64, + F32, + F64, + RefNull, + FuncRef, + InternalRef, +} + +impl ArbValueType { + pub fn serialize(self) -> u8 { + self as u8 + } +} + +impl TryFrom for ArbValueType { + type Error = eyre::Error; + + fn try_from(ty: ValType) -> Result { + use ValType as V; + Ok(match ty { + V::I32 => Self::I32, + V::I64 => Self::I64, + V::F32 => Self::F32, + V::F64 => Self::F64, + V::Ref(ty) => ty.try_into()?, + V::V128 => bail!("128-bit types are not supported"), + }) + } +} + +impl TryFrom for ArbValueType { + type Error = eyre::Error; + + fn try_from(value: RefType) -> Result { + Ok(match value { + RefType::FUNCREF => Self::FuncRef, + RefType::EXTERNREF => Self::FuncRef, + RefType::NULLREF => Self::RefNull, + _ => bail!("ref extensions not supported"), + }) + } +} + +impl From for ValType { + fn from(ty: ArbValueType) -> Self { + use ArbValueType as V; + match ty { + V::I32 => Self::I32, + V::I64 => Self::I64, + V::F32 => Self::F32, + V::F64 => Self::F64, + V::RefNull => Self::Ref(RefType::NULLREF), + V::FuncRef => Self::Ref(RefType::FUNCREF), + V::InternalRef => Self::Ref(RefType::FUNCREF), // not analogous, but essentially a func pointer + } + } +} + +#[cfg(feature = "native")] +pub fn parser_type(ty: &wasmer::Type) -> wasmer::wasmparser::ValType { + match ty { + wasmer::Type::I32 => wasmer::wasmparser::ValType::I32, + wasmer::Type::I64 => wasmer::wasmparser::ValType::I64, + wasmer::Type::F32 => wasmer::wasmparser::ValType::F32, + wasmer::Type::F64 => wasmer::wasmparser::ValType::F64, + wasmer::Type::V128 => wasmer::wasmparser::ValType::V128, + wasmer::Type::ExternRef => wasmer::wasmparser::ValType::Ref(RefType::EXTERNREF), + wasmer::Type::FuncRef => wasmer::wasmparser::ValType::Ref(RefType::FUNCREF), + #[cfg(feature = "sp1")] + _ => todo!(), + } +} + +#[cfg(feature = "native")] +pub fn parser_func_type(ty: wasmer::FunctionType) -> FuncType { + let convert = |t: &[wasmer::Type]| -> Vec { t.iter().map(parser_type).collect() }; + let params = convert(ty.params()); + let results = convert(ty.results()); + FuncType::new(params, results) +} + +impl From for ArbValueType { + fn from(ty: FloatType) -> ArbValueType { + match ty { + FloatType::F32 => ArbValueType::F32, + FloatType::F64 => ArbValueType::F64, + } + } +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize, Deserialize)] +pub enum IntegerValType { + I32, + I64, +} + +impl From for ArbValueType { + fn from(ty: IntegerValType) -> ArbValueType { + match ty { + IntegerValType::I32 => ArbValueType::I32, + IntegerValType::I64 => ArbValueType::I64, + } + } +} + +#[serde_as] +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] +pub struct ProgramCounter { + #[serde_as(as = "TryFromInto")] + pub module: u32, + #[serde_as(as = "TryFromInto")] + pub func: u32, + #[serde_as(as = "TryFromInto")] + pub inst: u32, +} + +#[cfg(not(any(target_pointer_width = "32", target_pointer_width = "64",)))] +compile_error!("Architectures with less than a 32 bit pointer width are not supported"); + +impl ProgramCounter { + pub fn serialize(self) -> Bytes32 { + let mut b = [0u8; 32]; + b[28..].copy_from_slice(&self.inst.to_be_bytes()); + b[24..28].copy_from_slice(&self.func.to_be_bytes()); + b[20..24].copy_from_slice(&self.module.to_be_bytes()); + Bytes32(b) + } + + // These casts are safe because we checked above that a usize is at least as big as a u32 + + pub fn module(self) -> usize { + self.module as usize + } + + pub fn func(self) -> usize { + self.func as usize + } + + pub fn inst(self) -> usize { + self.inst as usize + } +} + +impl Add for ProgramCounter { + type Output = ProgramCounter; + + fn add(self, rhs: u32) -> Self::Output { + let mut counter = self; + counter.inst += rhs; + counter + } +} + +impl Display for ProgramCounter { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{} {} {} {}{}{}", + "inst".grey(), + self.inst.pink(), + "in".grey(), + self.module.pink(), + ":".grey(), + self.func.pink() + ) + } +} + +#[derive(Clone, Copy, Debug, Serialize, Deserialize)] +pub enum Value { + I32(u32), + I64(u64), + F32(f32), + F64(f64), + RefNull, + FuncRef(u32), + InternalRef(ProgramCounter), +} + +impl Value { + pub fn ty(self) -> ArbValueType { + match self { + Value::I32(_) => ArbValueType::I32, + Value::I64(_) => ArbValueType::I64, + Value::F32(_) => ArbValueType::F32, + Value::F64(_) => ArbValueType::F64, + Value::RefNull => ArbValueType::RefNull, + Value::FuncRef(_) => ArbValueType::FuncRef, + Value::InternalRef(_) => ArbValueType::InternalRef, + } + } + + pub fn contents_for_proof(self) -> Bytes32 { + match self { + Value::I32(x) => x.into(), + Value::I64(x) => x.into(), + Value::F32(x) => x.to_bits().into(), + Value::F64(x) => x.to_bits().into(), + Value::RefNull => Bytes32::default(), + Value::FuncRef(x) => x.into(), + Value::InternalRef(pc) => pc.serialize(), + } + } + + pub fn serialize_for_proof(self) -> [u8; 33] { + let mut ret = [0u8; 33]; + ret[0] = self.ty().serialize(); + ret[1..].copy_from_slice(&*self.contents_for_proof()); + ret + } + + pub fn is_i32_zero(self) -> bool { + match self { + Value::I32(0) => true, + Value::I32(_) => false, + _ => panic!("WASM validation failed: i32.eqz equivalent called on {self:?}",), + } + } + + pub fn is_i64_zero(self) -> bool { + match self { + Value::I64(0) => true, + Value::I64(_) => false, + _ => panic!("WASM validation failed: i64.eqz equivalent called on {self:?}",), + } + } + + pub fn assume_u32(self) -> u32 { + match self { + Value::I32(x) => x, + _ => panic!("WASM validation failed: assume_u32 called on {self:?}"), + } + } + + pub fn assume_u64(self) -> u64 { + match self { + Value::I64(x) => x, + _ => panic!("WASM validation failed: assume_u64 called on {self:?}"), + } + } + + pub fn hash(self) -> Bytes32 { + let mut h = Keccak256::new(); + h.update(b"Value:"); + h.update([self.ty() as u8]); + h.update(self.contents_for_proof()); + h.finalize().into() + } + + pub fn default_of_type(ty: ArbValueType) -> Value { + match ty { + ArbValueType::I32 => Value::I32(0), + ArbValueType::I64 => Value::I64(0), + ArbValueType::F32 => Value::F32(0.), + ArbValueType::F64 => Value::F64(0.), + ArbValueType::RefNull | ArbValueType::FuncRef | ArbValueType::InternalRef => { + Value::RefNull + } + } + } +} + +impl Display for Value { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let lparem = "(".grey(); + let rparem = ")".grey(); + + macro_rules! single { + ($ty:expr, $value:expr) => {{ write!(f, "{}{}{}{}", $ty.grey(), lparem, $value, rparem) }}; + } + macro_rules! pair { + ($ty:expr, $left:expr, $right:expr) => {{ + let eq = "=".grey(); + write!( + f, + "{}{}{} {} {}{}", + $ty.grey(), + lparem, + $left, + eq, + $right, + rparem + ) + }}; + } + match self { + Value::I32(value) => { + if (*value as i32) < 0 { + pair!("i32", *value as i32, value) + } else { + single!("i32", *value) + } + } + Value::I64(value) => { + if (*value as i64) < 0 { + pair!("i64", *value as i64, value) + } else { + single!("i64", *value) + } + } + Value::F32(value) => single!("f32", *value), + Value::F64(value) => single!("f64", *value), + Value::RefNull => write!(f, "null"), + Value::FuncRef(func) => write!(f, "func {func}"), + Value::InternalRef(pc) => write!(f, "{pc}"), + } + } +} + +impl PartialEq for Value { + fn eq(&self, other: &Self) -> bool { + self.ty() == other.ty() && self.contents_for_proof() == other.contents_for_proof() + } +} + +impl From for Value { + fn from(value: u8) -> Self { + Value::I32(value.into()) + } +} + +impl From for Value { + fn from(value: u16) -> Self { + Value::I32(value.into()) + } +} + +impl From for Value { + fn from(value: u32) -> Self { + Value::I32(value) + } +} + +impl From for Value { + fn from(value: u64) -> Self { + Value::I64(value) + } +} + +impl From for Value { + fn from(value: f32) -> Self { + Value::F32(value) + } +} + +impl From for Value { + fn from(value: f64) -> Self { + Value::F64(value) + } +} + +impl From for Value { + fn from(value: ProgramCounter) -> Self { + Value::InternalRef(value) + } +} + +impl TryInto for Value { + type Error = ErrReport; + + fn try_into(self) -> Result { + match self { + Value::I32(value) => Ok(value), + _ => bail!("value not a u32"), + } + } +} + +impl TryInto for Value { + type Error = ErrReport; + + fn try_into(self) -> Result { + match self { + Value::I64(value) => Ok(value), + _ => bail!("value not a u64"), + } + } +} + +impl Eq for Value {} + +#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] +pub struct FunctionType { + pub inputs: Vec, + pub outputs: Vec, +} + +impl FunctionType { + pub fn new(inputs: T, outputs: U) -> FunctionType + where + T: Into>, + U: Into>, + { + FunctionType { + inputs: inputs.into(), + outputs: outputs.into(), + } + } + + pub fn hash(&self) -> Bytes32 { + let mut h = Keccak256::new(); + h.update(b"Function type:"); + h.update(Bytes32::from(self.inputs.len())); + for input in &self.inputs { + h.update([*input as u8]); + } + h.update(Bytes32::from(self.outputs.len())); + for output in &self.outputs { + h.update([*output as u8]); + } + h.finalize().into() + } +} + +impl TryFrom for FunctionType { + type Error = eyre::Error; + + fn try_from(func: FuncType) -> Result { + let mut inputs = vec![]; + let mut outputs = vec![]; + + for input in func.params() { + inputs.push(ArbValueType::try_from(*input)?) + } + for output in func.results() { + outputs.push(ArbValueType::try_from(*output)?) + } + Ok(Self { inputs, outputs }) + } +} + +impl Display for FunctionType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let mut signature = "λ(".to_string(); + if !self.inputs.is_empty() { + for arg in &self.inputs { + signature += &format!("{arg}, "); + } + signature.pop(); + signature.pop(); + } + signature += ")"; + + let output_tuple = self.outputs.len() > 2; + if !self.outputs.is_empty() { + signature += " -> "; + if output_tuple { + signature += "("; + } + for out in &self.outputs { + signature += &format!("{out}, "); + } + signature.pop(); + signature.pop(); + if output_tuple { + signature += ")"; + } + } + write!(f, "{signature}") + } +} + +impl Display for ArbValueType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + use ArbValueType::*; + match self { + I32 => write!(f, "i32"), + I64 => write!(f, "i64"), + F32 => write!(f, "f32"), + F64 => write!(f, "f64"), + RefNull => write!(f, "null"), + FuncRef => write!(f, "func"), + InternalRef => write!(f, "internal"), + } + } +} + +/// Represents the internal hostio functions a module may have. +#[derive(Clone, Copy, Debug, FromPrimitive)] +#[repr(u64)] +pub enum InternalFunc { + WavmCallerLoad8, + WavmCallerLoad32, + WavmCallerStore8, + WavmCallerStore32, + MemoryFill, + MemoryCopy, + UserInkLeft, + UserInkStatus, + UserSetInk, + UserStackLeft, + UserSetStack, + UserMemorySize, + CallMain, +} + +impl InternalFunc { + pub fn ty(&self) -> FunctionType { + use ArbValueType::*; + use InternalFunc::*; + macro_rules! func { + ([$($args:expr),*], [$($outs:expr),*]) => { + FunctionType::new(vec![$($args),*], vec![$($outs),*]) + }; + } + #[rustfmt::skip] + let ty = match self { + WavmCallerLoad8 | WavmCallerLoad32 => func!([I32], [I32]), + WavmCallerStore8 | WavmCallerStore32 => func!([I32, I32], []), + MemoryFill | MemoryCopy => func!([I32, I32, I32], []), + UserInkLeft => func!([], [I64]), // λ() → ink_left + UserInkStatus => func!([], [I32]), // λ() → ink_status + UserSetInk => func!([I64, I32], []), // λ(ink_left, ink_status) + UserStackLeft => func!([], [I32]), // λ() → stack_left + UserSetStack => func!([I32], []), // λ(stack_left) + UserMemorySize => func!([], [I32]), // λ() → memory_size + CallMain => func!([I32], [I32]), // λ(args_len) → status + }; + ty + } +} + +pub struct MemoryType { + pub min: Pages, + pub max: Option, +} + +impl MemoryType { + pub fn new(min: Pages, max: Option) -> Self { + Self { min, max } + } +} + +impl From<&wasmer_types::MemoryType> for MemoryType { + fn from(value: &wasmer_types::MemoryType) -> Self { + Self::new(value.minimum, value.maximum) + } +} + +impl TryFrom<&wasmparser::MemoryType> for MemoryType { + type Error = ErrReport; + + fn try_from(value: &wasmparser::MemoryType) -> std::result::Result { + Ok(Self { + min: Pages(value.initial.try_into()?), + max: value.maximum.map(|x| x.try_into()).transpose()?.map(Pages), + }) + } +} diff --git a/sp1-crates/prover/src/lib.rs b/sp1-crates/prover/src/lib.rs index 99bd2bb6c9a..63a98634204 100644 --- a/sp1-crates/prover/src/lib.rs +++ b/sp1-crates/prover/src/lib.rs @@ -7,18 +7,19 @@ #![allow(unexpected_cfgs)] #[cfg(feature = "native")] -#[path = "../../../crates/prover/src/binary.rs"] +#[path = "../../../arbitrator/prover/src/binary.rs"] pub mod binary; +#[path = "../../../arbitrator/prover/src/parse_input.rs"] pub mod parse_input; #[cfg(feature = "native")] -#[path = "../../../crates/prover/src/programs/mod.rs"] +#[path = "../../../arbitrator/prover/src/programs/mod.rs"] pub mod programs; #[cfg(feature = "native")] -#[path = "../../../crates/prover/src/value.rs"] +#[path = "../../../arbitrator/prover/src/value.rs"] pub mod value; #[cfg(feature = "native")] -#[path = "../../../crates/arbutil/src/operator.rs"] +#[path = "../../../arbitrator/arbutil/src/operator.rs"] pub mod operator; pub mod binary_input; From a7e155d6df9839079f85fcba16e4ad88c4aa9a2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 10 Feb 2026 17:16:43 +0100 Subject: [PATCH 005/189] Update the module names for EC recovery, Keccak and dumping elf --- sp1-crates/program/src/replay.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/sp1-crates/program/src/replay.rs b/sp1-crates/program/src/replay.rs index 6683e862c7e..90a7495d89d 100644 --- a/sp1-crates/program/src/replay.rs +++ b/sp1-crates/program/src/replay.rs @@ -319,6 +319,13 @@ fn build_imports( "brotli_compress" => func!(arbcompress::brotli_compress), "brotli_decompress" => func!(arbcompress::brotli_decompress), }, + "arbcrypto" => { + "ecrecovery" => func!(precompiles::ecrecover), + "keccak256" => func!(precompiles::keccak256), + }, + "hooks" => { + "beforeFirstIO" => func!(precompiles::dump_elf), + }, "wasi_snapshot_preview1" => { "proc_exit" => func!(wasi_stub::proc_exit), "sched_yield" => func!(wasi_stub::sched_yield), @@ -380,11 +387,6 @@ fn build_imports( "activate" => func!(programs::activate), "activate_v2" => func!(programs::activate_v2), }, - "sp1" => { - "dump_elf" => func!(precompiles::dump_elf), - "ecrecover" => func!(precompiles::ecrecover), - "keccak256" => func!(precompiles::keccak256), - }, }, func_env, ) From fe03de2d293c2349779d685b5a04b19325251423 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 10 Feb 2026 17:28:02 +0100 Subject: [PATCH 006/189] Add program_prepare and program_requires_prepare stubs --- sp1-crates/program/src/imports/programs.rs | 23 ++++++++++++++++++++++ sp1-crates/program/src/replay.rs | 2 ++ 2 files changed, 25 insertions(+) diff --git a/sp1-crates/program/src/imports/programs.rs b/sp1-crates/program/src/imports/programs.rs index ab1a65d477f..e54edf4d2ff 100644 --- a/sp1-crates/program/src/imports/programs.rs +++ b/sp1-crates/program/src/imports/programs.rs @@ -291,3 +291,26 @@ pub fn activate_v2( fn heapify(value: T) -> *mut T { Box::into_raw(Box::new(value)) } + +/// program_requires_prepare +pub fn program_requires_prepare( + mut _env: FunctionEnvMut, + _module_hash_ptr: WasmPtr, +) -> Result { + Ok(0) +} + +/// program_prepare +pub fn program_prepare( + mut _env: FunctionEnvMut, + _wasm_ptr: WasmPtr, + _wasm_size: u64, + _module_hash_ptr: WasmPtr, + _code_hash_ptr: WasmPtr, + _max_wasm_size: u32, + _page_limit: u32, + _debug_mode: u32, + _stylus_version: u32, +) -> MaybeEscape { + Ok(()) +} diff --git a/sp1-crates/program/src/replay.rs b/sp1-crates/program/src/replay.rs index 90a7495d89d..55aa3ccfe42 100644 --- a/sp1-crates/program/src/replay.rs +++ b/sp1-crates/program/src/replay.rs @@ -374,6 +374,8 @@ fn build_imports( "validateCertificate" => func!(wavmio::validate_certificate), }, "programs" => { + "program_prepare" => func!(programs::program_prepare), + "program_requires_prepare" => func!(programs::program_requires_prepare), "new_program" => func!(programs::new_program), "pop" => func!(programs::pop), "set_response" => func!(programs::set_response), From ec33ac39d54dedba6c622a0e7f802e417e8e8d11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 10 Feb 2026 17:53:16 +0100 Subject: [PATCH 007/189] Fix ecrecover signature --- sp1-crates/program/src/imports/precompiles.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sp1-crates/program/src/imports/precompiles.rs b/sp1-crates/program/src/imports/precompiles.rs index 597cef826cb..0e8ff45e90a 100644 --- a/sp1-crates/program/src/imports/precompiles.rs +++ b/sp1-crates/program/src/imports/precompiles.rs @@ -9,9 +9,14 @@ use secp256k1::{ pub fn ecrecover( mut ctx: FunctionEnvMut, hash: Ptr, + hash_len: u32, sig: Ptr, + sig_len: u32, output: Ptr, ) -> Result { + assert_eq!(hash_len, 32, "Hash length must be 32 bytes"); + assert_eq!(sig_len, 65, "Signature length must be 65 bytes (64 for signature + 1 for recovery id)"); + let (data, store) = ctx.data_and_store_mut(); let memory = data.memory.clone().unwrap().view(&store); From 22d096e265574b8d4445d200ca5cda22a6395799 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 10 Feb 2026 18:04:18 +0100 Subject: [PATCH 008/189] Record stylus program for wasm target as well --- system_tests/program_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system_tests/program_test.go b/system_tests/program_test.go index c7d3fe51265..b8d7d3bcb94 100644 --- a/system_tests/program_test.go +++ b/system_tests/program_test.go @@ -435,7 +435,7 @@ func storageTest(t *testing.T, jit bool) { // Captures a block_inputs json file for the block that included the // storage write transaction. Include wasm targets necessary for arbitrator prover and jit binaries - recordBlock(t, receipt.BlockNumber.Uint64(), builder, rawdb.TargetWavm, rawdb.LocalTarget()) + recordBlock(t, receipt.BlockNumber.Uint64(), builder, rawdb.TargetWavm, rawdb.TargetWasm, rawdb.LocalTarget()) } func TestProgramTransientStorage(t *testing.T) { From 8e74af31cb7ba795021bf77136bb41c9907f0e46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Wed, 11 Feb 2026 10:20:17 +0100 Subject: [PATCH 009/189] Satisfy shellcheck --- sp1-crates/build.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sp1-crates/build.sh b/sp1-crates/build.sh index d02b78dc0e1..89340f4213f 100755 --- a/sp1-crates/build.sh +++ b/sp1-crates/build.sh @@ -5,32 +5,32 @@ set -ex SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" export TOP=$SCRIPT_DIR/.. -cd $TOP +cd "$TOP" # Build nitro dependencies make build-replay-env test-go-deps rm -rf target/sp1 mkdir -p target/sp1 export OUTPUT_DIR=$TOP/target/sp1 # Build replay.wasm, but with SP1 optimizations -GOOS=wasip1 GOARCH=wasm go build -tags sp1 -o $OUTPUT_DIR/replay.wasm $TOP/cmd/replay/... +GOOS=wasip1 GOARCH=wasm go build -tags sp1 -o "$OUTPUT_DIR"/replay.wasm "$TOP"/cmd/replay/... # Build a sample Arbitrum test block rm -rf system_tests/test-data go test -run TestProgramStorage ./system_tests/ -- \ - -recordBlockInputs.WithBaseDir=`pwd`/system_tests/test-data \ + -recordBlockInputs.WithBaseDir="$(pwd)"/system_tests/test-data \ -recordBlockInputs.WithTimestampDirEnabled=false \ -recordBlockInputs.enable=true cp system_tests/test-data/TestProgramStorage/*.json target/sp1/ -cd $SCRIPT_DIR +cd "$SCRIPT_DIR" # Bump SP1's maximum heap memory size export SP1_ZKVM_MAX_MEMORY=1099511627776 # Build SP1 program and run bootloading process -cargo run --release -p sp1-builder -- --replay-wasm $OUTPUT_DIR/replay.wasm --output-folder $OUTPUT_DIR +cargo run --release -p sp1-builder -- --replay-wasm "$OUTPUT_DIR"/replay.wasm --output-folder "$OUTPUT_DIR" # Build the SP1 runner cargo build --release -p sp1-runner # Copy relavant files to target folder -cp target/elf-compilation/riscv64im-succinct-zkvm-elf/release/stylus-compiler-program $OUTPUT_DIR -cp target/release/sp1-runner $OUTPUT_DIR +cp target/elf-compilation/riscv64im-succinct-zkvm-elf/release/stylus-compiler-program "$OUTPUT_DIR" +cp target/release/sp1-runner "$OUTPUT_DIR" echo "SP1 runner is successfully built!" From d79af74006dd07bb14d6923fdab4c3d1bec042cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Wed, 11 Feb 2026 10:21:24 +0100 Subject: [PATCH 010/189] Changelog --- changelog/zk-prove-any-sp1-runner.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 changelog/zk-prove-any-sp1-runner.md diff --git a/changelog/zk-prove-any-sp1-runner.md b/changelog/zk-prove-any-sp1-runner.md new file mode 100644 index 00000000000..4355dfef33b --- /dev/null +++ b/changelog/zk-prove-any-sp1-runner.md @@ -0,0 +1,2 @@ +### Ignored + - PLACEHOLDER TO SATISFY CI - WILL BE REPLACED WITH ACTUAL CHANGELOG ENTRY IN THE FUTURE \ No newline at end of file From 04c4444013668ef8d6b34b1fa79250c4d1b4069a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Wed, 11 Feb 2026 10:33:41 +0100 Subject: [PATCH 011/189] Install SP1 toolchain --- .github/workflows/zk-proving.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .github/workflows/zk-proving.yml diff --git a/.github/workflows/zk-proving.yml b/.github/workflows/zk-proving.yml new file mode 100644 index 00000000000..9b55cff8d1e --- /dev/null +++ b/.github/workflows/zk-proving.yml @@ -0,0 +1,27 @@ +name: Run SP1 runner on `replay.wasm` + +on: + workflow_dispatch: + pull_request: + branches: + - zk-prove-any/sp1-runner + +jobs: + zk-proving: + name: Run SP1 runner on `replay.wasm` + runs-on: arbitrator-ci + steps: + - name: Checkout + uses: actions/checkout@v6 + with: + submodules: recursive + + - name: Install SP1 toolchain + run: >- + curl -L https://sp1up.succinct.xyz | bash + sp1up -v v6.0.0-beta.1 + + - name: Print versions + run: >- + rustc +succinct --version + rustc +succinct --print target-list | grep succinct From 37acb19d21e4942da8400f48ade84f09fb9e63a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Wed, 11 Feb 2026 10:35:01 +0100 Subject: [PATCH 012/189] Run the build.sh script --- .github/workflows/zk-proving.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/zk-proving.yml b/.github/workflows/zk-proving.yml index 9b55cff8d1e..46062a6f608 100644 --- a/.github/workflows/zk-proving.yml +++ b/.github/workflows/zk-proving.yml @@ -25,3 +25,6 @@ jobs: run: >- rustc +succinct --version rustc +succinct --print target-list | grep succinct + + - name: Build binaries and record block + run: ./sp1-crates/build.sh \ No newline at end of file From d5f03ea8ecb2fd5c63318ba9b6e6ef85ee930f35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Wed, 11 Feb 2026 10:41:24 +0100 Subject: [PATCH 013/189] Run validation --- .github/workflows/zk-proving.yml | 37 +++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/.github/workflows/zk-proving.yml b/.github/workflows/zk-proving.yml index 46062a6f608..d7583d9c90c 100644 --- a/.github/workflows/zk-proving.yml +++ b/.github/workflows/zk-proving.yml @@ -27,4 +27,39 @@ jobs: rustc +succinct --print target-list | grep succinct - name: Build binaries and record block - run: ./sp1-crates/build.sh \ No newline at end of file + run: ./sp1-crates/build.sh + + - name: Run validation + run: >- + SP1_HASH=$(./target/sp1/sp1-runner \ + --program target/sp1/dumped_replay_wasm.elf \ + --stylus-compiler-program target/sp1/stylus-compiler-program \ + --block-file target/sp1/block_inputs_7.json 2>&1 \ + | grep "Validation succeeds with hash" \ + | awk '{print $NF}') + + if [ -z "$SP1_HASH" ]; then + echo "Error: Failed to capture hash." + exit 1 + fi + + JIT_HASH=$(./target/bin/jit \ + --debug --cranelift \ + --binary target/machines/latest/replay.wasm \ + json --inputs=target/sp1/block_inputs_7.json 2>&1 \ + | grep "Completed in .* with hash" \ + | awk '{print $NF}' \ + | sed 's/\.$//') + + if [ -z "$JIT_HASH" ]; then + echo "Error: Failed to capture JIT hash." + exit 1 + fi + + echo "SP1 Hash: $SP1_HASH" + echo "JIT Hash: $JIT_HASH" + + if [ "$SP1_HASH" != "$JIT_HASH" ]; then + echo "Error: Hash mismatch!" + exit 1 + fi From 740c4b2ec005c9493bb8d10322f1941669ab4760 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Wed, 11 Feb 2026 10:44:33 +0100 Subject: [PATCH 014/189] Small fixes --- .github/workflows/zk-proving.yml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/zk-proving.yml b/.github/workflows/zk-proving.yml index d7583d9c90c..bc9c61ff23e 100644 --- a/.github/workflows/zk-proving.yml +++ b/.github/workflows/zk-proving.yml @@ -30,7 +30,12 @@ jobs: run: ./sp1-crates/build.sh - name: Run validation - run: >- + run: | + # Exit if any command in a pipe fails + set -e -o pipefail + + echo "--- Running SP1 Validation ---" + # Extracting only the hex string using grep -o SP1_HASH=$(./target/sp1/sp1-runner \ --program target/sp1/dumped_replay_wasm.elf \ --stylus-compiler-program target/sp1/stylus-compiler-program \ @@ -43,6 +48,7 @@ jobs: exit 1 fi + echo "--- Running JIT Validation ---" JIT_HASH=$(./target/bin/jit \ --debug --cranelift \ --binary target/machines/latest/replay.wasm \ @@ -60,6 +66,8 @@ jobs: echo "JIT Hash: $JIT_HASH" if [ "$SP1_HASH" != "$JIT_HASH" ]; then - echo "Error: Hash mismatch!" + echo "::error::Hash mismatch detected!" + echo "Expected: $SP1_HASH" + echo "Actual: $JIT_HASH" exit 1 fi From 798b639da53fd48ba40b50c671b93d4160449343 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Wed, 11 Feb 2026 10:52:43 +0100 Subject: [PATCH 015/189] Use sh --- .github/workflows/zk-proving.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/zk-proving.yml b/.github/workflows/zk-proving.yml index bc9c61ff23e..8f4c9755fd9 100644 --- a/.github/workflows/zk-proving.yml +++ b/.github/workflows/zk-proving.yml @@ -18,7 +18,7 @@ jobs: - name: Install SP1 toolchain run: >- - curl -L https://sp1up.succinct.xyz | bash + curl -L https://sp1up.succinct.xyz | sh sp1up -v v6.0.0-beta.1 - name: Print versions From c61311f8bd4f0558445a56f185a04958545d809e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Wed, 11 Feb 2026 10:53:53 +0100 Subject: [PATCH 016/189] Changelog --- changelog/pmikolajczyk-nit-4504.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 changelog/pmikolajczyk-nit-4504.md diff --git a/changelog/pmikolajczyk-nit-4504.md b/changelog/pmikolajczyk-nit-4504.md new file mode 100644 index 00000000000..fa24dae720a --- /dev/null +++ b/changelog/pmikolajczyk-nit-4504.md @@ -0,0 +1,2 @@ +### Internal +- CI: build and run SP1 validation \ No newline at end of file From 93699641ad5ee7e7c84e9a2df0f712d5c10ac561 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Wed, 11 Feb 2026 11:12:11 +0100 Subject: [PATCH 017/189] Fix line breaks --- .github/workflows/zk-proving.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/zk-proving.yml b/.github/workflows/zk-proving.yml index 8f4c9755fd9..4b3a9b6af74 100644 --- a/.github/workflows/zk-proving.yml +++ b/.github/workflows/zk-proving.yml @@ -17,12 +17,12 @@ jobs: submodules: recursive - name: Install SP1 toolchain - run: >- - curl -L https://sp1up.succinct.xyz | sh + run: | + curl -L https://sp1up.succinct.xyz | bash sp1up -v v6.0.0-beta.1 - name: Print versions - run: >- + run: | rustc +succinct --version rustc +succinct --print target-list | grep succinct From 4e0b9ce2655486cb3297fa9458fa840215d66591 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Wed, 11 Feb 2026 11:16:58 +0100 Subject: [PATCH 018/189] source /home/runner/.bashrc --- .github/workflows/zk-proving.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/zk-proving.yml b/.github/workflows/zk-proving.yml index 4b3a9b6af74..138019e7938 100644 --- a/.github/workflows/zk-proving.yml +++ b/.github/workflows/zk-proving.yml @@ -19,6 +19,7 @@ jobs: - name: Install SP1 toolchain run: | curl -L https://sp1up.succinct.xyz | bash + source /home/runner/.bashrc sp1up -v v6.0.0-beta.1 - name: Print versions From fe91d0092d88fae5d7acff5d5cc8220a43b38d6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Wed, 11 Feb 2026 11:27:22 +0100 Subject: [PATCH 019/189] PATH --- .github/workflows/zk-proving.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/zk-proving.yml b/.github/workflows/zk-proving.yml index 138019e7938..bf1b3398ab6 100644 --- a/.github/workflows/zk-proving.yml +++ b/.github/workflows/zk-proving.yml @@ -19,6 +19,8 @@ jobs: - name: Install SP1 toolchain run: | curl -L https://sp1up.succinct.xyz | bash + echo $PATH + export PATH="$HOME/.sp1up/bin:$PATH" source /home/runner/.bashrc sp1up -v v6.0.0-beta.1 From 3697c4ea54335c0c4d6bef3b955877548514a37a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Wed, 11 Feb 2026 11:35:35 +0100 Subject: [PATCH 020/189] Set bash shell --- .github/workflows/zk-proving.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/zk-proving.yml b/.github/workflows/zk-proving.yml index bf1b3398ab6..c2829801fdb 100644 --- a/.github/workflows/zk-proving.yml +++ b/.github/workflows/zk-proving.yml @@ -10,6 +10,9 @@ jobs: zk-proving: name: Run SP1 runner on `replay.wasm` runs-on: arbitrator-ci + defaults: + run: + shell: bash steps: - name: Checkout uses: actions/checkout@v6 @@ -19,8 +22,6 @@ jobs: - name: Install SP1 toolchain run: | curl -L https://sp1up.succinct.xyz | bash - echo $PATH - export PATH="$HOME/.sp1up/bin:$PATH" source /home/runner/.bashrc sp1up -v v6.0.0-beta.1 From 48e01109b890983e62cfa79520cec62cf01ac559 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Wed, 11 Feb 2026 11:43:47 +0100 Subject: [PATCH 021/189] Go with full path --- .github/workflows/zk-proving.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/zk-proving.yml b/.github/workflows/zk-proving.yml index c2829801fdb..b44ec8cd084 100644 --- a/.github/workflows/zk-proving.yml +++ b/.github/workflows/zk-proving.yml @@ -22,8 +22,7 @@ jobs: - name: Install SP1 toolchain run: | curl -L https://sp1up.succinct.xyz | bash - source /home/runner/.bashrc - sp1up -v v6.0.0-beta.1 + $HOME/.sp1/bin/sp1up -v v6.0.0-beta.1 - name: Print versions run: | From b1bd93a025717afdbbde3d2f4cece4d67ad654bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Wed, 11 Feb 2026 11:50:14 +0100 Subject: [PATCH 022/189] Setup CI --- .github/workflows/zk-proving.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/zk-proving.yml b/.github/workflows/zk-proving.yml index b44ec8cd084..4f7cfbf9019 100644 --- a/.github/workflows/zk-proving.yml +++ b/.github/workflows/zk-proving.yml @@ -19,6 +19,9 @@ jobs: with: submodules: recursive + - name: Setup CI + uses: ./.github/actions/ci-setup + - name: Install SP1 toolchain run: | curl -L https://sp1up.succinct.xyz | bash From 80a0c8c1aedba9c2c67a7d9dfdb7d55a7169e375 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Wed, 11 Feb 2026 12:10:03 +0100 Subject: [PATCH 023/189] Install protobuf-compiler --- .github/workflows/zk-proving.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/zk-proving.yml b/.github/workflows/zk-proving.yml index 4f7cfbf9019..3de41a9475b 100644 --- a/.github/workflows/zk-proving.yml +++ b/.github/workflows/zk-proving.yml @@ -22,6 +22,9 @@ jobs: - name: Setup CI uses: ./.github/actions/ci-setup + - name: Install protobuf-compiler + run: sudo apt install -y protobuf-compiler + - name: Install SP1 toolchain run: | curl -L https://sp1up.succinct.xyz | bash From 826af4340b4e5c2d5c6cd7e92f905a593a857633 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Wed, 11 Feb 2026 12:39:53 +0100 Subject: [PATCH 024/189] Install LLVM 21 --- .github/workflows/zk-proving.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/zk-proving.yml b/.github/workflows/zk-proving.yml index 3de41a9475b..5a6b58fafcb 100644 --- a/.github/workflows/zk-proving.yml +++ b/.github/workflows/zk-proving.yml @@ -25,6 +25,11 @@ jobs: - name: Install protobuf-compiler run: sudo apt install -y protobuf-compiler + - name: Setup LLVM + uses: ZhongRuoyu/setup-llvm@v0 + with: + llvm-version: 21 + - name: Install SP1 toolchain run: | curl -L https://sp1up.succinct.xyz | bash From 61da4a8f3e84dd08dbe8b7d047b24499005b3f3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Thu, 12 Feb 2026 10:23:32 +0100 Subject: [PATCH 025/189] Cancel workflow run when a new commit arrives --- .github/workflows/zk-proving.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/zk-proving.yml b/.github/workflows/zk-proving.yml index 5a6b58fafcb..71920f9b16f 100644 --- a/.github/workflows/zk-proving.yml +++ b/.github/workflows/zk-proving.yml @@ -6,6 +6,10 @@ on: branches: - zk-prove-any/sp1-runner +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}-${{ github.ref }} + cancel-in-progress: true + jobs: zk-proving: name: Run SP1 runner on `replay.wasm` From 4157eacfd88572b428104a3b43ec18530de758a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Thu, 12 Feb 2026 10:25:39 +0100 Subject: [PATCH 026/189] Do not require changelog for PRs not against master --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 81b356fc738..e2d5929ad07 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -54,6 +54,7 @@ jobs: # --- Ensure changelog is updated (required by can_proceed) --- changelog: + if: github.base_ref == 'master' needs: changes uses: ./.github/workflows/_changelog.yml secrets: inherit From fe4aeccae838789c8b093e8fc940d907401556de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 13 Feb 2026 16:37:11 +0100 Subject: [PATCH 027/189] Remove two unused dependencies --- Cargo.lock | 15 +- sp1-crates/Cargo.lock | 520 +++++++++++++++++++++++++++++++----------- sp1-crates/Cargo.toml | 4 - 3 files changed, 397 insertions(+), 142 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ce6fb36d82a..03df4e9409f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1338,7 +1338,7 @@ dependencies = [ "futures-core", "futures-sink", "http", - "indexmap 2.3.0", + "indexmap 2.13.0", "slab", "tokio", "tokio-util", @@ -1700,13 +1700,14 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.3.0" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" dependencies = [ "equivalent", - "hashbrown 0.14.5", + "hashbrown 0.16.1", "serde", + "serde_core", ] [[package]] @@ -3057,7 +3058,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.3.0", + "indexmap 2.13.0", "serde", "serde_derive", "serde_json", @@ -3545,7 +3546,7 @@ version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ - "indexmap 2.3.0", + "indexmap 2.13.0", "toml_datetime", "winnow", ] @@ -4101,7 +4102,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9dbe55c8f9d0dbd25d9447a5a889ff90c0cc3feaa7395310d3d826b2c703eaab" dependencies = [ "bitflags 2.6.0", - "indexmap 2.3.0", + "indexmap 2.13.0", "semver", ] diff --git a/sp1-crates/Cargo.lock b/sp1-crates/Cargo.lock index 019c782a021..610b3826f6e 100644 --- a/sp1-crates/Cargo.lock +++ b/sp1-crates/Cargo.lock @@ -826,7 +826,7 @@ dependencies = [ "cfg-if", "libc", "scopeguard", - "sp1-primitives 6.0.0", + "sp1-primitives 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "sp1-zkvm", "windows-sys 0.59.0", ] @@ -1792,7 +1792,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" dependencies = [ "fallible-iterator", - "indexmap 2.12.1", + "indexmap 2.13.0", "stable_deref_trait", ] @@ -1837,7 +1837,7 @@ dependencies = [ "futures-core", "futures-sink", "http", - "indexmap 2.12.1", + "indexmap 2.13.0", "slab", "tokio", "tokio-util", @@ -2225,9 +2225,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.12.1" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" dependencies = [ "equivalent", "hashbrown 0.16.1", @@ -2385,7 +2385,7 @@ dependencies = [ "once_cell", "sha2", "signature", - "sp1-lib 6.0.0", + "sp1-lib 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2899,7 +2899,7 @@ dependencies = [ "crc32fast", "flate2", "hashbrown 0.15.5", - "indexmap 2.12.1", + "indexmap 2.13.0", "memchr", "ruzstd", ] @@ -2913,7 +2913,7 @@ dependencies = [ "crc32fast", "flate2", "hashbrown 0.16.1", - "indexmap 2.12.1", + "indexmap 2.13.0", "memchr", "ruzstd", ] @@ -3015,6 +3015,21 @@ dependencies = [ "serde", ] +[[package]] +name = "p3-bn254-fr" +version = "0.3.1-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebf15b2e55afdfc5ef84bb0a2508a96a924f3d86b8b616053ee727293a02121d" +dependencies = [ + "ff 0.13.1", + "num-bigint 0.4.6", + "p3-field 0.3.1-succinct", + "p3-poseidon2 0.3.1-succinct", + "p3-symmetric 0.3.1-succinct", + "rand 0.8.5", + "serde", +] + [[package]] name = "p3-challenger" version = "0.1.0" @@ -3028,13 +3043,27 @@ dependencies = [ "tracing", ] +[[package]] +name = "p3-challenger" +version = "0.3.1-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b647fe6cb51bb873d09aab77cecf3afe38bd94284fc14d04d57d52f0d26666" +dependencies = [ + "p3-field 0.3.1-succinct", + "p3-maybe-rayon 0.3.1-succinct", + "p3-symmetric 0.3.1-succinct", + "p3-util 0.3.1-succinct", + "serde", + "tracing", +] + [[package]] name = "p3-commit" version = "0.1.0" source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" dependencies = [ "itertools 0.12.1", - "p3-challenger", + "p3-challenger 0.1.0", "p3-field 0.1.0", "p3-matrix 0.1.0", "p3-util 0.1.0", @@ -3066,6 +3095,19 @@ dependencies = [ "tracing", ] +[[package]] +name = "p3-dft" +version = "0.3.1-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8169aac0ed2575c6c44953a7fa162e3dd07f9a22021e36b4db9d8bd15a3373b8" +dependencies = [ + "p3-field 0.3.1-succinct", + "p3-matrix 0.3.1-succinct", + "p3-maybe-rayon 0.3.1-succinct", + "p3-util 0.3.1-succinct", + "tracing", +] + [[package]] name = "p3-field" version = "0.1.0" @@ -3093,13 +3135,27 @@ dependencies = [ "serde", ] +[[package]] +name = "p3-field" +version = "0.3.1-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f82ed2dfd1e7d6e8759a9605c71b8a2a543069017dfdb6dafe71e7a2ccca937" +dependencies = [ + "itertools 0.12.1", + "num-bigint 0.4.6", + "num-traits", + "p3-util 0.3.1-succinct", + "rand 0.8.5", + "serde", +] + [[package]] name = "p3-fri" version = "0.1.0" source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" dependencies = [ "itertools 0.12.1", - "p3-challenger", + "p3-challenger 0.1.0", "p3-commit", "p3-dft 0.1.0", "p3-field 0.1.0", @@ -3148,6 +3204,21 @@ dependencies = [ "serde", ] +[[package]] +name = "p3-koala-bear" +version = "0.3.1-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60e2d5bc3601f6115afd9a55a718bdab49e98d44710438008204d2084d5d70d0" +dependencies = [ + "num-bigint 0.4.6", + "p3-field 0.3.1-succinct", + "p3-mds 0.3.1-succinct", + "p3-poseidon2 0.3.1-succinct", + "p3-symmetric 0.3.1-succinct", + "rand 0.8.5", + "serde", +] + [[package]] name = "p3-matrix" version = "0.1.0" @@ -3177,6 +3248,21 @@ dependencies = [ "tracing", ] +[[package]] +name = "p3-matrix" +version = "0.3.1-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ef05490e47c906f102e08493986b1d3c6b6e2c6be9937eaab2c970ccf5385e8" +dependencies = [ + "itertools 0.12.1", + "p3-field 0.3.1-succinct", + "p3-maybe-rayon 0.3.1-succinct", + "p3-util 0.3.1-succinct", + "rand 0.8.5", + "serde", + "tracing", +] + [[package]] name = "p3-maybe-rayon" version = "0.1.0" @@ -3191,6 +3277,12 @@ version = "0.2.3-succinct" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3968ad1160310296eb04f91a5f4edfa38fe1d6b2b8cd6b5c64e6f9b7370979e" +[[package]] +name = "p3-maybe-rayon" +version = "0.3.1-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d38c20290b92011f12a3fc040a999197e71e1663614998393a24aee4d430da" + [[package]] name = "p3-mds" version = "0.1.0" @@ -3220,6 +3312,21 @@ dependencies = [ "rand 0.8.5", ] +[[package]] +name = "p3-mds" +version = "0.3.1-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b707ec6432a15661ce67e5fc3abb1c2653e0064030d99c8cece4a049b31ebb1a" +dependencies = [ + "itertools 0.12.1", + "p3-dft 0.3.1-succinct", + "p3-field 0.3.1-succinct", + "p3-matrix 0.3.1-succinct", + "p3-symmetric 0.3.1-succinct", + "p3-util 0.3.1-succinct", + "rand 0.8.5", +] + [[package]] name = "p3-merkle-tree" version = "0.1.0" @@ -3263,6 +3370,20 @@ dependencies = [ "serde", ] +[[package]] +name = "p3-poseidon2" +version = "0.3.1-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9c6dbf170a3fb4d7556023315a525e08c4b94b572bc307eadbf9065bddaf489" +dependencies = [ + "gcd", + "p3-field 0.3.1-succinct", + "p3-mds 0.3.1-succinct", + "p3-symmetric 0.3.1-succinct", + "rand 0.8.5", + "serde", +] + [[package]] name = "p3-symmetric" version = "0.1.0" @@ -3284,6 +3405,17 @@ dependencies = [ "serde", ] +[[package]] +name = "p3-symmetric" +version = "0.3.1-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7ec3a99c3dc3d55d0e78ef7041e0d90bdfbf03451e4f0bae3f9877af99cabb3" +dependencies = [ + "itertools 0.12.1", + "p3-field 0.3.1-succinct", + "serde", +] + [[package]] name = "p3-uni-stark" version = "0.1.0" @@ -3291,7 +3423,7 @@ source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb9 dependencies = [ "itertools 0.12.1", "p3-air", - "p3-challenger", + "p3-challenger 0.1.0", "p3-commit", "p3-dft 0.1.0", "p3-field 0.1.0", @@ -3319,6 +3451,15 @@ dependencies = [ "serde", ] +[[package]] +name = "p3-util" +version = "0.3.1-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712473f2a848b672eee90c3b9cd4bfcd3da042112c53a0dc6b088fc3964538ab" +dependencies = [ + "serde", +] + [[package]] name = "pairing" version = "0.22.0" @@ -3435,7 +3576,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" dependencies = [ "fixedbitset", - "indexmap 2.12.1", + "indexmap 2.13.0", ] [[package]] @@ -4035,7 +4176,7 @@ dependencies = [ "bitflags 1.3.2", "libc", "mach2 0.4.3", - "sp1-primitives 6.0.0", + "sp1-primitives 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "sp1-zkvm", "windows-sys 0.52.0", ] @@ -4132,7 +4273,7 @@ dependencies = [ "bytecheck", "bytes", "hashbrown 0.15.5", - "indexmap 2.12.1", + "indexmap 2.13.0", "munge", "ptr_meta", "rancor", @@ -4508,7 +4649,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.12.1", + "indexmap 2.13.0", "schemars 0.9.0", "schemars 1.1.0", "serde_core", @@ -4673,6 +4814,17 @@ dependencies = [ "p3-air", ] +[[package]] +name = "slop-algebra" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c99cdaa39f7db4823cf18938544a135f20bf779eb4b3561652a72ba07ac3c41" +dependencies = [ + "itertools 0.14.0", + "p3-field 0.3.1-succinct", + "serde", +] + [[package]] name = "slop-algebra" version = "6.0.0" @@ -4689,7 +4841,7 @@ version = "6.0.0" source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ "serde", - "slop-algebra", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "thiserror 1.0.69", ] @@ -4701,10 +4853,10 @@ dependencies = [ "lazy_static", "p3-baby-bear 0.1.0", "serde", - "slop-algebra", - "slop-challenger", - "slop-poseidon2", - "slop-symmetric", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-poseidon2 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", ] [[package]] @@ -4715,15 +4867,15 @@ dependencies = [ "derive-where", "itertools 0.13.0", "serde", - "slop-algebra", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-alloc", "slop-baby-bear", - "slop-bn254", - "slop-challenger", - "slop-koala-bear", + "slop-bn254 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-koala-bear 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-merkle-tree", "slop-multilinear", - "slop-primitives", + "slop-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-tensor", "slop-utils", "thiserror 1.0.69", @@ -4738,17 +4890,17 @@ dependencies = [ "itertools 0.13.0", "rand 0.8.5", "serde", - "slop-algebra", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-alloc", "slop-baby-bear", "slop-basefold", - "slop-bn254", - "slop-challenger", + "slop-bn254 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-commit", "slop-dft", "slop-fri", "slop-futures", - "slop-koala-bear", + "slop-koala-bear 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-merkle-tree", "slop-multilinear", "slop-tensor", @@ -4756,31 +4908,60 @@ dependencies = [ "tokio", ] +[[package]] +name = "slop-bn254" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce30d587559808f7a984ea96af231de14f8f793836300347d1ee13d28e194ad" +dependencies = [ + "ff 0.13.1", + "p3-bn254-fr 0.3.1-succinct", + "serde", + "slop-algebra 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slop-challenger 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slop-poseidon2 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slop-symmetric 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "zkhash", +] + [[package]] name = "slop-bn254" version = "6.0.0" source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ "ff 0.13.1", - "p3-bn254-fr", + "p3-bn254-fr 0.1.0", "serde", - "slop-algebra", - "slop-challenger", - "slop-poseidon2", - "slop-symmetric", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-poseidon2 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "zkhash", ] +[[package]] +name = "slop-challenger" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15fed3b1414bd79c56a21e3ac75c5b549003a0d8f715eb501000d4ac3d7b8a9f" +dependencies = [ + "futures", + "p3-challenger 0.3.1-succinct", + "serde", + "slop-algebra 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slop-symmetric 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "slop-challenger" version = "6.0.0" source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ "futures", - "p3-challenger", + "p3-challenger 0.1.0", "serde", - "slop-algebra", - "slop-symmetric", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", ] [[package]] @@ -4800,7 +4981,7 @@ source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b21 dependencies = [ "p3-dft 0.1.0", "serde", - "slop-algebra", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-alloc", "slop-matrix", "slop-tensor", @@ -4840,21 +5021,21 @@ dependencies = [ "rand 0.8.5", "rayon", "serde", - "slop-algebra", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-alloc", "slop-baby-bear", "slop-basefold", "slop-basefold-prover", - "slop-bn254", - "slop-challenger", + "slop-bn254 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-commit", "slop-futures", - "slop-koala-bear", + "slop-koala-bear 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-merkle-tree", "slop-multilinear", "slop-stacked", "slop-sumcheck", - "slop-symmetric", + "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-tensor", "slop-utils", "thiserror 1.0.69", @@ -4870,18 +5051,33 @@ dependencies = [ "p3-keccak-air", ] +[[package]] +name = "slop-koala-bear" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "402c403f847e811a788882c7c5ee018ab7076c8bafbf4f46f569fe97f44610d1" +dependencies = [ + "lazy_static", + "p3-koala-bear 0.3.1-succinct", + "serde", + "slop-algebra 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slop-challenger 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slop-poseidon2 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slop-symmetric 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "slop-koala-bear" version = "6.0.0" source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ "lazy_static", - "p3-koala-bear", + "p3-koala-bear 0.1.0", "serde", - "slop-algebra", - "slop-challenger", - "slop-poseidon2", - "slop-symmetric", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-poseidon2 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", ] [[package]] @@ -4910,17 +5106,17 @@ dependencies = [ "itertools 0.13.0", "p3-merkle-tree", "serde", - "slop-algebra", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-alloc", "slop-baby-bear", - "slop-bn254", - "slop-challenger", + "slop-bn254 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-commit", "slop-futures", - "slop-koala-bear", + "slop-koala-bear 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-matrix", - "slop-poseidon2", - "slop-symmetric", + "slop-poseidon2 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-tensor", "thiserror 1.0.69", "tokio", @@ -4938,9 +5134,9 @@ dependencies = [ "rand 0.8.5", "rayon", "serde", - "slop-algebra", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-alloc", - "slop-challenger", + "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-commit", "slop-futures", "slop-matrix", @@ -4948,6 +5144,15 @@ dependencies = [ "tokio", ] +[[package]] +name = "slop-poseidon2" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bc5ba869130dd0711cf7bd54f93785cd566b5c71201f38801fa3f500d508cc4" +dependencies = [ + "p3-poseidon2 0.3.1-succinct", +] + [[package]] name = "slop-poseidon2" version = "6.0.0" @@ -4956,12 +5161,21 @@ dependencies = [ "p3-poseidon2 0.1.0", ] +[[package]] +name = "slop-primitives" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "786111f9498e8d465b39cfef062297ef4e9b688f250a39abdafaca08e772b56c" +dependencies = [ + "slop-algebra 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "slop-primitives" version = "6.0.0" source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ - "slop-algebra", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", ] [[package]] @@ -4973,11 +5187,11 @@ dependencies = [ "futures", "itertools 0.13.0", "serde", - "slop-algebra", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-alloc", "slop-basefold", "slop-basefold-prover", - "slop-challenger", + "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-commit", "slop-futures", "slop-merkle-tree", @@ -4996,14 +5210,23 @@ dependencies = [ "itertools 0.13.0", "rayon", "serde", - "slop-algebra", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-alloc", "slop-baby-bear", - "slop-challenger", + "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-multilinear", "thiserror 1.0.69", ] +[[package]] +name = "slop-symmetric" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c41115c944fdb8eec425d4515cbc1649852ab4ddcc6be67a069c8d2aa5205209" +dependencies = [ + "p3-symmetric 0.3.1-succinct", +] + [[package]] name = "slop-symmetric" version = "6.0.0" @@ -5023,7 +5246,7 @@ dependencies = [ "rand 0.8.5", "rayon", "serde", - "slop-algebra", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-alloc", "slop-futures", "slop-matrix", @@ -5061,15 +5284,15 @@ dependencies = [ "rand 0.8.5", "rayon", "serde", - "slop-algebra", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-alloc", "slop-baby-bear", "slop-basefold", - "slop-challenger", + "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-commit", "slop-dft", "slop-jagged", - "slop-koala-bear", + "slop-koala-bear 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-matrix", "slop-merkle-tree", "slop-multilinear", @@ -5128,7 +5351,7 @@ dependencies = [ "chrono", "clap", "dirs", - "sp1-primitives 6.0.0", + "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", ] [[package]] @@ -5171,13 +5394,13 @@ dependencies = [ "serde_arrays", "serde_json", "slop-air", - "slop-algebra", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-maybe-rayon", - "slop-symmetric", + "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "sp1-curves", "sp1-hypercube", "sp1-jit", - "sp1-primitives 6.0.0", + "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "strum", "subenum", "thiserror 1.0.69", @@ -5207,8 +5430,8 @@ dependencies = [ "serde", "serde_json", "slop-air", - "slop-algebra", - "slop-challenger", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-futures", "slop-keccak-air", "slop-matrix", @@ -5220,7 +5443,7 @@ dependencies = [ "sp1-derive", "sp1-hypercube", "sp1-jit", - "sp1-primitives 6.0.0", + "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "static_assertions", "strum", "sysinfo", @@ -5246,7 +5469,7 @@ dependencies = [ "serde_json", "sp1-core-executor", "sp1-core-machine", - "sp1-primitives 6.0.0", + "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "sp1-prover", "sp1-prover-types", "thiserror 1.0.69", @@ -5268,9 +5491,9 @@ dependencies = [ "num", "p256", "serde", - "slop-algebra", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "snowbridge-amcl", - "sp1-primitives 6.0.0", + "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "typenum", ] @@ -5302,27 +5525,27 @@ dependencies = [ "rayon-scan", "serde", "slop-air", - "slop-algebra", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-alloc", "slop-basefold", "slop-basefold-prover", - "slop-challenger", + "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-commit", "slop-futures", "slop-jagged", - "slop-koala-bear", + "slop-koala-bear 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-matrix", "slop-merkle-tree", "slop-multilinear", - "slop-poseidon2", + "slop-poseidon2 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-stacked", "slop-sumcheck", - "slop-symmetric", + "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-tensor", "slop-uni-stark", "slop-whir", "sp1-derive", - "sp1-primitives 6.0.0", + "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "strum", "thiserror 1.0.69", "thousands", @@ -5340,7 +5563,7 @@ dependencies = [ "memfd", "memmap2 0.9.9", "serde", - "sp1-primitives 6.0.0", + "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "tracing", "uuid", ] @@ -5360,12 +5583,23 @@ dependencies = [ [[package]] name = "sp1-lib" version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53f179ca7ad5d0d0ca36356ef2c4851eea02226cd409e4b414e4379d79582f11" dependencies = [ "bincode", "elliptic-curve", "serde", - "sp1-primitives 6.0.0", + "sp1-primitives 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sp1-lib" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "bincode", + "serde", + "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", ] [[package]] @@ -5388,6 +5622,30 @@ dependencies = [ "sha2", ] +[[package]] +name = "sp1-primitives" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bda0eaba853f3c162e6b62dc8eb25f25100ee0792f59919ef905811809e81e5" +dependencies = [ + "bincode", + "blake3", + "elf", + "hex", + "itertools 0.14.0", + "lazy_static", + "num-bigint 0.4.6", + "serde", + "sha2", + "slop-algebra 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slop-bn254 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slop-challenger 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slop-koala-bear 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slop-poseidon2 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slop-primitives 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slop-symmetric 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "sp1-primitives" version = "6.0.0" @@ -5402,13 +5660,13 @@ dependencies = [ "num-bigint 0.4.6", "serde", "sha2", - "slop-algebra", - "slop-bn254", - "slop-challenger", - "slop-koala-bear", - "slop-poseidon2", - "slop-primitives", - "slop-symmetric", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-bn254 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-koala-bear 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-poseidon2 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", ] [[package]] @@ -5441,21 +5699,21 @@ dependencies = [ "serial_test", "sha2", "slop-air", - "slop-algebra", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-basefold", - "slop-bn254", - "slop-challenger", + "slop-bn254 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-futures", "slop-jagged", "slop-multilinear", "slop-stacked", - "slop-symmetric", + "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "sp1-core-executor", "sp1-core-machine", "sp1-derive", "sp1-hypercube", "sp1-jit", - "sp1-primitives 6.0.0", + "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "sp1-prover-types", "sp1-recursion-circuit", "sp1-recursion-compiler", @@ -5504,28 +5762,28 @@ dependencies = [ "rayon", "serde", "slop-air", - "slop-algebra", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-alloc", "slop-basefold", "slop-basefold-prover", - "slop-bn254", - "slop-challenger", + "slop-bn254 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-commit", "slop-jagged", - "slop-koala-bear", + "slop-koala-bear 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-matrix", "slop-merkle-tree", "slop-multilinear", "slop-stacked", "slop-sumcheck", - "slop-symmetric", + "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-tensor", "slop-whir", "sp1-core-executor", "sp1-core-machine", "sp1-derive", "sp1-hypercube", - "sp1-primitives 6.0.0", + "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "sp1-recursion-compiler", "sp1-recursion-executor", "sp1-recursion-machine", @@ -5541,12 +5799,12 @@ dependencies = [ "cfg-if", "itertools 0.13.0", "serde", - "slop-algebra", - "slop-bn254", - "slop-symmetric", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-bn254 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "sp1-core-machine", "sp1-hypercube", - "sp1-primitives 6.0.0", + "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "sp1-recursion-executor", "tracing", "vec_map", @@ -5563,10 +5821,10 @@ dependencies = [ "itertools 0.13.0", "range-set-blaze", "serde", - "slop-algebra", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-maybe-rayon", - "slop-poseidon2", - "slop-symmetric", + "slop-poseidon2 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "smallvec", "sp1-derive", "sp1-hypercube", @@ -5589,10 +5847,10 @@ dependencies = [ "serde", "serde_json", "sha2", - "slop-algebra", - "slop-symmetric", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "sp1-hypercube", - "sp1-primitives 6.0.0", + "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "sp1-recursion-compiler", "sp1-verifier", "tempfile", @@ -5607,14 +5865,14 @@ dependencies = [ "itertools 0.13.0", "rand 0.8.5", "slop-air", - "slop-algebra", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-basefold", "slop-matrix", "slop-maybe-rayon", - "slop-symmetric", + "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "sp1-derive", "sp1-hypercube", - "sp1-primitives 6.0.0", + "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "sp1-recursion-executor", "strum", "tracing", @@ -5654,13 +5912,13 @@ dependencies = [ "k256 0.13.4 (registry+https://github.com/rust-lang/crates.io-index)", "num-bigint 0.4.6", "serde", - "slop-algebra", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "sp1-build", "sp1-core-executor", "sp1-core-machine", "sp1-cuda", "sp1-hypercube", - "sp1-primitives 6.0.0", + "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "sp1-prover", "sp1-prover-types", "sp1-recursion-executor", @@ -5686,11 +5944,11 @@ dependencies = [ "lazy_static", "serde", "sha2", - "slop-algebra", - "slop-primitives", - "slop-symmetric", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "sp1-hypercube", - "sp1-primitives 6.0.0", + "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "sp1-recursion-executor", "sp1-recursion-machine", "strum", @@ -5712,8 +5970,8 @@ dependencies = [ "libm", "rand 0.8.5", "sha2", - "sp1-lib 6.0.0", - "sp1-primitives 6.0.0", + "sp1-lib 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", ] [[package]] @@ -6028,7 +6286,7 @@ source = "git+https://github.com/sp1-patches/tiny-keccak?tag=patch-2.0.2-sp1-6.0 dependencies = [ "cfg-if", "crunchy", - "sp1-lib 6.0.0", + "sp1-lib 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6138,7 +6396,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.12.1", + "indexmap 2.13.0", "toml_datetime 0.6.11", "winnow 0.5.40", ] @@ -6149,7 +6407,7 @@ version = "0.23.10+spec-1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" dependencies = [ - "indexmap 2.12.1", + "indexmap 2.13.0", "toml_datetime 0.7.5+spec-1.1.0", "toml_parser", "winnow 0.7.14", @@ -6605,7 +6863,7 @@ dependencies = [ "cfg-if", "cmake", "derive_more 2.1.0", - "indexmap 2.12.1", + "indexmap 2.13.0", "js-sys", "more-asserts", "paste", @@ -6726,7 +6984,7 @@ dependencies = [ "enumset", "getrandom 0.2.16", "hex", - "indexmap 2.12.1", + "indexmap 2.13.0", "more-asserts", "rkyv", "sha2", @@ -6748,7 +7006,7 @@ dependencies = [ "dashmap", "enum-iterator", "fnv", - "indexmap 2.12.1", + "indexmap 2.13.0", "libc", "libunwind", "mach2 0.6.0", @@ -6770,7 +7028,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9dbe55c8f9d0dbd25d9447a5a889ff90c0cc3feaa7395310d3d826b2c703eaab" dependencies = [ "bitflags 2.10.0", - "indexmap 2.12.1", + "indexmap 2.13.0", "semver", ] @@ -6782,7 +7040,7 @@ checksum = "04f17a5917c2ddd3819e84c661fae0d6ba29d7b9c1f0e96c708c65a9c4188e11" dependencies = [ "bitflags 2.10.0", "hashbrown 0.15.5", - "indexmap 2.12.1", + "indexmap 2.13.0", "semver", "serde", ] diff --git a/sp1-crates/Cargo.toml b/sp1-crates/Cargo.toml index cd7210acd4e..9cdd3db85f0 100644 --- a/sp1-crates/Cargo.toml +++ b/sp1-crates/Cargo.toml @@ -6,8 +6,6 @@ members = ["program", "builder", "stylus-compiler-program", "prover", "runner"] [workspace.dependencies] sp1-build = { version = "6.0.0", features = ["may_dump_elf"] } sp1-core-executor = "6.0.0" -sp1-lib = "6.0.0" -sp1-primitives = "6.0.0" sp1-sdk = { version = "6.0.0", features = ["profiling"] } sp1-zkvm = { version = "6.0.0", features = ["untrusted_programs", "may_dump_elf"] } @@ -78,7 +76,5 @@ which = { git = "https://github.com/wakabat/which-rs", branch = "patch-v8.0.0" } sp1-build = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe" } sp1-core-executor = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe" } -sp1-lib = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe" } -sp1-primitives = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe" } sp1-sdk = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe" } sp1-zkvm = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe" } From f956f0ccf378ffa8db4596cf5fa1b3c909f87526 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 13 Feb 2026 17:14:21 +0100 Subject: [PATCH 028/189] Tidy up workspace deps --- sp1-crates/Cargo.toml | 89 +++++++++++++++++-------------------------- 1 file changed, 34 insertions(+), 55 deletions(-) diff --git a/sp1-crates/Cargo.toml b/sp1-crates/Cargo.toml index 9cdd3db85f0..b04716b9f9d 100644 --- a/sp1-crates/Cargo.toml +++ b/sp1-crates/Cargo.toml @@ -4,69 +4,48 @@ resolver = "3" members = ["program", "builder", "stylus-compiler-program", "prover", "runner"] [workspace.dependencies] -sp1-build = { version = "6.0.0", features = ["may_dump_elf"] } -sp1-core-executor = "6.0.0" -sp1-sdk = { version = "6.0.0", features = ["profiling"] } -sp1-zkvm = { version = "6.0.0", features = ["untrusted_programs", "may_dump_elf"] } - arbutil = { path = "../crates/arbutil" } prover = { path = "prover", default-features = false, features = ["sp1"] } -bincode = "1.3.3" -bytes = "1" +bincode = { version = "1.3.3" } +bytes = { version = "1" } clap = { version = "4.5.53", features = ["cargo", "derive"] } -corosensei = "0.3.0" -derivative = "2.2.0" -digest = "0.10.7" -eyre = "0.6.5" -fnv = "1.0.7" -hex = "0.4.3" -lazy_static = "1.4.0" -nom = "7.0.0" -num-derive = "0.4.1" -num-traits = "0.2.17" -num_enum = "0.7.1" -once_cell = "1.21.3" -parking_lot = "0.12.1" -rand_pcg = { version = "0.3.1", default-features = false } +corosensei = { version = "0.3.0" } +derivative = { version = "2.2.0" } +digest = { version = "0.10.7" } +eyre = { version = "0.6.5" } +fnv = { version = "1.0.7" } +hex = { version = "0.4.3" } +lazy_static = { version = "1.4.0" } +nom = { version = "7.0.0" } +num-derive = { version = "0.4.1" } +num-traits = { version = "0.2.17" } +num_enum = { version = "0.7.1" } +once_cell = { version = "1.21.3" } +parking_lot = { version = "0.12.1" } rand = { version = "0.8.4", default-features = false } +rand_pcg = { version = "0.3.1", default-features = false } rkyv = { version = "0.8.8", features = ["indexmap-2", "bytes-1"] } -ruint2 = "1.9.0" -tracing = "0.1.40" -tokio = "1.42.0" -serde = "1.0.130" -serde_json = "1.0.67" -serde_with = "3.8.1" -sha3 = "0.10.8" -thiserror = "1.0.33" -wasmparser = "0.224.0" +ruint2 = { version = "1.9.0" } +serde = { version = "1.0.130" } +serde_json = { version = "1.0.67" } +serde_with = { version = "3.8.1" } +sha3 = { version = "0.10.8" } +sp1-build = { version = "6.0.0", features = ["may_dump_elf"] } +sp1-core-executor = { version = "6.0.0" } +sp1-sdk = { version = "6.0.0", features = ["profiling"] } +sp1-zkvm = { version = "6.0.0", features = ["untrusted_programs", "may_dump_elf"] } +thiserror = { version = "1.0.33" } +tokio = { version = "1.42.0" } +tracing = { version = "0.1.40" } +wasmparser = { version = "0.224.0" } brotli = { git = "https://github.com/wakabat/rust-brotli", rev = "37b6403" } - -[workspace.dependencies.secp256k1] -git = "https://github.com/sp1-patches/rust-secp256k1" -tag = "patch-0.29.1-sp1-6.0.0" -features = [ "recovery", "global-context" ] - -[workspace.dependencies.tiny-keccak] -git = "https://github.com/sp1-patches/tiny-keccak" -tag = "patch-2.0.2-sp1-6.0.0" -features = ["keccak"] - -[workspace.dependencies.wasmer] -git = "https://github.com/wakabat/official-wasmer" -rev = "e065880" -default-features = false -features = ["sys", "compiler", "singlepass", "wasmparser"] - -[workspace.dependencies.wasmer-types] -git = "https://github.com/wakabat/official-wasmer" -rev = "e065880" - -[workspace.dependencies.wasmer-vm] -git = "https://github.com/wakabat/official-wasmer" -rev = "e065880" -features = ["force-baremetal"] +secp256k1 = { git = "https://github.com/sp1-patches/rust-secp256k1", tag = "patch-0.29.1-sp1-6.0.0", features = ["recovery", "global-context"] } +tiny-keccak = { git = "https://github.com/sp1-patches/tiny-keccak", tag = "patch-2.0.2-sp1-6.0.0", features = ["keccak"] } +wasmer = { git = "https://github.com/wakabat/official-wasmer", rev = "e065880", default-features = false, features = ["sys", "compiler", "singlepass", "wasmparser"] } +wasmer-types = { git = "https://github.com/wakabat/official-wasmer", rev = "e065880" } +wasmer-vm = { git = "https://github.com/wakabat/official-wasmer", rev = "e065880", features = ["force-baremetal"] } [patch.crates-io] target-lexicon = { git = "https://github.com/wakabat/target-lexicon", branch = "patch-v0.13.3" } From 797cdc73fc900a99d7a4e88066fabff254e1688c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Mon, 16 Feb 2026 16:41:54 +0100 Subject: [PATCH 029/189] Add validation to dependencies --- sp1-crates/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/sp1-crates/Cargo.toml b/sp1-crates/Cargo.toml index b04716b9f9d..ac87d7429ee 100644 --- a/sp1-crates/Cargo.toml +++ b/sp1-crates/Cargo.toml @@ -6,6 +6,7 @@ members = ["program", "builder", "stylus-compiler-program", "prover", "runner"] [workspace.dependencies] arbutil = { path = "../crates/arbutil" } prover = { path = "prover", default-features = false, features = ["sp1"] } +validation = { path = "../crates/validation" } bincode = { version = "1.3.3" } bytes = { version = "1" } From 14ae0702a37994301eb6675c98d8f6ad6d8c9d71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Mon, 16 Feb 2026 16:50:47 +0100 Subject: [PATCH 030/189] Use validation crate for the input reading --- arbitrator/prover/src/parse_input.rs | 121 -------------------------- sp1-crates/Cargo.lock | 27 +++++- sp1-crates/prover/Cargo.toml | 4 +- sp1-crates/prover/src/binary_input.rs | 22 +++-- sp1-crates/prover/src/lib.rs | 2 - sp1-crates/runner/Cargo.toml | 1 + sp1-crates/runner/src/main.rs | 6 +- 7 files changed, 38 insertions(+), 145 deletions(-) delete mode 100644 arbitrator/prover/src/parse_input.rs diff --git a/arbitrator/prover/src/parse_input.rs b/arbitrator/prover/src/parse_input.rs deleted file mode 100644 index 334f0864b53..00000000000 --- a/arbitrator/prover/src/parse_input.rs +++ /dev/null @@ -1,121 +0,0 @@ -use arbutil::Bytes32; -use serde::Deserialize; -use serde_json; -use serde_with::As; -use serde_with::DisplayFromStr; -use serde_with::base64::Base64; -use std::{ - collections::HashMap, - io::{self, BufRead}, -}; - -/// prefixed_hex deserializes hex strings which are prefixed with `0x` -/// -/// The default hex deserializer does not support prefixed hex strings. -/// -/// It is an error to use this deserializer on a string that does not -/// begin with `0x`. -mod prefixed_hex { - use serde::{self, Deserialize, Deserializer}; - - pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> - where - D: Deserializer<'de>, - { - let s = String::deserialize(deserializer)?; - if let Some(s) = s.strip_prefix("0x") { - hex::decode(s).map_err(serde::de::Error::custom) - } else { - Err(serde::de::Error::custom("missing 0x prefix")) - } - } -} - -#[derive(Debug)] -pub struct UserWasm(Vec); - -/// UserWasm is a wrapper around Vec -/// -/// It is useful for decompressing a brotli-compressed wasm module. -/// -/// Note: The wrapped Vec is already Base64 decoded before -/// from(Vec) is called by serde. -impl UserWasm { - /// as_vec returns the decompressed wasm module as a Vec - pub fn as_vec(&self) -> Vec { - self.0.clone() - } -} - -impl AsRef<[u8]> for UserWasm { - fn as_ref(&self) -> &[u8] { - &self.0 - } -} - -/// The Vec is compressed using brotli, and must be decompressed before use. -#[cfg(not(feature = "sp1"))] -impl From> for UserWasm { - fn from(data: Vec) -> Self { - let decompressed = brotli::decompress(&data, brotli::Dictionary::Empty).unwrap(); - Self(decompressed) - } -} - -/// Due to alignment reason, we will do the decompression elsewhere in SP1. -#[cfg(feature = "sp1")] -impl From> for UserWasm { - fn from(data: Vec) -> Self { - Self(data) - } -} - -#[derive(Debug, Clone, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct BatchInfo { - pub number: u64, - #[serde(with = "As::")] - pub data_b64: Vec, -} - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct StartState { - #[serde(with = "prefixed_hex")] - pub block_hash: Vec, - #[serde(with = "prefixed_hex")] - pub send_root: Vec, - pub batch: u64, - pub pos_in_batch: u64, -} - -/// FileData is the deserialized form of the input JSON file. -/// -/// The go JSON library in json.go uses some custom serialization and -/// compression logic that needs to be reversed when deserializing the -/// JSON in rust. -/// -/// Note: It is important to change this file whenever the go JSON -/// serialization changes. -#[derive(Debug, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct FileData { - pub id: u64, - pub has_delayed_msg: bool, - pub delayed_msg_nr: u64, - #[serde(with = "As::>>")] - pub preimages_b64: HashMap>>, - pub batch_info: Vec, - #[serde(with = "As::")] - pub delayed_msg_b64: Vec, - pub start_state: StartState, - #[serde(with = "As::>>")] - pub user_wasms: HashMap>, -} - -impl FileData { - pub fn from_reader(mut reader: R) -> io::Result { - let data = serde_json::from_reader(&mut reader)?; - Ok(data) - } -} diff --git a/sp1-crates/Cargo.lock b/sp1-crates/Cargo.lock index 610b3826f6e..76473560f42 100644 --- a/sp1-crates/Cargo.lock +++ b/sp1-crates/Cargo.lock @@ -517,6 +517,14 @@ dependencies = [ "subtle", ] +[[package]] +name = "brotli" +version = "0.1.0" +dependencies = [ + "lazy_static", + "num_enum 0.7.5", +] + [[package]] name = "brotli" version = "8.0.1" @@ -3768,7 +3776,7 @@ name = "program" version = "0.1.0" dependencies = [ "arbutil", - "brotli", + "brotli 8.0.1", "bytes", "corosensei", "eyre", @@ -3848,13 +3856,12 @@ name = "prover" version = "0.1.0" dependencies = [ "arbutil", - "brotli", + "brotli 8.0.1", "bytes", "derivative", "digest", "eyre", "fnv", - "hex", "lazy_static", "nom", "num-derive", @@ -3862,9 +3869,9 @@ dependencies = [ "parking_lot", "rkyv", "serde", - "serde_json", "serde_with", "sha3", + "validation", "wasmer", "wasmer-types", "wasmparser 0.224.1", @@ -5892,6 +5899,7 @@ dependencies = [ "sp1-sdk", "tokio", "tracing", + "validation", ] [[package]] @@ -6737,6 +6745,17 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "validation" +version = "0.1.0" +dependencies = [ + "arbutil", + "brotli 0.1.0", + "serde", + "serde_json", + "serde_with", +] + [[package]] name = "valuable" version = "0.1.1" diff --git a/sp1-crates/prover/Cargo.toml b/sp1-crates/prover/Cargo.toml index d922538f659..a6059457ba5 100644 --- a/sp1-crates/prover/Cargo.toml +++ b/sp1-crates/prover/Cargo.toml @@ -11,18 +11,16 @@ derivative = { workspace = true } digest = { workspace = true } eyre = { workspace = true } fnv = { workspace = true } -hex = { workspace = true } lazy_static = { workspace = true } nom = { workspace = true } num-derive = { workspace = true } num-traits = { workspace = true } parking_lot = { workspace = true } serde = { workspace = true, features = ["derive", "rc"] } -serde_json = { workspace = true } serde_with = { workspace = true, features = ["base64"] } sha3 = { workspace = true } rkyv = { workspace = true } - +validation = { workspace = true } wasmer = { workspace = true, optional = true } wasmer-types = { workspace = true, optional = true } wasmparser = { workspace = true, optional = true } diff --git a/sp1-crates/prover/src/binary_input.rs b/sp1-crates/prover/src/binary_input.rs index 3330b3e1eea..fc8f2d62d5d 100644 --- a/sp1-crates/prover/src/binary_input.rs +++ b/sp1-crates/prover/src/binary_input.rs @@ -1,9 +1,9 @@ -use crate::parse_input::{FileData, UserWasm}; use bytes::{Bytes, BytesMut}; use std::{ collections::{BTreeMap, HashMap}, io::Read, }; +use validation::{UserWasm, ValidationInput}; /// This groups components in Arbitrum's WasmEnv that come from FileData. /// It helps us maintain a clear separation between Arbitrum inputs, and other @@ -48,24 +48,22 @@ pub fn decompress_aligned(user_wasm: &UserWasm) -> ModuleAsm { impl Input { /// This takes hint from `arbitrator/jit/src/prepare.rs` - pub fn from_file_data(data: FileData) -> eyre::Result { - let block_hash: [u8; 32] = data.start_state.block_hash.try_into().unwrap(); - let send_root: [u8; 32] = data.start_state.send_root.try_into().unwrap(); - let bytes32_vals: [[u8; 32]; 2] = [block_hash, send_root]; - let u64_vals: [u64; 2] = [data.start_state.batch, data.start_state.pos_in_batch]; + pub fn from_file_data(data: ValidationInput) -> eyre::Result { + let large_globals = [data.start_state.block_hash.0, data.start_state.send_root.0]; + let small_globals = [data.start_state.batch, data.start_state.pos_in_batch]; let mut sequencer_messages = Inbox::default(); for batch_info in data.batch_info.iter() { - sequencer_messages.insert(batch_info.number, batch_info.data_b64.clone()); + sequencer_messages.insert(batch_info.number, batch_info.data.clone()); } let mut delayed_messages = Inbox::default(); - if data.delayed_msg_nr != 0 && !data.delayed_msg_b64.is_empty() { - delayed_messages.insert(data.delayed_msg_nr, data.delayed_msg_b64.clone()); + if data.delayed_msg_nr != 0 && !data.delayed_msg.is_empty() { + delayed_messages.insert(data.delayed_msg_nr, data.delayed_msg.clone()); } let mut preimages = Preimages::default(); - for (preimage_ty, inner_map) in data.preimages_b64 { + for (preimage_ty, inner_map) in data.preimages { let map = preimages.entry(preimage_ty as u8).or_default(); for (hash, preimage) in inner_map { map.insert(*hash, preimage); @@ -80,8 +78,8 @@ impl Input { } Ok(Self { - small_globals: u64_vals, - large_globals: bytes32_vals, + small_globals, + large_globals, preimages, module_asms, sequencer_messages, diff --git a/sp1-crates/prover/src/lib.rs b/sp1-crates/prover/src/lib.rs index 63a98634204..5a9499d2339 100644 --- a/sp1-crates/prover/src/lib.rs +++ b/sp1-crates/prover/src/lib.rs @@ -9,8 +9,6 @@ #[cfg(feature = "native")] #[path = "../../../arbitrator/prover/src/binary.rs"] pub mod binary; -#[path = "../../../arbitrator/prover/src/parse_input.rs"] -pub mod parse_input; #[cfg(feature = "native")] #[path = "../../../arbitrator/prover/src/programs/mod.rs"] pub mod programs; diff --git a/sp1-crates/runner/Cargo.toml b/sp1-crates/runner/Cargo.toml index 1cd82f767f8..cea8bfb0bcd 100644 --- a/sp1-crates/runner/Cargo.toml +++ b/sp1-crates/runner/Cargo.toml @@ -8,6 +8,7 @@ edition = "2024" sp1-core-executor = { workspace = true } sp1-sdk = { workspace = true } prover = { workspace = true } +validation = { workspace = true } bincode = { workspace = true } clap = { workspace = true } diff --git a/sp1-crates/runner/src/main.rs b/sp1-crates/runner/src/main.rs index 6ce0fc22f71..c86804ff27e 100644 --- a/sp1-crates/runner/src/main.rs +++ b/sp1-crates/runner/src/main.rs @@ -1,7 +1,6 @@ use clap::{ArgAction, Parser, ValueEnum}; use prover::{ binary_input::{Input, decompress_aligned}, - parse_input::FileData, }; use sp1_core_executor::{MinimalExecutor, Program}; use sp1_sdk::{Elf, Prover, ProverClient, SP1Stdin}; @@ -9,6 +8,7 @@ use std::collections::HashMap; use std::ops::Deref; use std::sync::Arc; use std::time::SystemTime; +use validation::ValidationInput; #[derive(Debug, Parser)] #[command(version, about, long_about = None)] @@ -117,8 +117,8 @@ async fn main() { // Build SP1 input from Arbitrum block. It is serialized to Vec, so // we can easily inject debugging code to dump stdin when needed. fn build_input(cli: &Cli) -> Vec { - let file_data: FileData = - serde_json::from_slice(&std::fs::read(&cli.block_file).expect("read input block")) + let file_data = + serde_json::from_slice::(&std::fs::read(&cli.block_file).expect("read input block")) .expect("parse input block"); let mut module_asms = HashMap::default(); From c1dff918da4aa621bed0e66dd4290af84cad9079 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Mon, 16 Feb 2026 17:09:57 +0100 Subject: [PATCH 031/189] impl Send for ForceSync (seems to be required by new Rust) --- crates/brotli/src/dicts/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/brotli/src/dicts/mod.rs b/crates/brotli/src/dicts/mod.rs index 5945d59eaa5..db474317dfa 100644 --- a/crates/brotli/src/dicts/mod.rs +++ b/crates/brotli/src/dicts/mod.rs @@ -31,6 +31,7 @@ extern "C" { struct ForceSync(T); unsafe impl Sync for ForceSync {} +unsafe impl Send for ForceSync {} lazy_static! { /// Memoizes dictionary preperation. From 5c2c7a9c41bbebefebd2835bf9e8f888195fc4d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Mon, 16 Feb 2026 17:46:44 +0100 Subject: [PATCH 032/189] Update path from build.rs --- crates/brotli/build.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/brotli/build.rs b/crates/brotli/build.rs index 2f2f3fe5953..1f0913491cc 100644 --- a/crates/brotli/build.rs +++ b/crates/brotli/build.rs @@ -11,6 +11,7 @@ fn main() { println!("cargo:rustc-link-search=target/lib-wasm/"); } else { println!("cargo:rustc-link-search=target/lib/"); + println!("cargo:rustc-link-search=../../target/lib/"); } println!("cargo:rustc-link-lib=static=brotlienc-static"); println!("cargo:rustc-link-lib=static=brotlidec-static"); From d17310dfa6d5111eb93cbae560169938671bfc4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Mon, 16 Feb 2026 17:47:00 +0100 Subject: [PATCH 033/189] Do not decompress twice --- sp1-crates/prover/src/binary_input.rs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/sp1-crates/prover/src/binary_input.rs b/sp1-crates/prover/src/binary_input.rs index fc8f2d62d5d..3571b9f6974 100644 --- a/sp1-crates/prover/src/binary_input.rs +++ b/sp1-crates/prover/src/binary_input.rs @@ -23,15 +23,7 @@ pub struct Input { // SP1 has additional alignment requirements, we have to decompress the data // into aligned bytes pub fn decompress_aligned(user_wasm: &UserWasm) -> ModuleAsm { - let data = { - let mut decompressor = - brotli::Decompressor::new(std::io::Cursor::new(user_wasm.as_vec()), 4096); - let mut result = vec![]; - decompressor - .read_to_end(&mut result) - .expect("decompressing"); - result - }; + let data = user_wasm.as_ref(); // This is less ideal but until one of the following happens, we // will have to stick with it: // * Allocator allocates aligned memory From 09830afbe83f3b84db6eec3dbf1a827b0465d3cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 17 Feb 2026 09:58:38 +0100 Subject: [PATCH 034/189] Remove brotli from dependencies --- sp1-crates/Cargo.lock | 1 - sp1-crates/prover/Cargo.toml | 1 - 2 files changed, 2 deletions(-) diff --git a/sp1-crates/Cargo.lock b/sp1-crates/Cargo.lock index 76473560f42..991063b76e3 100644 --- a/sp1-crates/Cargo.lock +++ b/sp1-crates/Cargo.lock @@ -3856,7 +3856,6 @@ name = "prover" version = "0.1.0" dependencies = [ "arbutil", - "brotli 8.0.1", "bytes", "derivative", "digest", diff --git a/sp1-crates/prover/Cargo.toml b/sp1-crates/prover/Cargo.toml index a6059457ba5..93b32b7566e 100644 --- a/sp1-crates/prover/Cargo.toml +++ b/sp1-crates/prover/Cargo.toml @@ -5,7 +5,6 @@ edition = "2024" [dependencies] arbutil = { workspace = true } -brotli = { workspace = true } bytes = { workspace = true } derivative = { workspace = true } digest = { workspace = true } From 629b7342c18a68ab3b6eb40f5d0cb86d6e788bb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 17 Feb 2026 14:05:47 +0100 Subject: [PATCH 035/189] Use OCL forks --- sp1-crates/Cargo.lock | 10 +++++----- sp1-crates/Cargo.toml | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/sp1-crates/Cargo.lock b/sp1-crates/Cargo.lock index 610b3826f6e..c3ae98fa518 100644 --- a/sp1-crates/Cargo.lock +++ b/sp1-crates/Cargo.lock @@ -820,7 +820,7 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "corosensei" version = "0.3.2" -source = "git+https://github.com/wakabat/corosensei?branch=patch-v0.3.2#08e582a7492621acb09318eab166a96715f3eebd" +source = "git+https://github.com/OffchainLabs/corosensei?tag=v0.3.2-sp1#08e582a7492621acb09318eab166a96715f3eebd" dependencies = [ "autocfg", "cfg-if", @@ -4171,7 +4171,7 @@ checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] name = "region" version = "3.0.2" -source = "git+https://github.com/wakabat/region-rs?branch=patch-v3.0.2#ae1c35abce8fbe14deeb7844f95f6b9468bf3fb7" +source = "git+https://github.com/OffchainLabs/region-rs?tag=v3.0.2-sp1#ece52311bd1deff19b48f861ab2abe121b55007e" dependencies = [ "bitflags 1.3.2", "libc", @@ -6168,8 +6168,8 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.13.3" -source = "git+https://github.com/wakabat/target-lexicon?branch=patch-v0.13.3#de11745aa0f7a24c39f2b7faa5d5283825310ae3" +version = "0.13.5" +source = "git+https://github.com/OffchainLabs/target-lexicon?tag=v0.13.5-sp1#b36201fb3efd8babeb625c26217bfb4fb7af32a5" [[package]] name = "tempfile" @@ -7077,7 +7077,7 @@ dependencies = [ [[package]] name = "which" version = "8.0.0" -source = "git+https://github.com/wakabat/which-rs?branch=patch-v8.0.0#9a426008c3d86d89425f6f8644700aa2d4b0a739" +source = "git+https://github.com/OffchainLabs/which-rs?tag=v8.0.0-sp1#8b6efc73303047db5b2c8a014cb36cf2804ee3d3" dependencies = [ "env_home", "rustix", diff --git a/sp1-crates/Cargo.toml b/sp1-crates/Cargo.toml index b04716b9f9d..3cd5c5919fa 100644 --- a/sp1-crates/Cargo.toml +++ b/sp1-crates/Cargo.toml @@ -48,10 +48,10 @@ wasmer-types = { git = "https://github.com/wakabat/official-wasmer", rev = "e065 wasmer-vm = { git = "https://github.com/wakabat/official-wasmer", rev = "e065880", features = ["force-baremetal"] } [patch.crates-io] -target-lexicon = { git = "https://github.com/wakabat/target-lexicon", branch = "patch-v0.13.3" } -region = { git = "https://github.com/wakabat/region-rs", branch = "patch-v3.0.2" } -corosensei = { git = "https://github.com/wakabat/corosensei", branch = "patch-v0.3.2" } -which = { git = "https://github.com/wakabat/which-rs", branch = "patch-v8.0.0" } +target-lexicon = { git = "https://github.com/OffchainLabs/target-lexicon", tag = "v0.13.5-sp1" } +region = { git = "https://github.com/OffchainLabs/region-rs", tag = "v3.0.2-sp1" } +corosensei = { git = "https://github.com/OffchainLabs/corosensei", tag = "v0.3.2-sp1" } +which = { git = "https://github.com/OffchainLabs/which-rs", tag = "v8.0.0-sp1" } sp1-build = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe" } sp1-core-executor = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe" } From 54c0d69b3d31afbfe0b40609a3d8d0e00496e838 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Wed, 18 Feb 2026 13:43:36 +0100 Subject: [PATCH 036/189] Make user wasm decompressing feature-gated in validation crate --- crates/validation/Cargo.toml | 6 +++++- crates/validation/src/lib.rs | 14 +++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/crates/validation/Cargo.toml b/crates/validation/Cargo.toml index 01890c463b1..a7518ef05e4 100644 --- a/crates/validation/Cargo.toml +++ b/crates/validation/Cargo.toml @@ -11,7 +11,11 @@ rust-version.workspace = true [dependencies] arbutil = { workspace = true } -brotli = { workspace = true } +brotli = { workspace = true, optional = true } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } serde_with = { workspace = true, features = ["base64"] } + +[features] +default = ["decompress-user-wasm"] +decompress-user-wasm = ["brotli"] diff --git a/crates/validation/src/lib.rs b/crates/validation/src/lib.rs index 52e61b7575b..80c1fb19764 100644 --- a/crates/validation/src/lib.rs +++ b/crates/validation/src/lib.rs @@ -1,7 +1,6 @@ // Copyright 2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md use arbutil::{Bytes32, PreimageType}; -use brotli::BrotliStatus; use serde::{Deserialize, Serialize}; use serde_with::{base64::Base64, As, DisplayFromStr}; use std::{ @@ -51,7 +50,8 @@ pub struct BatchInfo { /// `UserWasm` is a wrapper around `Vec` /// -/// It is useful for decompressing a `brotli`-compressed wasm module. +/// If the `decompress-user-wasm` feature is on, it contains `brotli`-decompressed wasm module. +/// Otherwise, it contains the compressed wasm module as-is, and the caller is responsible for decompressing it before use. /// /// Note: The wrapped `Vec` is already `Base64` decoded before /// `from(Vec)` is called by `serde`. @@ -71,12 +71,16 @@ impl AsRef<[u8]> for UserWasm { } } -/// The `Vec` is assumed to be compressed using `brotli`, and must be decompressed before use. impl TryFrom> for UserWasm { - type Error = BrotliStatus; + #[cfg(feature = "decompress-user-wasm")] + type Error = brotli::BrotliStatus; + #[cfg(not(feature = "decompress-user-wasm"))] + type Error = (); fn try_from(data: Vec) -> Result { - Ok(Self(brotli::decompress(&data, brotli::Dictionary::Empty)?)) + #[cfg(feature = "decompress-user-wasm")] + let data = brotli::decompress(&data, brotli::Dictionary::Empty)?; + Ok(Self(data)) } } From e1fcdcaa336f766346ad7f2be19873b63b77e1f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Wed, 18 Feb 2026 13:45:47 +0100 Subject: [PATCH 037/189] Fix dependencies in sp1 workspace --- sp1-crates/Cargo.lock | 13 +------------ sp1-crates/Cargo.toml | 2 +- sp1-crates/program/Cargo.toml | 2 -- 3 files changed, 2 insertions(+), 15 deletions(-) diff --git a/sp1-crates/Cargo.lock b/sp1-crates/Cargo.lock index 2d931333a92..79582595113 100644 --- a/sp1-crates/Cargo.lock +++ b/sp1-crates/Cargo.lock @@ -517,14 +517,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "brotli" -version = "0.1.0" -dependencies = [ - "lazy_static", - "num_enum 0.7.5", -] - [[package]] name = "brotli" version = "8.0.1" @@ -3776,20 +3768,18 @@ name = "program" version = "0.1.0" dependencies = [ "arbutil", - "brotli 8.0.1", + "brotli", "bytes", "corosensei", "eyre", "hex", "num-traits", - "num_enum 0.7.5", "once_cell", "prover", "rand 0.8.5", "rand_pcg", "ruint2", "secp256k1", - "serde", "serde_json", "sp1-zkvm", "thiserror 1.0.69", @@ -6749,7 +6739,6 @@ name = "validation" version = "0.1.0" dependencies = [ "arbutil", - "brotli 0.1.0", "serde", "serde_json", "serde_with", diff --git a/sp1-crates/Cargo.toml b/sp1-crates/Cargo.toml index 732927a5fd0..5ea979f53d8 100644 --- a/sp1-crates/Cargo.toml +++ b/sp1-crates/Cargo.toml @@ -6,7 +6,7 @@ members = ["program", "builder", "stylus-compiler-program", "prover", "runner"] [workspace.dependencies] arbutil = { path = "../crates/arbutil" } prover = { path = "prover", default-features = false, features = ["sp1"] } -validation = { path = "../crates/validation" } +validation = { path = "../crates/validation", default-features = false } bincode = { version = "1.3.3" } bytes = { version = "1" } diff --git a/sp1-crates/program/Cargo.toml b/sp1-crates/program/Cargo.toml index 6ba6bc52096..65d7527d0b4 100644 --- a/sp1-crates/program/Cargo.toml +++ b/sp1-crates/program/Cargo.toml @@ -17,14 +17,12 @@ bytes = { workspace = true } corosensei = { workspace = true } eyre = { workspace = true } hex = { workspace = true } -num_enum = { workspace = true } num-traits = { workspace = true } once_cell = { workspace = true } rand_pcg = { workspace = true } rand = { workspace = true } ruint2 = { workspace = true } secp256k1 = { workspace = true } -serde = { workspace = true } serde_json = { workspace = true } thiserror = { workspace = true } tiny-keccak = { workspace = true } From 19a4ae0e6ed741c0cd88592a6ec60c52dd917126 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Wed, 18 Feb 2026 13:49:51 +0100 Subject: [PATCH 038/189] Restore Rust brotli decompression --- sp1-crates/Cargo.lock | 1 + sp1-crates/Cargo.toml | 1 - sp1-crates/prover/Cargo.toml | 1 + sp1-crates/prover/src/binary_input.rs | 12 +++++++++++- 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/sp1-crates/Cargo.lock b/sp1-crates/Cargo.lock index 79582595113..30baec67399 100644 --- a/sp1-crates/Cargo.lock +++ b/sp1-crates/Cargo.lock @@ -3846,6 +3846,7 @@ name = "prover" version = "0.1.0" dependencies = [ "arbutil", + "brotli", "bytes", "derivative", "digest", diff --git a/sp1-crates/Cargo.toml b/sp1-crates/Cargo.toml index 5ea979f53d8..e068d045a18 100644 --- a/sp1-crates/Cargo.toml +++ b/sp1-crates/Cargo.toml @@ -21,7 +21,6 @@ lazy_static = { version = "1.4.0" } nom = { version = "7.0.0" } num-derive = { version = "0.4.1" } num-traits = { version = "0.2.17" } -num_enum = { version = "0.7.1" } once_cell = { version = "1.21.3" } parking_lot = { version = "0.12.1" } rand = { version = "0.8.4", default-features = false } diff --git a/sp1-crates/prover/Cargo.toml b/sp1-crates/prover/Cargo.toml index 93b32b7566e..a6059457ba5 100644 --- a/sp1-crates/prover/Cargo.toml +++ b/sp1-crates/prover/Cargo.toml @@ -5,6 +5,7 @@ edition = "2024" [dependencies] arbutil = { workspace = true } +brotli = { workspace = true } bytes = { workspace = true } derivative = { workspace = true } digest = { workspace = true } diff --git a/sp1-crates/prover/src/binary_input.rs b/sp1-crates/prover/src/binary_input.rs index 3571b9f6974..e321910b62e 100644 --- a/sp1-crates/prover/src/binary_input.rs +++ b/sp1-crates/prover/src/binary_input.rs @@ -23,7 +23,17 @@ pub struct Input { // SP1 has additional alignment requirements, we have to decompress the data // into aligned bytes pub fn decompress_aligned(user_wasm: &UserWasm) -> ModuleAsm { - let data = user_wasm.as_ref(); + // brotli-decompress the data first, since the `validation.decompress_user_wasm` feature is not + // enabled - C-binded brotli used in `validation` is not supported in SP1. + let data = { + let mut decompressor = + brotli::Decompressor::new(std::io::Cursor::new(user_wasm.as_vec()), 4096); + let mut result = vec![]; + decompressor + .read_to_end(&mut result) + .expect("decompressing"); + result + }; // This is less ideal but until one of the following happens, we // will have to stick with it: // * Allocator allocates aligned memory From 1c94b6f70d48fd479fc7222656e21d495c085aff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Mon, 2 Mar 2026 16:51:38 +0100 Subject: [PATCH 039/189] Add WavmState trait to caller-env --- crates/caller-env/src/lib.rs | 1 + crates/caller-env/src/wavmio.rs | 13 +++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 crates/caller-env/src/wavmio.rs diff --git a/crates/caller-env/src/lib.rs b/crates/caller-env/src/lib.rs index d0ee1ffaa00..aca39608eb7 100644 --- a/crates/caller-env/src/lib.rs +++ b/crates/caller-env/src/lib.rs @@ -21,6 +21,7 @@ pub mod wasmer_traits; pub mod brotli; pub mod arbcrypto; +pub mod wavmio; mod guest_ptr; pub mod wasip1_stub; diff --git a/crates/caller-env/src/wavmio.rs b/crates/caller-env/src/wavmio.rs new file mode 100644 index 00000000000..5a3896fcb33 --- /dev/null +++ b/crates/caller-env/src/wavmio.rs @@ -0,0 +1,13 @@ +// Copyright 2026, Offchain Labs, Inc. +// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md + +/// Trait for accessing wavmio host state (globals, inbox, preimages). +pub trait WavmState { + fn get_u64_global(&self, idx: usize) -> Option; + fn set_u64_global(&mut self, idx: usize, val: u64) -> bool; + fn get_bytes32_global(&self, idx: usize) -> Option<&[u8; 32]>; + fn set_bytes32_global(&mut self, idx: usize, val: [u8; 32]) -> bool; + fn get_sequencer_message(&self, num: u64) -> Option<&[u8]>; + fn get_delayed_message(&self, num: u64) -> Option<&[u8]>; + fn get_preimage(&self, preimage_type: u8, hash: &[u8; 32]) -> Option<&[u8]>; +} From 33f94b20a8cb12d6076306c21e8c68ff4b17aef5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Mon, 2 Mar 2026 16:55:04 +0100 Subject: [PATCH 040/189] Add get_global_state_bytes32 generic implementation --- crates/caller-env/src/wavmio.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/crates/caller-env/src/wavmio.rs b/crates/caller-env/src/wavmio.rs index 5a3896fcb33..e701e3bff6b 100644 --- a/crates/caller-env/src/wavmio.rs +++ b/crates/caller-env/src/wavmio.rs @@ -1,6 +1,8 @@ // Copyright 2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md +use crate::{GuestPtr, MemAccess}; + /// Trait for accessing wavmio host state (globals, inbox, preimages). pub trait WavmState { fn get_u64_global(&self, idx: usize) -> Option; @@ -11,3 +13,17 @@ pub trait WavmState { fn get_delayed_message(&self, num: u64) -> Option<&[u8]>; fn get_preimage(&self, preimage_type: u8, hash: &[u8; 32]) -> Option<&[u8]>; } + +/// Reads 32-bytes of global state and writes to guest memory. +pub fn get_global_state_bytes32( + mem: &mut M, + state: &S, + idx: u32, + out_ptr: GuestPtr, +) -> Result<(), String> { + let Some(global) = state.get_bytes32_global(idx as usize) else { + return Err("global read out of bounds in wavmio.getGlobalStateBytes32".into()); + }; + mem.write_slice(out_ptr, &global[..]); + Ok(()) +} From 0abe2454ab4277d8362dfc1042c349e4f3fc8540 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Mon, 2 Mar 2026 17:03:10 +0100 Subject: [PATCH 041/189] Implement WavmState for WasmEnv --- crates/jit/src/caller_env.rs | 49 +++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/crates/jit/src/caller_env.rs b/crates/jit/src/caller_env.rs index a30662049fb..66a240b9496 100644 --- a/crates/jit/src/caller_env.rs +++ b/crates/jit/src/caller_env.rs @@ -2,7 +2,8 @@ // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md use crate::machine::{WasmEnv, WasmEnvMut}; -use arbutil::{Bytes20, Bytes32}; +use arbutil::{Bytes20, Bytes32, PreimageType}; +use caller_env::wavmio::WavmState; use caller_env::{ExecEnv, GuestPtr, MemAccess}; use rand::RngCore; use std::mem::{self, MaybeUninit}; @@ -132,3 +133,49 @@ impl ExecEnv for JitExecEnv<'_> { } } } + +impl WavmState for WasmEnv { + fn get_u64_global(&self, idx: usize) -> Option { + self.small_globals.get(idx).copied() + } + + fn set_u64_global(&mut self, idx: usize, val: u64) -> bool { + match self.small_globals.get_mut(idx) { + Some(g) => { + *g = val; + true + } + None => false, + } + } + + fn get_bytes32_global(&self, idx: usize) -> Option<&[u8; 32]> { + self.large_globals.get(idx).map(|b| &b.0) + } + + fn set_bytes32_global(&mut self, idx: usize, val: [u8; 32]) -> bool { + match self.large_globals.get_mut(idx) { + Some(g) => { + *g = val.into(); + true + } + None => false, + } + } + + fn get_sequencer_message(&self, num: u64) -> Option<&[u8]> { + self.sequencer_messages.get(&num).map(|v| v.as_slice()) + } + + fn get_delayed_message(&self, num: u64) -> Option<&[u8]> { + self.delayed_messages.get(&num).map(|v| v.as_slice()) + } + + fn get_preimage(&self, preimage_type: u8, hash: &[u8; 32]) -> Option<&[u8]> { + let pt: PreimageType = preimage_type.try_into().ok()?; + self.preimages + .get(&pt) + .and_then(|m| m.get(&Bytes32::from(*hash))) + .map(|v| v.as_slice()) + } +} From e83c8c3259450f86dcb799cf4aaa6a9addbef65e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Mon, 2 Mar 2026 17:06:21 +0100 Subject: [PATCH 042/189] Use caller_env::wavmio::get_global_state_bytes32 in JIT --- crates/jit/src/wavmio.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/crates/jit/src/wavmio.rs b/crates/jit/src/wavmio.rs index 97d07e4e2ac..edc265e905c 100644 --- a/crates/jit/src/wavmio.rs +++ b/crates/jit/src/wavmio.rs @@ -20,12 +20,8 @@ use validation::transfer::receive_validation_input; pub fn get_global_state_bytes32(mut env: WasmEnvMut, idx: u32, out_ptr: GuestPtr) -> MaybeEscape { let (mut mem, exec) = env.jit_env(); ready_hostio(exec)?; - - let Some(global) = exec.large_globals.get(idx as usize) else { - return Escape::hostio("global read out of bounds in wavmio.getGlobalStateBytes32"); - }; - mem.write_slice(out_ptr, &global[..32]); - Ok(()) + caller_env::wavmio::get_global_state_bytes32(&mut mem, exec, idx, out_ptr) + .map_err(Escape::HostIO) } /// Writes 32-bytes of global state. From 9bfb5f4624f7ebff076bb4bdab3514cc0e7eaba7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Mon, 2 Mar 2026 17:25:19 +0100 Subject: [PATCH 043/189] Provide adapters for SP1 --- sp1-crates/Cargo.lock | 23 ++- sp1-crates/Cargo.toml | 1 + sp1-crates/program/Cargo.toml | 1 + sp1-crates/program/src/caller_env_adapters.rs | 142 ++++++++++++++++++ sp1-crates/program/src/lib.rs | 1 + 5 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 sp1-crates/program/src/caller_env_adapters.rs diff --git a/sp1-crates/Cargo.lock b/sp1-crates/Cargo.lock index 30baec67399..afc0db9fccb 100644 --- a/sp1-crates/Cargo.lock +++ b/sp1-crates/Cargo.lock @@ -604,6 +604,17 @@ version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" +[[package]] +name = "caller-env" +version = "0.1.0" +dependencies = [ + "k256 0.13.4 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.8.5", + "rand_pcg", + "spin 0.10.0", + "tiny-keccak 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "camino" version = "1.2.2" @@ -2403,7 +2414,7 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" dependencies = [ - "spin", + "spin 0.9.8", ] [[package]] @@ -3770,6 +3781,7 @@ dependencies = [ "arbutil", "brotli", "bytes", + "caller-env", "corosensei", "eyre", "hex", @@ -5978,6 +5990,15 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +[[package]] +name = "spin" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591" +dependencies = [ + "lock_api", +] + [[package]] name = "spki" version = "0.7.3" diff --git a/sp1-crates/Cargo.toml b/sp1-crates/Cargo.toml index e068d045a18..65e03a6b05b 100644 --- a/sp1-crates/Cargo.toml +++ b/sp1-crates/Cargo.toml @@ -5,6 +5,7 @@ members = ["program", "builder", "stylus-compiler-program", "prover", "runner"] [workspace.dependencies] arbutil = { path = "../crates/arbutil" } +caller-env = { path = "../crates/caller-env", default-features = false } prover = { path = "prover", default-features = false, features = ["sp1"] } validation = { path = "../crates/validation", default-features = false } diff --git a/sp1-crates/program/Cargo.toml b/sp1-crates/program/Cargo.toml index 65d7527d0b4..fa012b4803e 100644 --- a/sp1-crates/program/Cargo.toml +++ b/sp1-crates/program/Cargo.toml @@ -5,6 +5,7 @@ version = "0.1.0" edition = "2024" [dependencies] +caller-env = { workspace = true } sp1-zkvm = { workspace = true } wasmer = { workspace = true } wasmer-types = { workspace = true } diff --git a/sp1-crates/program/src/caller_env_adapters.rs b/sp1-crates/program/src/caller_env_adapters.rs new file mode 100644 index 00000000000..5ac200c272f --- /dev/null +++ b/sp1-crates/program/src/caller_env_adapters.rs @@ -0,0 +1,142 @@ +// Copyright 2026, Offchain Labs, Inc. +// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md + +use caller_env::wavmio::WavmState; +use caller_env::{GuestPtr, MemAccess}; +use prover::binary_input::Input; +use wasmer::{FunctionEnvMut, Memory, StoreMut}; + +use crate::replay::CustomEnvData; + +/// Adapter implementing MemAccess over wasmer MemoryView. +pub(crate) struct Sp1MemAccess<'s> { + pub memory: Memory, + pub store: StoreMut<'s>, +} + +impl Sp1MemAccess<'_> { + fn view(&self) -> wasmer::MemoryView<'_> { + self.memory.view(&self.store) + } +} + +impl MemAccess for Sp1MemAccess<'_> { + fn read_u8(&self, ptr: GuestPtr) -> u8 { + let mut buf = [0u8; 1]; + self.view().read(ptr.to_u64(), &mut buf).unwrap(); + buf[0] + } + + fn read_u16(&self, ptr: GuestPtr) -> u16 { + let mut buf = [0u8; 2]; + self.view().read(ptr.to_u64(), &mut buf).unwrap(); + u16::from_le_bytes(buf) + } + + fn read_u32(&self, ptr: GuestPtr) -> u32 { + let mut buf = [0u8; 4]; + self.view().read(ptr.to_u64(), &mut buf).unwrap(); + u32::from_le_bytes(buf) + } + + fn read_u64(&self, ptr: GuestPtr) -> u64 { + let mut buf = [0u8; 8]; + self.view().read(ptr.to_u64(), &mut buf).unwrap(); + u64::from_le_bytes(buf) + } + + fn write_u8(&mut self, ptr: GuestPtr, x: u8) { + self.view().write(ptr.to_u64(), &[x]).unwrap(); + } + + fn write_u16(&mut self, ptr: GuestPtr, x: u16) { + self.view().write(ptr.to_u64(), &x.to_le_bytes()).unwrap(); + } + + fn write_u32(&mut self, ptr: GuestPtr, x: u32) { + self.view().write(ptr.to_u64(), &x.to_le_bytes()).unwrap(); + } + + fn write_u64(&mut self, ptr: GuestPtr, x: u64) { + self.view().write(ptr.to_u64(), &x.to_le_bytes()).unwrap(); + } + + fn read_slice(&self, ptr: GuestPtr, len: usize) -> Vec { + let mut data = vec![0u8; len]; + self.view().read(ptr.to_u64(), &mut data).unwrap(); + data + } + + fn read_fixed(&self, ptr: GuestPtr) -> [u8; N] { + let mut buf = [0u8; N]; + self.view().read(ptr.to_u64(), &mut buf).unwrap(); + buf + } + + fn write_slice(&mut self, ptr: GuestPtr, data: &[u8]) { + self.view().write(ptr.to_u64(), data).unwrap(); + } +} + +/// Newtype wrapper to implement WavmState for Input (orphan rule). +pub(crate) struct WavmInput<'a>(pub &'a mut Input); + +impl WavmState for WavmInput<'_> { + fn get_u64_global(&self, idx: usize) -> Option { + self.0.small_globals.get(idx).copied() + } + + fn set_u64_global(&mut self, idx: usize, val: u64) -> bool { + match self.0.small_globals.get_mut(idx) { + Some(g) => { + *g = val; + true + } + None => false, + } + } + + fn get_bytes32_global(&self, idx: usize) -> Option<&[u8; 32]> { + self.0.large_globals.get(idx) + } + + fn set_bytes32_global(&mut self, idx: usize, val: [u8; 32]) -> bool { + match self.0.large_globals.get_mut(idx) { + Some(g) => { + *g = val; + true + } + None => false, + } + } + + fn get_sequencer_message(&self, num: u64) -> Option<&[u8]> { + self.0.sequencer_messages.get(&num).map(|v| v.as_slice()) + } + + fn get_delayed_message(&self, num: u64) -> Option<&[u8]> { + self.0.delayed_messages.get(&num).map(|v| v.as_slice()) + } + + fn get_preimage(&self, preimage_type: u8, hash: &[u8; 32]) -> Option<&[u8]> { + self.0 + .preimages + .get(&preimage_type) + .and_then(|m| m.get(hash)) + .map(|v| v.as_slice()) + } +} + +/// Extraction trait for splitting FunctionEnvMut into MemAccess + WavmState. +pub(crate) trait Sp1Env { + fn sp1_env(&mut self) -> (Sp1MemAccess<'_>, WavmInput<'_>); +} + +impl Sp1Env for FunctionEnvMut<'_, CustomEnvData> { + fn sp1_env(&mut self) -> (Sp1MemAccess<'_>, WavmInput<'_>) { + let memory = self.data().memory.clone().unwrap(); + let (data, store) = self.data_and_store_mut(); + let input = data.input_mut(); + (Sp1MemAccess { memory, store }, WavmInput(input)) + } +} diff --git a/sp1-crates/program/src/lib.rs b/sp1-crates/program/src/lib.rs index d6eeccf0ce5..18c6e241e3d 100644 --- a/sp1-crates/program/src/lib.rs +++ b/sp1-crates/program/src/lib.rs @@ -2,6 +2,7 @@ pub mod imports; pub mod platform; pub mod replay; pub mod stylus; +mod caller_env_adapters; use arbutil::{ Bytes20, Bytes32, From 92236dfc1180bc94fd005656c2bfd127a558809f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Mon, 2 Mar 2026 17:27:03 +0100 Subject: [PATCH 044/189] Implement get_global_state_bytes32 in SP1 --- sp1-crates/program/src/imports/wavmio.rs | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/sp1-crates/program/src/imports/wavmio.rs b/sp1-crates/program/src/imports/wavmio.rs index 1714a9ecf0b..395689198f8 100644 --- a/sp1-crates/program/src/imports/wavmio.rs +++ b/sp1-crates/program/src/imports/wavmio.rs @@ -6,22 +6,17 @@ use crate::{Escape, MaybeEscape, Ptr, read_bytes32, replay::CustomEnvData}; use std::ops::Deref; use wasmer::{FunctionEnvMut, MemoryView}; +use caller_env::GuestPtr; +use crate::caller_env_adapters::Sp1Env; pub fn get_global_state_bytes32( mut ctx: FunctionEnvMut, idx: u32, out_ptr: Ptr, ) -> MaybeEscape { - let (data, store) = ctx.data_and_store_mut(); - let memory = data.memory.clone().unwrap().view(&store); - - let Some(global) = data.input().large_globals.get(idx as usize) else { - return Escape::logical("global read out of bounds in wavmio.getGlobalStateBytes32"); - }; - - memory.write(out_ptr.offset() as u64, &global[..32])?; - - Ok(()) + let (mut mem, state) = ctx.sp1_env(); + caller_env::wavmio::get_global_state_bytes32(&mut mem, &state, idx, GuestPtr(out_ptr.offset())) + .map_err(Escape::Logical) } pub fn set_global_state_bytes32( From 94adc95199d6a9a9517cdbced561b3bd98171549 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Mon, 2 Mar 2026 17:35:44 +0100 Subject: [PATCH 045/189] Missing import for no-std build --- crates/caller-env/src/wavmio.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/caller-env/src/wavmio.rs b/crates/caller-env/src/wavmio.rs index e701e3bff6b..c7f3d4776a3 100644 --- a/crates/caller-env/src/wavmio.rs +++ b/crates/caller-env/src/wavmio.rs @@ -1,6 +1,7 @@ // Copyright 2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md +use alloc::string::String; use crate::{GuestPtr, MemAccess}; /// Trait for accessing wavmio host state (globals, inbox, preimages). From d4cda16ab108a98f0c508f27a9b6a00e95fd2ffe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Mon, 2 Mar 2026 17:46:25 +0100 Subject: [PATCH 046/189] The rest of wavmio functions in caller env and JIT --- Cargo.lock | 1 + crates/caller-env/Cargo.toml | 1 + crates/caller-env/src/wavmio.rs | 117 ++++++++++++++++++++++++ crates/jit/src/wavmio.rs | 152 ++++++++++---------------------- sp1-crates/Cargo.lock | 1 + 5 files changed, 168 insertions(+), 104 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 55d8c92e85a..16e2aa2c74e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -426,6 +426,7 @@ name = "caller-env" version = "0.1.0" dependencies = [ "brotli", + "hex", "k256", "rand 0.8.5", "rand_pcg", diff --git a/crates/caller-env/Cargo.toml b/crates/caller-env/Cargo.toml index 33f22141cf8..1cbb7be97a3 100644 --- a/crates/caller-env/Cargo.toml +++ b/crates/caller-env/Cargo.toml @@ -11,6 +11,7 @@ rust-version.workspace = true [dependencies] brotli = { workspace = true, optional = true } +hex = { workspace = true } k256 = { workspace = true, features = ["ecdsa"] } rand = { workspace = true } rand_pcg = { workspace = true } diff --git a/crates/caller-env/src/wavmio.rs b/crates/caller-env/src/wavmio.rs index c7f3d4776a3..52debdbaf91 100644 --- a/crates/caller-env/src/wavmio.rs +++ b/crates/caller-env/src/wavmio.rs @@ -1,6 +1,7 @@ // Copyright 2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md +use core::cmp::min; use alloc::string::String; use crate::{GuestPtr, MemAccess}; @@ -28,3 +29,119 @@ pub fn get_global_state_bytes32( mem.write_slice(out_ptr, &global[..]); Ok(()) } + +/// Reads 32-bytes from guest memory and writes to global state. +pub fn set_global_state_bytes32( + mem: &M, + state: &mut S, + idx: u32, + src_ptr: GuestPtr, +) -> Result<(), String> { + let val = mem.read_fixed(src_ptr); + if !state.set_bytes32_global(idx as usize, val) { + return Err("global write oob in wavmio.setGlobalStateBytes32".into()); + } + Ok(()) +} + +/// Reads 8-bytes of global state. +pub fn get_global_state_u64(state: &S, idx: u32) -> Result { + match state.get_u64_global(idx as usize) { + Some(val) => Ok(val), + None => Err("global read out of bounds in wavmio.getGlobalStateU64".into()), + } +} + +/// Writes 8-bytes of global state. +pub fn set_global_state_u64( + state: &mut S, + idx: u32, + val: u64, +) -> Result<(), String> { + if !state.set_u64_global(idx as usize, val) { + return Err("global write out of bounds in wavmio.setGlobalStateU64".into()); + } + Ok(()) +} + +/// Reads up to 32 bytes of a sequencer inbox message at the given offset. +pub fn read_inbox_message( + mem: &mut M, + state: &S, + msg_num: u64, + offset: u32, + out_ptr: GuestPtr, +) -> Result { + let message = match state.get_sequencer_message(msg_num) { + Some(message) => message, + None => return Err(format!("missing sequencer inbox message {msg_num}")), + }; + let offset = offset as usize; + let len = min(32, message.len().saturating_sub(offset)); + let read = message.get(offset..(offset + len)).unwrap_or_default(); + mem.write_slice(out_ptr, read); + Ok(read.len() as u32) +} + +/// Reads up to 32 bytes of a delayed inbox message at the given offset. +pub fn read_delayed_inbox_message( + mem: &mut M, + state: &S, + msg_num: u64, + offset: u32, + out_ptr: GuestPtr, +) -> Result { + let message = match state.get_delayed_message(msg_num) { + Some(message) => message, + None => return Err(format!("missing delayed inbox message {msg_num}")), + }; + let offset = offset as usize; + let len = min(32, message.len().saturating_sub(offset)); + let read = message.get(offset..(offset + len)).unwrap_or_default(); + mem.write_slice(out_ptr, read); + Ok(read.len() as u32) +} + +/// Looks up a preimage by type and hash, reads up to 32 bytes at an aligned offset. +pub fn resolve_preimage( + mem: &mut M, + state: &S, + preimage_type: u8, + hash_ptr: GuestPtr, + offset: u32, + out_ptr: GuestPtr, + name: &str, +) -> Result { + let hash = mem.read_fixed(hash_ptr); + let offset = offset as usize; + + let Some(preimage) = state.get_preimage(preimage_type, &hash) else { + let hash_hex = hex::encode(hash); + return Err(format!( + "Missing requested preimage for hash {hash_hex} in {name}" + )); + }; + + if offset % 32 != 0 { + return Err(format!("bad offset {offset} in {name}")); + } + + let len = min(32, preimage.len().saturating_sub(offset)); + let read = preimage.get(offset..(offset + len)).unwrap_or_default(); + mem.write_slice(out_ptr, read); + Ok(read.len() as u32) +} + +/// Returns 1 if a preimage exists for the given type and hash, 0 otherwise. +pub fn validate_certificate( + mem: &M, + state: &S, + preimage_type: u8, + hash_ptr: GuestPtr, +) -> u8 { + let hash = mem.read_fixed(hash_ptr); + match state.get_preimage(preimage_type, &hash) { + Some(_) => 1, + None => 0, + } +} diff --git a/crates/jit/src/wavmio.rs b/crates/jit/src/wavmio.rs index edc265e905c..5113d8249fb 100644 --- a/crates/jit/src/wavmio.rs +++ b/crates/jit/src/wavmio.rs @@ -6,7 +6,7 @@ use crate::{ machine::{Escape, MaybeEscape, WasmEnv, WasmEnvMut}, }; use arbutil::Color; -use caller_env::{GuestPtr, MemAccess}; +use caller_env::GuestPtr; use std::{ io, io::{BufReader, BufWriter, ErrorKind}, @@ -28,37 +28,22 @@ pub fn get_global_state_bytes32(mut env: WasmEnvMut, idx: u32, out_ptr: GuestPtr pub fn set_global_state_bytes32(mut env: WasmEnvMut, idx: u32, src_ptr: GuestPtr) -> MaybeEscape { let (mem, exec) = env.jit_env(); ready_hostio(exec)?; - - let slice = mem.read_slice(src_ptr, 32); - let slice = &slice.try_into().unwrap(); - match exec.large_globals.get_mut(idx as usize) { - Some(global) => *global = *slice, - None => return Escape::hostio("global write oob in wavmio.setGlobalStateBytes32"), - }; - Ok(()) + caller_env::wavmio::set_global_state_bytes32(&mem, exec, idx, src_ptr) + .map_err(Escape::HostIO) } /// Reads 8-bytes of global state pub fn get_global_state_u64(mut env: WasmEnvMut, idx: u32) -> Result { let (_, exec) = env.jit_env(); ready_hostio(exec)?; - - match exec.small_globals.get(idx as usize) { - Some(global) => Ok(*global), - None => Escape::hostio("global read out of bounds in wavmio.getGlobalStateU64"), - } + caller_env::wavmio::get_global_state_u64(exec, idx).map_err(Escape::HostIO) } /// Writes 8-bytes of global state pub fn set_global_state_u64(mut env: WasmEnvMut, idx: u32, val: u64) -> MaybeEscape { let (_, exec) = env.jit_env(); ready_hostio(exec)?; - - match exec.small_globals.get_mut(idx as usize) { - Some(global) => *global = val, - None => return Escape::hostio("global write out of bounds in wavmio.setGlobalStateU64"), - } - Ok(()) + caller_env::wavmio::set_global_state_u64(exec, idx, val).map_err(Escape::HostIO) } /// Reads an inbox message. @@ -70,16 +55,8 @@ pub fn read_inbox_message( ) -> Result { let (mut mem, exec) = env.jit_env(); ready_hostio(exec)?; - - let message = match exec.sequencer_messages.get(&msg_num) { - Some(message) => message, - None => return Escape::hostio(format!("missing sequencer inbox message {msg_num}")), - }; - let offset = offset as usize; - let len = std::cmp::min(32, message.len().saturating_sub(offset)); - let read = message.get(offset..(offset + len)).unwrap_or_default(); - mem.write_slice(out_ptr, read); - Ok(read.len() as u32) + caller_env::wavmio::read_inbox_message(&mut mem, exec, msg_num, offset, out_ptr) + .map_err(Escape::HostIO) } /// Reads a delayed inbox message. @@ -91,16 +68,8 @@ pub fn read_delayed_inbox_message( ) -> Result { let (mut mem, exec) = env.jit_env(); ready_hostio(exec)?; - - let message = match exec.delayed_messages.get(&msg_num) { - Some(message) => message, - None => return Escape::hostio(format!("missing delayed inbox message {msg_num}")), - }; - let offset = offset as usize; - let len = std::cmp::min(32, message.len().saturating_sub(offset)); - let read = message.get(offset..(offset + len)).unwrap_or_default(); - mem.write_slice(out_ptr, read); - Ok(read.len() as u32) + caller_env::wavmio::read_delayed_inbox_message(&mut mem, exec, msg_num, offset, out_ptr) + .map_err(Escape::HostIO) } /// Retrieves the preimage of the given hash. @@ -131,7 +100,7 @@ pub fn resolve_typed_preimage( ) } -pub fn resolve_preimage_impl( +fn resolve_preimage_impl( mut env: WasmEnvMut, preimage_type: u8, hash_ptr: GuestPtr, @@ -140,30 +109,6 @@ pub fn resolve_preimage_impl( name: &str, ) -> Result { let (mut mem, exec) = env.jit_env(); - let offset = offset as usize; - - let Ok(preimage_type) = preimage_type.try_into() else { - eprintln!("Go trying to resolve pre image with unknown type {preimage_type}"); - return Ok(0); - }; - - macro_rules! error { - ($text:expr $(,$args:expr)*) => {{ - let text = format!($text $(,$args)*); - return Escape::hostio(&text) - }}; - } - - let hash = mem.read_bytes32(hash_ptr); - - let Some(preimage) = exec - .preimages - .get(&preimage_type) - .and_then(|m| m.get(&hash)) - else { - let hash_hex = hex::encode(hash); - error!("Missing requested preimage for hash {hash_hex} in {name}") - }; #[cfg(debug_assertions)] { @@ -171,31 +116,46 @@ pub fn resolve_preimage_impl( use sha2::Sha256; use sha3::{Digest, Keccak256}; - // Check if preimage rehashes to the provided hash. Exclude blob preimages - let calculated_hash: [u8; 32] = match preimage_type { - PreimageType::Keccak256 => Keccak256::digest(preimage).into(), - PreimageType::Sha2_256 => Sha256::digest(preimage).into(), - PreimageType::EthVersionedHash => *hash, - PreimageType::DACertificate => *hash, // Can't verify DACertificate hash, just accept it + let hash = mem.read_bytes32(hash_ptr); + + let Ok(preimage_type) = preimage_type.try_into() else { + eprintln!("Go trying to resolve pre image with unknown type {preimage_type}"); + return Ok(0); }; - if calculated_hash != *hash { - error!( - "Calculated hash {} of preimage {} does not match provided hash {}", - hex::encode(calculated_hash), - hex::encode(preimage), - hex::encode(*hash) - ); + + if let Some(preimage) = exec + .preimages + .get(&preimage_type) + .and_then(|m| m.get(&hash)) + { + // Check if preimage rehashes to the provided hash. Exclude blob preimages + let calculated_hash: [u8; 32] = match preimage_type { + PreimageType::Keccak256 => Keccak256::digest(preimage).into(), + PreimageType::Sha2_256 => Sha256::digest(preimage).into(), + PreimageType::EthVersionedHash => *hash, + PreimageType::DACertificate => *hash, // Can't verify DACertificate hash, just accept it + }; + if calculated_hash != *hash { + return Escape::hostio(format!( + "Calculated hash {} of preimage {} does not match provided hash {}", + hex::encode(calculated_hash), + hex::encode(preimage), + hex::encode(*hash) + )); + } } } - if offset % 32 != 0 { - error!("bad offset {offset} in {name}") - }; - - let len = std::cmp::min(32, preimage.len().saturating_sub(offset)); - let read = preimage.get(offset..(offset + len)).unwrap_or_default(); - mem.write_slice(out_ptr, read); - Ok(read.len() as u32) + caller_env::wavmio::resolve_preimage( + &mut mem, + exec, + preimage_type, + hash_ptr, + offset, + out_ptr, + name, + ) + .map_err(Escape::HostIO) } pub fn validate_certificate( @@ -203,24 +163,8 @@ pub fn validate_certificate( preimage_type: u8, hash_ptr: GuestPtr, ) -> Result { - let (mut mem, exec) = env.jit_env(); - let hash = mem.read_bytes32(hash_ptr); - - let Ok(preimage_type) = preimage_type.try_into() else { - eprintln!( - "Go trying to validate certificate for preimage with unknown type {preimage_type}" - ); - return Ok(0); - }; - - // Check if preimage exists - let exists = exec - .preimages - .get(&preimage_type) - .and_then(|m| m.get(&hash)) - .is_some(); - - Ok(if exists { 1 } else { 0 }) + let (mem, exec) = env.jit_env(); + Ok(caller_env::wavmio::validate_certificate(&mem, exec, preimage_type, hash_ptr)) } fn ready_hostio(env: &mut WasmEnv) -> MaybeEscape { diff --git a/sp1-crates/Cargo.lock b/sp1-crates/Cargo.lock index afc0db9fccb..5d5cab059e2 100644 --- a/sp1-crates/Cargo.lock +++ b/sp1-crates/Cargo.lock @@ -608,6 +608,7 @@ checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" name = "caller-env" version = "0.1.0" dependencies = [ + "hex", "k256 0.13.4 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.8.5", "rand_pcg", From 3d3464fffe8e1cdd9aea3018b30c8ee7938859bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Mon, 2 Mar 2026 17:57:10 +0100 Subject: [PATCH 047/189] and for SP1 --- sp1-crates/program/src/imports/wavmio.rs | 188 ++++++----------------- 1 file changed, 49 insertions(+), 139 deletions(-) diff --git a/sp1-crates/program/src/imports/wavmio.rs b/sp1-crates/program/src/imports/wavmio.rs index 395689198f8..6ba2ed7707f 100644 --- a/sp1-crates/program/src/imports/wavmio.rs +++ b/sp1-crates/program/src/imports/wavmio.rs @@ -1,13 +1,13 @@ //! wavmio functions //! -//! The code here is heavily borrowed from nitro's own implementation: -//! https://github.com/OffchainLabs/nitro/blob/3710544c6b36a8927a8dab26d928ad553f08175d/arbitrator/jit/src/wavmio.rs +//! The code here delegates to shared implementations in caller-env. -use crate::{Escape, MaybeEscape, Ptr, read_bytes32, replay::CustomEnvData}; -use std::ops::Deref; -use wasmer::{FunctionEnvMut, MemoryView}; +use core::ops::Deref; +use crate::{ + Escape, MaybeEscape, Ptr, caller_env_adapters::Sp1Env, read_bytes32, replay::CustomEnvData, +}; use caller_env::GuestPtr; -use crate::caller_env_adapters::Sp1Env; +use wasmer::{FunctionEnvMut, MemoryView}; pub fn get_global_state_bytes32( mut ctx: FunctionEnvMut, @@ -24,27 +24,17 @@ pub fn set_global_state_bytes32( idx: u32, src_ptr: Ptr, ) -> MaybeEscape { - let (data, store) = ctx.data_and_store_mut(); - let memory = data.memory.clone().unwrap().view(&store); - - let slice = read_bytes32(src_ptr, &memory)?; - match data.input_mut().large_globals.get_mut(idx as usize) { - Some(global) => *global = *slice, - None => return Escape::logical("global write oob in wavmio.setGlobalStateBytes32"), - } - Ok(()) + let (mem, mut state) = ctx.sp1_env(); + caller_env::wavmio::set_global_state_bytes32(&mem, &mut state, idx, GuestPtr(src_ptr.offset())) + .map_err(Escape::Logical) } pub fn get_global_state_u64( mut ctx: FunctionEnvMut, idx: u32, ) -> Result { - let (data, _store) = ctx.data_and_store_mut(); - - Ok(match data.input().small_globals.get(idx as usize) { - Some(global) => *global, - None => return Escape::logical("global read out of bounds in wavmio.getGlobalStateU64"), - }) + let (_mem, state) = ctx.sp1_env(); + caller_env::wavmio::get_global_state_u64(&state, idx).map_err(Escape::Logical) } pub fn set_global_state_u64( @@ -52,13 +42,8 @@ pub fn set_global_state_u64( idx: u32, val: u64, ) -> MaybeEscape { - let (data, _store) = ctx.data_and_store_mut(); - - match data.input_mut().small_globals.get_mut(idx as usize) { - Some(global) => *global = val, - None => return Escape::logical("global write out of bounds in wavmio.setGlobalStateU64"), - } - Ok(()) + let (_mem, mut state) = ctx.sp1_env(); + caller_env::wavmio::set_global_state_u64(&mut state, idx, val).map_err(Escape::Logical) } pub fn read_inbox_message( @@ -67,19 +52,15 @@ pub fn read_inbox_message( offset: u32, out_ptr: Ptr, ) -> Result { - let (data, store) = ctx.data_and_store_mut(); - let memory = data.memory.clone().unwrap().view(&store); - - let message = match data.input().sequencer_messages.get(&msg_num) { - Some(message) => message, - None => return Escape::logical("missing sequencer inbox message {msg_num}"), - }; - let offset = offset as usize; - let len = std::cmp::min(32, message.len().saturating_sub(offset)); - let read = message.get(offset..(offset + len)).unwrap_or_default(); - memory.write(out_ptr.offset() as u64, read)?; - - Ok(read.len() as u32) + let (mut mem, state) = ctx.sp1_env(); + caller_env::wavmio::read_inbox_message( + &mut mem, + &state, + msg_num, + offset, + GuestPtr(out_ptr.offset()), + ) + .map_err(Escape::Logical) } pub fn read_delayed_inbox_message( @@ -88,19 +69,15 @@ pub fn read_delayed_inbox_message( offset: u32, out_ptr: Ptr, ) -> Result { - let (data, store) = ctx.data_and_store_mut(); - let memory = data.memory.clone().unwrap().view(&store); - - let message = match data.input().delayed_messages.get(&msg_num) { - Some(message) => message, - None => return Escape::logical("missing delayed inbox message {msg_num}"), - }; - let offset = offset as usize; - let len = std::cmp::min(32, message.len().saturating_sub(offset)); - let read = message.get(offset..(offset + len)).unwrap_or_default(); - memory.write(out_ptr.offset() as u64, read)?; - - Ok(read.len() as u32) + let (mut mem, state) = ctx.sp1_env(); + caller_env::wavmio::read_delayed_inbox_message( + &mut mem, + &state, + msg_num, + offset, + GuestPtr(out_ptr.offset()), + ) + .map_err(Escape::Logical) } pub fn resolve_keccak_preimage( @@ -117,20 +94,13 @@ pub fn validate_certificate( preimage_type: u8, hash_ptr: Ptr, ) -> Result { - let (data, store) = ctx.data_and_store_mut(); - let memory = data.memory.clone().unwrap().view(&store); - - let hash = read_bytes32(hash_ptr, &memory)?; - - // Check if preimage exists - let exists = data - .input() - .preimages - .get(&preimage_type) - .and_then(|m| m.get(hash.deref())) - .is_some(); - - Ok(if exists { 1 } else { 0 }) + let (mem, state) = ctx.sp1_env(); + Ok(caller_env::wavmio::validate_certificate( + &mem, + &state, + preimage_type, + GuestPtr(hash_ptr.offset()), + )) } pub fn resolve_typed_preimage( @@ -177,55 +147,17 @@ fn resolve_preimage_impl( out_ptr: Ptr, name: &str, ) -> Result { - let (data, store) = ctx.data_and_store_mut(); - let memory = data.memory.clone().unwrap().view(&store); - let offset = offset as usize; - - let hash = read_bytes32(hash_ptr, &memory)?; - - let Some(preimage) = data - .input() - .preimages - .get(&preimage_type) - .and_then(|m| m.get(hash.deref())) - else { - let hash_hex = hex::encode(hash); - return Escape::logical(format!( - "Missing requested preimage for hash {hash_hex} in {name}" - )); - }; - - #[cfg(debug_assertions)] - { - use crate::input_types::PreimageType; - use sha2::Sha256; - use sha3::{Digest, Keccak256}; - - // Check if preimage rehashes to the provided hash. Exclude blob preimages - let calculated_hash: [u8; 32] = match preimage_type { - PreimageType::Keccak256 => Keccak256::digest(preimage).into(), - PreimageType::Sha2_256 => Sha256::digest(preimage).into(), - PreimageType::EthVersionedHash => *hash, - }; - if calculated_hash != *hash { - panic!( - "Calculated hash {} of preimage {} does not match provided hash {}", - hex::encode(calculated_hash), - hex::encode(preimage), - hex::encode(*hash) - ); - } - } - - if offset % 32 != 0 { - return Escape::logical(format!("bad offset {offset} in {name}")); - } - - let len = std::cmp::min(32, preimage.len().saturating_sub(offset)); - let read = preimage.get(offset..(offset + len)).unwrap_or_default(); - memory.write(out_ptr.offset() as u64, read)?; - - Ok(read.len() as u32) + let (mut mem, state) = ctx.sp1_env(); + caller_env::wavmio::resolve_preimage( + &mut mem, + &state, + preimage_type, + GuestPtr(hash_ptr.offset()), + offset, + GuestPtr(out_ptr.offset()), + name, + ) + .map_err(Escape::Logical) } fn greedy_read( @@ -272,27 +204,5 @@ fn greedy_resolve_typed_preimage_impl( )); }; - #[cfg(debug_assertions)] - { - use crate::input_types::PreimageType; - use sha2::Sha256; - use sha3::{Digest, Keccak256}; - - // Check if preimage rehashes to the provided hash. Exclude blob preimages - let calculated_hash: [u8; 32] = match preimage_type { - PreimageType::Keccak256 => Keccak256::digest(preimage).into(), - PreimageType::Sha2_256 => Sha256::digest(preimage).into(), - PreimageType::EthVersionedHash => *hash, - }; - if calculated_hash != *hash { - panic!( - "Calculated hash {} of preimage {} does not match provided hash {}", - hex::encode(calculated_hash), - hex::encode(preimage), - hex::encode(*hash) - ); - } - } - greedy_read(&preimage, &memory, offset, available, out_ptr) } From 48804af2b32493d4cc485eed9d934845309829fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Mon, 2 Mar 2026 17:57:24 +0100 Subject: [PATCH 048/189] fmt --- crates/caller-env/src/wavmio.rs | 10 +++------- crates/jit/src/wavmio.rs | 10 +++++++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/crates/caller-env/src/wavmio.rs b/crates/caller-env/src/wavmio.rs index 52debdbaf91..7ec39e5ed6d 100644 --- a/crates/caller-env/src/wavmio.rs +++ b/crates/caller-env/src/wavmio.rs @@ -1,9 +1,9 @@ // Copyright 2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md -use core::cmp::min; -use alloc::string::String; use crate::{GuestPtr, MemAccess}; +use alloc::string::String; +use core::cmp::min; /// Trait for accessing wavmio host state (globals, inbox, preimages). pub trait WavmState { @@ -53,11 +53,7 @@ pub fn get_global_state_u64(state: &S, idx: u32) -> Result( - state: &mut S, - idx: u32, - val: u64, -) -> Result<(), String> { +pub fn set_global_state_u64(state: &mut S, idx: u32, val: u64) -> Result<(), String> { if !state.set_u64_global(idx as usize, val) { return Err("global write out of bounds in wavmio.setGlobalStateU64".into()); } diff --git a/crates/jit/src/wavmio.rs b/crates/jit/src/wavmio.rs index 5113d8249fb..5f760724437 100644 --- a/crates/jit/src/wavmio.rs +++ b/crates/jit/src/wavmio.rs @@ -28,8 +28,7 @@ pub fn get_global_state_bytes32(mut env: WasmEnvMut, idx: u32, out_ptr: GuestPtr pub fn set_global_state_bytes32(mut env: WasmEnvMut, idx: u32, src_ptr: GuestPtr) -> MaybeEscape { let (mem, exec) = env.jit_env(); ready_hostio(exec)?; - caller_env::wavmio::set_global_state_bytes32(&mem, exec, idx, src_ptr) - .map_err(Escape::HostIO) + caller_env::wavmio::set_global_state_bytes32(&mem, exec, idx, src_ptr).map_err(Escape::HostIO) } /// Reads 8-bytes of global state @@ -164,7 +163,12 @@ pub fn validate_certificate( hash_ptr: GuestPtr, ) -> Result { let (mem, exec) = env.jit_env(); - Ok(caller_env::wavmio::validate_certificate(&mem, exec, preimage_type, hash_ptr)) + Ok(caller_env::wavmio::validate_certificate( + &mem, + exec, + preimage_type, + hash_ptr, + )) } fn ready_hostio(env: &mut WasmEnv) -> MaybeEscape { From 4629553f77f976a2a43939d9edc706eb252ee956 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Mon, 2 Mar 2026 18:09:26 +0100 Subject: [PATCH 049/189] hex features --- Cargo.toml | 2 +- crates/caller-env/Cargo.toml | 2 +- crates/caller-env/src/wavmio.rs | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 31b52755c1c..f76e977105a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -55,7 +55,7 @@ enum-iterator = { version = "2.0.1" } eyre = { version = "0.6.5" } fnv = { version = "1.0.7" } gperftools = { version = "0.2.0" } -hex = { version = "0.4.3" } +hex = { version = "0.4.3", default-features = false } k256 = { version = "0.13.4", default-features = false} lazy_static = { version = "1.4.0" } libc = { version = "0.2.132" } diff --git a/crates/caller-env/Cargo.toml b/crates/caller-env/Cargo.toml index 1cbb7be97a3..1e58e055388 100644 --- a/crates/caller-env/Cargo.toml +++ b/crates/caller-env/Cargo.toml @@ -11,7 +11,7 @@ rust-version.workspace = true [dependencies] brotli = { workspace = true, optional = true } -hex = { workspace = true } +hex = { workspace = true, features = ["alloc"] } k256 = { workspace = true, features = ["ecdsa"] } rand = { workspace = true } rand_pcg = { workspace = true } diff --git a/crates/caller-env/src/wavmio.rs b/crates/caller-env/src/wavmio.rs index 7ec39e5ed6d..ab1f2d24b86 100644 --- a/crates/caller-env/src/wavmio.rs +++ b/crates/caller-env/src/wavmio.rs @@ -3,6 +3,7 @@ use crate::{GuestPtr, MemAccess}; use alloc::string::String; +use alloc::format; use core::cmp::min; /// Trait for accessing wavmio host state (globals, inbox, preimages). From 80c8e84574c9ac16bedd26ac274d255a2f3ae226 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 3 Mar 2026 09:04:09 +0100 Subject: [PATCH 050/189] Alias import; gp helper --- crates/jit/src/wavmio.rs | 31 +++---- sp1-crates/program/src/imports/wavmio.rs | 113 ++++++++++------------- 2 files changed, 61 insertions(+), 83 deletions(-) diff --git a/crates/jit/src/wavmio.rs b/crates/jit/src/wavmio.rs index 5f760724437..ed9876d63cf 100644 --- a/crates/jit/src/wavmio.rs +++ b/crates/jit/src/wavmio.rs @@ -6,7 +6,8 @@ use crate::{ machine::{Escape, MaybeEscape, WasmEnv, WasmEnvMut}, }; use arbutil::Color; -use caller_env::GuestPtr; +use ::caller_env::wavmio as caller_env; +use ::caller_env::GuestPtr; use std::{ io, io::{BufReader, BufWriter, ErrorKind}, @@ -16,36 +17,30 @@ use std::{ use validation::local_target; use validation::transfer::receive_validation_input; -/// Reads 32-bytes of global state. pub fn get_global_state_bytes32(mut env: WasmEnvMut, idx: u32, out_ptr: GuestPtr) -> MaybeEscape { let (mut mem, exec) = env.jit_env(); ready_hostio(exec)?; - caller_env::wavmio::get_global_state_bytes32(&mut mem, exec, idx, out_ptr) - .map_err(Escape::HostIO) + caller_env::get_global_state_bytes32(&mut mem, exec, idx, out_ptr).map_err(Escape::HostIO) } -/// Writes 32-bytes of global state. pub fn set_global_state_bytes32(mut env: WasmEnvMut, idx: u32, src_ptr: GuestPtr) -> MaybeEscape { let (mem, exec) = env.jit_env(); ready_hostio(exec)?; - caller_env::wavmio::set_global_state_bytes32(&mem, exec, idx, src_ptr).map_err(Escape::HostIO) + caller_env::set_global_state_bytes32(&mem, exec, idx, src_ptr).map_err(Escape::HostIO) } -/// Reads 8-bytes of global state pub fn get_global_state_u64(mut env: WasmEnvMut, idx: u32) -> Result { let (_, exec) = env.jit_env(); ready_hostio(exec)?; - caller_env::wavmio::get_global_state_u64(exec, idx).map_err(Escape::HostIO) + caller_env::get_global_state_u64(exec, idx).map_err(Escape::HostIO) } -/// Writes 8-bytes of global state pub fn set_global_state_u64(mut env: WasmEnvMut, idx: u32, val: u64) -> MaybeEscape { let (_, exec) = env.jit_env(); ready_hostio(exec)?; - caller_env::wavmio::set_global_state_u64(exec, idx, val).map_err(Escape::HostIO) + caller_env::set_global_state_u64(exec, idx, val).map_err(Escape::HostIO) } -/// Reads an inbox message. pub fn read_inbox_message( mut env: WasmEnvMut, msg_num: u64, @@ -54,11 +49,9 @@ pub fn read_inbox_message( ) -> Result { let (mut mem, exec) = env.jit_env(); ready_hostio(exec)?; - caller_env::wavmio::read_inbox_message(&mut mem, exec, msg_num, offset, out_ptr) - .map_err(Escape::HostIO) + caller_env::read_inbox_message(&mut mem, exec, msg_num, offset, out_ptr).map_err(Escape::HostIO) } -/// Reads a delayed inbox message. pub fn read_delayed_inbox_message( mut env: WasmEnvMut, msg_num: u64, @@ -67,11 +60,10 @@ pub fn read_delayed_inbox_message( ) -> Result { let (mut mem, exec) = env.jit_env(); ready_hostio(exec)?; - caller_env::wavmio::read_delayed_inbox_message(&mut mem, exec, msg_num, offset, out_ptr) + caller_env::read_delayed_inbox_message(&mut mem, exec, msg_num, offset, out_ptr) .map_err(Escape::HostIO) } -/// Retrieves the preimage of the given hash. #[deprecated] // we're just keeping this around until we no longer need to validate old replay binaries pub fn resolve_keccak_preimage( env: WasmEnvMut, @@ -127,12 +119,11 @@ fn resolve_preimage_impl( .get(&preimage_type) .and_then(|m| m.get(&hash)) { - // Check if preimage rehashes to the provided hash. Exclude blob preimages let calculated_hash: [u8; 32] = match preimage_type { PreimageType::Keccak256 => Keccak256::digest(preimage).into(), PreimageType::Sha2_256 => Sha256::digest(preimage).into(), PreimageType::EthVersionedHash => *hash, - PreimageType::DACertificate => *hash, // Can't verify DACertificate hash, just accept it + PreimageType::DACertificate => *hash, }; if calculated_hash != *hash { return Escape::hostio(format!( @@ -145,7 +136,7 @@ fn resolve_preimage_impl( } } - caller_env::wavmio::resolve_preimage( + caller_env::resolve_preimage( &mut mem, exec, preimage_type, @@ -163,7 +154,7 @@ pub fn validate_certificate( hash_ptr: GuestPtr, ) -> Result { let (mem, exec) = env.jit_env(); - Ok(caller_env::wavmio::validate_certificate( + Ok(caller_env::validate_certificate( &mem, exec, preimage_type, diff --git a/sp1-crates/program/src/imports/wavmio.rs b/sp1-crates/program/src/imports/wavmio.rs index 6ba2ed7707f..ae23c707542 100644 --- a/sp1-crates/program/src/imports/wavmio.rs +++ b/sp1-crates/program/src/imports/wavmio.rs @@ -1,22 +1,24 @@ -//! wavmio functions -//! -//! The code here delegates to shared implementations in caller-env. +//! wavmio functions — thin wrappers delegating to caller_env::wavmio. -use core::ops::Deref; use crate::{ Escape, MaybeEscape, Ptr, caller_env_adapters::Sp1Env, read_bytes32, replay::CustomEnvData, }; -use caller_env::GuestPtr; +use ::caller_env::wavmio as caller_env; +use ::caller_env::GuestPtr; +use core::ops::Deref; use wasmer::{FunctionEnvMut, MemoryView}; +fn gp(p: Ptr) -> GuestPtr { + GuestPtr(p.offset()) +} + pub fn get_global_state_bytes32( mut ctx: FunctionEnvMut, idx: u32, out_ptr: Ptr, ) -> MaybeEscape { let (mut mem, state) = ctx.sp1_env(); - caller_env::wavmio::get_global_state_bytes32(&mut mem, &state, idx, GuestPtr(out_ptr.offset())) - .map_err(Escape::Logical) + caller_env::get_global_state_bytes32(&mut mem, &state, idx, gp(out_ptr)).map_err(Escape::Logical) } pub fn set_global_state_bytes32( @@ -25,8 +27,7 @@ pub fn set_global_state_bytes32( src_ptr: Ptr, ) -> MaybeEscape { let (mem, mut state) = ctx.sp1_env(); - caller_env::wavmio::set_global_state_bytes32(&mem, &mut state, idx, GuestPtr(src_ptr.offset())) - .map_err(Escape::Logical) + caller_env::set_global_state_bytes32(&mem, &mut state, idx, gp(src_ptr)).map_err(Escape::Logical) } pub fn get_global_state_u64( @@ -34,7 +35,7 @@ pub fn get_global_state_u64( idx: u32, ) -> Result { let (_mem, state) = ctx.sp1_env(); - caller_env::wavmio::get_global_state_u64(&state, idx).map_err(Escape::Logical) + caller_env::get_global_state_u64(&state, idx).map_err(Escape::Logical) } pub fn set_global_state_u64( @@ -43,7 +44,7 @@ pub fn set_global_state_u64( val: u64, ) -> MaybeEscape { let (_mem, mut state) = ctx.sp1_env(); - caller_env::wavmio::set_global_state_u64(&mut state, idx, val).map_err(Escape::Logical) + caller_env::set_global_state_u64(&mut state, idx, val).map_err(Escape::Logical) } pub fn read_inbox_message( @@ -53,14 +54,8 @@ pub fn read_inbox_message( out_ptr: Ptr, ) -> Result { let (mut mem, state) = ctx.sp1_env(); - caller_env::wavmio::read_inbox_message( - &mut mem, - &state, - msg_num, - offset, - GuestPtr(out_ptr.offset()), - ) - .map_err(Escape::Logical) + caller_env::read_inbox_message(&mut mem, &state, msg_num, offset, gp(out_ptr)) + .map_err(Escape::Logical) } pub fn read_delayed_inbox_message( @@ -70,14 +65,8 @@ pub fn read_delayed_inbox_message( out_ptr: Ptr, ) -> Result { let (mut mem, state) = ctx.sp1_env(); - caller_env::wavmio::read_delayed_inbox_message( - &mut mem, - &state, - msg_num, - offset, - GuestPtr(out_ptr.offset()), - ) - .map_err(Escape::Logical) + caller_env::read_delayed_inbox_message(&mut mem, &state, msg_num, offset, gp(out_ptr)) + .map_err(Escape::Logical) } pub fn resolve_keccak_preimage( @@ -89,37 +78,60 @@ pub fn resolve_keccak_preimage( resolve_preimage_impl(ctx, 0, hash_ptr, offset, out_ptr, "wavmio.ResolvePreImage") } +pub fn resolve_typed_preimage( + ctx: FunctionEnvMut, + preimage_type: u8, + hash_ptr: Ptr, + offset: u32, + out_ptr: Ptr, +) -> Result { + resolve_preimage_impl( + ctx, + preimage_type, + hash_ptr, + offset, + out_ptr, + "wavmio.ResolveTypedPreimage", + ) +} + pub fn validate_certificate( mut ctx: FunctionEnvMut, preimage_type: u8, hash_ptr: Ptr, ) -> Result { let (mem, state) = ctx.sp1_env(); - Ok(caller_env::wavmio::validate_certificate( + Ok(caller_env::validate_certificate( &mem, &state, preimage_type, - GuestPtr(hash_ptr.offset()), + gp(hash_ptr), )) } -pub fn resolve_typed_preimage( - ctx: FunctionEnvMut, +fn resolve_preimage_impl( + mut ctx: FunctionEnvMut, preimage_type: u8, hash_ptr: Ptr, offset: u32, out_ptr: Ptr, + name: &str, ) -> Result { - resolve_preimage_impl( - ctx, + let (mut mem, state) = ctx.sp1_env(); + caller_env::resolve_preimage( + &mut mem, + &state, preimage_type, - hash_ptr, + gp(hash_ptr), offset, - out_ptr, - "wavmio.ResolveTypedPreimage", + gp(out_ptr), + name, ) + .map_err(Escape::Logical) } +// Greedy preimage resolution — kept separate, will be refactored independently. + pub fn greedy_resolve_typed_preimage( ctx: FunctionEnvMut, preimage_type: u8, @@ -139,27 +151,6 @@ pub fn greedy_resolve_typed_preimage( ) } -fn resolve_preimage_impl( - mut ctx: FunctionEnvMut, - preimage_type: u8, - hash_ptr: Ptr, - offset: u32, - out_ptr: Ptr, - name: &str, -) -> Result { - let (mut mem, state) = ctx.sp1_env(); - caller_env::wavmio::resolve_preimage( - &mut mem, - &state, - preimage_type, - GuestPtr(hash_ptr.offset()), - offset, - GuestPtr(out_ptr.offset()), - name, - ) - .map_err(Escape::Logical) -} - fn greedy_read( data: &[u8], memory: &MemoryView, @@ -173,7 +164,6 @@ fn greedy_read( .get(offset..(offset + len as usize)) .unwrap_or_default(); memory.write(out_ptr.offset() as u64, read)?; - Ok(full_len) } @@ -189,20 +179,17 @@ fn greedy_resolve_typed_preimage_impl( let (data, store) = ctx.data_and_store_mut(); let memory = data.memory.clone().unwrap().view(&store); let offset = offset as usize; - let hash = read_bytes32(hash_ptr, &memory)?; - let Some(preimage) = data .input() .preimages .get(&preimage_type) .and_then(|m| m.get(hash.deref())) else { - let hash_hex = hex::encode(hash); return Escape::logical(format!( - "Missing requested preimage for hash {hash_hex} in {name}" + "Missing requested preimage for hash {} in {name}", + hex::encode(hash) )); }; - greedy_read(&preimage, &memory, offset, available, out_ptr) } From 2d7cc201466f53c28ca21605e69ec5033cea78dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 3 Mar 2026 10:10:16 +0100 Subject: [PATCH 051/189] Introduce WavmEnv trait and move split to caller-env --- crates/caller-env/src/wavmio.rs | 56 +++++--- crates/jit/src/caller_env.rs | 35 +++-- crates/jit/src/wavmio.rs | 63 ++++----- sp1-crates/program/src/caller_env_adapters.rs | 19 +-- sp1-crates/program/src/imports/wavmio.rs | 120 +++--------------- 5 files changed, 113 insertions(+), 180 deletions(-) diff --git a/crates/caller-env/src/wavmio.rs b/crates/caller-env/src/wavmio.rs index ab1f2d24b86..9a08a50c51a 100644 --- a/crates/caller-env/src/wavmio.rs +++ b/crates/caller-env/src/wavmio.rs @@ -17,13 +17,20 @@ pub trait WavmState { fn get_preimage(&self, preimage_type: u8, hash: &[u8; 32]) -> Option<&[u8]>; } +/// Unified environment trait: implementors split their wasmer FunctionEnvMut into (MemAccess, WavmState). +pub trait WavmEnv { + type Mem<'a>: MemAccess where Self: 'a; + type State<'a>: WavmState where Self: 'a; + fn wavm_env(&mut self) -> (Self::Mem<'_>, Self::State<'_>); +} + /// Reads 32-bytes of global state and writes to guest memory. -pub fn get_global_state_bytes32( - mem: &mut M, - state: &S, +pub fn get_global_state_bytes32( + env: &mut impl WavmEnv, idx: u32, out_ptr: GuestPtr, ) -> Result<(), String> { + let (mut mem, state) = env.wavm_env(); let Some(global) = state.get_bytes32_global(idx as usize) else { return Err("global read out of bounds in wavmio.getGlobalStateBytes32".into()); }; @@ -32,12 +39,12 @@ pub fn get_global_state_bytes32( } /// Reads 32-bytes from guest memory and writes to global state. -pub fn set_global_state_bytes32( - mem: &M, - state: &mut S, +pub fn set_global_state_bytes32( + env: &mut impl WavmEnv, idx: u32, src_ptr: GuestPtr, ) -> Result<(), String> { + let (mem, mut state) = env.wavm_env(); let val = mem.read_fixed(src_ptr); if !state.set_bytes32_global(idx as usize, val) { return Err("global write oob in wavmio.setGlobalStateBytes32".into()); @@ -46,7 +53,11 @@ pub fn set_global_state_bytes32( } /// Reads 8-bytes of global state. -pub fn get_global_state_u64(state: &S, idx: u32) -> Result { +pub fn get_global_state_u64( + env: &mut impl WavmEnv, + idx: u32, +) -> Result { + let (_mem, state) = env.wavm_env(); match state.get_u64_global(idx as usize) { Some(val) => Ok(val), None => Err("global read out of bounds in wavmio.getGlobalStateU64".into()), @@ -54,7 +65,12 @@ pub fn get_global_state_u64(state: &S, idx: u32) -> Result(state: &mut S, idx: u32, val: u64) -> Result<(), String> { +pub fn set_global_state_u64( + env: &mut impl WavmEnv, + idx: u32, + val: u64, +) -> Result<(), String> { + let (_mem, mut state) = env.wavm_env(); if !state.set_u64_global(idx as usize, val) { return Err("global write out of bounds in wavmio.setGlobalStateU64".into()); } @@ -62,13 +78,13 @@ pub fn set_global_state_u64(state: &mut S, idx: u32, val: u64) -> } /// Reads up to 32 bytes of a sequencer inbox message at the given offset. -pub fn read_inbox_message( - mem: &mut M, - state: &S, +pub fn read_inbox_message( + env: &mut impl WavmEnv, msg_num: u64, offset: u32, out_ptr: GuestPtr, ) -> Result { + let (mut mem, state) = env.wavm_env(); let message = match state.get_sequencer_message(msg_num) { Some(message) => message, None => return Err(format!("missing sequencer inbox message {msg_num}")), @@ -81,13 +97,13 @@ pub fn read_inbox_message( } /// Reads up to 32 bytes of a delayed inbox message at the given offset. -pub fn read_delayed_inbox_message( - mem: &mut M, - state: &S, +pub fn read_delayed_inbox_message( + env: &mut impl WavmEnv, msg_num: u64, offset: u32, out_ptr: GuestPtr, ) -> Result { + let (mut mem, state) = env.wavm_env(); let message = match state.get_delayed_message(msg_num) { Some(message) => message, None => return Err(format!("missing delayed inbox message {msg_num}")), @@ -100,15 +116,15 @@ pub fn read_delayed_inbox_message( } /// Looks up a preimage by type and hash, reads up to 32 bytes at an aligned offset. -pub fn resolve_preimage( - mem: &mut M, - state: &S, +pub fn resolve_preimage( + env: &mut impl WavmEnv, preimage_type: u8, hash_ptr: GuestPtr, offset: u32, out_ptr: GuestPtr, name: &str, ) -> Result { + let (mut mem, state) = env.wavm_env(); let hash = mem.read_fixed(hash_ptr); let offset = offset as usize; @@ -130,12 +146,12 @@ pub fn resolve_preimage( } /// Returns 1 if a preimage exists for the given type and hash, 0 otherwise. -pub fn validate_certificate( - mem: &M, - state: &S, +pub fn validate_certificate( + env: &mut impl WavmEnv, preimage_type: u8, hash_ptr: GuestPtr, ) -> u8 { + let (mem, state) = env.wavm_env(); let hash = mem.read_fixed(hash_ptr); match state.get_preimage(preimage_type, &hash) { Some(_) => 1, diff --git a/crates/jit/src/caller_env.rs b/crates/jit/src/caller_env.rs index 66a240b9496..3cfd6807c5b 100644 --- a/crates/jit/src/caller_env.rs +++ b/crates/jit/src/caller_env.rs @@ -3,7 +3,7 @@ use crate::machine::{WasmEnv, WasmEnvMut}; use arbutil::{Bytes20, Bytes32, PreimageType}; -use caller_env::wavmio::WavmState; +use caller_env::wavmio::{WavmEnv, WavmState}; use caller_env::{ExecEnv, GuestPtr, MemAccess}; use rand::RngCore; use std::mem::{self, MaybeUninit}; @@ -30,6 +30,22 @@ impl<'a> JitEnv<'a> for WasmEnvMut<'a> { } } +/// Newtype for implementing WavmEnv (orphan rule: FunctionEnvMut is foreign). +pub(crate) struct JitWavm<'e>(pub WasmEnvMut<'e>); + +/// Newtype wrapping &mut WasmEnv to implement WavmState (orphan rule). +pub(crate) struct JitState<'a>(pub &'a mut WasmEnv); + +impl WavmEnv for JitWavm<'_> { + type Mem<'a> = JitMemAccess<'a> where Self: 'a; + type State<'a> = JitState<'a> where Self: 'a; + + fn wavm_env(&mut self) -> (JitMemAccess<'_>, JitState<'_>) { + let (mem, wenv) = self.0.jit_env(); + (mem, JitState(wenv)) + } +} + impl JitMemAccess<'_> { fn view(&self) -> MemoryView<'_> { self.memory.view(&self.store) @@ -134,13 +150,13 @@ impl ExecEnv for JitExecEnv<'_> { } } -impl WavmState for WasmEnv { +impl WavmState for JitState<'_> { fn get_u64_global(&self, idx: usize) -> Option { - self.small_globals.get(idx).copied() + self.0.small_globals.get(idx).copied() } fn set_u64_global(&mut self, idx: usize, val: u64) -> bool { - match self.small_globals.get_mut(idx) { + match self.0.small_globals.get_mut(idx) { Some(g) => { *g = val; true @@ -150,11 +166,11 @@ impl WavmState for WasmEnv { } fn get_bytes32_global(&self, idx: usize) -> Option<&[u8; 32]> { - self.large_globals.get(idx).map(|b| &b.0) + self.0.large_globals.get(idx).map(|b| &b.0) } fn set_bytes32_global(&mut self, idx: usize, val: [u8; 32]) -> bool { - match self.large_globals.get_mut(idx) { + match self.0.large_globals.get_mut(idx) { Some(g) => { *g = val.into(); true @@ -164,16 +180,17 @@ impl WavmState for WasmEnv { } fn get_sequencer_message(&self, num: u64) -> Option<&[u8]> { - self.sequencer_messages.get(&num).map(|v| v.as_slice()) + self.0.sequencer_messages.get(&num).map(|v| v.as_slice()) } fn get_delayed_message(&self, num: u64) -> Option<&[u8]> { - self.delayed_messages.get(&num).map(|v| v.as_slice()) + self.0.delayed_messages.get(&num).map(|v| v.as_slice()) } fn get_preimage(&self, preimage_type: u8, hash: &[u8; 32]) -> Option<&[u8]> { let pt: PreimageType = preimage_type.try_into().ok()?; - self.preimages + self.0 + .preimages .get(&pt) .and_then(|m| m.get(&Bytes32::from(*hash))) .map(|v| v.as_slice()) diff --git a/crates/jit/src/wavmio.rs b/crates/jit/src/wavmio.rs index ed9876d63cf..354f023dfc9 100644 --- a/crates/jit/src/wavmio.rs +++ b/crates/jit/src/wavmio.rs @@ -1,10 +1,8 @@ // Copyright 2022-2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md -use crate::{ - caller_env::JitEnv, - machine::{Escape, MaybeEscape, WasmEnv, WasmEnvMut}, -}; +use crate::caller_env::JitWavm; +use crate::machine::{Escape, MaybeEscape, WasmEnv, WasmEnvMut}; use arbutil::Color; use ::caller_env::wavmio as caller_env; use ::caller_env::GuestPtr; @@ -18,27 +16,23 @@ use validation::local_target; use validation::transfer::receive_validation_input; pub fn get_global_state_bytes32(mut env: WasmEnvMut, idx: u32, out_ptr: GuestPtr) -> MaybeEscape { - let (mut mem, exec) = env.jit_env(); - ready_hostio(exec)?; - caller_env::get_global_state_bytes32(&mut mem, exec, idx, out_ptr).map_err(Escape::HostIO) + ready_hostio(env.data_mut())?; + caller_env::get_global_state_bytes32(&mut JitWavm(env), idx, out_ptr).map_err(Escape::HostIO) } pub fn set_global_state_bytes32(mut env: WasmEnvMut, idx: u32, src_ptr: GuestPtr) -> MaybeEscape { - let (mem, exec) = env.jit_env(); - ready_hostio(exec)?; - caller_env::set_global_state_bytes32(&mem, exec, idx, src_ptr).map_err(Escape::HostIO) + ready_hostio(env.data_mut())?; + caller_env::set_global_state_bytes32(&mut JitWavm(env), idx, src_ptr).map_err(Escape::HostIO) } pub fn get_global_state_u64(mut env: WasmEnvMut, idx: u32) -> Result { - let (_, exec) = env.jit_env(); - ready_hostio(exec)?; - caller_env::get_global_state_u64(exec, idx).map_err(Escape::HostIO) + ready_hostio(env.data_mut())?; + caller_env::get_global_state_u64(&mut JitWavm(env), idx).map_err(Escape::HostIO) } pub fn set_global_state_u64(mut env: WasmEnvMut, idx: u32, val: u64) -> MaybeEscape { - let (_, exec) = env.jit_env(); - ready_hostio(exec)?; - caller_env::set_global_state_u64(exec, idx, val).map_err(Escape::HostIO) + ready_hostio(env.data_mut())?; + caller_env::set_global_state_u64(&mut JitWavm(env), idx, val).map_err(Escape::HostIO) } pub fn read_inbox_message( @@ -47,9 +41,9 @@ pub fn read_inbox_message( offset: u32, out_ptr: GuestPtr, ) -> Result { - let (mut mem, exec) = env.jit_env(); - ready_hostio(exec)?; - caller_env::read_inbox_message(&mut mem, exec, msg_num, offset, out_ptr).map_err(Escape::HostIO) + ready_hostio(env.data_mut())?; + caller_env::read_inbox_message(&mut JitWavm(env), msg_num, offset, out_ptr) + .map_err(Escape::HostIO) } pub fn read_delayed_inbox_message( @@ -58,9 +52,8 @@ pub fn read_delayed_inbox_message( offset: u32, out_ptr: GuestPtr, ) -> Result { - let (mut mem, exec) = env.jit_env(); - ready_hostio(exec)?; - caller_env::read_delayed_inbox_message(&mut mem, exec, msg_num, offset, out_ptr) + ready_hostio(env.data_mut())?; + caller_env::read_delayed_inbox_message(&mut JitWavm(env), msg_num, offset, out_ptr) .map_err(Escape::HostIO) } @@ -99,14 +92,16 @@ fn resolve_preimage_impl( out_ptr: GuestPtr, name: &str, ) -> Result { - let (mut mem, exec) = env.jit_env(); + ready_hostio(env.data_mut())?; #[cfg(debug_assertions)] { + use crate::caller_env::JitEnv; use arbutil::PreimageType; use sha2::Sha256; use sha3::{Digest, Keccak256}; + let (mut mem, exec) = env.jit_env(); let hash = mem.read_bytes32(hash_ptr); let Ok(preimage_type) = preimage_type.try_into() else { @@ -136,30 +131,16 @@ fn resolve_preimage_impl( } } - caller_env::resolve_preimage( - &mut mem, - exec, - preimage_type, - hash_ptr, - offset, - out_ptr, - name, - ) - .map_err(Escape::HostIO) + caller_env::resolve_preimage(&mut JitWavm(env), preimage_type, hash_ptr, offset, out_ptr, name) + .map_err(Escape::HostIO) } pub fn validate_certificate( - mut env: WasmEnvMut, + env: WasmEnvMut, preimage_type: u8, hash_ptr: GuestPtr, ) -> Result { - let (mem, exec) = env.jit_env(); - Ok(caller_env::validate_certificate( - &mem, - exec, - preimage_type, - hash_ptr, - )) + Ok(caller_env::validate_certificate(&mut JitWavm(env), preimage_type, hash_ptr)) } fn ready_hostio(env: &mut WasmEnv) -> MaybeEscape { diff --git a/sp1-crates/program/src/caller_env_adapters.rs b/sp1-crates/program/src/caller_env_adapters.rs index 5ac200c272f..d2796b475bf 100644 --- a/sp1-crates/program/src/caller_env_adapters.rs +++ b/sp1-crates/program/src/caller_env_adapters.rs @@ -1,7 +1,7 @@ // Copyright 2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md -use caller_env::wavmio::WavmState; +use caller_env::wavmio::{WavmEnv, WavmState}; use caller_env::{GuestPtr, MemAccess}; use prover::binary_input::Input; use wasmer::{FunctionEnvMut, Memory, StoreMut}; @@ -127,15 +127,16 @@ impl WavmState for WavmInput<'_> { } } -/// Extraction trait for splitting FunctionEnvMut into MemAccess + WavmState. -pub(crate) trait Sp1Env { - fn sp1_env(&mut self) -> (Sp1MemAccess<'_>, WavmInput<'_>); -} +/// Newtype for implementing WavmEnv (orphan rule: FunctionEnvMut is foreign). +pub(crate) struct Sp1Wavm<'e>(pub FunctionEnvMut<'e, CustomEnvData>); + +impl WavmEnv for Sp1Wavm<'_> { + type Mem<'a> = Sp1MemAccess<'a> where Self: 'a; + type State<'a> = WavmInput<'a> where Self: 'a; -impl Sp1Env for FunctionEnvMut<'_, CustomEnvData> { - fn sp1_env(&mut self) -> (Sp1MemAccess<'_>, WavmInput<'_>) { - let memory = self.data().memory.clone().unwrap(); - let (data, store) = self.data_and_store_mut(); + fn wavm_env(&mut self) -> (Sp1MemAccess<'_>, WavmInput<'_>) { + let memory = self.0.data().memory.clone().unwrap(); + let (data, store) = self.0.data_and_store_mut(); let input = data.input_mut(); (Sp1MemAccess { memory, store }, WavmInput(input)) } diff --git a/sp1-crates/program/src/imports/wavmio.rs b/sp1-crates/program/src/imports/wavmio.rs index ae23c707542..293f2e8275d 100644 --- a/sp1-crates/program/src/imports/wavmio.rs +++ b/sp1-crates/program/src/imports/wavmio.rs @@ -1,7 +1,7 @@ //! wavmio functions — thin wrappers delegating to caller_env::wavmio. use crate::{ - Escape, MaybeEscape, Ptr, caller_env_adapters::Sp1Env, read_bytes32, replay::CustomEnvData, + Escape, MaybeEscape, Ptr, caller_env_adapters::Sp1Wavm, read_bytes32, replay::CustomEnvData, }; use ::caller_env::wavmio as caller_env; use ::caller_env::GuestPtr; @@ -12,122 +12,40 @@ fn gp(p: Ptr) -> GuestPtr { GuestPtr(p.offset()) } -pub fn get_global_state_bytes32( - mut ctx: FunctionEnvMut, - idx: u32, - out_ptr: Ptr, -) -> MaybeEscape { - let (mut mem, state) = ctx.sp1_env(); - caller_env::get_global_state_bytes32(&mut mem, &state, idx, gp(out_ptr)).map_err(Escape::Logical) +pub fn get_global_state_bytes32(ctx: FunctionEnvMut, idx: u32, out_ptr: Ptr) -> MaybeEscape { + caller_env::get_global_state_bytes32(&mut Sp1Wavm(ctx), idx, gp(out_ptr)).map_err(Escape::Logical) } -pub fn set_global_state_bytes32( - mut ctx: FunctionEnvMut, - idx: u32, - src_ptr: Ptr, -) -> MaybeEscape { - let (mem, mut state) = ctx.sp1_env(); - caller_env::set_global_state_bytes32(&mem, &mut state, idx, gp(src_ptr)).map_err(Escape::Logical) +pub fn set_global_state_bytes32(ctx: FunctionEnvMut, idx: u32, src_ptr: Ptr) -> MaybeEscape { + caller_env::set_global_state_bytes32(&mut Sp1Wavm(ctx), idx, gp(src_ptr)).map_err(Escape::Logical) } -pub fn get_global_state_u64( - mut ctx: FunctionEnvMut, - idx: u32, -) -> Result { - let (_mem, state) = ctx.sp1_env(); - caller_env::get_global_state_u64(&state, idx).map_err(Escape::Logical) +pub fn get_global_state_u64(ctx: FunctionEnvMut, idx: u32) -> Result { + caller_env::get_global_state_u64(&mut Sp1Wavm(ctx), idx).map_err(Escape::Logical) } -pub fn set_global_state_u64( - mut ctx: FunctionEnvMut, - idx: u32, - val: u64, -) -> MaybeEscape { - let (_mem, mut state) = ctx.sp1_env(); - caller_env::set_global_state_u64(&mut state, idx, val).map_err(Escape::Logical) +pub fn set_global_state_u64(ctx: FunctionEnvMut, idx: u32, val: u64) -> MaybeEscape { + caller_env::set_global_state_u64(&mut Sp1Wavm(ctx), idx, val).map_err(Escape::Logical) } -pub fn read_inbox_message( - mut ctx: FunctionEnvMut, - msg_num: u64, - offset: u32, - out_ptr: Ptr, -) -> Result { - let (mut mem, state) = ctx.sp1_env(); - caller_env::read_inbox_message(&mut mem, &state, msg_num, offset, gp(out_ptr)) - .map_err(Escape::Logical) +pub fn read_inbox_message(ctx: FunctionEnvMut, msg_num: u64, offset: u32, out_ptr: Ptr) -> Result { + caller_env::read_inbox_message(&mut Sp1Wavm(ctx), msg_num, offset, gp(out_ptr)).map_err(Escape::Logical) } -pub fn read_delayed_inbox_message( - mut ctx: FunctionEnvMut, - msg_num: u64, - offset: u32, - out_ptr: Ptr, -) -> Result { - let (mut mem, state) = ctx.sp1_env(); - caller_env::read_delayed_inbox_message(&mut mem, &state, msg_num, offset, gp(out_ptr)) - .map_err(Escape::Logical) +pub fn read_delayed_inbox_message(ctx: FunctionEnvMut, msg_num: u64, offset: u32, out_ptr: Ptr) -> Result { + caller_env::read_delayed_inbox_message(&mut Sp1Wavm(ctx), msg_num, offset, gp(out_ptr)).map_err(Escape::Logical) } -pub fn resolve_keccak_preimage( - ctx: FunctionEnvMut, - hash_ptr: Ptr, - offset: u32, - out_ptr: Ptr, -) -> Result { - resolve_preimage_impl(ctx, 0, hash_ptr, offset, out_ptr, "wavmio.ResolvePreImage") -} - -pub fn resolve_typed_preimage( - ctx: FunctionEnvMut, - preimage_type: u8, - hash_ptr: Ptr, - offset: u32, - out_ptr: Ptr, -) -> Result { - resolve_preimage_impl( - ctx, - preimage_type, - hash_ptr, - offset, - out_ptr, - "wavmio.ResolveTypedPreimage", - ) +pub fn resolve_keccak_preimage(ctx: FunctionEnvMut, hash_ptr: Ptr, offset: u32, out_ptr: Ptr) -> Result { + caller_env::resolve_preimage(&mut Sp1Wavm(ctx), 0, gp(hash_ptr), offset, gp(out_ptr), "wavmio.ResolvePreImage").map_err(Escape::Logical) } -pub fn validate_certificate( - mut ctx: FunctionEnvMut, - preimage_type: u8, - hash_ptr: Ptr, -) -> Result { - let (mem, state) = ctx.sp1_env(); - Ok(caller_env::validate_certificate( - &mem, - &state, - preimage_type, - gp(hash_ptr), - )) +pub fn resolve_typed_preimage(ctx: FunctionEnvMut, preimage_type: u8, hash_ptr: Ptr, offset: u32, out_ptr: Ptr) -> Result { + caller_env::resolve_preimage(&mut Sp1Wavm(ctx), preimage_type, gp(hash_ptr), offset, gp(out_ptr), "wavmio.ResolveTypedPreimage").map_err(Escape::Logical) } -fn resolve_preimage_impl( - mut ctx: FunctionEnvMut, - preimage_type: u8, - hash_ptr: Ptr, - offset: u32, - out_ptr: Ptr, - name: &str, -) -> Result { - let (mut mem, state) = ctx.sp1_env(); - caller_env::resolve_preimage( - &mut mem, - &state, - preimage_type, - gp(hash_ptr), - offset, - gp(out_ptr), - name, - ) - .map_err(Escape::Logical) +pub fn validate_certificate(ctx: FunctionEnvMut, preimage_type: u8, hash_ptr: Ptr) -> Result { + Ok(caller_env::validate_certificate(&mut Sp1Wavm(ctx), preimage_type, gp(hash_ptr))) } // Greedy preimage resolution — kept separate, will be refactored independently. From 36bc89518bd34280b273ef346d748ada3418e3b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 3 Mar 2026 12:15:15 +0100 Subject: [PATCH 052/189] Remove JitEnv trait --- crates/jit/src/arbcompress.rs | 7 +++---- crates/jit/src/arbcrypto.rs | 10 ++++----- crates/jit/src/caller_env.rs | 22 ++++++++------------ crates/jit/src/program.rs | 38 +++++++++++++++++------------------ crates/jit/src/wasip1_stub.rs | 7 +++---- crates/jit/src/wavmio.rs | 6 +++--- 6 files changed, 41 insertions(+), 49 deletions(-) diff --git a/crates/jit/src/arbcompress.rs b/crates/jit/src/arbcompress.rs index 2faad117185..a2e4934ce52 100644 --- a/crates/jit/src/arbcompress.rs +++ b/crates/jit/src/arbcompress.rs @@ -1,7 +1,7 @@ // Copyright 2022-2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md -use crate::caller_env::{JitEnv, JitExecEnv}; +use crate::caller_env::{jit_env, JitExecEnv}; use crate::machine::Escape; use crate::machine::WasmEnvMut; use brotli::{BrotliStatus, Dictionary}; @@ -12,9 +12,8 @@ macro_rules! wrap { $( #[allow(clippy::too_many_arguments)] pub fn $func_name(mut src: WasmEnvMut, $($arg_name : $arg_type),*) -> Result<$return_type, Escape> { - let (mut mem, wenv) = src.jit_env(); - - Ok(caller_env::brotli::$func_name(&mut mem, &mut JitExecEnv { wenv }, $($arg_name),*)) + let (mut mem, state) = jit_env(&mut src); + Ok(caller_env::brotli::$func_name(&mut mem, &mut JitExecEnv { wenv: state.0 }, $($arg_name),*)) } )* }; diff --git a/crates/jit/src/arbcrypto.rs b/crates/jit/src/arbcrypto.rs index e4bd8586161..91ad8d6c80c 100644 --- a/crates/jit/src/arbcrypto.rs +++ b/crates/jit/src/arbcrypto.rs @@ -1,6 +1,6 @@ // Copyright 2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md -use crate::caller_env::{JitEnv, JitExecEnv}; +use crate::caller_env::{jit_env, JitExecEnv}; use crate::machine::{Escape, MaybeEscape, WasmEnvMut}; use caller_env::GuestPtr; @@ -12,11 +12,11 @@ pub fn ecrecovery( sig_len: u32, pub_ptr: GuestPtr, ) -> Result { - let (mut mem, wenv) = src.jit_env(); + let (mut mem, state) = jit_env(&mut src); Ok(caller_env::arbcrypto::ecrecovery( &mut mem, - &mut JitExecEnv { wenv }, + &mut JitExecEnv { wenv: state.0 }, hash_ptr, hash_len, sig_ptr, @@ -31,11 +31,11 @@ pub fn keccak256( in_buf_len: u32, out_buf_ptr: GuestPtr, ) -> MaybeEscape { - let (mut mem, wenv) = src.jit_env(); + let (mut mem, state) = jit_env(&mut src); caller_env::arbcrypto::keccak256( &mut mem, - &mut JitExecEnv { wenv }, + &mut JitExecEnv { wenv: state.0 }, in_buf_ptr, in_buf_len, out_buf_ptr, diff --git a/crates/jit/src/caller_env.rs b/crates/jit/src/caller_env.rs index 3cfd6807c5b..1f0d25d65b9 100644 --- a/crates/jit/src/caller_env.rs +++ b/crates/jit/src/caller_env.rs @@ -18,31 +18,25 @@ pub struct JitExecEnv<'s> { pub wenv: &'s mut WasmEnv, } -pub(crate) trait JitEnv<'a> { - fn jit_env(&mut self) -> (JitMemAccess<'_>, &mut WasmEnv); -} - -impl<'a> JitEnv<'a> for WasmEnvMut<'a> { - fn jit_env(&mut self) -> (JitMemAccess<'_>, &mut WasmEnv) { - let memory = self.data().memory.clone().unwrap(); - let (wenv, store) = self.data_and_store_mut(); - (JitMemAccess { memory, store }, wenv) - } -} - /// Newtype for implementing WavmEnv (orphan rule: FunctionEnvMut is foreign). pub(crate) struct JitWavm<'e>(pub WasmEnvMut<'e>); /// Newtype wrapping &mut WasmEnv to implement WavmState (orphan rule). pub(crate) struct JitState<'a>(pub &'a mut WasmEnv); +/// Extracts (JitMemAccess, JitState) from a WasmEnvMut in place. +pub(crate) fn jit_env<'a>(env: &'a mut WasmEnvMut) -> (JitMemAccess<'a>, JitState<'a>) { + let memory = env.data().memory.clone().unwrap(); + let (wenv, store) = env.data_and_store_mut(); + (JitMemAccess { memory, store }, JitState(wenv)) +} + impl WavmEnv for JitWavm<'_> { type Mem<'a> = JitMemAccess<'a> where Self: 'a; type State<'a> = JitState<'a> where Self: 'a; fn wavm_env(&mut self) -> (JitMemAccess<'_>, JitState<'_>) { - let (mem, wenv) = self.0.jit_env(); - (mem, JitState(wenv)) + jit_env(&mut self.0) } } diff --git a/crates/jit/src/program.rs b/crates/jit/src/program.rs index df0ee24e5ef..a706429682b 100644 --- a/crates/jit/src/program.rs +++ b/crates/jit/src/program.rs @@ -3,7 +3,7 @@ #![allow(clippy::too_many_arguments)] -use crate::caller_env::JitEnv; +use crate::caller_env::jit_env; use crate::machine::{Escape, MaybeEscape, WasmEnv, WasmEnvMut}; use crate::stylus_backend::{exec_wasm, MessageFromCothread}; use arbutil::evm::api::Gas; @@ -73,7 +73,7 @@ pub fn activate_v2( err_buf: GuestPtr, err_buf_len: u32, ) -> Result { - let (mut mem, _) = env.jit_env(); + let (mut mem, _) = jit_env(&mut env); let wasm = mem.read_slice(wasm_ptr, wasm_size as usize); let codehash = &mem.read_bytes32(codehash); let debug = debug != 0; @@ -125,21 +125,21 @@ pub fn new_program( evm_data_handler: u64, gas: u64, ) -> Result { - let (mut mem, exec) = env.jit_env(); + let (mut mem, state) = jit_env(&mut env); let compiled_hash = mem.read_bytes32(compiled_hash_ptr); let calldata = mem.read_slice(calldata_ptr, calldata_size as usize); let evm_data: EvmData = unsafe { *Box::from_raw(evm_data_handler as *mut EvmData) }; let config: JitConfig = unsafe { *Box::from_raw(stylus_config_handler as *mut JitConfig) }; - let Some(module) = exec.module_asms.get(&compiled_hash).cloned() else { + let Some(module) = state.0.module_asms.get(&compiled_hash).cloned() else { return Err(Escape::Failure(format!( "module hash {:?} not found in {:?}", compiled_hash, - exec.module_asms.keys() + state.0.module_asms.keys() ))); }; - launch_program_thread(exec, module, calldata, config, evm_data, gas) + launch_program_thread(state.0, module, calldata, config, evm_data, gas) } pub fn launch_program_thread( @@ -173,8 +173,8 @@ pub fn launch_program_thread( /// module MUST match last module number returned from new_program /// returns request_id for the first request from the program pub fn start_program(mut env: WasmEnvMut, module: u32) -> Result { - let (_, exec) = env.jit_env(); - start_program_with_wasm_env(exec, module) + let (_, state) = jit_env(&mut env); + start_program_with_wasm_env(state.0, module) } /// program_requires_prepare @@ -216,8 +216,8 @@ pub fn start_program_with_wasm_env(exec: &mut WasmEnv, module: u32) -> Result Result { - let (mut mem, exec) = env.jit_env(); - let msg = get_last_msg(exec, id)?; + let (mut mem, state) = jit_env(&mut env); + let msg = get_last_msg(state.0, id)?; mem.write_u32(len_ptr, msg.req_data.len() as u32); Ok(msg.req_type) } @@ -235,8 +235,8 @@ pub fn get_last_msg(exec: &mut WasmEnv, id: u32) -> Result MaybeEscape { - let (mut mem, exec) = env.jit_env(); - let msg = get_last_msg(exec, id)?; + let (mut mem, state) = jit_env(&mut env); + let msg = get_last_msg(state.0, id)?; mem.write_slice(data_ptr, &msg.req_data); Ok(()) } @@ -252,11 +252,11 @@ pub fn set_response( raw_data_ptr: GuestPtr, raw_data_len: u32, ) -> MaybeEscape { - let (mem, exec) = env.jit_env(); + let (mem, state) = jit_env(&mut env); let result = mem.read_slice(result_ptr, result_len as usize); let raw_data = mem.read_slice(raw_data_ptr, raw_data_len as usize); - set_response_with_wasm_env(exec, id, gas, result, raw_data) + set_response_with_wasm_env(state.0, id, gas, result, raw_data) } pub fn set_response_with_wasm_env( @@ -274,8 +274,8 @@ pub fn set_response_with_wasm_env( /// MUST be called right after set_response to the same id /// returns request_id for the next request pub fn send_response(mut env: WasmEnvMut, req_id: u32) -> Result { - let (_, exec) = env.jit_env(); - let thread = exec.threads.last_mut().unwrap(); + let (_, state) = jit_env(&mut env); + let thread = state.0.threads.last_mut().unwrap(); let msg = thread.last_message()?; if msg.1 != req_id { return Escape::hostio("get_request id doesn't match"); @@ -287,8 +287,8 @@ pub fn send_response(mut env: WasmEnvMut, req_id: u32) -> Result { /// removes the last created program pub fn pop(mut env: WasmEnvMut) -> MaybeEscape { - let (_, exec) = env.jit_env(); - pop_with_wasm_env(exec) + let (_, state) = jit_env(&mut env); + pop_with_wasm_env(state.0) } pub fn pop_with_wasm_env(exec: &mut WasmEnv) -> MaybeEscape { @@ -377,7 +377,7 @@ pub fn create_evm_data_v2( cached: u32, reentrant: u32, ) -> Result { - let (mut mem, _) = env.jit_env(); + let (mut mem, _) = jit_env(&mut env); let evm_data = EvmData { arbos_version, diff --git a/crates/jit/src/wasip1_stub.rs b/crates/jit/src/wasip1_stub.rs index 1f6005135f8..752edc2b437 100644 --- a/crates/jit/src/wasip1_stub.rs +++ b/crates/jit/src/wasip1_stub.rs @@ -3,7 +3,7 @@ #![allow(clippy::too_many_arguments)] -use crate::caller_env::{JitEnv, JitExecEnv}; +use crate::caller_env::{jit_env, JitExecEnv}; use crate::machine::{Escape, WasmEnvMut}; use caller_env::{self, wasip1_stub::Errno, GuestPtr}; @@ -15,9 +15,8 @@ macro_rules! wrap { ($(fn $func_name:ident ($($arg_name:ident : $arg_type:ty),* ) -> $return_type:ty);*) => { $( pub fn $func_name(mut src: WasmEnvMut, $($arg_name : $arg_type),*) -> Result<$return_type, Escape> { - let (mut mem, wenv) = src.jit_env(); - - Ok(caller_env::wasip1_stub::$func_name(&mut mem, &mut JitExecEnv { wenv }, $($arg_name),*)) + let (mut mem, state) = jit_env(&mut src); + Ok(caller_env::wasip1_stub::$func_name(&mut mem, &mut JitExecEnv { wenv: state.0 }, $($arg_name),*)) } )* }; diff --git a/crates/jit/src/wavmio.rs b/crates/jit/src/wavmio.rs index 354f023dfc9..cb98ed039db 100644 --- a/crates/jit/src/wavmio.rs +++ b/crates/jit/src/wavmio.rs @@ -96,12 +96,12 @@ fn resolve_preimage_impl( #[cfg(debug_assertions)] { - use crate::caller_env::JitEnv; + use crate::caller_env::jit_env; use arbutil::PreimageType; use sha2::Sha256; use sha3::{Digest, Keccak256}; - let (mut mem, exec) = env.jit_env(); + let (mut mem, state) = jit_env(&mut env); let hash = mem.read_bytes32(hash_ptr); let Ok(preimage_type) = preimage_type.try_into() else { @@ -109,7 +109,7 @@ fn resolve_preimage_impl( return Ok(0); }; - if let Some(preimage) = exec + if let Some(preimage) = state.0 .preimages .get(&preimage_type) .and_then(|m| m.get(&hash)) From 09a9912ac92b41b9f1f397774bbdb2ae7bba19c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 3 Mar 2026 12:31:25 +0100 Subject: [PATCH 053/189] Remove JitExecEnv --- crates/jit/src/arbcompress.rs | 6 +++--- crates/jit/src/arbcrypto.rs | 10 +++++----- crates/jit/src/caller_env.rs | 12 ++++-------- crates/jit/src/wasip1_stub.rs | 6 +++--- 4 files changed, 15 insertions(+), 19 deletions(-) diff --git a/crates/jit/src/arbcompress.rs b/crates/jit/src/arbcompress.rs index a2e4934ce52..4e4d0b5859e 100644 --- a/crates/jit/src/arbcompress.rs +++ b/crates/jit/src/arbcompress.rs @@ -1,7 +1,7 @@ // Copyright 2022-2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md -use crate::caller_env::{jit_env, JitExecEnv}; +use crate::caller_env::jit_env; use crate::machine::Escape; use crate::machine::WasmEnvMut; use brotli::{BrotliStatus, Dictionary}; @@ -12,8 +12,8 @@ macro_rules! wrap { $( #[allow(clippy::too_many_arguments)] pub fn $func_name(mut src: WasmEnvMut, $($arg_name : $arg_type),*) -> Result<$return_type, Escape> { - let (mut mem, state) = jit_env(&mut src); - Ok(caller_env::brotli::$func_name(&mut mem, &mut JitExecEnv { wenv: state.0 }, $($arg_name),*)) + let (mut mem, mut state) = jit_env(&mut src); + Ok(caller_env::brotli::$func_name(&mut mem, &mut state, $($arg_name),*)) } )* }; diff --git a/crates/jit/src/arbcrypto.rs b/crates/jit/src/arbcrypto.rs index 91ad8d6c80c..f2ff35799b0 100644 --- a/crates/jit/src/arbcrypto.rs +++ b/crates/jit/src/arbcrypto.rs @@ -1,6 +1,6 @@ // Copyright 2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md -use crate::caller_env::{jit_env, JitExecEnv}; +use crate::caller_env::jit_env; use crate::machine::{Escape, MaybeEscape, WasmEnvMut}; use caller_env::GuestPtr; @@ -12,11 +12,11 @@ pub fn ecrecovery( sig_len: u32, pub_ptr: GuestPtr, ) -> Result { - let (mut mem, state) = jit_env(&mut src); + let (mut mem, mut state) = jit_env(&mut src); Ok(caller_env::arbcrypto::ecrecovery( &mut mem, - &mut JitExecEnv { wenv: state.0 }, + &mut state, hash_ptr, hash_len, sig_ptr, @@ -31,11 +31,11 @@ pub fn keccak256( in_buf_len: u32, out_buf_ptr: GuestPtr, ) -> MaybeEscape { - let (mut mem, state) = jit_env(&mut src); + let (mut mem, mut state) = jit_env(&mut src); caller_env::arbcrypto::keccak256( &mut mem, - &mut JitExecEnv { wenv: state.0 }, + &mut state, in_buf_ptr, in_buf_len, out_buf_ptr, diff --git a/crates/jit/src/caller_env.rs b/crates/jit/src/caller_env.rs index 1f0d25d65b9..a607e788cad 100644 --- a/crates/jit/src/caller_env.rs +++ b/crates/jit/src/caller_env.rs @@ -14,10 +14,6 @@ pub struct JitMemAccess<'s> { pub store: StoreMut<'s>, } -pub struct JitExecEnv<'s> { - pub wenv: &'s mut WasmEnv, -} - /// Newtype for implementing WavmEnv (orphan rule: FunctionEnvMut is foreign). pub(crate) struct JitWavm<'e>(pub WasmEnvMut<'e>); @@ -120,17 +116,17 @@ impl MemAccess for JitMemAccess<'_> { } } -impl ExecEnv for JitExecEnv<'_> { +impl ExecEnv for JitState<'_> { fn advance_time(&mut self, ns: u64) { - self.wenv.go_state.time += ns; + self.0.go_state.time += ns; } fn get_time(&self) -> u64 { - self.wenv.go_state.time + self.0.go_state.time } fn next_rand_u32(&mut self) -> u32 { - self.wenv.go_state.rng.next_u32() + self.0.go_state.rng.next_u32() } fn print_string(&mut self, bytes: &[u8]) { diff --git a/crates/jit/src/wasip1_stub.rs b/crates/jit/src/wasip1_stub.rs index 752edc2b437..a97b439c0f5 100644 --- a/crates/jit/src/wasip1_stub.rs +++ b/crates/jit/src/wasip1_stub.rs @@ -3,7 +3,7 @@ #![allow(clippy::too_many_arguments)] -use crate::caller_env::{jit_env, JitExecEnv}; +use crate::caller_env::jit_env; use crate::machine::{Escape, WasmEnvMut}; use caller_env::{self, wasip1_stub::Errno, GuestPtr}; @@ -15,8 +15,8 @@ macro_rules! wrap { ($(fn $func_name:ident ($($arg_name:ident : $arg_type:ty),* ) -> $return_type:ty);*) => { $( pub fn $func_name(mut src: WasmEnvMut, $($arg_name : $arg_type),*) -> Result<$return_type, Escape> { - let (mut mem, state) = jit_env(&mut src); - Ok(caller_env::wasip1_stub::$func_name(&mut mem, &mut JitExecEnv { wenv: state.0 }, $($arg_name),*)) + let (mut mem, mut state) = jit_env(&mut src); + Ok(caller_env::wasip1_stub::$func_name(&mut mem, &mut state, $($arg_name),*)) } )* }; From e6129754d4f4122676edb621e6e2518cad78518a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 3 Mar 2026 12:37:17 +0100 Subject: [PATCH 054/189] Rename WavmInput to Sp1State --- sp1-crates/program/src/caller_env_adapters.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sp1-crates/program/src/caller_env_adapters.rs b/sp1-crates/program/src/caller_env_adapters.rs index d2796b475bf..e5b0e92b4c8 100644 --- a/sp1-crates/program/src/caller_env_adapters.rs +++ b/sp1-crates/program/src/caller_env_adapters.rs @@ -79,9 +79,9 @@ impl MemAccess for Sp1MemAccess<'_> { } /// Newtype wrapper to implement WavmState for Input (orphan rule). -pub(crate) struct WavmInput<'a>(pub &'a mut Input); +pub(crate) struct Sp1State<'a>(pub &'a mut Input); -impl WavmState for WavmInput<'_> { +impl WavmState for Sp1State<'_> { fn get_u64_global(&self, idx: usize) -> Option { self.0.small_globals.get(idx).copied() } @@ -132,12 +132,12 @@ pub(crate) struct Sp1Wavm<'e>(pub FunctionEnvMut<'e, CustomEnvData>); impl WavmEnv for Sp1Wavm<'_> { type Mem<'a> = Sp1MemAccess<'a> where Self: 'a; - type State<'a> = WavmInput<'a> where Self: 'a; + type State<'a> = Sp1State<'a> where Self: 'a; - fn wavm_env(&mut self) -> (Sp1MemAccess<'_>, WavmInput<'_>) { + fn wavm_env(&mut self) -> (Sp1MemAccess<'_>, Sp1State<'_>) { let memory = self.0.data().memory.clone().unwrap(); let (data, store) = self.0.data_and_store_mut(); let input = data.input_mut(); - (Sp1MemAccess { memory, store }, WavmInput(input)) + (Sp1MemAccess { memory, store }, Sp1State(input)) } } From d247f90b83a17f74fa56554e433dc4a06628c6ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 3 Mar 2026 16:42:52 +0100 Subject: [PATCH 055/189] wasip1_stub --- crates/caller-env/src/wasip1_stub.rs | 162 ++++---- crates/caller-env/src/wavmio.rs | 4 +- crates/jit/src/wasip1_stub.rs | 7 +- sp1-crates/program/src/caller_env_adapters.rs | 47 ++- sp1-crates/program/src/imports/wasi_stub.rs | 356 ++++-------------- sp1-crates/program/src/imports/wavmio.rs | 8 +- 6 files changed, 190 insertions(+), 394 deletions(-) diff --git a/crates/caller-env/src/wasip1_stub.rs b/crates/caller-env/src/wasip1_stub.rs index bc0b3b27422..bdd357ba742 100644 --- a/crates/caller-env/src/wasip1_stub.rs +++ b/crates/caller-env/src/wasip1_stub.rs @@ -7,10 +7,10 @@ #![allow(clippy::too_many_arguments)] -use crate::{ExecEnv, GuestPtr, MemAccess}; +use crate::{ExecEnv, GuestPtr, MemAccess, wavmio::WavmEnv}; #[repr(transparent)] -pub struct Errno(pub(crate) u16); +pub struct Errno(pub u16); pub const ERRNO_SUCCESS: Errno = Errno(0); pub const ERRNO_BADF: Errno = Errno(8); @@ -18,12 +18,12 @@ pub const ERRNO_INVAL: Errno = Errno(28); /// Writes the number and total size of args passed by the OS. /// Note that this currently consists of just the program name `bin`. -pub fn args_sizes_get( - mem: &mut M, - _: &mut E, +pub fn args_sizes_get( + env: &mut impl WavmEnv, length_ptr: GuestPtr, data_size_ptr: GuestPtr, ) -> Errno { + let (mut mem, _) = env.wavm_env(); mem.write_u32(length_ptr, 1); mem.write_u32(data_size_ptr, 4); ERRNO_SUCCESS @@ -31,12 +31,12 @@ pub fn args_sizes_get( /// Writes the args passed by the OS. /// Note that this currently consists of just the program name `bin`. -pub fn args_get( - mem: &mut M, - _: &mut E, +pub fn args_get( + env: &mut impl WavmEnv, argv_buf: GuestPtr, data_buf: GuestPtr, ) -> Errno { + let (mut mem, _) = env.wavm_env(); mem.write_u32(argv_buf, data_buf.into()); mem.write_u32(data_buf, 0x6E6962); // "bin\0" ERRNO_SUCCESS @@ -44,12 +44,12 @@ pub fn args_get( /// Writes the number and total size of OS environment variables. /// Note that none exist in Nitro. -pub fn environ_sizes_get( - mem: &mut M, - _env: &mut E, +pub fn environ_sizes_get( + env: &mut impl WavmEnv, length_ptr: GuestPtr, data_size_ptr: GuestPtr, ) -> Errno { + let (mut mem, _) = env.wavm_env(); mem.write_u32(length_ptr, 0); mem.write_u32(data_size_ptr, 0); ERRNO_SUCCESS @@ -57,9 +57,8 @@ pub fn environ_sizes_get( /// Writes the number and total size of OS environment variables. /// Note that none exist in Nitro. -pub fn environ_get( - _: &mut M, - _: &mut E, +pub fn environ_get( + _: &mut impl WavmEnv, _: GuestPtr, _: GuestPtr, ) -> Errno { @@ -68,9 +67,8 @@ pub fn environ_get( /// Writes to the given file descriptor. /// Note that we only support stdout and stderr. -pub fn fd_write( - mem: &mut M, - env: &mut E, +pub fn fd_write( + env: &mut impl WavmEnv, fd: u32, iovecs_ptr: GuestPtr, iovecs_len: u32, @@ -79,13 +77,14 @@ pub fn fd_write( if fd != 1 && fd != 2 { return ERRNO_BADF; } + let (mut mem, mut state) = env.wavm_env(); let mut size = 0; for i in 0..iovecs_len { let ptr = iovecs_ptr + i * 8; let len = mem.read_u32(ptr + 4); let ptr = mem.read_u32(ptr); // TODO: string might be split across utf-8 character boundary let data = mem.read_slice(GuestPtr(ptr), len as usize); - env.print_string(&data); + state.print_string(&data); size += len; } mem.write_u32(ret_ptr, size); @@ -93,14 +92,13 @@ pub fn fd_write( } /// Closes the given file descriptor. Unsupported. -pub fn fd_close(_: &mut M, _: &mut E, _: u32) -> Errno { +pub fn fd_close(_: &mut impl WavmEnv, _: u32) -> Errno { ERRNO_BADF } /// Reads from the given file descriptor. Unsupported. -pub fn fd_read( - _: &mut M, - _: &mut E, +pub fn fd_read( + _: &mut impl WavmEnv, _: u32, _: u32, _: u32, @@ -110,9 +108,8 @@ pub fn fd_read( } /// Reads the contents of a directory. Unsupported. -pub fn fd_readdir( - _: &mut M, - _: &mut E, +pub fn fd_readdir( + _: &mut impl WavmEnv, _fd: u32, _: u32, _: u32, @@ -123,14 +120,13 @@ pub fn fd_readdir( } /// Syncs a file to disk. Unsupported. -pub fn fd_sync(_: &mut M, _: &mut E, _: u32) -> Errno { +pub fn fd_sync(_: &mut impl WavmEnv, _: u32) -> Errno { ERRNO_SUCCESS } /// Move within a file. Unsupported. -pub fn fd_seek( - _: &mut M, - _: &mut E, +pub fn fd_seek( + _: &mut impl WavmEnv, _fd: u32, _offset: u64, _whence: u8, @@ -140,19 +136,18 @@ pub fn fd_seek( } /// Syncs file contents to disk. Unsupported. -pub fn fd_datasync(_: &mut M, _: &mut E, _fd: u32) -> Errno { +pub fn fd_datasync(_: &mut impl WavmEnv, _fd: u32) -> Errno { ERRNO_BADF } /// Retrieves attributes about a file descriptor. Unsupported. -pub fn fd_fdstat_get(_: &mut M, _: &mut E, _: u32, _: u32) -> Errno { +pub fn fd_fdstat_get(_: &mut impl WavmEnv, _: u32, _: u32) -> Errno { ERRNO_INVAL } /// Sets the attributes of a file descriptor. Unsupported. -pub fn fd_fdstat_set_flags( - _: &mut M, - _: &mut E, +pub fn fd_fdstat_set_flags( + _: &mut impl WavmEnv, _: u32, _: u32, ) -> Errno { @@ -160,9 +155,8 @@ pub fn fd_fdstat_set_flags( } /// Opens the file or directory at the given path. Unsupported. -pub fn path_open( - _: &mut M, - _: &mut E, +pub fn path_open( + _: &mut impl WavmEnv, _: u32, _: u32, _: u32, @@ -177,9 +171,8 @@ pub fn path_open( } /// Creates a directory. Unsupported. -pub fn path_create_directory( - _: &mut M, - _: &mut E, +pub fn path_create_directory( + _: &mut impl WavmEnv, _: u32, _: u32, _: u32, @@ -188,9 +181,8 @@ pub fn path_create_directory( } /// Unlinks a directory. Unsupported. -pub fn path_remove_directory( - _: &mut M, - _: &mut E, +pub fn path_remove_directory( + _: &mut impl WavmEnv, _: u32, _: u32, _: u32, @@ -199,9 +191,8 @@ pub fn path_remove_directory( } /// Resolves a symbolic link. Unsupported. -pub fn path_readlink( - _: &mut M, - _: &mut E, +pub fn path_readlink( + _: &mut impl WavmEnv, _: u32, _: u32, _: u32, @@ -213,9 +204,8 @@ pub fn path_readlink( } /// Moves a file. Unsupported. -pub fn path_rename( - _: &mut M, - _: &mut E, +pub fn path_rename( + _: &mut impl WavmEnv, _: u32, _: u32, _: u32, @@ -227,9 +217,8 @@ pub fn path_rename( } /// Retrieves info about an open file. Unsupported. -pub fn path_filestat_get( - _: &mut M, - _: &mut E, +pub fn path_filestat_get( + _: &mut impl WavmEnv, _: u32, _: u32, _: u32, @@ -240,9 +229,8 @@ pub fn path_filestat_get( } /// Unlinks the file at the given path. Unsupported. -pub fn path_unlink_file( - _: &mut M, - _: &mut E, +pub fn path_unlink_file( + _: &mut impl WavmEnv, _: u32, _: u32, _: u32, @@ -251,14 +239,13 @@ pub fn path_unlink_file( } /// Retrieves info about a file. Unsupported. -pub fn fd_prestat_get(_: &mut M, _: &mut E, _: u32, _: u32) -> Errno { +pub fn fd_prestat_get(_: &mut impl WavmEnv, _: u32, _: u32) -> Errno { ERRNO_BADF } /// Retrieves info about a directory. Unsupported. -pub fn fd_prestat_dir_name( - _: &mut M, - _: &mut E, +pub fn fd_prestat_dir_name( + _: &mut impl WavmEnv, _: u32, _: u32, _: u32, @@ -267,9 +254,8 @@ pub fn fd_prestat_dir_name( } /// Retrieves info about a file. Unsupported. -pub fn fd_filestat_get( - _: &mut M, - _: &mut E, +pub fn fd_filestat_get( + _: &mut impl WavmEnv, _fd: u32, _filestat: u32, ) -> Errno { @@ -277,9 +263,8 @@ pub fn fd_filestat_get( } /// Sets the size of an open file. Unsupported. -pub fn fd_filestat_set_size( - _: &mut M, - _: &mut E, +pub fn fd_filestat_set_size( + _: &mut impl WavmEnv, _fd: u32, _: u64, ) -> Errno { @@ -287,9 +272,8 @@ pub fn fd_filestat_set_size( } /// Peaks within a descriptor without modifying its state. Unsupported. -pub fn fd_pread( - _: &mut M, - _: &mut E, +pub fn fd_pread( + _: &mut impl WavmEnv, _fd: u32, _: u32, _: u32, @@ -300,9 +284,8 @@ pub fn fd_pread( } /// Writes to a descriptor without modifying the current offset. Unsupported. -pub fn fd_pwrite( - _: &mut M, - _: &mut E, +pub fn fd_pwrite( + _: &mut impl WavmEnv, _fd: u32, _: u32, _: u32, @@ -313,9 +296,8 @@ pub fn fd_pwrite( } /// Accepts a new connection. Unsupported. -pub fn sock_accept( - _: &mut M, - _: &mut E, +pub fn sock_accept( + _: &mut impl WavmEnv, _fd: u32, _: u32, _: u32, @@ -324,12 +306,12 @@ pub fn sock_accept( } /// Shuts down a socket. Unsupported. -pub fn sock_shutdown(_: &mut M, _: &mut E, _: u32, _: u32) -> Errno { +pub fn sock_shutdown(_: &mut impl WavmEnv, _: u32, _: u32) -> Errno { ERRNO_BADF } /// Yields execution to the OS scheduler. Effectively does nothing in Nitro due to the lack of threads. -pub fn sched_yield(_: &mut M, _: &mut E) -> Errno { +pub fn sched_yield(_: &mut impl WavmEnv) -> Errno { ERRNO_SUCCESS } @@ -339,34 +321,34 @@ static TIME_INTERVAL: u64 = 10_000_000; /// Retrieves the time in ns of the given clock. /// Note that in Nitro, all clocks point to the same deterministic counter that advances 10ms whenever /// this function is called. -pub fn clock_time_get( - mem: &mut M, - env: &mut E, +pub fn clock_time_get( + env: &mut impl WavmEnv, _clock_id: u32, _precision: u64, time_ptr: GuestPtr, ) -> Errno { - env.advance_time(TIME_INTERVAL); - mem.write_u64(time_ptr, env.get_time()); + let (mut mem, mut state) = env.wavm_env(); + state.advance_time(TIME_INTERVAL); + mem.write_u64(time_ptr, state.get_time()); ERRNO_SUCCESS } /// Fills a slice with psuedo-random bytes. /// Note that in Nitro, the bytes are deterministically generated from a common seed. -pub fn random_get( - mem: &mut M, - env: &mut E, +pub fn random_get( + env: &mut impl WavmEnv, mut buf: GuestPtr, mut len: u32, ) -> Errno { + let (mut mem, mut state) = env.wavm_env(); while len >= 4 { - let next_rand = env.next_rand_u32(); + let next_rand = state.next_rand_u32(); mem.write_u32(buf, next_rand); buf += 4; len -= 4; } if len > 0 { - let mut rem = env.next_rand_u32(); + let mut rem = state.next_rand_u32(); for _ in 0..len { mem.write_u8(buf, rem as u8); buf += 1; @@ -378,16 +360,16 @@ pub fn random_get( /// Poll for events. /// Note that we always simulate a timeout and skip all others. -pub fn poll_oneoff( - mem: &mut M, - env: &mut E, +pub fn poll_oneoff( + env: &mut impl WavmEnv, in_subs: GuestPtr, out_evt: GuestPtr, num_subscriptions: u32, num_events_ptr: GuestPtr, ) -> Errno { + let (mut mem, mut state) = env.wavm_env(); // simulate the passage of time each poll request - env.advance_time(TIME_INTERVAL); + state.advance_time(TIME_INTERVAL); const SUBSCRIPTION_SIZE: u32 = 48; // user data + 40-byte union for index in 0..num_subscriptions { diff --git a/crates/caller-env/src/wavmio.rs b/crates/caller-env/src/wavmio.rs index 9a08a50c51a..605c2425736 100644 --- a/crates/caller-env/src/wavmio.rs +++ b/crates/caller-env/src/wavmio.rs @@ -1,13 +1,13 @@ // Copyright 2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md -use crate::{GuestPtr, MemAccess}; +use crate::{ExecEnv, GuestPtr, MemAccess}; use alloc::string::String; use alloc::format; use core::cmp::min; /// Trait for accessing wavmio host state (globals, inbox, preimages). -pub trait WavmState { +pub trait WavmState: ExecEnv { fn get_u64_global(&self, idx: usize) -> Option; fn set_u64_global(&mut self, idx: usize, val: u64) -> bool; fn get_bytes32_global(&self, idx: usize) -> Option<&[u8; 32]>; diff --git a/crates/jit/src/wasip1_stub.rs b/crates/jit/src/wasip1_stub.rs index a97b439c0f5..dfae393fcc7 100644 --- a/crates/jit/src/wasip1_stub.rs +++ b/crates/jit/src/wasip1_stub.rs @@ -3,7 +3,7 @@ #![allow(clippy::too_many_arguments)] -use crate::caller_env::jit_env; +use crate::caller_env::JitWavm; use crate::machine::{Escape, WasmEnvMut}; use caller_env::{self, wasip1_stub::Errno, GuestPtr}; @@ -14,9 +14,8 @@ pub fn proc_exit(mut _env: WasmEnvMut, code: u32) -> Result<(), Escape> { macro_rules! wrap { ($(fn $func_name:ident ($($arg_name:ident : $arg_type:ty),* ) -> $return_type:ty);*) => { $( - pub fn $func_name(mut src: WasmEnvMut, $($arg_name : $arg_type),*) -> Result<$return_type, Escape> { - let (mut mem, mut state) = jit_env(&mut src); - Ok(caller_env::wasip1_stub::$func_name(&mut mem, &mut state, $($arg_name),*)) + pub fn $func_name(src: WasmEnvMut, $($arg_name : $arg_type),*) -> Result<$return_type, Escape> { + Ok(caller_env::wasip1_stub::$func_name(&mut JitWavm(src), $($arg_name),*)) } )* }; diff --git a/sp1-crates/program/src/caller_env_adapters.rs b/sp1-crates/program/src/caller_env_adapters.rs index e5b0e92b4c8..7b8bf5277a3 100644 --- a/sp1-crates/program/src/caller_env_adapters.rs +++ b/sp1-crates/program/src/caller_env_adapters.rs @@ -2,8 +2,8 @@ // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md use caller_env::wavmio::{WavmEnv, WavmState}; -use caller_env::{GuestPtr, MemAccess}; -use prover::binary_input::Input; +use caller_env::{ExecEnv, GuestPtr, MemAccess}; +use rand::RngCore; use wasmer::{FunctionEnvMut, Memory, StoreMut}; use crate::replay::CustomEnvData; @@ -78,16 +78,34 @@ impl MemAccess for Sp1MemAccess<'_> { } } -/// Newtype wrapper to implement WavmState for Input (orphan rule). -pub(crate) struct Sp1State<'a>(pub &'a mut Input); +/// Newtype wrapper to implement WavmState and ExecEnv over CustomEnvData. +pub(crate) struct Sp1State<'a>(pub &'a mut CustomEnvData); + +impl ExecEnv for Sp1State<'_> { + fn advance_time(&mut self, ns: u64) { + self.0.time += ns; + } + + fn get_time(&self) -> u64 { + self.0.time + } + + fn next_rand_u32(&mut self) -> u32 { + self.0.pcg.next_u32() + } + + fn print_string(&mut self, bytes: &[u8]) { + crate::platform::print_string(2, bytes); + } +} impl WavmState for Sp1State<'_> { fn get_u64_global(&self, idx: usize) -> Option { - self.0.small_globals.get(idx).copied() + self.0.input().small_globals.get(idx).copied() } fn set_u64_global(&mut self, idx: usize, val: u64) -> bool { - match self.0.small_globals.get_mut(idx) { + match self.0.input_mut().small_globals.get_mut(idx) { Some(g) => { *g = val; true @@ -97,11 +115,11 @@ impl WavmState for Sp1State<'_> { } fn get_bytes32_global(&self, idx: usize) -> Option<&[u8; 32]> { - self.0.large_globals.get(idx) + self.0.input().large_globals.get(idx) } fn set_bytes32_global(&mut self, idx: usize, val: [u8; 32]) -> bool { - match self.0.large_globals.get_mut(idx) { + match self.0.input_mut().large_globals.get_mut(idx) { Some(g) => { *g = val; true @@ -111,15 +129,16 @@ impl WavmState for Sp1State<'_> { } fn get_sequencer_message(&self, num: u64) -> Option<&[u8]> { - self.0.sequencer_messages.get(&num).map(|v| v.as_slice()) + self.0.input().sequencer_messages.get(&num).map(|v| v.as_slice()) } fn get_delayed_message(&self, num: u64) -> Option<&[u8]> { - self.0.delayed_messages.get(&num).map(|v| v.as_slice()) + self.0.input().delayed_messages.get(&num).map(|v| v.as_slice()) } fn get_preimage(&self, preimage_type: u8, hash: &[u8; 32]) -> Option<&[u8]> { self.0 + .input() .preimages .get(&preimage_type) .and_then(|m| m.get(hash)) @@ -137,7 +156,11 @@ impl WavmEnv for Sp1Wavm<'_> { fn wavm_env(&mut self) -> (Sp1MemAccess<'_>, Sp1State<'_>) { let memory = self.0.data().memory.clone().unwrap(); let (data, store) = self.0.data_and_store_mut(); - let input = data.input_mut(); - (Sp1MemAccess { memory, store }, Sp1State(input)) + (Sp1MemAccess { memory, store }, Sp1State(data)) } } + +/// Converts a wasmer `Ptr` (WasmPtr) to a caller-env `GuestPtr`. +pub(crate) fn gp(p: crate::Ptr) -> GuestPtr { + GuestPtr(p.offset()) +} diff --git a/sp1-crates/program/src/imports/wasi_stub.rs b/sp1-crates/program/src/imports/wasi_stub.rs index 18af7ff4c56..355c6b9f9d5 100644 --- a/sp1-crates/program/src/imports/wasi_stub.rs +++ b/sp1-crates/program/src/imports/wasi_stub.rs @@ -1,17 +1,10 @@ -//! WASI stubs -//! -//! The code used here is heavily borrowed from nitro's own WASI stubs: -//! https://github.com/OffchainLabs/nitro/blob/c858ed93a5a4fd81908277d94fb72974058a3615/arbitrator/caller-env/src/wasip1_stub.rs +//! WASI stubs delegating to caller-env's shared implementation. -use crate::{Escape, Ptr, platform, read_slice, replay::CustomEnvData}; -use rand::RngCore; -use wasmer::FunctionEnvMut; - -pub type Errno = u16; +#![allow(clippy::too_many_arguments)] -pub const ERRNO_SUCCESS: Errno = 0; -pub const ERRNO_BADF: Errno = 8; -pub const ERRNO_INVAL: Errno = 28; +use crate::{Escape, Ptr, caller_env_adapters::{Sp1Wavm, gp}, platform, replay::CustomEnvData}; +use caller_env; +use wasmer::FunctionEnvMut; pub fn proc_exit(mut ctx: FunctionEnvMut, code: u32) { let (data, _store) = ctx.data_and_store_mut(); @@ -31,309 +24,112 @@ pub fn proc_exit(mut ctx: FunctionEnvMut, code: u32) { } pub fn args_sizes_get( - mut ctx: FunctionEnvMut, + ctx: FunctionEnvMut, argc: Ptr, argv_buf_size: Ptr, -) -> Result { - let (data, store) = ctx.data_and_store_mut(); - let memory = data.memory.clone().unwrap().view(&store); - - argc.write(&memory, 1)?; - argv_buf_size.write(&memory, 4)?; - - Ok(ERRNO_SUCCESS) +) -> Result { + Ok(caller_env::wasip1_stub::args_sizes_get(&mut Sp1Wavm(ctx), gp(argc), gp(argv_buf_size)).0) } pub fn args_get( - mut ctx: FunctionEnvMut, + ctx: FunctionEnvMut, argv_buf: Ptr, data_buf: Ptr, -) -> Result { - let (data, store) = ctx.data_and_store_mut(); - let memory = data.memory.clone().unwrap().view(&store); - - let data_buf = data_buf.deref(&memory); - - argv_buf.write(&memory, data_buf.offset() as u32)?; - data_buf.write(0x6E6962)?; // "bin\0" - - Ok(ERRNO_SUCCESS) +) -> Result { + Ok(caller_env::wasip1_stub::args_get(&mut Sp1Wavm(ctx), gp(argv_buf), gp(data_buf)).0) } pub fn environ_sizes_get( - mut ctx: FunctionEnvMut, + ctx: FunctionEnvMut, length_ptr: Ptr, data_size_ptr: Ptr, -) -> Result { - let (data, store) = ctx.data_and_store_mut(); - let memory = data.memory.clone().unwrap().view(&store); - - length_ptr.write(&memory, 0)?; - data_size_ptr.write(&memory, 0)?; - - Ok(ERRNO_SUCCESS) +) -> Result { + Ok(caller_env::wasip1_stub::environ_sizes_get(&mut Sp1Wavm(ctx), gp(length_ptr), gp(data_size_ptr)).0) } -pub fn environ_get(_ctx: FunctionEnvMut, _: Ptr, _: Ptr) -> Errno { - ERRNO_SUCCESS +pub fn environ_get(ctx: FunctionEnvMut, a: Ptr, b: Ptr) -> u16 { + caller_env::wasip1_stub::environ_get(&mut Sp1Wavm(ctx), gp(a), gp(b)).0 } pub fn fd_write( - mut ctx: FunctionEnvMut, + ctx: FunctionEnvMut, fd: u32, iovecs_ptr: Ptr, iovecs_len: u32, ret_ptr: Ptr, -) -> Result { - if fd != 1 && fd != 2 { - return Ok(ERRNO_BADF); - } - - let (data, store) = ctx.data_and_store_mut(); - let memory = data.memory.clone().unwrap().view(&store); - - let mut size = 0; - for i in 0..iovecs_len { - let ptr = iovecs_ptr.add_offset((i * 2).into()).unwrap(); - let len = ptr.add_offset(1).unwrap().read(&memory)?; - let ptr = Ptr::new(ptr.read(&memory)?); - let data = read_slice(ptr, len as usize, &memory)?; - - platform::print_string(fd, &data); - - size += len; - } - - ret_ptr.write(&memory, size)?; - Ok(ERRNO_SUCCESS) -} - -pub fn fd_close(_ctx: FunctionEnvMut, _fd: u32) -> Errno { - ERRNO_BADF -} - -pub fn fd_read(_ctx: FunctionEnvMut, _: u32, _: u32, _: u32, _: u32) -> Errno { - ERRNO_BADF -} - -pub fn fd_readdir( - _ctx: FunctionEnvMut, - _fd: u32, - _: u32, - _: u32, - _: u64, - _: u32, -) -> Errno { - ERRNO_BADF -} - -pub fn fd_sync(_ctx: FunctionEnvMut, _: u32) -> Errno { - ERRNO_SUCCESS -} - -pub fn fd_seek(_ctx: FunctionEnvMut, _: u32, _: u64, _: u32, _: u32) -> Errno { - ERRNO_BADF -} - -pub fn fd_datasync(_ctx: FunctionEnvMut, _: u32) -> Errno { - ERRNO_BADF -} - -pub fn fd_prestat_get(_ctx: FunctionEnvMut, _: u32, _: u32) -> Errno { - ERRNO_BADF -} - -pub fn fd_prestat_dir_name(_ctx: FunctionEnvMut, _: u32, _: u32, _: u32) -> Errno { - ERRNO_BADF -} - -pub fn fd_filestat_get(_ctx: FunctionEnvMut, _: u32, _: u32) -> Errno { - ERRNO_BADF -} - -pub fn fd_filestat_set_size(_ctx: FunctionEnvMut, _: u32, _: u64) -> Errno { - ERRNO_BADF +) -> Result { + Ok(caller_env::wasip1_stub::fd_write(&mut Sp1Wavm(ctx), fd, gp(iovecs_ptr), iovecs_len, gp(ret_ptr)).0) } -pub fn fd_pread( - _ctx: FunctionEnvMut, - _fd: u32, - _: u32, - _: u32, - _: u64, - _: u32, -) -> Errno { - ERRNO_BADF -} - -pub fn fd_pwrite( - _ctx: FunctionEnvMut, - _fd: u32, - _: u32, - _: u32, - _: u64, - _: u32, -) -> Errno { - ERRNO_BADF -} - -pub fn fd_fdstat_get(_ctx: FunctionEnvMut, _: u32, _: u32) -> Errno { - ERRNO_INVAL -} - -pub fn fd_fdstat_set_flags(_ctx: FunctionEnvMut, _: u32, _: u32) -> Errno { - ERRNO_INVAL -} - -const TIME_INTERVAL: u64 = 10_000_000; - pub fn clock_time_get( - mut ctx: FunctionEnvMut, - _clock_id: u32, - _precision: u64, + ctx: FunctionEnvMut, + clock_id: u32, + precision: u64, time_ptr: Ptr, -) -> Result { - let (data, store) = ctx.data_and_store_mut(); - let memory = data.memory.clone().unwrap().view(&store); - - data.time += TIME_INTERVAL; - time_ptr.cast::().write(&memory, data.time)?; - - Ok(ERRNO_SUCCESS) +) -> Result { + Ok(caller_env::wasip1_stub::clock_time_get(&mut Sp1Wavm(ctx), clock_id, precision, gp(time_ptr)).0) } pub fn random_get( - mut ctx: FunctionEnvMut, - mut buf: Ptr, - mut len: u32, -) -> Result { - let (data, store) = ctx.data_and_store_mut(); - let memory = data.memory.clone().unwrap().view(&store); - - while len >= 4 { - let next_rand = data.pcg.next_u32(); - buf.write(&memory, next_rand)?; - buf = buf.add_offset(1).unwrap(); - len -= 4; - } - if len > 0 { - let mut rem = data.pcg.next_u32(); - let mut buf = buf.cast::(); - - for _ in 0..len { - buf.write(&memory, rem as u8)?; - buf = buf.add_offset(1).unwrap(); - rem >>= 8; - } - } - Ok(ERRNO_SUCCESS) + ctx: FunctionEnvMut, + buf: Ptr, + len: u32, +) -> Result { + Ok(caller_env::wasip1_stub::random_get(&mut Sp1Wavm(ctx), gp(buf), len).0) } pub fn poll_oneoff( - mut ctx: FunctionEnvMut, + ctx: FunctionEnvMut, in_subs: Ptr, out_evt: Ptr, num_subscriptions: u32, num_events_ptr: Ptr, -) -> Result { - let (data, store) = ctx.data_and_store_mut(); - let memory = data.memory.clone().unwrap().view(&store); - - data.time += TIME_INTERVAL; - - const SUBSCRIPTION_SIZE: u32 = 48; - for index in 0..num_subscriptions { - let subs_base = in_subs - .cast::() - .add_offset(SUBSCRIPTION_SIZE * index) - .unwrap(); - let subs_type = subs_base - .add_offset(8) - .unwrap() - .cast::() - .read(&memory)?; - if subs_type != 0 { - continue; - } - let user_data = subs_base.cast::().read(&memory)?; - out_evt.write(&memory, user_data)?; - out_evt.add_offset(2).unwrap().write(&memory, subs_type)?; - num_events_ptr.write(&memory, 1)?; - return Ok(ERRNO_SUCCESS); - } - Ok(ERRNO_INVAL) +) -> Result { + Ok(caller_env::wasip1_stub::poll_oneoff(&mut Sp1Wavm(ctx), gp(in_subs), gp(out_evt), num_subscriptions, gp(num_events_ptr)).0) } -pub fn sched_yield(_ctx: FunctionEnvMut) -> Errno { - ERRNO_SUCCESS -} - -pub fn path_open( - _ctx: FunctionEnvMut, - _: u32, - _: u32, - _: u32, - _: u32, - _: u32, - _: u64, - _: u64, - _: u32, - _: u32, -) -> Errno { - ERRNO_BADF -} - -pub fn path_create_directory(_ctx: FunctionEnvMut, _: u32, _: u32, _: u32) -> Errno { - ERRNO_BADF -} - -pub fn path_remove_directory(_ctx: FunctionEnvMut, _: u32, _: u32, _: u32) -> Errno { - ERRNO_BADF -} - -pub fn path_readlink( - _ctx: FunctionEnvMut, - _: u32, - _: u32, - _: u32, - _: u32, - _: u32, - _: u32, -) -> Errno { - ERRNO_BADF -} - -pub fn path_rename( - _ctx: FunctionEnvMut, - _: u32, - _: u32, - _: u32, - _: u32, - _: u32, - _: u32, -) -> Errno { - ERRNO_BADF -} - -pub fn path_filestat_get( - _ctx: FunctionEnvMut, - _: u32, - _: u32, - _: u32, - _: u32, - _: u32, -) -> Errno { - ERRNO_BADF -} - -pub fn path_unlink_file(_ctx: FunctionEnvMut, _: u32, _: u32, _: u32) -> Errno { - ERRNO_BADF -} - -pub fn sock_accept(_ctx: FunctionEnvMut, _: u32, _: u32, _: u32) -> Errno { - ERRNO_BADF -} - -pub fn sock_shutdown(_ctx: FunctionEnvMut, _: u32, _: u32) -> Errno { - ERRNO_BADF +pub fn fd_seek( + ctx: FunctionEnvMut, + fd: u32, + offset: u64, + whence: u32, + filesize: u32, +) -> u16 { + caller_env::wasip1_stub::fd_seek(&mut Sp1Wavm(ctx), fd, offset, whence as u8, filesize).0 +} + +macro_rules! wrap { + ($(fn $func_name:ident ($($arg_name:ident : $arg_type:ty),*));* $(;)?) => { + $( + pub fn $func_name(ctx: FunctionEnvMut, $($arg_name : $arg_type),*) -> u16 { + caller_env::wasip1_stub::$func_name(&mut Sp1Wavm(ctx), $($arg_name),*).0 + } + )* + }; +} + +wrap! { + fn fd_close(fd: u32); + fn fd_read(a: u32, b: u32, c: u32, d: u32); + fn fd_readdir(fd: u32, a: u32, b: u32, c: u64, d: u32); + fn fd_sync(a: u32); + fn fd_datasync(fd: u32); + fn fd_fdstat_get(a: u32, b: u32); + fn fd_fdstat_set_flags(a: u32, b: u32); + fn fd_prestat_get(a: u32, b: u32); + fn fd_prestat_dir_name(a: u32, b: u32, c: u32); + fn fd_filestat_get(fd: u32, filestat: u32); + fn fd_filestat_set_size(fd: u32, size: u64); + fn fd_pread(fd: u32, a: u32, b: u32, c: u64, d: u32); + fn fd_pwrite(fd: u32, a: u32, b: u32, c: u64, d: u32); + fn path_open(a: u32, b: u32, c: u32, d: u32, e: u32, f: u64, g: u64, h: u32, i: u32); + fn path_create_directory(a: u32, b: u32, c: u32); + fn path_remove_directory(a: u32, b: u32, c: u32); + fn path_readlink(a: u32, b: u32, c: u32, d: u32, e: u32, f: u32); + fn path_rename(a: u32, b: u32, c: u32, d: u32, e: u32, f: u32); + fn path_filestat_get(a: u32, b: u32, c: u32, d: u32, e: u32); + fn path_unlink_file(a: u32, b: u32, c: u32); + fn sock_accept(fd: u32, a: u32, b: u32); + fn sock_shutdown(a: u32, b: u32); + fn sched_yield() } diff --git a/sp1-crates/program/src/imports/wavmio.rs b/sp1-crates/program/src/imports/wavmio.rs index 293f2e8275d..6fc2b5a3cd0 100644 --- a/sp1-crates/program/src/imports/wavmio.rs +++ b/sp1-crates/program/src/imports/wavmio.rs @@ -1,17 +1,13 @@ //! wavmio functions — thin wrappers delegating to caller_env::wavmio. use crate::{ - Escape, MaybeEscape, Ptr, caller_env_adapters::Sp1Wavm, read_bytes32, replay::CustomEnvData, + Escape, MaybeEscape, Ptr, caller_env_adapters::{Sp1Wavm, gp}, read_bytes32, + replay::CustomEnvData, }; use ::caller_env::wavmio as caller_env; -use ::caller_env::GuestPtr; use core::ops::Deref; use wasmer::{FunctionEnvMut, MemoryView}; -fn gp(p: Ptr) -> GuestPtr { - GuestPtr(p.offset()) -} - pub fn get_global_state_bytes32(ctx: FunctionEnvMut, idx: u32, out_ptr: Ptr) -> MaybeEscape { caller_env::get_global_state_bytes32(&mut Sp1Wavm(ctx), idx, gp(out_ptr)).map_err(Escape::Logical) } From 01e5cd618878feac65388b345c8aeab28b128ccd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 3 Mar 2026 17:15:10 +0100 Subject: [PATCH 056/189] move memory things to dedicated modules --- crates/jit/src/caller_env.rs | 92 +------------------ crates/jit/src/lib.rs | 1 + crates/jit/src/memory.rs | 92 +++++++++++++++++++ sp1-crates/program/src/caller_env_adapters.rs | 75 +-------------- sp1-crates/program/src/lib.rs | 1 + sp1-crates/program/src/memory.rs | 75 +++++++++++++++ 6 files changed, 175 insertions(+), 161 deletions(-) create mode 100644 crates/jit/src/memory.rs create mode 100644 sp1-crates/program/src/memory.rs diff --git a/crates/jit/src/caller_env.rs b/crates/jit/src/caller_env.rs index a607e788cad..621cd945761 100644 --- a/crates/jit/src/caller_env.rs +++ b/crates/jit/src/caller_env.rs @@ -2,17 +2,11 @@ // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md use crate::machine::{WasmEnv, WasmEnvMut}; -use arbutil::{Bytes20, Bytes32, PreimageType}; +use crate::memory::JitMemAccess; +use arbutil::{Bytes32, PreimageType}; use caller_env::wavmio::{WavmEnv, WavmState}; -use caller_env::{ExecEnv, GuestPtr, MemAccess}; +use caller_env::ExecEnv; use rand::RngCore; -use std::mem::{self, MaybeUninit}; -use wasmer::{Memory, MemoryView, StoreMut, WasmPtr}; - -pub struct JitMemAccess<'s> { - pub memory: Memory, - pub store: StoreMut<'s>, -} /// Newtype for implementing WavmEnv (orphan rule: FunctionEnvMut is foreign). pub(crate) struct JitWavm<'e>(pub WasmEnvMut<'e>); @@ -36,86 +30,6 @@ impl WavmEnv for JitWavm<'_> { } } -impl JitMemAccess<'_> { - fn view(&self) -> MemoryView<'_> { - self.memory.view(&self.store) - } - - pub fn write_bytes32(&mut self, ptr: GuestPtr, val: Bytes32) { - self.write_slice(ptr, val.as_slice()) - } - - pub fn read_bytes20(&mut self, ptr: GuestPtr) -> Bytes20 { - self.read_fixed(ptr).into() - } - - pub fn read_bytes32(&mut self, ptr: GuestPtr) -> Bytes32 { - self.read_fixed(ptr).into() - } -} - -impl MemAccess for JitMemAccess<'_> { - fn read_u8(&self, ptr: GuestPtr) -> u8 { - let ptr: WasmPtr = ptr.into(); - ptr.deref(&self.view()).read().unwrap() - } - - fn read_u16(&self, ptr: GuestPtr) -> u16 { - let ptr: WasmPtr = ptr.into(); - ptr.deref(&self.view()).read().unwrap() - } - - fn read_u32(&self, ptr: GuestPtr) -> u32 { - let ptr: WasmPtr = ptr.into(); - ptr.deref(&self.view()).read().unwrap() - } - - fn read_u64(&self, ptr: GuestPtr) -> u64 { - let ptr: WasmPtr = ptr.into(); - ptr.deref(&self.view()).read().unwrap() - } - - fn write_u8(&mut self, ptr: GuestPtr, x: u8) { - let ptr: WasmPtr = ptr.into(); - ptr.deref(&self.view()).write(x).unwrap(); - } - - fn write_u16(&mut self, ptr: GuestPtr, x: u16) { - let ptr: WasmPtr = ptr.into(); - ptr.deref(&self.view()).write(x).unwrap(); - } - - fn write_u32(&mut self, ptr: GuestPtr, x: u32) { - let ptr: WasmPtr = ptr.into(); - ptr.deref(&self.view()).write(x).unwrap(); - } - - fn write_u64(&mut self, ptr: GuestPtr, x: u64) { - let ptr: WasmPtr = ptr.into(); - ptr.deref(&self.view()).write(x).unwrap(); - } - - fn read_slice(&self, ptr: GuestPtr, len: usize) -> Vec { - let mut data: Vec> = Vec::with_capacity(len); - // SAFETY: read_uninit fills all available space - unsafe { - data.set_len(len); - self.view() - .read_uninit(ptr.into(), &mut data) - .expect("bad read"); - mem::transmute::>, Vec>(data) - } - } - - fn read_fixed(&self, ptr: GuestPtr) -> [u8; N] { - self.read_slice(ptr, N).try_into().unwrap() - } - - fn write_slice(&mut self, ptr: GuestPtr, src: &[u8]) { - self.view().write(ptr.into(), src).unwrap(); - } -} - impl ExecEnv for JitState<'_> { fn advance_time(&mut self, ns: u64) { self.0.go_state.time += ns; diff --git a/crates/jit/src/lib.rs b/crates/jit/src/lib.rs index 8a60dcae697..91770949794 100644 --- a/crates/jit/src/lib.rs +++ b/crates/jit/src/lib.rs @@ -16,6 +16,7 @@ mod arbcompress; mod arbcrypto; mod caller_env; pub mod machine; +mod memory; mod prepare; pub mod program; pub mod stylus_backend; diff --git a/crates/jit/src/memory.rs b/crates/jit/src/memory.rs new file mode 100644 index 00000000000..c222ed46f43 --- /dev/null +++ b/crates/jit/src/memory.rs @@ -0,0 +1,92 @@ +// Copyright 2022-2026, Offchain Labs, Inc. +// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md + +use arbutil::{Bytes20, Bytes32}; +use caller_env::{GuestPtr, MemAccess}; +use std::mem::{self, MaybeUninit}; +use wasmer::{Memory, MemoryView, StoreMut, WasmPtr}; + +pub struct JitMemAccess<'s> { + pub memory: Memory, + pub store: StoreMut<'s>, +} + +impl JitMemAccess<'_> { + fn view(&self) -> MemoryView<'_> { + self.memory.view(&self.store) + } + + pub fn write_bytes32(&mut self, ptr: GuestPtr, val: Bytes32) { + self.write_slice(ptr, val.as_slice()) + } + + pub fn read_bytes20(&mut self, ptr: GuestPtr) -> Bytes20 { + self.read_fixed(ptr).into() + } + + pub fn read_bytes32(&mut self, ptr: GuestPtr) -> Bytes32 { + self.read_fixed(ptr).into() + } +} + +impl MemAccess for JitMemAccess<'_> { + fn read_u8(&self, ptr: GuestPtr) -> u8 { + let ptr: WasmPtr = ptr.into(); + ptr.deref(&self.view()).read().unwrap() + } + + fn read_u16(&self, ptr: GuestPtr) -> u16 { + let ptr: WasmPtr = ptr.into(); + ptr.deref(&self.view()).read().unwrap() + } + + fn read_u32(&self, ptr: GuestPtr) -> u32 { + let ptr: WasmPtr = ptr.into(); + ptr.deref(&self.view()).read().unwrap() + } + + fn read_u64(&self, ptr: GuestPtr) -> u64 { + let ptr: WasmPtr = ptr.into(); + ptr.deref(&self.view()).read().unwrap() + } + + fn write_u8(&mut self, ptr: GuestPtr, x: u8) { + let ptr: WasmPtr = ptr.into(); + ptr.deref(&self.view()).write(x).unwrap(); + } + + fn write_u16(&mut self, ptr: GuestPtr, x: u16) { + let ptr: WasmPtr = ptr.into(); + ptr.deref(&self.view()).write(x).unwrap(); + } + + fn write_u32(&mut self, ptr: GuestPtr, x: u32) { + let ptr: WasmPtr = ptr.into(); + ptr.deref(&self.view()).write(x).unwrap(); + } + + fn write_u64(&mut self, ptr: GuestPtr, x: u64) { + let ptr: WasmPtr = ptr.into(); + ptr.deref(&self.view()).write(x).unwrap(); + } + + fn read_slice(&self, ptr: GuestPtr, len: usize) -> Vec { + let mut data: Vec> = Vec::with_capacity(len); + // SAFETY: read_uninit fills all available space + unsafe { + data.set_len(len); + self.view() + .read_uninit(ptr.into(), &mut data) + .expect("bad read"); + mem::transmute::>, Vec>(data) + } + } + + fn read_fixed(&self, ptr: GuestPtr) -> [u8; N] { + self.read_slice(ptr, N).try_into().unwrap() + } + + fn write_slice(&mut self, ptr: GuestPtr, src: &[u8]) { + self.view().write(ptr.into(), src).unwrap(); + } +} diff --git a/sp1-crates/program/src/caller_env_adapters.rs b/sp1-crates/program/src/caller_env_adapters.rs index 7b8bf5277a3..55078e0bbc6 100644 --- a/sp1-crates/program/src/caller_env_adapters.rs +++ b/sp1-crates/program/src/caller_env_adapters.rs @@ -2,82 +2,13 @@ // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md use caller_env::wavmio::{WavmEnv, WavmState}; -use caller_env::{ExecEnv, GuestPtr, MemAccess}; +use caller_env::{ExecEnv, GuestPtr}; use rand::RngCore; -use wasmer::{FunctionEnvMut, Memory, StoreMut}; +use wasmer::FunctionEnvMut; +use crate::memory::Sp1MemAccess; use crate::replay::CustomEnvData; -/// Adapter implementing MemAccess over wasmer MemoryView. -pub(crate) struct Sp1MemAccess<'s> { - pub memory: Memory, - pub store: StoreMut<'s>, -} - -impl Sp1MemAccess<'_> { - fn view(&self) -> wasmer::MemoryView<'_> { - self.memory.view(&self.store) - } -} - -impl MemAccess for Sp1MemAccess<'_> { - fn read_u8(&self, ptr: GuestPtr) -> u8 { - let mut buf = [0u8; 1]; - self.view().read(ptr.to_u64(), &mut buf).unwrap(); - buf[0] - } - - fn read_u16(&self, ptr: GuestPtr) -> u16 { - let mut buf = [0u8; 2]; - self.view().read(ptr.to_u64(), &mut buf).unwrap(); - u16::from_le_bytes(buf) - } - - fn read_u32(&self, ptr: GuestPtr) -> u32 { - let mut buf = [0u8; 4]; - self.view().read(ptr.to_u64(), &mut buf).unwrap(); - u32::from_le_bytes(buf) - } - - fn read_u64(&self, ptr: GuestPtr) -> u64 { - let mut buf = [0u8; 8]; - self.view().read(ptr.to_u64(), &mut buf).unwrap(); - u64::from_le_bytes(buf) - } - - fn write_u8(&mut self, ptr: GuestPtr, x: u8) { - self.view().write(ptr.to_u64(), &[x]).unwrap(); - } - - fn write_u16(&mut self, ptr: GuestPtr, x: u16) { - self.view().write(ptr.to_u64(), &x.to_le_bytes()).unwrap(); - } - - fn write_u32(&mut self, ptr: GuestPtr, x: u32) { - self.view().write(ptr.to_u64(), &x.to_le_bytes()).unwrap(); - } - - fn write_u64(&mut self, ptr: GuestPtr, x: u64) { - self.view().write(ptr.to_u64(), &x.to_le_bytes()).unwrap(); - } - - fn read_slice(&self, ptr: GuestPtr, len: usize) -> Vec { - let mut data = vec![0u8; len]; - self.view().read(ptr.to_u64(), &mut data).unwrap(); - data - } - - fn read_fixed(&self, ptr: GuestPtr) -> [u8; N] { - let mut buf = [0u8; N]; - self.view().read(ptr.to_u64(), &mut buf).unwrap(); - buf - } - - fn write_slice(&mut self, ptr: GuestPtr, data: &[u8]) { - self.view().write(ptr.to_u64(), data).unwrap(); - } -} - /// Newtype wrapper to implement WavmState and ExecEnv over CustomEnvData. pub(crate) struct Sp1State<'a>(pub &'a mut CustomEnvData); diff --git a/sp1-crates/program/src/lib.rs b/sp1-crates/program/src/lib.rs index 18c6e241e3d..64c86fb2665 100644 --- a/sp1-crates/program/src/lib.rs +++ b/sp1-crates/program/src/lib.rs @@ -3,6 +3,7 @@ pub mod platform; pub mod replay; pub mod stylus; mod caller_env_adapters; +mod memory; use arbutil::{ Bytes20, Bytes32, diff --git a/sp1-crates/program/src/memory.rs b/sp1-crates/program/src/memory.rs new file mode 100644 index 00000000000..4d7b40ebaaf --- /dev/null +++ b/sp1-crates/program/src/memory.rs @@ -0,0 +1,75 @@ +// Copyright 2026, Offchain Labs, Inc. +// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md + +use caller_env::{GuestPtr, MemAccess}; +use wasmer::{Memory, StoreMut}; + +/// Adapter implementing MemAccess over wasmer MemoryView. +pub(crate) struct Sp1MemAccess<'s> { + pub memory: Memory, + pub store: StoreMut<'s>, +} + +impl Sp1MemAccess<'_> { + fn view(&self) -> wasmer::MemoryView<'_> { + self.memory.view(&self.store) + } +} + +impl MemAccess for Sp1MemAccess<'_> { + fn read_u8(&self, ptr: GuestPtr) -> u8 { + let mut buf = [0u8; 1]; + self.view().read(ptr.to_u64(), &mut buf).unwrap(); + buf[0] + } + + fn read_u16(&self, ptr: GuestPtr) -> u16 { + let mut buf = [0u8; 2]; + self.view().read(ptr.to_u64(), &mut buf).unwrap(); + u16::from_le_bytes(buf) + } + + fn read_u32(&self, ptr: GuestPtr) -> u32 { + let mut buf = [0u8; 4]; + self.view().read(ptr.to_u64(), &mut buf).unwrap(); + u32::from_le_bytes(buf) + } + + fn read_u64(&self, ptr: GuestPtr) -> u64 { + let mut buf = [0u8; 8]; + self.view().read(ptr.to_u64(), &mut buf).unwrap(); + u64::from_le_bytes(buf) + } + + fn write_u8(&mut self, ptr: GuestPtr, x: u8) { + self.view().write(ptr.to_u64(), &[x]).unwrap(); + } + + fn write_u16(&mut self, ptr: GuestPtr, x: u16) { + self.view().write(ptr.to_u64(), &x.to_le_bytes()).unwrap(); + } + + fn write_u32(&mut self, ptr: GuestPtr, x: u32) { + self.view().write(ptr.to_u64(), &x.to_le_bytes()).unwrap(); + } + + fn write_u64(&mut self, ptr: GuestPtr, x: u64) { + self.view().write(ptr.to_u64(), &x.to_le_bytes()).unwrap(); + } + + fn read_slice(&self, ptr: GuestPtr, len: usize) -> Vec { + let mut data = vec![0u8; len]; + self.view().read(ptr.to_u64(), &mut data).unwrap(); + data + } + + fn read_fixed(&self, ptr: GuestPtr) -> [u8; N] { + let mut buf = [0u8; N]; + self.view().read(ptr.to_u64(), &mut buf).unwrap(); + buf + } + + fn write_slice(&mut self, ptr: GuestPtr, data: &[u8]) { + self.view().write(ptr.to_u64(), data).unwrap(); + } +} From 6922050c9b3386b0c0635907ecbaefab95d92aff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Wed, 4 Mar 2026 10:43:07 +0100 Subject: [PATCH 057/189] rename module to state --- crates/jit/src/arbcompress.rs | 2 +- crates/jit/src/arbcrypto.rs | 2 +- crates/jit/src/lib.rs | 2 +- crates/jit/src/program.rs | 2 +- crates/jit/src/{caller_env.rs => state.rs} | 0 crates/jit/src/wasip1_stub.rs | 2 +- crates/jit/src/wavmio.rs | 4 ++-- sp1-crates/program/src/imports/wasi_stub.rs | 2 +- sp1-crates/program/src/imports/wavmio.rs | 2 +- sp1-crates/program/src/lib.rs | 2 +- sp1-crates/program/src/{caller_env_adapters.rs => state.rs} | 0 11 files changed, 10 insertions(+), 10 deletions(-) rename crates/jit/src/{caller_env.rs => state.rs} (100%) rename sp1-crates/program/src/{caller_env_adapters.rs => state.rs} (100%) diff --git a/crates/jit/src/arbcompress.rs b/crates/jit/src/arbcompress.rs index 4e4d0b5859e..1e44d961e7e 100644 --- a/crates/jit/src/arbcompress.rs +++ b/crates/jit/src/arbcompress.rs @@ -1,7 +1,7 @@ // Copyright 2022-2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md -use crate::caller_env::jit_env; +use crate::state::jit_env; use crate::machine::Escape; use crate::machine::WasmEnvMut; use brotli::{BrotliStatus, Dictionary}; diff --git a/crates/jit/src/arbcrypto.rs b/crates/jit/src/arbcrypto.rs index f2ff35799b0..a29d452fad9 100644 --- a/crates/jit/src/arbcrypto.rs +++ b/crates/jit/src/arbcrypto.rs @@ -1,6 +1,6 @@ // Copyright 2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md -use crate::caller_env::jit_env; +use crate::state::jit_env; use crate::machine::{Escape, MaybeEscape, WasmEnvMut}; use caller_env::GuestPtr; diff --git a/crates/jit/src/lib.rs b/crates/jit/src/lib.rs index 91770949794..c7ef29f4285 100644 --- a/crates/jit/src/lib.rs +++ b/crates/jit/src/lib.rs @@ -14,7 +14,7 @@ use wasmer::{FrameInfo, FunctionEnv, Instance, Pages, Store}; mod arbcompress; mod arbcrypto; -mod caller_env; +mod state; pub mod machine; mod memory; mod prepare; diff --git a/crates/jit/src/program.rs b/crates/jit/src/program.rs index a706429682b..95bc3ed1764 100644 --- a/crates/jit/src/program.rs +++ b/crates/jit/src/program.rs @@ -3,7 +3,7 @@ #![allow(clippy::too_many_arguments)] -use crate::caller_env::jit_env; +use crate::state::jit_env; use crate::machine::{Escape, MaybeEscape, WasmEnv, WasmEnvMut}; use crate::stylus_backend::{exec_wasm, MessageFromCothread}; use arbutil::evm::api::Gas; diff --git a/crates/jit/src/caller_env.rs b/crates/jit/src/state.rs similarity index 100% rename from crates/jit/src/caller_env.rs rename to crates/jit/src/state.rs diff --git a/crates/jit/src/wasip1_stub.rs b/crates/jit/src/wasip1_stub.rs index dfae393fcc7..204ab2ac330 100644 --- a/crates/jit/src/wasip1_stub.rs +++ b/crates/jit/src/wasip1_stub.rs @@ -3,7 +3,7 @@ #![allow(clippy::too_many_arguments)] -use crate::caller_env::JitWavm; +use crate::state::JitWavm; use crate::machine::{Escape, WasmEnvMut}; use caller_env::{self, wasip1_stub::Errno, GuestPtr}; diff --git a/crates/jit/src/wavmio.rs b/crates/jit/src/wavmio.rs index cb98ed039db..e207cdea0ec 100644 --- a/crates/jit/src/wavmio.rs +++ b/crates/jit/src/wavmio.rs @@ -1,7 +1,7 @@ // Copyright 2022-2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md -use crate::caller_env::JitWavm; +use crate::state::JitWavm; use crate::machine::{Escape, MaybeEscape, WasmEnv, WasmEnvMut}; use arbutil::Color; use ::caller_env::wavmio as caller_env; @@ -96,7 +96,7 @@ fn resolve_preimage_impl( #[cfg(debug_assertions)] { - use crate::caller_env::jit_env; + use crate::state::jit_env; use arbutil::PreimageType; use sha2::Sha256; use sha3::{Digest, Keccak256}; diff --git a/sp1-crates/program/src/imports/wasi_stub.rs b/sp1-crates/program/src/imports/wasi_stub.rs index 355c6b9f9d5..eadcd91ae72 100644 --- a/sp1-crates/program/src/imports/wasi_stub.rs +++ b/sp1-crates/program/src/imports/wasi_stub.rs @@ -2,7 +2,7 @@ #![allow(clippy::too_many_arguments)] -use crate::{Escape, Ptr, caller_env_adapters::{Sp1Wavm, gp}, platform, replay::CustomEnvData}; +use crate::{Escape, Ptr, state::{Sp1Wavm, gp}, platform, replay::CustomEnvData}; use caller_env; use wasmer::FunctionEnvMut; diff --git a/sp1-crates/program/src/imports/wavmio.rs b/sp1-crates/program/src/imports/wavmio.rs index 6fc2b5a3cd0..34c8c82670c 100644 --- a/sp1-crates/program/src/imports/wavmio.rs +++ b/sp1-crates/program/src/imports/wavmio.rs @@ -1,7 +1,7 @@ //! wavmio functions — thin wrappers delegating to caller_env::wavmio. use crate::{ - Escape, MaybeEscape, Ptr, caller_env_adapters::{Sp1Wavm, gp}, read_bytes32, + Escape, MaybeEscape, Ptr, state::{Sp1Wavm, gp}, read_bytes32, replay::CustomEnvData, }; use ::caller_env::wavmio as caller_env; diff --git a/sp1-crates/program/src/lib.rs b/sp1-crates/program/src/lib.rs index 64c86fb2665..007b777b639 100644 --- a/sp1-crates/program/src/lib.rs +++ b/sp1-crates/program/src/lib.rs @@ -2,7 +2,7 @@ pub mod imports; pub mod platform; pub mod replay; pub mod stylus; -mod caller_env_adapters; +mod state; mod memory; use arbutil::{ diff --git a/sp1-crates/program/src/caller_env_adapters.rs b/sp1-crates/program/src/state.rs similarity index 100% rename from sp1-crates/program/src/caller_env_adapters.rs rename to sp1-crates/program/src/state.rs From 0f81c3f4e6d5804a922ef70ea682c5efde97bbbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Wed, 4 Mar 2026 10:52:15 +0100 Subject: [PATCH 058/189] another trait to handle statics --- crates/caller-env/src/static_caller.rs | 12 +++- crates/caller-env/src/wasip1_stub.rs | 80 +++++++++++++------------- crates/caller-env/src/wavmio.rs | 19 +++++- crates/wasm-libraries/wasi-stub/lib.rs | 5 +- 4 files changed, 71 insertions(+), 45 deletions(-) diff --git a/crates/caller-env/src/static_caller.rs b/crates/caller-env/src/static_caller.rs index 79c0ba2649b..9f24fdc8d20 100644 --- a/crates/caller-env/src/static_caller.rs +++ b/crates/caller-env/src/static_caller.rs @@ -1,7 +1,7 @@ // Copyright 2021-2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md -use crate::{ExecEnv, GoRuntimeState, GuestPtr, MemAccess}; +use crate::{ExecEnv, GoRuntimeState, GuestPtr, MemAccess, wavmio::WasmEnv}; use alloc::vec::Vec; use rand::RngCore; use spin::{Lazy, Mutex, MutexGuard}; @@ -12,6 +12,16 @@ extern crate alloc; pub struct StaticMem; /// Static execution environment for Go runtime in WAVM. pub struct StaticExecEnv; +/// Bundled static environment implementing WasmEnv. +pub struct StaticWasmEnv; + +impl WasmEnv for StaticWasmEnv { + type Mem<'a> = StaticMem; + type State<'a> = StaticExecEnv; + fn wasm_env(&mut self) -> (StaticMem, StaticExecEnv) { + (StaticMem, StaticExecEnv) + } +} static GO_RUNTIME_STATE: Lazy> = Lazy::new(Default::default); diff --git a/crates/caller-env/src/wasip1_stub.rs b/crates/caller-env/src/wasip1_stub.rs index bdd357ba742..8222624586c 100644 --- a/crates/caller-env/src/wasip1_stub.rs +++ b/crates/caller-env/src/wasip1_stub.rs @@ -7,7 +7,7 @@ #![allow(clippy::too_many_arguments)] -use crate::{ExecEnv, GuestPtr, MemAccess, wavmio::WavmEnv}; +use crate::{ExecEnv, GuestPtr, MemAccess, wavmio::WasmEnv}; #[repr(transparent)] pub struct Errno(pub u16); @@ -19,11 +19,11 @@ pub const ERRNO_INVAL: Errno = Errno(28); /// Writes the number and total size of args passed by the OS. /// Note that this currently consists of just the program name `bin`. pub fn args_sizes_get( - env: &mut impl WavmEnv, + env: &mut impl WasmEnv, length_ptr: GuestPtr, data_size_ptr: GuestPtr, ) -> Errno { - let (mut mem, _) = env.wavm_env(); + let (mut mem, _) = env.wasm_env(); mem.write_u32(length_ptr, 1); mem.write_u32(data_size_ptr, 4); ERRNO_SUCCESS @@ -32,11 +32,11 @@ pub fn args_sizes_get( /// Writes the args passed by the OS. /// Note that this currently consists of just the program name `bin`. pub fn args_get( - env: &mut impl WavmEnv, + env: &mut impl WasmEnv, argv_buf: GuestPtr, data_buf: GuestPtr, ) -> Errno { - let (mut mem, _) = env.wavm_env(); + let (mut mem, _) = env.wasm_env(); mem.write_u32(argv_buf, data_buf.into()); mem.write_u32(data_buf, 0x6E6962); // "bin\0" ERRNO_SUCCESS @@ -45,11 +45,11 @@ pub fn args_get( /// Writes the number and total size of OS environment variables. /// Note that none exist in Nitro. pub fn environ_sizes_get( - env: &mut impl WavmEnv, + env: &mut impl WasmEnv, length_ptr: GuestPtr, data_size_ptr: GuestPtr, ) -> Errno { - let (mut mem, _) = env.wavm_env(); + let (mut mem, _) = env.wasm_env(); mem.write_u32(length_ptr, 0); mem.write_u32(data_size_ptr, 0); ERRNO_SUCCESS @@ -58,7 +58,7 @@ pub fn environ_sizes_get( /// Writes the number and total size of OS environment variables. /// Note that none exist in Nitro. pub fn environ_get( - _: &mut impl WavmEnv, + _: &mut impl WasmEnv, _: GuestPtr, _: GuestPtr, ) -> Errno { @@ -68,7 +68,7 @@ pub fn environ_get( /// Writes to the given file descriptor. /// Note that we only support stdout and stderr. pub fn fd_write( - env: &mut impl WavmEnv, + env: &mut impl WasmEnv, fd: u32, iovecs_ptr: GuestPtr, iovecs_len: u32, @@ -77,7 +77,7 @@ pub fn fd_write( if fd != 1 && fd != 2 { return ERRNO_BADF; } - let (mut mem, mut state) = env.wavm_env(); + let (mut mem, mut state) = env.wasm_env(); let mut size = 0; for i in 0..iovecs_len { let ptr = iovecs_ptr + i * 8; @@ -92,13 +92,13 @@ pub fn fd_write( } /// Closes the given file descriptor. Unsupported. -pub fn fd_close(_: &mut impl WavmEnv, _: u32) -> Errno { +pub fn fd_close(_: &mut impl WasmEnv, _: u32) -> Errno { ERRNO_BADF } /// Reads from the given file descriptor. Unsupported. pub fn fd_read( - _: &mut impl WavmEnv, + _: &mut impl WasmEnv, _: u32, _: u32, _: u32, @@ -109,7 +109,7 @@ pub fn fd_read( /// Reads the contents of a directory. Unsupported. pub fn fd_readdir( - _: &mut impl WavmEnv, + _: &mut impl WasmEnv, _fd: u32, _: u32, _: u32, @@ -120,13 +120,13 @@ pub fn fd_readdir( } /// Syncs a file to disk. Unsupported. -pub fn fd_sync(_: &mut impl WavmEnv, _: u32) -> Errno { +pub fn fd_sync(_: &mut impl WasmEnv, _: u32) -> Errno { ERRNO_SUCCESS } /// Move within a file. Unsupported. pub fn fd_seek( - _: &mut impl WavmEnv, + _: &mut impl WasmEnv, _fd: u32, _offset: u64, _whence: u8, @@ -136,18 +136,18 @@ pub fn fd_seek( } /// Syncs file contents to disk. Unsupported. -pub fn fd_datasync(_: &mut impl WavmEnv, _fd: u32) -> Errno { +pub fn fd_datasync(_: &mut impl WasmEnv, _fd: u32) -> Errno { ERRNO_BADF } /// Retrieves attributes about a file descriptor. Unsupported. -pub fn fd_fdstat_get(_: &mut impl WavmEnv, _: u32, _: u32) -> Errno { +pub fn fd_fdstat_get(_: &mut impl WasmEnv, _: u32, _: u32) -> Errno { ERRNO_INVAL } /// Sets the attributes of a file descriptor. Unsupported. pub fn fd_fdstat_set_flags( - _: &mut impl WavmEnv, + _: &mut impl WasmEnv, _: u32, _: u32, ) -> Errno { @@ -156,7 +156,7 @@ pub fn fd_fdstat_set_flags( /// Opens the file or directory at the given path. Unsupported. pub fn path_open( - _: &mut impl WavmEnv, + _: &mut impl WasmEnv, _: u32, _: u32, _: u32, @@ -172,7 +172,7 @@ pub fn path_open( /// Creates a directory. Unsupported. pub fn path_create_directory( - _: &mut impl WavmEnv, + _: &mut impl WasmEnv, _: u32, _: u32, _: u32, @@ -182,7 +182,7 @@ pub fn path_create_directory( /// Unlinks a directory. Unsupported. pub fn path_remove_directory( - _: &mut impl WavmEnv, + _: &mut impl WasmEnv, _: u32, _: u32, _: u32, @@ -192,7 +192,7 @@ pub fn path_remove_directory( /// Resolves a symbolic link. Unsupported. pub fn path_readlink( - _: &mut impl WavmEnv, + _: &mut impl WasmEnv, _: u32, _: u32, _: u32, @@ -205,7 +205,7 @@ pub fn path_readlink( /// Moves a file. Unsupported. pub fn path_rename( - _: &mut impl WavmEnv, + _: &mut impl WasmEnv, _: u32, _: u32, _: u32, @@ -218,7 +218,7 @@ pub fn path_rename( /// Retrieves info about an open file. Unsupported. pub fn path_filestat_get( - _: &mut impl WavmEnv, + _: &mut impl WasmEnv, _: u32, _: u32, _: u32, @@ -230,7 +230,7 @@ pub fn path_filestat_get( /// Unlinks the file at the given path. Unsupported. pub fn path_unlink_file( - _: &mut impl WavmEnv, + _: &mut impl WasmEnv, _: u32, _: u32, _: u32, @@ -239,13 +239,13 @@ pub fn path_unlink_file( } /// Retrieves info about a file. Unsupported. -pub fn fd_prestat_get(_: &mut impl WavmEnv, _: u32, _: u32) -> Errno { +pub fn fd_prestat_get(_: &mut impl WasmEnv, _: u32, _: u32) -> Errno { ERRNO_BADF } /// Retrieves info about a directory. Unsupported. pub fn fd_prestat_dir_name( - _: &mut impl WavmEnv, + _: &mut impl WasmEnv, _: u32, _: u32, _: u32, @@ -255,7 +255,7 @@ pub fn fd_prestat_dir_name( /// Retrieves info about a file. Unsupported. pub fn fd_filestat_get( - _: &mut impl WavmEnv, + _: &mut impl WasmEnv, _fd: u32, _filestat: u32, ) -> Errno { @@ -264,7 +264,7 @@ pub fn fd_filestat_get( /// Sets the size of an open file. Unsupported. pub fn fd_filestat_set_size( - _: &mut impl WavmEnv, + _: &mut impl WasmEnv, _fd: u32, _: u64, ) -> Errno { @@ -273,7 +273,7 @@ pub fn fd_filestat_set_size( /// Peaks within a descriptor without modifying its state. Unsupported. pub fn fd_pread( - _: &mut impl WavmEnv, + _: &mut impl WasmEnv, _fd: u32, _: u32, _: u32, @@ -285,7 +285,7 @@ pub fn fd_pread( /// Writes to a descriptor without modifying the current offset. Unsupported. pub fn fd_pwrite( - _: &mut impl WavmEnv, + _: &mut impl WasmEnv, _fd: u32, _: u32, _: u32, @@ -297,7 +297,7 @@ pub fn fd_pwrite( /// Accepts a new connection. Unsupported. pub fn sock_accept( - _: &mut impl WavmEnv, + _: &mut impl WasmEnv, _fd: u32, _: u32, _: u32, @@ -306,12 +306,12 @@ pub fn sock_accept( } /// Shuts down a socket. Unsupported. -pub fn sock_shutdown(_: &mut impl WavmEnv, _: u32, _: u32) -> Errno { +pub fn sock_shutdown(_: &mut impl WasmEnv, _: u32, _: u32) -> Errno { ERRNO_BADF } /// Yields execution to the OS scheduler. Effectively does nothing in Nitro due to the lack of threads. -pub fn sched_yield(_: &mut impl WavmEnv) -> Errno { +pub fn sched_yield(_: &mut impl WasmEnv) -> Errno { ERRNO_SUCCESS } @@ -322,12 +322,12 @@ static TIME_INTERVAL: u64 = 10_000_000; /// Note that in Nitro, all clocks point to the same deterministic counter that advances 10ms whenever /// this function is called. pub fn clock_time_get( - env: &mut impl WavmEnv, + env: &mut impl WasmEnv, _clock_id: u32, _precision: u64, time_ptr: GuestPtr, ) -> Errno { - let (mut mem, mut state) = env.wavm_env(); + let (mut mem, mut state) = env.wasm_env(); state.advance_time(TIME_INTERVAL); mem.write_u64(time_ptr, state.get_time()); ERRNO_SUCCESS @@ -336,11 +336,11 @@ pub fn clock_time_get( /// Fills a slice with psuedo-random bytes. /// Note that in Nitro, the bytes are deterministically generated from a common seed. pub fn random_get( - env: &mut impl WavmEnv, + env: &mut impl WasmEnv, mut buf: GuestPtr, mut len: u32, ) -> Errno { - let (mut mem, mut state) = env.wavm_env(); + let (mut mem, mut state) = env.wasm_env(); while len >= 4 { let next_rand = state.next_rand_u32(); mem.write_u32(buf, next_rand); @@ -361,13 +361,13 @@ pub fn random_get( /// Poll for events. /// Note that we always simulate a timeout and skip all others. pub fn poll_oneoff( - env: &mut impl WavmEnv, + env: &mut impl WasmEnv, in_subs: GuestPtr, out_evt: GuestPtr, num_subscriptions: u32, num_events_ptr: GuestPtr, ) -> Errno { - let (mut mem, mut state) = env.wavm_env(); + let (mut mem, mut state) = env.wasm_env(); // simulate the passage of time each poll request state.advance_time(TIME_INTERVAL); diff --git a/crates/caller-env/src/wavmio.rs b/crates/caller-env/src/wavmio.rs index 605c2425736..ada28407fb2 100644 --- a/crates/caller-env/src/wavmio.rs +++ b/crates/caller-env/src/wavmio.rs @@ -17,13 +17,30 @@ pub trait WavmState: ExecEnv { fn get_preimage(&self, preimage_type: u8, hash: &[u8; 32]) -> Option<&[u8]>; } -/// Unified environment trait: implementors split their wasmer FunctionEnvMut into (MemAccess, WavmState). +/// Base environment trait: splits a context into (MemAccess, ExecEnv). +/// Used by wasip1_stub which only needs mem + exec. +pub trait WasmEnv { + type Mem<'a>: MemAccess where Self: 'a; + type State<'a>: ExecEnv where Self: 'a; + fn wasm_env(&mut self) -> (Self::Mem<'_>, Self::State<'_>); +} + +/// Extended environment for wavmio: State additionally implements WavmState. pub trait WavmEnv { type Mem<'a>: MemAccess where Self: 'a; type State<'a>: WavmState where Self: 'a; fn wavm_env(&mut self) -> (Self::Mem<'_>, Self::State<'_>); } +/// Every WavmEnv is automatically a WasmEnv. +impl WasmEnv for T { + type Mem<'a> = ::Mem<'a> where Self: 'a; + type State<'a> = ::State<'a> where Self: 'a; + fn wasm_env(&mut self) -> (Self::Mem<'_>, Self::State<'_>) { + self.wavm_env() + } +} + /// Reads 32-bytes of global state and writes to guest memory. pub fn get_global_state_bytes32( env: &mut impl WavmEnv, diff --git a/crates/wasm-libraries/wasi-stub/lib.rs b/crates/wasm-libraries/wasi-stub/lib.rs index 70a0121ad21..5b6dd4eadf3 100644 --- a/crates/wasm-libraries/wasi-stub/lib.rs +++ b/crates/wasm-libraries/wasi-stub/lib.rs @@ -6,7 +6,7 @@ use caller_env::{ self, - static_caller::{StaticExecEnv, StaticMem}, + static_caller::StaticWasmEnv, wasip1_stub::Errno, GuestPtr, }; @@ -44,8 +44,7 @@ macro_rules! wrap { #[no_mangle] pub unsafe extern "C" fn []($($arg_name : $arg_type),*) -> $return_type { caller_env::wasip1_stub::$func_name( - &mut StaticMem, - &mut StaticExecEnv, + &mut StaticWasmEnv, $($arg_name),* ) } From 98663a207884b7a5a63fc1c0a3094912102eef71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Wed, 4 Mar 2026 11:33:49 +0100 Subject: [PATCH 059/189] remove auxiliary traits, newtypes and just pass the two objects --- crates/caller-env/src/static_caller.rs | 12 +- crates/caller-env/src/wasip1_stub.rs | 176 +++++++------------- crates/caller-env/src/wavmio.rs | 54 ++---- crates/jit/src/state.rs | 14 +- crates/jit/src/wasip1_stub.rs | 7 +- crates/jit/src/wavmio.rs | 28 ++-- crates/wasm-libraries/wasi-stub/lib.rs | 5 +- sp1-crates/program/src/imports/wasi_stub.rs | 52 +++--- sp1-crates/program/src/imports/wavmio.rs | 47 +++--- sp1-crates/program/src/state.rs | 21 +-- 10 files changed, 165 insertions(+), 251 deletions(-) diff --git a/crates/caller-env/src/static_caller.rs b/crates/caller-env/src/static_caller.rs index 9f24fdc8d20..79c0ba2649b 100644 --- a/crates/caller-env/src/static_caller.rs +++ b/crates/caller-env/src/static_caller.rs @@ -1,7 +1,7 @@ // Copyright 2021-2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md -use crate::{ExecEnv, GoRuntimeState, GuestPtr, MemAccess, wavmio::WasmEnv}; +use crate::{ExecEnv, GoRuntimeState, GuestPtr, MemAccess}; use alloc::vec::Vec; use rand::RngCore; use spin::{Lazy, Mutex, MutexGuard}; @@ -12,16 +12,6 @@ extern crate alloc; pub struct StaticMem; /// Static execution environment for Go runtime in WAVM. pub struct StaticExecEnv; -/// Bundled static environment implementing WasmEnv. -pub struct StaticWasmEnv; - -impl WasmEnv for StaticWasmEnv { - type Mem<'a> = StaticMem; - type State<'a> = StaticExecEnv; - fn wasm_env(&mut self) -> (StaticMem, StaticExecEnv) { - (StaticMem, StaticExecEnv) - } -} static GO_RUNTIME_STATE: Lazy> = Lazy::new(Default::default); diff --git a/crates/caller-env/src/wasip1_stub.rs b/crates/caller-env/src/wasip1_stub.rs index 8222624586c..03f87a46338 100644 --- a/crates/caller-env/src/wasip1_stub.rs +++ b/crates/caller-env/src/wasip1_stub.rs @@ -7,7 +7,7 @@ #![allow(clippy::too_many_arguments)] -use crate::{ExecEnv, GuestPtr, MemAccess, wavmio::WasmEnv}; +use crate::{ExecEnv, GuestPtr, MemAccess}; #[repr(transparent)] pub struct Errno(pub u16); @@ -19,11 +19,11 @@ pub const ERRNO_INVAL: Errno = Errno(28); /// Writes the number and total size of args passed by the OS. /// Note that this currently consists of just the program name `bin`. pub fn args_sizes_get( - env: &mut impl WasmEnv, + mem: &mut impl MemAccess, + _: &mut impl ExecEnv, length_ptr: GuestPtr, data_size_ptr: GuestPtr, ) -> Errno { - let (mut mem, _) = env.wasm_env(); mem.write_u32(length_ptr, 1); mem.write_u32(data_size_ptr, 4); ERRNO_SUCCESS @@ -32,11 +32,11 @@ pub fn args_sizes_get( /// Writes the args passed by the OS. /// Note that this currently consists of just the program name `bin`. pub fn args_get( - env: &mut impl WasmEnv, + mem: &mut impl MemAccess, + _: &mut impl ExecEnv, argv_buf: GuestPtr, data_buf: GuestPtr, ) -> Errno { - let (mut mem, _) = env.wasm_env(); mem.write_u32(argv_buf, data_buf.into()); mem.write_u32(data_buf, 0x6E6962); // "bin\0" ERRNO_SUCCESS @@ -45,11 +45,11 @@ pub fn args_get( /// Writes the number and total size of OS environment variables. /// Note that none exist in Nitro. pub fn environ_sizes_get( - env: &mut impl WasmEnv, + mem: &mut impl MemAccess, + _: &mut impl ExecEnv, length_ptr: GuestPtr, data_size_ptr: GuestPtr, ) -> Errno { - let (mut mem, _) = env.wasm_env(); mem.write_u32(length_ptr, 0); mem.write_u32(data_size_ptr, 0); ERRNO_SUCCESS @@ -58,7 +58,8 @@ pub fn environ_sizes_get( /// Writes the number and total size of OS environment variables. /// Note that none exist in Nitro. pub fn environ_get( - _: &mut impl WasmEnv, + _: &mut impl MemAccess, + _: &mut impl ExecEnv, _: GuestPtr, _: GuestPtr, ) -> Errno { @@ -68,7 +69,8 @@ pub fn environ_get( /// Writes to the given file descriptor. /// Note that we only support stdout and stderr. pub fn fd_write( - env: &mut impl WasmEnv, + mem: &mut impl MemAccess, + state: &mut impl ExecEnv, fd: u32, iovecs_ptr: GuestPtr, iovecs_len: u32, @@ -77,7 +79,6 @@ pub fn fd_write( if fd != 1 && fd != 2 { return ERRNO_BADF; } - let (mut mem, mut state) = env.wasm_env(); let mut size = 0; for i in 0..iovecs_len { let ptr = iovecs_ptr + i * 8; @@ -92,24 +93,19 @@ pub fn fd_write( } /// Closes the given file descriptor. Unsupported. -pub fn fd_close(_: &mut impl WasmEnv, _: u32) -> Errno { +pub fn fd_close(_: &mut impl MemAccess, _: &mut impl ExecEnv, _: u32) -> Errno { ERRNO_BADF } /// Reads from the given file descriptor. Unsupported. -pub fn fd_read( - _: &mut impl WasmEnv, - _: u32, - _: u32, - _: u32, - _: u32, -) -> Errno { +pub fn fd_read(_: &mut impl MemAccess, _: &mut impl ExecEnv, _: u32, _: u32, _: u32, _: u32) -> Errno { ERRNO_BADF } /// Reads the contents of a directory. Unsupported. pub fn fd_readdir( - _: &mut impl WasmEnv, + _: &mut impl MemAccess, + _: &mut impl ExecEnv, _fd: u32, _: u32, _: u32, @@ -120,13 +116,14 @@ pub fn fd_readdir( } /// Syncs a file to disk. Unsupported. -pub fn fd_sync(_: &mut impl WasmEnv, _: u32) -> Errno { +pub fn fd_sync(_: &mut impl MemAccess, _: &mut impl ExecEnv, _: u32) -> Errno { ERRNO_SUCCESS } /// Move within a file. Unsupported. pub fn fd_seek( - _: &mut impl WasmEnv, + _: &mut impl MemAccess, + _: &mut impl ExecEnv, _fd: u32, _offset: u64, _whence: u8, @@ -136,182 +133,123 @@ pub fn fd_seek( } /// Syncs file contents to disk. Unsupported. -pub fn fd_datasync(_: &mut impl WasmEnv, _fd: u32) -> Errno { +pub fn fd_datasync(_: &mut impl MemAccess, _: &mut impl ExecEnv, _fd: u32) -> Errno { ERRNO_BADF } /// Retrieves attributes about a file descriptor. Unsupported. -pub fn fd_fdstat_get(_: &mut impl WasmEnv, _: u32, _: u32) -> Errno { +pub fn fd_fdstat_get(_: &mut impl MemAccess, _: &mut impl ExecEnv, _: u32, _: u32) -> Errno { ERRNO_INVAL } /// Sets the attributes of a file descriptor. Unsupported. -pub fn fd_fdstat_set_flags( - _: &mut impl WasmEnv, - _: u32, - _: u32, -) -> Errno { +pub fn fd_fdstat_set_flags(_: &mut impl MemAccess, _: &mut impl ExecEnv, _: u32, _: u32) -> Errno { ERRNO_INVAL } /// Opens the file or directory at the given path. Unsupported. pub fn path_open( - _: &mut impl WasmEnv, - _: u32, - _: u32, - _: u32, - _: u32, - _: u32, - _: u64, - _: u64, - _: u32, - _: u32, + _: &mut impl MemAccess, + _: &mut impl ExecEnv, + _: u32, _: u32, _: u32, _: u32, _: u32, + _: u64, _: u64, + _: u32, _: u32, ) -> Errno { ERRNO_BADF } /// Creates a directory. Unsupported. -pub fn path_create_directory( - _: &mut impl WasmEnv, - _: u32, - _: u32, - _: u32, -) -> Errno { +pub fn path_create_directory(_: &mut impl MemAccess, _: &mut impl ExecEnv, _: u32, _: u32, _: u32) -> Errno { ERRNO_BADF } /// Unlinks a directory. Unsupported. -pub fn path_remove_directory( - _: &mut impl WasmEnv, - _: u32, - _: u32, - _: u32, -) -> Errno { +pub fn path_remove_directory(_: &mut impl MemAccess, _: &mut impl ExecEnv, _: u32, _: u32, _: u32) -> Errno { ERRNO_BADF } /// Resolves a symbolic link. Unsupported. pub fn path_readlink( - _: &mut impl WasmEnv, - _: u32, - _: u32, - _: u32, - _: u32, - _: u32, - _: u32, + _: &mut impl MemAccess, + _: &mut impl ExecEnv, + _: u32, _: u32, _: u32, _: u32, _: u32, _: u32, ) -> Errno { ERRNO_BADF } /// Moves a file. Unsupported. pub fn path_rename( - _: &mut impl WasmEnv, - _: u32, - _: u32, - _: u32, - _: u32, - _: u32, - _: u32, + _: &mut impl MemAccess, + _: &mut impl ExecEnv, + _: u32, _: u32, _: u32, _: u32, _: u32, _: u32, ) -> Errno { ERRNO_BADF } /// Retrieves info about an open file. Unsupported. pub fn path_filestat_get( - _: &mut impl WasmEnv, - _: u32, - _: u32, - _: u32, - _: u32, - _: u32, + _: &mut impl MemAccess, + _: &mut impl ExecEnv, + _: u32, _: u32, _: u32, _: u32, _: u32, ) -> Errno { ERRNO_BADF } /// Unlinks the file at the given path. Unsupported. -pub fn path_unlink_file( - _: &mut impl WasmEnv, - _: u32, - _: u32, - _: u32, -) -> Errno { +pub fn path_unlink_file(_: &mut impl MemAccess, _: &mut impl ExecEnv, _: u32, _: u32, _: u32) -> Errno { ERRNO_BADF } /// Retrieves info about a file. Unsupported. -pub fn fd_prestat_get(_: &mut impl WasmEnv, _: u32, _: u32) -> Errno { +pub fn fd_prestat_get(_: &mut impl MemAccess, _: &mut impl ExecEnv, _: u32, _: u32) -> Errno { ERRNO_BADF } /// Retrieves info about a directory. Unsupported. -pub fn fd_prestat_dir_name( - _: &mut impl WasmEnv, - _: u32, - _: u32, - _: u32, -) -> Errno { +pub fn fd_prestat_dir_name(_: &mut impl MemAccess, _: &mut impl ExecEnv, _: u32, _: u32, _: u32) -> Errno { ERRNO_BADF } /// Retrieves info about a file. Unsupported. -pub fn fd_filestat_get( - _: &mut impl WasmEnv, - _fd: u32, - _filestat: u32, -) -> Errno { +pub fn fd_filestat_get(_: &mut impl MemAccess, _: &mut impl ExecEnv, _fd: u32, _filestat: u32) -> Errno { ERRNO_BADF } /// Sets the size of an open file. Unsupported. -pub fn fd_filestat_set_size( - _: &mut impl WasmEnv, - _fd: u32, - _: u64, -) -> Errno { +pub fn fd_filestat_set_size(_: &mut impl MemAccess, _: &mut impl ExecEnv, _fd: u32, _: u64) -> Errno { ERRNO_BADF } /// Peaks within a descriptor without modifying its state. Unsupported. pub fn fd_pread( - _: &mut impl WasmEnv, - _fd: u32, - _: u32, - _: u32, - _: u64, - _: u32, + _: &mut impl MemAccess, + _: &mut impl ExecEnv, + _fd: u32, _: u32, _: u32, _: u64, _: u32, ) -> Errno { ERRNO_BADF } /// Writes to a descriptor without modifying the current offset. Unsupported. pub fn fd_pwrite( - _: &mut impl WasmEnv, - _fd: u32, - _: u32, - _: u32, - _: u64, - _: u32, + _: &mut impl MemAccess, + _: &mut impl ExecEnv, + _fd: u32, _: u32, _: u32, _: u64, _: u32, ) -> Errno { ERRNO_BADF } /// Accepts a new connection. Unsupported. -pub fn sock_accept( - _: &mut impl WasmEnv, - _fd: u32, - _: u32, - _: u32, -) -> Errno { +pub fn sock_accept(_: &mut impl MemAccess, _: &mut impl ExecEnv, _fd: u32, _: u32, _: u32) -> Errno { ERRNO_BADF } /// Shuts down a socket. Unsupported. -pub fn sock_shutdown(_: &mut impl WasmEnv, _: u32, _: u32) -> Errno { +pub fn sock_shutdown(_: &mut impl MemAccess, _: &mut impl ExecEnv, _: u32, _: u32) -> Errno { ERRNO_BADF } /// Yields execution to the OS scheduler. Effectively does nothing in Nitro due to the lack of threads. -pub fn sched_yield(_: &mut impl WasmEnv) -> Errno { +pub fn sched_yield(_: &mut impl MemAccess, _: &mut impl ExecEnv) -> Errno { ERRNO_SUCCESS } @@ -322,12 +260,12 @@ static TIME_INTERVAL: u64 = 10_000_000; /// Note that in Nitro, all clocks point to the same deterministic counter that advances 10ms whenever /// this function is called. pub fn clock_time_get( - env: &mut impl WasmEnv, + mem: &mut impl MemAccess, + state: &mut impl ExecEnv, _clock_id: u32, _precision: u64, time_ptr: GuestPtr, ) -> Errno { - let (mut mem, mut state) = env.wasm_env(); state.advance_time(TIME_INTERVAL); mem.write_u64(time_ptr, state.get_time()); ERRNO_SUCCESS @@ -336,11 +274,11 @@ pub fn clock_time_get( /// Fills a slice with psuedo-random bytes. /// Note that in Nitro, the bytes are deterministically generated from a common seed. pub fn random_get( - env: &mut impl WasmEnv, + mem: &mut impl MemAccess, + state: &mut impl ExecEnv, mut buf: GuestPtr, mut len: u32, ) -> Errno { - let (mut mem, mut state) = env.wasm_env(); while len >= 4 { let next_rand = state.next_rand_u32(); mem.write_u32(buf, next_rand); @@ -361,13 +299,13 @@ pub fn random_get( /// Poll for events. /// Note that we always simulate a timeout and skip all others. pub fn poll_oneoff( - env: &mut impl WasmEnv, + mem: &mut impl MemAccess, + state: &mut impl ExecEnv, in_subs: GuestPtr, out_evt: GuestPtr, num_subscriptions: u32, num_events_ptr: GuestPtr, ) -> Errno { - let (mut mem, mut state) = env.wasm_env(); // simulate the passage of time each poll request state.advance_time(TIME_INTERVAL); diff --git a/crates/caller-env/src/wavmio.rs b/crates/caller-env/src/wavmio.rs index ada28407fb2..b5bd213c235 100644 --- a/crates/caller-env/src/wavmio.rs +++ b/crates/caller-env/src/wavmio.rs @@ -17,37 +17,13 @@ pub trait WavmState: ExecEnv { fn get_preimage(&self, preimage_type: u8, hash: &[u8; 32]) -> Option<&[u8]>; } -/// Base environment trait: splits a context into (MemAccess, ExecEnv). -/// Used by wasip1_stub which only needs mem + exec. -pub trait WasmEnv { - type Mem<'a>: MemAccess where Self: 'a; - type State<'a>: ExecEnv where Self: 'a; - fn wasm_env(&mut self) -> (Self::Mem<'_>, Self::State<'_>); -} - -/// Extended environment for wavmio: State additionally implements WavmState. -pub trait WavmEnv { - type Mem<'a>: MemAccess where Self: 'a; - type State<'a>: WavmState where Self: 'a; - fn wavm_env(&mut self) -> (Self::Mem<'_>, Self::State<'_>); -} - -/// Every WavmEnv is automatically a WasmEnv. -impl WasmEnv for T { - type Mem<'a> = ::Mem<'a> where Self: 'a; - type State<'a> = ::State<'a> where Self: 'a; - fn wasm_env(&mut self) -> (Self::Mem<'_>, Self::State<'_>) { - self.wavm_env() - } -} - /// Reads 32-bytes of global state and writes to guest memory. pub fn get_global_state_bytes32( - env: &mut impl WavmEnv, + mem: &mut impl MemAccess, + state: &impl WavmState, idx: u32, out_ptr: GuestPtr, ) -> Result<(), String> { - let (mut mem, state) = env.wavm_env(); let Some(global) = state.get_bytes32_global(idx as usize) else { return Err("global read out of bounds in wavmio.getGlobalStateBytes32".into()); }; @@ -57,11 +33,11 @@ pub fn get_global_state_bytes32( /// Reads 32-bytes from guest memory and writes to global state. pub fn set_global_state_bytes32( - env: &mut impl WavmEnv, + mem: &impl MemAccess, + state: &mut impl WavmState, idx: u32, src_ptr: GuestPtr, ) -> Result<(), String> { - let (mem, mut state) = env.wavm_env(); let val = mem.read_fixed(src_ptr); if !state.set_bytes32_global(idx as usize, val) { return Err("global write oob in wavmio.setGlobalStateBytes32".into()); @@ -71,10 +47,9 @@ pub fn set_global_state_bytes32( /// Reads 8-bytes of global state. pub fn get_global_state_u64( - env: &mut impl WavmEnv, + state: &impl WavmState, idx: u32, ) -> Result { - let (_mem, state) = env.wavm_env(); match state.get_u64_global(idx as usize) { Some(val) => Ok(val), None => Err("global read out of bounds in wavmio.getGlobalStateU64".into()), @@ -83,11 +58,10 @@ pub fn get_global_state_u64( /// Writes 8-bytes of global state. pub fn set_global_state_u64( - env: &mut impl WavmEnv, + state: &mut impl WavmState, idx: u32, val: u64, ) -> Result<(), String> { - let (_mem, mut state) = env.wavm_env(); if !state.set_u64_global(idx as usize, val) { return Err("global write out of bounds in wavmio.setGlobalStateU64".into()); } @@ -96,12 +70,12 @@ pub fn set_global_state_u64( /// Reads up to 32 bytes of a sequencer inbox message at the given offset. pub fn read_inbox_message( - env: &mut impl WavmEnv, + mem: &mut impl MemAccess, + state: &impl WavmState, msg_num: u64, offset: u32, out_ptr: GuestPtr, ) -> Result { - let (mut mem, state) = env.wavm_env(); let message = match state.get_sequencer_message(msg_num) { Some(message) => message, None => return Err(format!("missing sequencer inbox message {msg_num}")), @@ -115,12 +89,12 @@ pub fn read_inbox_message( /// Reads up to 32 bytes of a delayed inbox message at the given offset. pub fn read_delayed_inbox_message( - env: &mut impl WavmEnv, + mem: &mut impl MemAccess, + state: &impl WavmState, msg_num: u64, offset: u32, out_ptr: GuestPtr, ) -> Result { - let (mut mem, state) = env.wavm_env(); let message = match state.get_delayed_message(msg_num) { Some(message) => message, None => return Err(format!("missing delayed inbox message {msg_num}")), @@ -134,14 +108,14 @@ pub fn read_delayed_inbox_message( /// Looks up a preimage by type and hash, reads up to 32 bytes at an aligned offset. pub fn resolve_preimage( - env: &mut impl WavmEnv, + mem: &mut impl MemAccess, + state: &impl WavmState, preimage_type: u8, hash_ptr: GuestPtr, offset: u32, out_ptr: GuestPtr, name: &str, ) -> Result { - let (mut mem, state) = env.wavm_env(); let hash = mem.read_fixed(hash_ptr); let offset = offset as usize; @@ -164,11 +138,11 @@ pub fn resolve_preimage( /// Returns 1 if a preimage exists for the given type and hash, 0 otherwise. pub fn validate_certificate( - env: &mut impl WavmEnv, + mem: &impl MemAccess, + state: &impl WavmState, preimage_type: u8, hash_ptr: GuestPtr, ) -> u8 { - let (mem, state) = env.wavm_env(); let hash = mem.read_fixed(hash_ptr); match state.get_preimage(preimage_type, &hash) { Some(_) => 1, diff --git a/crates/jit/src/state.rs b/crates/jit/src/state.rs index 621cd945761..e10b431a5fc 100644 --- a/crates/jit/src/state.rs +++ b/crates/jit/src/state.rs @@ -4,13 +4,10 @@ use crate::machine::{WasmEnv, WasmEnvMut}; use crate::memory::JitMemAccess; use arbutil::{Bytes32, PreimageType}; -use caller_env::wavmio::{WavmEnv, WavmState}; +use caller_env::wavmio::WavmState; use caller_env::ExecEnv; use rand::RngCore; -/// Newtype for implementing WavmEnv (orphan rule: FunctionEnvMut is foreign). -pub(crate) struct JitWavm<'e>(pub WasmEnvMut<'e>); - /// Newtype wrapping &mut WasmEnv to implement WavmState (orphan rule). pub(crate) struct JitState<'a>(pub &'a mut WasmEnv); @@ -21,15 +18,6 @@ pub(crate) fn jit_env<'a>(env: &'a mut WasmEnvMut) -> (JitMemAccess<'a>, JitStat (JitMemAccess { memory, store }, JitState(wenv)) } -impl WavmEnv for JitWavm<'_> { - type Mem<'a> = JitMemAccess<'a> where Self: 'a; - type State<'a> = JitState<'a> where Self: 'a; - - fn wavm_env(&mut self) -> (JitMemAccess<'_>, JitState<'_>) { - jit_env(&mut self.0) - } -} - impl ExecEnv for JitState<'_> { fn advance_time(&mut self, ns: u64) { self.0.go_state.time += ns; diff --git a/crates/jit/src/wasip1_stub.rs b/crates/jit/src/wasip1_stub.rs index 204ab2ac330..1d33112dbaf 100644 --- a/crates/jit/src/wasip1_stub.rs +++ b/crates/jit/src/wasip1_stub.rs @@ -3,7 +3,7 @@ #![allow(clippy::too_many_arguments)] -use crate::state::JitWavm; +use crate::state::jit_env; use crate::machine::{Escape, WasmEnvMut}; use caller_env::{self, wasip1_stub::Errno, GuestPtr}; @@ -14,8 +14,9 @@ pub fn proc_exit(mut _env: WasmEnvMut, code: u32) -> Result<(), Escape> { macro_rules! wrap { ($(fn $func_name:ident ($($arg_name:ident : $arg_type:ty),* ) -> $return_type:ty);*) => { $( - pub fn $func_name(src: WasmEnvMut, $($arg_name : $arg_type),*) -> Result<$return_type, Escape> { - Ok(caller_env::wasip1_stub::$func_name(&mut JitWavm(src), $($arg_name),*)) + pub fn $func_name(mut src: WasmEnvMut, $($arg_name : $arg_type),*) -> Result<$return_type, Escape> { + let (mut mem, mut state) = jit_env(&mut src); + Ok(caller_env::wasip1_stub::$func_name(&mut mem, &mut state, $($arg_name),*)) } )* }; diff --git a/crates/jit/src/wavmio.rs b/crates/jit/src/wavmio.rs index e207cdea0ec..ca65bbe45c6 100644 --- a/crates/jit/src/wavmio.rs +++ b/crates/jit/src/wavmio.rs @@ -1,7 +1,7 @@ // Copyright 2022-2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md -use crate::state::JitWavm; +use crate::state::jit_env; use crate::machine::{Escape, MaybeEscape, WasmEnv, WasmEnvMut}; use arbutil::Color; use ::caller_env::wavmio as caller_env; @@ -17,22 +17,26 @@ use validation::transfer::receive_validation_input; pub fn get_global_state_bytes32(mut env: WasmEnvMut, idx: u32, out_ptr: GuestPtr) -> MaybeEscape { ready_hostio(env.data_mut())?; - caller_env::get_global_state_bytes32(&mut JitWavm(env), idx, out_ptr).map_err(Escape::HostIO) + let (mut mem, state) = jit_env(&mut env); + caller_env::get_global_state_bytes32(&mut mem, &state, idx, out_ptr).map_err(Escape::HostIO) } pub fn set_global_state_bytes32(mut env: WasmEnvMut, idx: u32, src_ptr: GuestPtr) -> MaybeEscape { ready_hostio(env.data_mut())?; - caller_env::set_global_state_bytes32(&mut JitWavm(env), idx, src_ptr).map_err(Escape::HostIO) + let (mem, mut state) = jit_env(&mut env); + caller_env::set_global_state_bytes32(&mem, &mut state, idx, src_ptr).map_err(Escape::HostIO) } pub fn get_global_state_u64(mut env: WasmEnvMut, idx: u32) -> Result { ready_hostio(env.data_mut())?; - caller_env::get_global_state_u64(&mut JitWavm(env), idx).map_err(Escape::HostIO) + let (_mem, state) = jit_env(&mut env); + caller_env::get_global_state_u64(&state, idx).map_err(Escape::HostIO) } pub fn set_global_state_u64(mut env: WasmEnvMut, idx: u32, val: u64) -> MaybeEscape { ready_hostio(env.data_mut())?; - caller_env::set_global_state_u64(&mut JitWavm(env), idx, val).map_err(Escape::HostIO) + let (_mem, mut state) = jit_env(&mut env); + caller_env::set_global_state_u64(&mut state, idx, val).map_err(Escape::HostIO) } pub fn read_inbox_message( @@ -42,7 +46,8 @@ pub fn read_inbox_message( out_ptr: GuestPtr, ) -> Result { ready_hostio(env.data_mut())?; - caller_env::read_inbox_message(&mut JitWavm(env), msg_num, offset, out_ptr) + let (mut mem, state) = jit_env(&mut env); + caller_env::read_inbox_message(&mut mem, &state, msg_num, offset, out_ptr) .map_err(Escape::HostIO) } @@ -53,7 +58,8 @@ pub fn read_delayed_inbox_message( out_ptr: GuestPtr, ) -> Result { ready_hostio(env.data_mut())?; - caller_env::read_delayed_inbox_message(&mut JitWavm(env), msg_num, offset, out_ptr) + let (mut mem, state) = jit_env(&mut env); + caller_env::read_delayed_inbox_message(&mut mem, &state, msg_num, offset, out_ptr) .map_err(Escape::HostIO) } @@ -131,16 +137,18 @@ fn resolve_preimage_impl( } } - caller_env::resolve_preimage(&mut JitWavm(env), preimage_type, hash_ptr, offset, out_ptr, name) + let (mut mem, state) = jit_env(&mut env); + caller_env::resolve_preimage(&mut mem, &state, preimage_type, hash_ptr, offset, out_ptr, name) .map_err(Escape::HostIO) } pub fn validate_certificate( - env: WasmEnvMut, + mut env: WasmEnvMut, preimage_type: u8, hash_ptr: GuestPtr, ) -> Result { - Ok(caller_env::validate_certificate(&mut JitWavm(env), preimage_type, hash_ptr)) + let (mem, state) = jit_env(&mut env); + Ok(caller_env::validate_certificate(&mem, &state, preimage_type, hash_ptr)) } fn ready_hostio(env: &mut WasmEnv) -> MaybeEscape { diff --git a/crates/wasm-libraries/wasi-stub/lib.rs b/crates/wasm-libraries/wasi-stub/lib.rs index 5b6dd4eadf3..70a0121ad21 100644 --- a/crates/wasm-libraries/wasi-stub/lib.rs +++ b/crates/wasm-libraries/wasi-stub/lib.rs @@ -6,7 +6,7 @@ use caller_env::{ self, - static_caller::StaticWasmEnv, + static_caller::{StaticExecEnv, StaticMem}, wasip1_stub::Errno, GuestPtr, }; @@ -44,7 +44,8 @@ macro_rules! wrap { #[no_mangle] pub unsafe extern "C" fn []($($arg_name : $arg_type),*) -> $return_type { caller_env::wasip1_stub::$func_name( - &mut StaticWasmEnv, + &mut StaticMem, + &mut StaticExecEnv, $($arg_name),* ) } diff --git a/sp1-crates/program/src/imports/wasi_stub.rs b/sp1-crates/program/src/imports/wasi_stub.rs index eadcd91ae72..a398aa50fc7 100644 --- a/sp1-crates/program/src/imports/wasi_stub.rs +++ b/sp1-crates/program/src/imports/wasi_stub.rs @@ -2,7 +2,7 @@ #![allow(clippy::too_many_arguments)] -use crate::{Escape, Ptr, state::{Sp1Wavm, gp}, platform, replay::CustomEnvData}; +use crate::{Escape, Ptr, state::{sp1_env, gp}, platform, replay::CustomEnvData}; use caller_env; use wasmer::FunctionEnvMut; @@ -24,85 +24,95 @@ pub fn proc_exit(mut ctx: FunctionEnvMut, code: u32) { } pub fn args_sizes_get( - ctx: FunctionEnvMut, + mut ctx: FunctionEnvMut, argc: Ptr, argv_buf_size: Ptr, ) -> Result { - Ok(caller_env::wasip1_stub::args_sizes_get(&mut Sp1Wavm(ctx), gp(argc), gp(argv_buf_size)).0) + let (mut mem, mut state) = sp1_env(&mut ctx); + Ok(caller_env::wasip1_stub::args_sizes_get(&mut mem, &mut state, gp(argc), gp(argv_buf_size)).0) } pub fn args_get( - ctx: FunctionEnvMut, + mut ctx: FunctionEnvMut, argv_buf: Ptr, data_buf: Ptr, ) -> Result { - Ok(caller_env::wasip1_stub::args_get(&mut Sp1Wavm(ctx), gp(argv_buf), gp(data_buf)).0) + let (mut mem, mut state) = sp1_env(&mut ctx); + Ok(caller_env::wasip1_stub::args_get(&mut mem, &mut state, gp(argv_buf), gp(data_buf)).0) } pub fn environ_sizes_get( - ctx: FunctionEnvMut, + mut ctx: FunctionEnvMut, length_ptr: Ptr, data_size_ptr: Ptr, ) -> Result { - Ok(caller_env::wasip1_stub::environ_sizes_get(&mut Sp1Wavm(ctx), gp(length_ptr), gp(data_size_ptr)).0) + let (mut mem, mut state) = sp1_env(&mut ctx); + Ok(caller_env::wasip1_stub::environ_sizes_get(&mut mem, &mut state, gp(length_ptr), gp(data_size_ptr)).0) } -pub fn environ_get(ctx: FunctionEnvMut, a: Ptr, b: Ptr) -> u16 { - caller_env::wasip1_stub::environ_get(&mut Sp1Wavm(ctx), gp(a), gp(b)).0 +pub fn environ_get(mut ctx: FunctionEnvMut, a: Ptr, b: Ptr) -> u16 { + let (mut mem, mut state) = sp1_env(&mut ctx); + caller_env::wasip1_stub::environ_get(&mut mem, &mut state, gp(a), gp(b)).0 } pub fn fd_write( - ctx: FunctionEnvMut, + mut ctx: FunctionEnvMut, fd: u32, iovecs_ptr: Ptr, iovecs_len: u32, ret_ptr: Ptr, ) -> Result { - Ok(caller_env::wasip1_stub::fd_write(&mut Sp1Wavm(ctx), fd, gp(iovecs_ptr), iovecs_len, gp(ret_ptr)).0) + let (mut mem, mut state) = sp1_env(&mut ctx); + Ok(caller_env::wasip1_stub::fd_write(&mut mem, &mut state, fd, gp(iovecs_ptr), iovecs_len, gp(ret_ptr)).0) } pub fn clock_time_get( - ctx: FunctionEnvMut, + mut ctx: FunctionEnvMut, clock_id: u32, precision: u64, time_ptr: Ptr, ) -> Result { - Ok(caller_env::wasip1_stub::clock_time_get(&mut Sp1Wavm(ctx), clock_id, precision, gp(time_ptr)).0) + let (mut mem, mut state) = sp1_env(&mut ctx); + Ok(caller_env::wasip1_stub::clock_time_get(&mut mem, &mut state, clock_id, precision, gp(time_ptr)).0) } pub fn random_get( - ctx: FunctionEnvMut, + mut ctx: FunctionEnvMut, buf: Ptr, len: u32, ) -> Result { - Ok(caller_env::wasip1_stub::random_get(&mut Sp1Wavm(ctx), gp(buf), len).0) + let (mut mem, mut state) = sp1_env(&mut ctx); + Ok(caller_env::wasip1_stub::random_get(&mut mem, &mut state, gp(buf), len).0) } pub fn poll_oneoff( - ctx: FunctionEnvMut, + mut ctx: FunctionEnvMut, in_subs: Ptr, out_evt: Ptr, num_subscriptions: u32, num_events_ptr: Ptr, ) -> Result { - Ok(caller_env::wasip1_stub::poll_oneoff(&mut Sp1Wavm(ctx), gp(in_subs), gp(out_evt), num_subscriptions, gp(num_events_ptr)).0) + let (mut mem, mut state) = sp1_env(&mut ctx); + Ok(caller_env::wasip1_stub::poll_oneoff(&mut mem, &mut state, gp(in_subs), gp(out_evt), num_subscriptions, gp(num_events_ptr)).0) } pub fn fd_seek( - ctx: FunctionEnvMut, + mut ctx: FunctionEnvMut, fd: u32, offset: u64, whence: u32, filesize: u32, ) -> u16 { - caller_env::wasip1_stub::fd_seek(&mut Sp1Wavm(ctx), fd, offset, whence as u8, filesize).0 + let (mut mem, mut state) = sp1_env(&mut ctx); + caller_env::wasip1_stub::fd_seek(&mut mem, &mut state, fd, offset, whence as u8, filesize).0 } macro_rules! wrap { ($(fn $func_name:ident ($($arg_name:ident : $arg_type:ty),*));* $(;)?) => { $( - pub fn $func_name(ctx: FunctionEnvMut, $($arg_name : $arg_type),*) -> u16 { - caller_env::wasip1_stub::$func_name(&mut Sp1Wavm(ctx), $($arg_name),*).0 + pub fn $func_name(mut ctx: FunctionEnvMut, $($arg_name : $arg_type),*) -> u16 { + let (mut mem, mut state) = sp1_env(&mut ctx); + caller_env::wasip1_stub::$func_name(&mut mem, &mut state, $($arg_name),*).0 } )* }; diff --git a/sp1-crates/program/src/imports/wavmio.rs b/sp1-crates/program/src/imports/wavmio.rs index 34c8c82670c..0943877091c 100644 --- a/sp1-crates/program/src/imports/wavmio.rs +++ b/sp1-crates/program/src/imports/wavmio.rs @@ -1,47 +1,56 @@ //! wavmio functions — thin wrappers delegating to caller_env::wavmio. use crate::{ - Escape, MaybeEscape, Ptr, state::{Sp1Wavm, gp}, read_bytes32, + Escape, MaybeEscape, Ptr, state::{sp1_env, gp}, read_bytes32, replay::CustomEnvData, }; use ::caller_env::wavmio as caller_env; use core::ops::Deref; use wasmer::{FunctionEnvMut, MemoryView}; -pub fn get_global_state_bytes32(ctx: FunctionEnvMut, idx: u32, out_ptr: Ptr) -> MaybeEscape { - caller_env::get_global_state_bytes32(&mut Sp1Wavm(ctx), idx, gp(out_ptr)).map_err(Escape::Logical) +pub fn get_global_state_bytes32(mut ctx: FunctionEnvMut, idx: u32, out_ptr: Ptr) -> MaybeEscape { + let (mut mem, state) = sp1_env(&mut ctx); + caller_env::get_global_state_bytes32(&mut mem, &state, idx, gp(out_ptr)).map_err(Escape::Logical) } -pub fn set_global_state_bytes32(ctx: FunctionEnvMut, idx: u32, src_ptr: Ptr) -> MaybeEscape { - caller_env::set_global_state_bytes32(&mut Sp1Wavm(ctx), idx, gp(src_ptr)).map_err(Escape::Logical) +pub fn set_global_state_bytes32(mut ctx: FunctionEnvMut, idx: u32, src_ptr: Ptr) -> MaybeEscape { + let (mem, mut state) = sp1_env(&mut ctx); + caller_env::set_global_state_bytes32(&mem, &mut state, idx, gp(src_ptr)).map_err(Escape::Logical) } -pub fn get_global_state_u64(ctx: FunctionEnvMut, idx: u32) -> Result { - caller_env::get_global_state_u64(&mut Sp1Wavm(ctx), idx).map_err(Escape::Logical) +pub fn get_global_state_u64(mut ctx: FunctionEnvMut, idx: u32) -> Result { + let (_mem, state) = sp1_env(&mut ctx); + caller_env::get_global_state_u64(&state, idx).map_err(Escape::Logical) } -pub fn set_global_state_u64(ctx: FunctionEnvMut, idx: u32, val: u64) -> MaybeEscape { - caller_env::set_global_state_u64(&mut Sp1Wavm(ctx), idx, val).map_err(Escape::Logical) +pub fn set_global_state_u64(mut ctx: FunctionEnvMut, idx: u32, val: u64) -> MaybeEscape { + let (_mem, mut state) = sp1_env(&mut ctx); + caller_env::set_global_state_u64(&mut state, idx, val).map_err(Escape::Logical) } -pub fn read_inbox_message(ctx: FunctionEnvMut, msg_num: u64, offset: u32, out_ptr: Ptr) -> Result { - caller_env::read_inbox_message(&mut Sp1Wavm(ctx), msg_num, offset, gp(out_ptr)).map_err(Escape::Logical) +pub fn read_inbox_message(mut ctx: FunctionEnvMut, msg_num: u64, offset: u32, out_ptr: Ptr) -> Result { + let (mut mem, state) = sp1_env(&mut ctx); + caller_env::read_inbox_message(&mut mem, &state, msg_num, offset, gp(out_ptr)).map_err(Escape::Logical) } -pub fn read_delayed_inbox_message(ctx: FunctionEnvMut, msg_num: u64, offset: u32, out_ptr: Ptr) -> Result { - caller_env::read_delayed_inbox_message(&mut Sp1Wavm(ctx), msg_num, offset, gp(out_ptr)).map_err(Escape::Logical) +pub fn read_delayed_inbox_message(mut ctx: FunctionEnvMut, msg_num: u64, offset: u32, out_ptr: Ptr) -> Result { + let (mut mem, state) = sp1_env(&mut ctx); + caller_env::read_delayed_inbox_message(&mut mem, &state, msg_num, offset, gp(out_ptr)).map_err(Escape::Logical) } -pub fn resolve_keccak_preimage(ctx: FunctionEnvMut, hash_ptr: Ptr, offset: u32, out_ptr: Ptr) -> Result { - caller_env::resolve_preimage(&mut Sp1Wavm(ctx), 0, gp(hash_ptr), offset, gp(out_ptr), "wavmio.ResolvePreImage").map_err(Escape::Logical) +pub fn resolve_keccak_preimage(mut ctx: FunctionEnvMut, hash_ptr: Ptr, offset: u32, out_ptr: Ptr) -> Result { + let (mut mem, state) = sp1_env(&mut ctx); + caller_env::resolve_preimage(&mut mem, &state, 0, gp(hash_ptr), offset, gp(out_ptr), "wavmio.ResolvePreImage").map_err(Escape::Logical) } -pub fn resolve_typed_preimage(ctx: FunctionEnvMut, preimage_type: u8, hash_ptr: Ptr, offset: u32, out_ptr: Ptr) -> Result { - caller_env::resolve_preimage(&mut Sp1Wavm(ctx), preimage_type, gp(hash_ptr), offset, gp(out_ptr), "wavmio.ResolveTypedPreimage").map_err(Escape::Logical) +pub fn resolve_typed_preimage(mut ctx: FunctionEnvMut, preimage_type: u8, hash_ptr: Ptr, offset: u32, out_ptr: Ptr) -> Result { + let (mut mem, state) = sp1_env(&mut ctx); + caller_env::resolve_preimage(&mut mem, &state, preimage_type, gp(hash_ptr), offset, gp(out_ptr), "wavmio.ResolveTypedPreimage").map_err(Escape::Logical) } -pub fn validate_certificate(ctx: FunctionEnvMut, preimage_type: u8, hash_ptr: Ptr) -> Result { - Ok(caller_env::validate_certificate(&mut Sp1Wavm(ctx), preimage_type, gp(hash_ptr))) +pub fn validate_certificate(mut ctx: FunctionEnvMut, preimage_type: u8, hash_ptr: Ptr) -> Result { + let (mem, state) = sp1_env(&mut ctx); + Ok(caller_env::validate_certificate(&mem, &state, preimage_type, gp(hash_ptr))) } // Greedy preimage resolution — kept separate, will be refactored independently. diff --git a/sp1-crates/program/src/state.rs b/sp1-crates/program/src/state.rs index 55078e0bbc6..a0813bb9af6 100644 --- a/sp1-crates/program/src/state.rs +++ b/sp1-crates/program/src/state.rs @@ -1,7 +1,7 @@ // Copyright 2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md -use caller_env::wavmio::{WavmEnv, WavmState}; +use caller_env::wavmio::WavmState; use caller_env::{ExecEnv, GuestPtr}; use rand::RngCore; use wasmer::FunctionEnvMut; @@ -77,18 +77,13 @@ impl WavmState for Sp1State<'_> { } } -/// Newtype for implementing WavmEnv (orphan rule: FunctionEnvMut is foreign). -pub(crate) struct Sp1Wavm<'e>(pub FunctionEnvMut<'e, CustomEnvData>); - -impl WavmEnv for Sp1Wavm<'_> { - type Mem<'a> = Sp1MemAccess<'a> where Self: 'a; - type State<'a> = Sp1State<'a> where Self: 'a; - - fn wavm_env(&mut self) -> (Sp1MemAccess<'_>, Sp1State<'_>) { - let memory = self.0.data().memory.clone().unwrap(); - let (data, store) = self.0.data_and_store_mut(); - (Sp1MemAccess { memory, store }, Sp1State(data)) - } +/// Extracts (Sp1MemAccess, Sp1State) from a FunctionEnvMut in place. +pub(crate) fn sp1_env<'a>( + ctx: &'a mut FunctionEnvMut<'_, CustomEnvData>, +) -> (Sp1MemAccess<'a>, Sp1State<'a>) { + let memory = ctx.data().memory.clone().unwrap(); + let (data, store) = ctx.data_and_store_mut(); + (Sp1MemAccess { memory, store }, Sp1State(data)) } /// Converts a wasmer `Ptr` (WasmPtr) to a caller-env `GuestPtr`. From ed321b2f3c8e1f8eb8a70a6013316d7f63a7ce99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Wed, 4 Mar 2026 11:42:02 +0100 Subject: [PATCH 060/189] revert changes to wasi stub --- crates/caller-env/src/wasip1_stub.rs | 238 ++++++++----- sp1-crates/program/src/imports/wasi_stub.rs | 352 +++++++++++++++----- 2 files changed, 432 insertions(+), 158 deletions(-) diff --git a/crates/caller-env/src/wasip1_stub.rs b/crates/caller-env/src/wasip1_stub.rs index 03f87a46338..bc0b3b27422 100644 --- a/crates/caller-env/src/wasip1_stub.rs +++ b/crates/caller-env/src/wasip1_stub.rs @@ -10,7 +10,7 @@ use crate::{ExecEnv, GuestPtr, MemAccess}; #[repr(transparent)] -pub struct Errno(pub u16); +pub struct Errno(pub(crate) u16); pub const ERRNO_SUCCESS: Errno = Errno(0); pub const ERRNO_BADF: Errno = Errno(8); @@ -18,9 +18,9 @@ pub const ERRNO_INVAL: Errno = Errno(28); /// Writes the number and total size of args passed by the OS. /// Note that this currently consists of just the program name `bin`. -pub fn args_sizes_get( - mem: &mut impl MemAccess, - _: &mut impl ExecEnv, +pub fn args_sizes_get( + mem: &mut M, + _: &mut E, length_ptr: GuestPtr, data_size_ptr: GuestPtr, ) -> Errno { @@ -31,9 +31,9 @@ pub fn args_sizes_get( /// Writes the args passed by the OS. /// Note that this currently consists of just the program name `bin`. -pub fn args_get( - mem: &mut impl MemAccess, - _: &mut impl ExecEnv, +pub fn args_get( + mem: &mut M, + _: &mut E, argv_buf: GuestPtr, data_buf: GuestPtr, ) -> Errno { @@ -44,9 +44,9 @@ pub fn args_get( /// Writes the number and total size of OS environment variables. /// Note that none exist in Nitro. -pub fn environ_sizes_get( - mem: &mut impl MemAccess, - _: &mut impl ExecEnv, +pub fn environ_sizes_get( + mem: &mut M, + _env: &mut E, length_ptr: GuestPtr, data_size_ptr: GuestPtr, ) -> Errno { @@ -57,9 +57,9 @@ pub fn environ_sizes_get( /// Writes the number and total size of OS environment variables. /// Note that none exist in Nitro. -pub fn environ_get( - _: &mut impl MemAccess, - _: &mut impl ExecEnv, +pub fn environ_get( + _: &mut M, + _: &mut E, _: GuestPtr, _: GuestPtr, ) -> Errno { @@ -68,9 +68,9 @@ pub fn environ_get( /// Writes to the given file descriptor. /// Note that we only support stdout and stderr. -pub fn fd_write( - mem: &mut impl MemAccess, - state: &mut impl ExecEnv, +pub fn fd_write( + mem: &mut M, + env: &mut E, fd: u32, iovecs_ptr: GuestPtr, iovecs_len: u32, @@ -85,7 +85,7 @@ pub fn fd_write( let len = mem.read_u32(ptr + 4); let ptr = mem.read_u32(ptr); // TODO: string might be split across utf-8 character boundary let data = mem.read_slice(GuestPtr(ptr), len as usize); - state.print_string(&data); + env.print_string(&data); size += len; } mem.write_u32(ret_ptr, size); @@ -93,19 +93,26 @@ pub fn fd_write( } /// Closes the given file descriptor. Unsupported. -pub fn fd_close(_: &mut impl MemAccess, _: &mut impl ExecEnv, _: u32) -> Errno { +pub fn fd_close(_: &mut M, _: &mut E, _: u32) -> Errno { ERRNO_BADF } /// Reads from the given file descriptor. Unsupported. -pub fn fd_read(_: &mut impl MemAccess, _: &mut impl ExecEnv, _: u32, _: u32, _: u32, _: u32) -> Errno { +pub fn fd_read( + _: &mut M, + _: &mut E, + _: u32, + _: u32, + _: u32, + _: u32, +) -> Errno { ERRNO_BADF } /// Reads the contents of a directory. Unsupported. -pub fn fd_readdir( - _: &mut impl MemAccess, - _: &mut impl ExecEnv, +pub fn fd_readdir( + _: &mut M, + _: &mut E, _fd: u32, _: u32, _: u32, @@ -116,14 +123,14 @@ pub fn fd_readdir( } /// Syncs a file to disk. Unsupported. -pub fn fd_sync(_: &mut impl MemAccess, _: &mut impl ExecEnv, _: u32) -> Errno { +pub fn fd_sync(_: &mut M, _: &mut E, _: u32) -> Errno { ERRNO_SUCCESS } /// Move within a file. Unsupported. -pub fn fd_seek( - _: &mut impl MemAccess, - _: &mut impl ExecEnv, +pub fn fd_seek( + _: &mut M, + _: &mut E, _fd: u32, _offset: u64, _whence: u8, @@ -133,123 +140,196 @@ pub fn fd_seek( } /// Syncs file contents to disk. Unsupported. -pub fn fd_datasync(_: &mut impl MemAccess, _: &mut impl ExecEnv, _fd: u32) -> Errno { +pub fn fd_datasync(_: &mut M, _: &mut E, _fd: u32) -> Errno { ERRNO_BADF } /// Retrieves attributes about a file descriptor. Unsupported. -pub fn fd_fdstat_get(_: &mut impl MemAccess, _: &mut impl ExecEnv, _: u32, _: u32) -> Errno { +pub fn fd_fdstat_get(_: &mut M, _: &mut E, _: u32, _: u32) -> Errno { ERRNO_INVAL } /// Sets the attributes of a file descriptor. Unsupported. -pub fn fd_fdstat_set_flags(_: &mut impl MemAccess, _: &mut impl ExecEnv, _: u32, _: u32) -> Errno { +pub fn fd_fdstat_set_flags( + _: &mut M, + _: &mut E, + _: u32, + _: u32, +) -> Errno { ERRNO_INVAL } /// Opens the file or directory at the given path. Unsupported. -pub fn path_open( - _: &mut impl MemAccess, - _: &mut impl ExecEnv, - _: u32, _: u32, _: u32, _: u32, _: u32, - _: u64, _: u64, - _: u32, _: u32, +pub fn path_open( + _: &mut M, + _: &mut E, + _: u32, + _: u32, + _: u32, + _: u32, + _: u32, + _: u64, + _: u64, + _: u32, + _: u32, ) -> Errno { ERRNO_BADF } /// Creates a directory. Unsupported. -pub fn path_create_directory(_: &mut impl MemAccess, _: &mut impl ExecEnv, _: u32, _: u32, _: u32) -> Errno { +pub fn path_create_directory( + _: &mut M, + _: &mut E, + _: u32, + _: u32, + _: u32, +) -> Errno { ERRNO_BADF } /// Unlinks a directory. Unsupported. -pub fn path_remove_directory(_: &mut impl MemAccess, _: &mut impl ExecEnv, _: u32, _: u32, _: u32) -> Errno { +pub fn path_remove_directory( + _: &mut M, + _: &mut E, + _: u32, + _: u32, + _: u32, +) -> Errno { ERRNO_BADF } /// Resolves a symbolic link. Unsupported. -pub fn path_readlink( - _: &mut impl MemAccess, - _: &mut impl ExecEnv, - _: u32, _: u32, _: u32, _: u32, _: u32, _: u32, +pub fn path_readlink( + _: &mut M, + _: &mut E, + _: u32, + _: u32, + _: u32, + _: u32, + _: u32, + _: u32, ) -> Errno { ERRNO_BADF } /// Moves a file. Unsupported. -pub fn path_rename( - _: &mut impl MemAccess, - _: &mut impl ExecEnv, - _: u32, _: u32, _: u32, _: u32, _: u32, _: u32, +pub fn path_rename( + _: &mut M, + _: &mut E, + _: u32, + _: u32, + _: u32, + _: u32, + _: u32, + _: u32, ) -> Errno { ERRNO_BADF } /// Retrieves info about an open file. Unsupported. -pub fn path_filestat_get( - _: &mut impl MemAccess, - _: &mut impl ExecEnv, - _: u32, _: u32, _: u32, _: u32, _: u32, +pub fn path_filestat_get( + _: &mut M, + _: &mut E, + _: u32, + _: u32, + _: u32, + _: u32, + _: u32, ) -> Errno { ERRNO_BADF } /// Unlinks the file at the given path. Unsupported. -pub fn path_unlink_file(_: &mut impl MemAccess, _: &mut impl ExecEnv, _: u32, _: u32, _: u32) -> Errno { +pub fn path_unlink_file( + _: &mut M, + _: &mut E, + _: u32, + _: u32, + _: u32, +) -> Errno { ERRNO_BADF } /// Retrieves info about a file. Unsupported. -pub fn fd_prestat_get(_: &mut impl MemAccess, _: &mut impl ExecEnv, _: u32, _: u32) -> Errno { +pub fn fd_prestat_get(_: &mut M, _: &mut E, _: u32, _: u32) -> Errno { ERRNO_BADF } /// Retrieves info about a directory. Unsupported. -pub fn fd_prestat_dir_name(_: &mut impl MemAccess, _: &mut impl ExecEnv, _: u32, _: u32, _: u32) -> Errno { +pub fn fd_prestat_dir_name( + _: &mut M, + _: &mut E, + _: u32, + _: u32, + _: u32, +) -> Errno { ERRNO_BADF } /// Retrieves info about a file. Unsupported. -pub fn fd_filestat_get(_: &mut impl MemAccess, _: &mut impl ExecEnv, _fd: u32, _filestat: u32) -> Errno { +pub fn fd_filestat_get( + _: &mut M, + _: &mut E, + _fd: u32, + _filestat: u32, +) -> Errno { ERRNO_BADF } /// Sets the size of an open file. Unsupported. -pub fn fd_filestat_set_size(_: &mut impl MemAccess, _: &mut impl ExecEnv, _fd: u32, _: u64) -> Errno { +pub fn fd_filestat_set_size( + _: &mut M, + _: &mut E, + _fd: u32, + _: u64, +) -> Errno { ERRNO_BADF } /// Peaks within a descriptor without modifying its state. Unsupported. -pub fn fd_pread( - _: &mut impl MemAccess, - _: &mut impl ExecEnv, - _fd: u32, _: u32, _: u32, _: u64, _: u32, +pub fn fd_pread( + _: &mut M, + _: &mut E, + _fd: u32, + _: u32, + _: u32, + _: u64, + _: u32, ) -> Errno { ERRNO_BADF } /// Writes to a descriptor without modifying the current offset. Unsupported. -pub fn fd_pwrite( - _: &mut impl MemAccess, - _: &mut impl ExecEnv, - _fd: u32, _: u32, _: u32, _: u64, _: u32, +pub fn fd_pwrite( + _: &mut M, + _: &mut E, + _fd: u32, + _: u32, + _: u32, + _: u64, + _: u32, ) -> Errno { ERRNO_BADF } /// Accepts a new connection. Unsupported. -pub fn sock_accept(_: &mut impl MemAccess, _: &mut impl ExecEnv, _fd: u32, _: u32, _: u32) -> Errno { +pub fn sock_accept( + _: &mut M, + _: &mut E, + _fd: u32, + _: u32, + _: u32, +) -> Errno { ERRNO_BADF } /// Shuts down a socket. Unsupported. -pub fn sock_shutdown(_: &mut impl MemAccess, _: &mut impl ExecEnv, _: u32, _: u32) -> Errno { +pub fn sock_shutdown(_: &mut M, _: &mut E, _: u32, _: u32) -> Errno { ERRNO_BADF } /// Yields execution to the OS scheduler. Effectively does nothing in Nitro due to the lack of threads. -pub fn sched_yield(_: &mut impl MemAccess, _: &mut impl ExecEnv) -> Errno { +pub fn sched_yield(_: &mut M, _: &mut E) -> Errno { ERRNO_SUCCESS } @@ -259,34 +339,34 @@ static TIME_INTERVAL: u64 = 10_000_000; /// Retrieves the time in ns of the given clock. /// Note that in Nitro, all clocks point to the same deterministic counter that advances 10ms whenever /// this function is called. -pub fn clock_time_get( - mem: &mut impl MemAccess, - state: &mut impl ExecEnv, +pub fn clock_time_get( + mem: &mut M, + env: &mut E, _clock_id: u32, _precision: u64, time_ptr: GuestPtr, ) -> Errno { - state.advance_time(TIME_INTERVAL); - mem.write_u64(time_ptr, state.get_time()); + env.advance_time(TIME_INTERVAL); + mem.write_u64(time_ptr, env.get_time()); ERRNO_SUCCESS } /// Fills a slice with psuedo-random bytes. /// Note that in Nitro, the bytes are deterministically generated from a common seed. -pub fn random_get( - mem: &mut impl MemAccess, - state: &mut impl ExecEnv, +pub fn random_get( + mem: &mut M, + env: &mut E, mut buf: GuestPtr, mut len: u32, ) -> Errno { while len >= 4 { - let next_rand = state.next_rand_u32(); + let next_rand = env.next_rand_u32(); mem.write_u32(buf, next_rand); buf += 4; len -= 4; } if len > 0 { - let mut rem = state.next_rand_u32(); + let mut rem = env.next_rand_u32(); for _ in 0..len { mem.write_u8(buf, rem as u8); buf += 1; @@ -298,16 +378,16 @@ pub fn random_get( /// Poll for events. /// Note that we always simulate a timeout and skip all others. -pub fn poll_oneoff( - mem: &mut impl MemAccess, - state: &mut impl ExecEnv, +pub fn poll_oneoff( + mem: &mut M, + env: &mut E, in_subs: GuestPtr, out_evt: GuestPtr, num_subscriptions: u32, num_events_ptr: GuestPtr, ) -> Errno { // simulate the passage of time each poll request - state.advance_time(TIME_INTERVAL); + env.advance_time(TIME_INTERVAL); const SUBSCRIPTION_SIZE: u32 = 48; // user data + 40-byte union for index in 0..num_subscriptions { diff --git a/sp1-crates/program/src/imports/wasi_stub.rs b/sp1-crates/program/src/imports/wasi_stub.rs index a398aa50fc7..18af7ff4c56 100644 --- a/sp1-crates/program/src/imports/wasi_stub.rs +++ b/sp1-crates/program/src/imports/wasi_stub.rs @@ -1,11 +1,18 @@ -//! WASI stubs delegating to caller-env's shared implementation. +//! WASI stubs +//! +//! The code used here is heavily borrowed from nitro's own WASI stubs: +//! https://github.com/OffchainLabs/nitro/blob/c858ed93a5a4fd81908277d94fb72974058a3615/arbitrator/caller-env/src/wasip1_stub.rs -#![allow(clippy::too_many_arguments)] - -use crate::{Escape, Ptr, state::{sp1_env, gp}, platform, replay::CustomEnvData}; -use caller_env; +use crate::{Escape, Ptr, platform, read_slice, replay::CustomEnvData}; +use rand::RngCore; use wasmer::FunctionEnvMut; +pub type Errno = u16; + +pub const ERRNO_SUCCESS: Errno = 0; +pub const ERRNO_BADF: Errno = 8; +pub const ERRNO_INVAL: Errno = 28; + pub fn proc_exit(mut ctx: FunctionEnvMut, code: u32) { let (data, _store) = ctx.data_and_store_mut(); @@ -27,32 +34,48 @@ pub fn args_sizes_get( mut ctx: FunctionEnvMut, argc: Ptr, argv_buf_size: Ptr, -) -> Result { - let (mut mem, mut state) = sp1_env(&mut ctx); - Ok(caller_env::wasip1_stub::args_sizes_get(&mut mem, &mut state, gp(argc), gp(argv_buf_size)).0) +) -> Result { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + argc.write(&memory, 1)?; + argv_buf_size.write(&memory, 4)?; + + Ok(ERRNO_SUCCESS) } pub fn args_get( mut ctx: FunctionEnvMut, argv_buf: Ptr, data_buf: Ptr, -) -> Result { - let (mut mem, mut state) = sp1_env(&mut ctx); - Ok(caller_env::wasip1_stub::args_get(&mut mem, &mut state, gp(argv_buf), gp(data_buf)).0) +) -> Result { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + let data_buf = data_buf.deref(&memory); + + argv_buf.write(&memory, data_buf.offset() as u32)?; + data_buf.write(0x6E6962)?; // "bin\0" + + Ok(ERRNO_SUCCESS) } pub fn environ_sizes_get( mut ctx: FunctionEnvMut, length_ptr: Ptr, data_size_ptr: Ptr, -) -> Result { - let (mut mem, mut state) = sp1_env(&mut ctx); - Ok(caller_env::wasip1_stub::environ_sizes_get(&mut mem, &mut state, gp(length_ptr), gp(data_size_ptr)).0) +) -> Result { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + length_ptr.write(&memory, 0)?; + data_size_ptr.write(&memory, 0)?; + + Ok(ERRNO_SUCCESS) } -pub fn environ_get(mut ctx: FunctionEnvMut, a: Ptr, b: Ptr) -> u16 { - let (mut mem, mut state) = sp1_env(&mut ctx); - caller_env::wasip1_stub::environ_get(&mut mem, &mut state, gp(a), gp(b)).0 +pub fn environ_get(_ctx: FunctionEnvMut, _: Ptr, _: Ptr) -> Errno { + ERRNO_SUCCESS } pub fn fd_write( @@ -61,28 +84,149 @@ pub fn fd_write( iovecs_ptr: Ptr, iovecs_len: u32, ret_ptr: Ptr, -) -> Result { - let (mut mem, mut state) = sp1_env(&mut ctx); - Ok(caller_env::wasip1_stub::fd_write(&mut mem, &mut state, fd, gp(iovecs_ptr), iovecs_len, gp(ret_ptr)).0) +) -> Result { + if fd != 1 && fd != 2 { + return Ok(ERRNO_BADF); + } + + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + let mut size = 0; + for i in 0..iovecs_len { + let ptr = iovecs_ptr.add_offset((i * 2).into()).unwrap(); + let len = ptr.add_offset(1).unwrap().read(&memory)?; + let ptr = Ptr::new(ptr.read(&memory)?); + let data = read_slice(ptr, len as usize, &memory)?; + + platform::print_string(fd, &data); + + size += len; + } + + ret_ptr.write(&memory, size)?; + Ok(ERRNO_SUCCESS) +} + +pub fn fd_close(_ctx: FunctionEnvMut, _fd: u32) -> Errno { + ERRNO_BADF } +pub fn fd_read(_ctx: FunctionEnvMut, _: u32, _: u32, _: u32, _: u32) -> Errno { + ERRNO_BADF +} + +pub fn fd_readdir( + _ctx: FunctionEnvMut, + _fd: u32, + _: u32, + _: u32, + _: u64, + _: u32, +) -> Errno { + ERRNO_BADF +} + +pub fn fd_sync(_ctx: FunctionEnvMut, _: u32) -> Errno { + ERRNO_SUCCESS +} + +pub fn fd_seek(_ctx: FunctionEnvMut, _: u32, _: u64, _: u32, _: u32) -> Errno { + ERRNO_BADF +} + +pub fn fd_datasync(_ctx: FunctionEnvMut, _: u32) -> Errno { + ERRNO_BADF +} + +pub fn fd_prestat_get(_ctx: FunctionEnvMut, _: u32, _: u32) -> Errno { + ERRNO_BADF +} + +pub fn fd_prestat_dir_name(_ctx: FunctionEnvMut, _: u32, _: u32, _: u32) -> Errno { + ERRNO_BADF +} + +pub fn fd_filestat_get(_ctx: FunctionEnvMut, _: u32, _: u32) -> Errno { + ERRNO_BADF +} + +pub fn fd_filestat_set_size(_ctx: FunctionEnvMut, _: u32, _: u64) -> Errno { + ERRNO_BADF +} + +pub fn fd_pread( + _ctx: FunctionEnvMut, + _fd: u32, + _: u32, + _: u32, + _: u64, + _: u32, +) -> Errno { + ERRNO_BADF +} + +pub fn fd_pwrite( + _ctx: FunctionEnvMut, + _fd: u32, + _: u32, + _: u32, + _: u64, + _: u32, +) -> Errno { + ERRNO_BADF +} + +pub fn fd_fdstat_get(_ctx: FunctionEnvMut, _: u32, _: u32) -> Errno { + ERRNO_INVAL +} + +pub fn fd_fdstat_set_flags(_ctx: FunctionEnvMut, _: u32, _: u32) -> Errno { + ERRNO_INVAL +} + +const TIME_INTERVAL: u64 = 10_000_000; + pub fn clock_time_get( mut ctx: FunctionEnvMut, - clock_id: u32, - precision: u64, + _clock_id: u32, + _precision: u64, time_ptr: Ptr, -) -> Result { - let (mut mem, mut state) = sp1_env(&mut ctx); - Ok(caller_env::wasip1_stub::clock_time_get(&mut mem, &mut state, clock_id, precision, gp(time_ptr)).0) +) -> Result { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + data.time += TIME_INTERVAL; + time_ptr.cast::().write(&memory, data.time)?; + + Ok(ERRNO_SUCCESS) } pub fn random_get( mut ctx: FunctionEnvMut, - buf: Ptr, - len: u32, -) -> Result { - let (mut mem, mut state) = sp1_env(&mut ctx); - Ok(caller_env::wasip1_stub::random_get(&mut mem, &mut state, gp(buf), len).0) + mut buf: Ptr, + mut len: u32, +) -> Result { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + while len >= 4 { + let next_rand = data.pcg.next_u32(); + buf.write(&memory, next_rand)?; + buf = buf.add_offset(1).unwrap(); + len -= 4; + } + if len > 0 { + let mut rem = data.pcg.next_u32(); + let mut buf = buf.cast::(); + + for _ in 0..len { + buf.write(&memory, rem as u8)?; + buf = buf.add_offset(1).unwrap(); + rem >>= 8; + } + } + Ok(ERRNO_SUCCESS) } pub fn poll_oneoff( @@ -91,55 +235,105 @@ pub fn poll_oneoff( out_evt: Ptr, num_subscriptions: u32, num_events_ptr: Ptr, -) -> Result { - let (mut mem, mut state) = sp1_env(&mut ctx); - Ok(caller_env::wasip1_stub::poll_oneoff(&mut mem, &mut state, gp(in_subs), gp(out_evt), num_subscriptions, gp(num_events_ptr)).0) +) -> Result { + let (data, store) = ctx.data_and_store_mut(); + let memory = data.memory.clone().unwrap().view(&store); + + data.time += TIME_INTERVAL; + + const SUBSCRIPTION_SIZE: u32 = 48; + for index in 0..num_subscriptions { + let subs_base = in_subs + .cast::() + .add_offset(SUBSCRIPTION_SIZE * index) + .unwrap(); + let subs_type = subs_base + .add_offset(8) + .unwrap() + .cast::() + .read(&memory)?; + if subs_type != 0 { + continue; + } + let user_data = subs_base.cast::().read(&memory)?; + out_evt.write(&memory, user_data)?; + out_evt.add_offset(2).unwrap().write(&memory, subs_type)?; + num_events_ptr.write(&memory, 1)?; + return Ok(ERRNO_SUCCESS); + } + Ok(ERRNO_INVAL) } -pub fn fd_seek( - mut ctx: FunctionEnvMut, - fd: u32, - offset: u64, - whence: u32, - filesize: u32, -) -> u16 { - let (mut mem, mut state) = sp1_env(&mut ctx); - caller_env::wasip1_stub::fd_seek(&mut mem, &mut state, fd, offset, whence as u8, filesize).0 -} - -macro_rules! wrap { - ($(fn $func_name:ident ($($arg_name:ident : $arg_type:ty),*));* $(;)?) => { - $( - pub fn $func_name(mut ctx: FunctionEnvMut, $($arg_name : $arg_type),*) -> u16 { - let (mut mem, mut state) = sp1_env(&mut ctx); - caller_env::wasip1_stub::$func_name(&mut mem, &mut state, $($arg_name),*).0 - } - )* - }; -} - -wrap! { - fn fd_close(fd: u32); - fn fd_read(a: u32, b: u32, c: u32, d: u32); - fn fd_readdir(fd: u32, a: u32, b: u32, c: u64, d: u32); - fn fd_sync(a: u32); - fn fd_datasync(fd: u32); - fn fd_fdstat_get(a: u32, b: u32); - fn fd_fdstat_set_flags(a: u32, b: u32); - fn fd_prestat_get(a: u32, b: u32); - fn fd_prestat_dir_name(a: u32, b: u32, c: u32); - fn fd_filestat_get(fd: u32, filestat: u32); - fn fd_filestat_set_size(fd: u32, size: u64); - fn fd_pread(fd: u32, a: u32, b: u32, c: u64, d: u32); - fn fd_pwrite(fd: u32, a: u32, b: u32, c: u64, d: u32); - fn path_open(a: u32, b: u32, c: u32, d: u32, e: u32, f: u64, g: u64, h: u32, i: u32); - fn path_create_directory(a: u32, b: u32, c: u32); - fn path_remove_directory(a: u32, b: u32, c: u32); - fn path_readlink(a: u32, b: u32, c: u32, d: u32, e: u32, f: u32); - fn path_rename(a: u32, b: u32, c: u32, d: u32, e: u32, f: u32); - fn path_filestat_get(a: u32, b: u32, c: u32, d: u32, e: u32); - fn path_unlink_file(a: u32, b: u32, c: u32); - fn sock_accept(fd: u32, a: u32, b: u32); - fn sock_shutdown(a: u32, b: u32); - fn sched_yield() +pub fn sched_yield(_ctx: FunctionEnvMut) -> Errno { + ERRNO_SUCCESS +} + +pub fn path_open( + _ctx: FunctionEnvMut, + _: u32, + _: u32, + _: u32, + _: u32, + _: u32, + _: u64, + _: u64, + _: u32, + _: u32, +) -> Errno { + ERRNO_BADF +} + +pub fn path_create_directory(_ctx: FunctionEnvMut, _: u32, _: u32, _: u32) -> Errno { + ERRNO_BADF +} + +pub fn path_remove_directory(_ctx: FunctionEnvMut, _: u32, _: u32, _: u32) -> Errno { + ERRNO_BADF +} + +pub fn path_readlink( + _ctx: FunctionEnvMut, + _: u32, + _: u32, + _: u32, + _: u32, + _: u32, + _: u32, +) -> Errno { + ERRNO_BADF +} + +pub fn path_rename( + _ctx: FunctionEnvMut, + _: u32, + _: u32, + _: u32, + _: u32, + _: u32, + _: u32, +) -> Errno { + ERRNO_BADF +} + +pub fn path_filestat_get( + _ctx: FunctionEnvMut, + _: u32, + _: u32, + _: u32, + _: u32, + _: u32, +) -> Errno { + ERRNO_BADF +} + +pub fn path_unlink_file(_ctx: FunctionEnvMut, _: u32, _: u32, _: u32) -> Errno { + ERRNO_BADF +} + +pub fn sock_accept(_ctx: FunctionEnvMut, _: u32, _: u32, _: u32) -> Errno { + ERRNO_BADF +} + +pub fn sock_shutdown(_ctx: FunctionEnvMut, _: u32, _: u32) -> Errno { + ERRNO_BADF } From 8bc44277bc006e357d93e63af440a510857ad473 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Wed, 4 Mar 2026 11:57:46 +0100 Subject: [PATCH 061/189] more reverts --- crates/jit/src/arbcompress.rs | 7 +- crates/jit/src/arbcrypto.rs | 10 +- crates/jit/src/{memory.rs => caller_env.rs} | 44 ++++- crates/jit/src/lib.rs | 3 +- crates/jit/src/program.rs | 38 ++-- crates/jit/src/state.rs | 90 --------- crates/jit/src/wasip1_stub.rs | 7 +- crates/jit/src/wavmio.rs | 192 ++++++++++++++------ 8 files changed, 210 insertions(+), 181 deletions(-) rename crates/jit/src/{memory.rs => caller_env.rs} (68%) delete mode 100644 crates/jit/src/state.rs diff --git a/crates/jit/src/arbcompress.rs b/crates/jit/src/arbcompress.rs index 1e44d961e7e..2faad117185 100644 --- a/crates/jit/src/arbcompress.rs +++ b/crates/jit/src/arbcompress.rs @@ -1,7 +1,7 @@ // Copyright 2022-2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md -use crate::state::jit_env; +use crate::caller_env::{JitEnv, JitExecEnv}; use crate::machine::Escape; use crate::machine::WasmEnvMut; use brotli::{BrotliStatus, Dictionary}; @@ -12,8 +12,9 @@ macro_rules! wrap { $( #[allow(clippy::too_many_arguments)] pub fn $func_name(mut src: WasmEnvMut, $($arg_name : $arg_type),*) -> Result<$return_type, Escape> { - let (mut mem, mut state) = jit_env(&mut src); - Ok(caller_env::brotli::$func_name(&mut mem, &mut state, $($arg_name),*)) + let (mut mem, wenv) = src.jit_env(); + + Ok(caller_env::brotli::$func_name(&mut mem, &mut JitExecEnv { wenv }, $($arg_name),*)) } )* }; diff --git a/crates/jit/src/arbcrypto.rs b/crates/jit/src/arbcrypto.rs index a29d452fad9..e4bd8586161 100644 --- a/crates/jit/src/arbcrypto.rs +++ b/crates/jit/src/arbcrypto.rs @@ -1,6 +1,6 @@ // Copyright 2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md -use crate::state::jit_env; +use crate::caller_env::{JitEnv, JitExecEnv}; use crate::machine::{Escape, MaybeEscape, WasmEnvMut}; use caller_env::GuestPtr; @@ -12,11 +12,11 @@ pub fn ecrecovery( sig_len: u32, pub_ptr: GuestPtr, ) -> Result { - let (mut mem, mut state) = jit_env(&mut src); + let (mut mem, wenv) = src.jit_env(); Ok(caller_env::arbcrypto::ecrecovery( &mut mem, - &mut state, + &mut JitExecEnv { wenv }, hash_ptr, hash_len, sig_ptr, @@ -31,11 +31,11 @@ pub fn keccak256( in_buf_len: u32, out_buf_ptr: GuestPtr, ) -> MaybeEscape { - let (mut mem, mut state) = jit_env(&mut src); + let (mut mem, wenv) = src.jit_env(); caller_env::arbcrypto::keccak256( &mut mem, - &mut state, + &mut JitExecEnv { wenv }, in_buf_ptr, in_buf_len, out_buf_ptr, diff --git a/crates/jit/src/memory.rs b/crates/jit/src/caller_env.rs similarity index 68% rename from crates/jit/src/memory.rs rename to crates/jit/src/caller_env.rs index c222ed46f43..a30662049fb 100644 --- a/crates/jit/src/memory.rs +++ b/crates/jit/src/caller_env.rs @@ -1,8 +1,10 @@ // Copyright 2022-2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md +use crate::machine::{WasmEnv, WasmEnvMut}; use arbutil::{Bytes20, Bytes32}; -use caller_env::{GuestPtr, MemAccess}; +use caller_env::{ExecEnv, GuestPtr, MemAccess}; +use rand::RngCore; use std::mem::{self, MaybeUninit}; use wasmer::{Memory, MemoryView, StoreMut, WasmPtr}; @@ -11,6 +13,22 @@ pub struct JitMemAccess<'s> { pub store: StoreMut<'s>, } +pub struct JitExecEnv<'s> { + pub wenv: &'s mut WasmEnv, +} + +pub(crate) trait JitEnv<'a> { + fn jit_env(&mut self) -> (JitMemAccess<'_>, &mut WasmEnv); +} + +impl<'a> JitEnv<'a> for WasmEnvMut<'a> { + fn jit_env(&mut self) -> (JitMemAccess<'_>, &mut WasmEnv) { + let memory = self.data().memory.clone().unwrap(); + let (wenv, store) = self.data_and_store_mut(); + (JitMemAccess { memory, store }, wenv) + } +} + impl JitMemAccess<'_> { fn view(&self) -> MemoryView<'_> { self.memory.view(&self.store) @@ -90,3 +108,27 @@ impl MemAccess for JitMemAccess<'_> { self.view().write(ptr.into(), src).unwrap(); } } + +impl ExecEnv for JitExecEnv<'_> { + fn advance_time(&mut self, ns: u64) { + self.wenv.go_state.time += ns; + } + + fn get_time(&self) -> u64 { + self.wenv.go_state.time + } + + fn next_rand_u32(&mut self) -> u32 { + self.wenv.go_state.rng.next_u32() + } + + fn print_string(&mut self, bytes: &[u8]) { + match String::from_utf8(bytes.to_vec()) { + Ok(s) => eprintln!("JIT: WASM says: {s}"), // TODO: this adds too many newlines since go calls this in chunks + Err(e) => { + let bytes = e.as_bytes(); + eprintln!("Go string {} is not valid utf8: {e:?}", hex::encode(bytes)); + } + } + } +} diff --git a/crates/jit/src/lib.rs b/crates/jit/src/lib.rs index c7ef29f4285..8a60dcae697 100644 --- a/crates/jit/src/lib.rs +++ b/crates/jit/src/lib.rs @@ -14,9 +14,8 @@ use wasmer::{FrameInfo, FunctionEnv, Instance, Pages, Store}; mod arbcompress; mod arbcrypto; -mod state; +mod caller_env; pub mod machine; -mod memory; mod prepare; pub mod program; pub mod stylus_backend; diff --git a/crates/jit/src/program.rs b/crates/jit/src/program.rs index 95bc3ed1764..df0ee24e5ef 100644 --- a/crates/jit/src/program.rs +++ b/crates/jit/src/program.rs @@ -3,7 +3,7 @@ #![allow(clippy::too_many_arguments)] -use crate::state::jit_env; +use crate::caller_env::JitEnv; use crate::machine::{Escape, MaybeEscape, WasmEnv, WasmEnvMut}; use crate::stylus_backend::{exec_wasm, MessageFromCothread}; use arbutil::evm::api::Gas; @@ -73,7 +73,7 @@ pub fn activate_v2( err_buf: GuestPtr, err_buf_len: u32, ) -> Result { - let (mut mem, _) = jit_env(&mut env); + let (mut mem, _) = env.jit_env(); let wasm = mem.read_slice(wasm_ptr, wasm_size as usize); let codehash = &mem.read_bytes32(codehash); let debug = debug != 0; @@ -125,21 +125,21 @@ pub fn new_program( evm_data_handler: u64, gas: u64, ) -> Result { - let (mut mem, state) = jit_env(&mut env); + let (mut mem, exec) = env.jit_env(); let compiled_hash = mem.read_bytes32(compiled_hash_ptr); let calldata = mem.read_slice(calldata_ptr, calldata_size as usize); let evm_data: EvmData = unsafe { *Box::from_raw(evm_data_handler as *mut EvmData) }; let config: JitConfig = unsafe { *Box::from_raw(stylus_config_handler as *mut JitConfig) }; - let Some(module) = state.0.module_asms.get(&compiled_hash).cloned() else { + let Some(module) = exec.module_asms.get(&compiled_hash).cloned() else { return Err(Escape::Failure(format!( "module hash {:?} not found in {:?}", compiled_hash, - state.0.module_asms.keys() + exec.module_asms.keys() ))); }; - launch_program_thread(state.0, module, calldata, config, evm_data, gas) + launch_program_thread(exec, module, calldata, config, evm_data, gas) } pub fn launch_program_thread( @@ -173,8 +173,8 @@ pub fn launch_program_thread( /// module MUST match last module number returned from new_program /// returns request_id for the first request from the program pub fn start_program(mut env: WasmEnvMut, module: u32) -> Result { - let (_, state) = jit_env(&mut env); - start_program_with_wasm_env(state.0, module) + let (_, exec) = env.jit_env(); + start_program_with_wasm_env(exec, module) } /// program_requires_prepare @@ -216,8 +216,8 @@ pub fn start_program_with_wasm_env(exec: &mut WasmEnv, module: u32) -> Result Result { - let (mut mem, state) = jit_env(&mut env); - let msg = get_last_msg(state.0, id)?; + let (mut mem, exec) = env.jit_env(); + let msg = get_last_msg(exec, id)?; mem.write_u32(len_ptr, msg.req_data.len() as u32); Ok(msg.req_type) } @@ -235,8 +235,8 @@ pub fn get_last_msg(exec: &mut WasmEnv, id: u32) -> Result MaybeEscape { - let (mut mem, state) = jit_env(&mut env); - let msg = get_last_msg(state.0, id)?; + let (mut mem, exec) = env.jit_env(); + let msg = get_last_msg(exec, id)?; mem.write_slice(data_ptr, &msg.req_data); Ok(()) } @@ -252,11 +252,11 @@ pub fn set_response( raw_data_ptr: GuestPtr, raw_data_len: u32, ) -> MaybeEscape { - let (mem, state) = jit_env(&mut env); + let (mem, exec) = env.jit_env(); let result = mem.read_slice(result_ptr, result_len as usize); let raw_data = mem.read_slice(raw_data_ptr, raw_data_len as usize); - set_response_with_wasm_env(state.0, id, gas, result, raw_data) + set_response_with_wasm_env(exec, id, gas, result, raw_data) } pub fn set_response_with_wasm_env( @@ -274,8 +274,8 @@ pub fn set_response_with_wasm_env( /// MUST be called right after set_response to the same id /// returns request_id for the next request pub fn send_response(mut env: WasmEnvMut, req_id: u32) -> Result { - let (_, state) = jit_env(&mut env); - let thread = state.0.threads.last_mut().unwrap(); + let (_, exec) = env.jit_env(); + let thread = exec.threads.last_mut().unwrap(); let msg = thread.last_message()?; if msg.1 != req_id { return Escape::hostio("get_request id doesn't match"); @@ -287,8 +287,8 @@ pub fn send_response(mut env: WasmEnvMut, req_id: u32) -> Result { /// removes the last created program pub fn pop(mut env: WasmEnvMut) -> MaybeEscape { - let (_, state) = jit_env(&mut env); - pop_with_wasm_env(state.0) + let (_, exec) = env.jit_env(); + pop_with_wasm_env(exec) } pub fn pop_with_wasm_env(exec: &mut WasmEnv) -> MaybeEscape { @@ -377,7 +377,7 @@ pub fn create_evm_data_v2( cached: u32, reentrant: u32, ) -> Result { - let (mut mem, _) = jit_env(&mut env); + let (mut mem, _) = env.jit_env(); let evm_data = EvmData { arbos_version, diff --git a/crates/jit/src/state.rs b/crates/jit/src/state.rs deleted file mode 100644 index e10b431a5fc..00000000000 --- a/crates/jit/src/state.rs +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright 2022-2026, Offchain Labs, Inc. -// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md - -use crate::machine::{WasmEnv, WasmEnvMut}; -use crate::memory::JitMemAccess; -use arbutil::{Bytes32, PreimageType}; -use caller_env::wavmio::WavmState; -use caller_env::ExecEnv; -use rand::RngCore; - -/// Newtype wrapping &mut WasmEnv to implement WavmState (orphan rule). -pub(crate) struct JitState<'a>(pub &'a mut WasmEnv); - -/// Extracts (JitMemAccess, JitState) from a WasmEnvMut in place. -pub(crate) fn jit_env<'a>(env: &'a mut WasmEnvMut) -> (JitMemAccess<'a>, JitState<'a>) { - let memory = env.data().memory.clone().unwrap(); - let (wenv, store) = env.data_and_store_mut(); - (JitMemAccess { memory, store }, JitState(wenv)) -} - -impl ExecEnv for JitState<'_> { - fn advance_time(&mut self, ns: u64) { - self.0.go_state.time += ns; - } - - fn get_time(&self) -> u64 { - self.0.go_state.time - } - - fn next_rand_u32(&mut self) -> u32 { - self.0.go_state.rng.next_u32() - } - - fn print_string(&mut self, bytes: &[u8]) { - match String::from_utf8(bytes.to_vec()) { - Ok(s) => eprintln!("JIT: WASM says: {s}"), // TODO: this adds too many newlines since go calls this in chunks - Err(e) => { - let bytes = e.as_bytes(); - eprintln!("Go string {} is not valid utf8: {e:?}", hex::encode(bytes)); - } - } - } -} - -impl WavmState for JitState<'_> { - fn get_u64_global(&self, idx: usize) -> Option { - self.0.small_globals.get(idx).copied() - } - - fn set_u64_global(&mut self, idx: usize, val: u64) -> bool { - match self.0.small_globals.get_mut(idx) { - Some(g) => { - *g = val; - true - } - None => false, - } - } - - fn get_bytes32_global(&self, idx: usize) -> Option<&[u8; 32]> { - self.0.large_globals.get(idx).map(|b| &b.0) - } - - fn set_bytes32_global(&mut self, idx: usize, val: [u8; 32]) -> bool { - match self.0.large_globals.get_mut(idx) { - Some(g) => { - *g = val.into(); - true - } - None => false, - } - } - - fn get_sequencer_message(&self, num: u64) -> Option<&[u8]> { - self.0.sequencer_messages.get(&num).map(|v| v.as_slice()) - } - - fn get_delayed_message(&self, num: u64) -> Option<&[u8]> { - self.0.delayed_messages.get(&num).map(|v| v.as_slice()) - } - - fn get_preimage(&self, preimage_type: u8, hash: &[u8; 32]) -> Option<&[u8]> { - let pt: PreimageType = preimage_type.try_into().ok()?; - self.0 - .preimages - .get(&pt) - .and_then(|m| m.get(&Bytes32::from(*hash))) - .map(|v| v.as_slice()) - } -} diff --git a/crates/jit/src/wasip1_stub.rs b/crates/jit/src/wasip1_stub.rs index 1d33112dbaf..1f6005135f8 100644 --- a/crates/jit/src/wasip1_stub.rs +++ b/crates/jit/src/wasip1_stub.rs @@ -3,7 +3,7 @@ #![allow(clippy::too_many_arguments)] -use crate::state::jit_env; +use crate::caller_env::{JitEnv, JitExecEnv}; use crate::machine::{Escape, WasmEnvMut}; use caller_env::{self, wasip1_stub::Errno, GuestPtr}; @@ -15,8 +15,9 @@ macro_rules! wrap { ($(fn $func_name:ident ($($arg_name:ident : $arg_type:ty),* ) -> $return_type:ty);*) => { $( pub fn $func_name(mut src: WasmEnvMut, $($arg_name : $arg_type),*) -> Result<$return_type, Escape> { - let (mut mem, mut state) = jit_env(&mut src); - Ok(caller_env::wasip1_stub::$func_name(&mut mem, &mut state, $($arg_name),*)) + let (mut mem, wenv) = src.jit_env(); + + Ok(caller_env::wasip1_stub::$func_name(&mut mem, &mut JitExecEnv { wenv }, $($arg_name),*)) } )* }; diff --git a/crates/jit/src/wavmio.rs b/crates/jit/src/wavmio.rs index ca65bbe45c6..97d07e4e2ac 100644 --- a/crates/jit/src/wavmio.rs +++ b/crates/jit/src/wavmio.rs @@ -1,11 +1,12 @@ // Copyright 2022-2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md -use crate::state::jit_env; -use crate::machine::{Escape, MaybeEscape, WasmEnv, WasmEnvMut}; +use crate::{ + caller_env::JitEnv, + machine::{Escape, MaybeEscape, WasmEnv, WasmEnvMut}, +}; use arbutil::Color; -use ::caller_env::wavmio as caller_env; -use ::caller_env::GuestPtr; +use caller_env::{GuestPtr, MemAccess}; use std::{ io, io::{BufReader, BufWriter, ErrorKind}, @@ -15,54 +16,98 @@ use std::{ use validation::local_target; use validation::transfer::receive_validation_input; +/// Reads 32-bytes of global state. pub fn get_global_state_bytes32(mut env: WasmEnvMut, idx: u32, out_ptr: GuestPtr) -> MaybeEscape { - ready_hostio(env.data_mut())?; - let (mut mem, state) = jit_env(&mut env); - caller_env::get_global_state_bytes32(&mut mem, &state, idx, out_ptr).map_err(Escape::HostIO) + let (mut mem, exec) = env.jit_env(); + ready_hostio(exec)?; + + let Some(global) = exec.large_globals.get(idx as usize) else { + return Escape::hostio("global read out of bounds in wavmio.getGlobalStateBytes32"); + }; + mem.write_slice(out_ptr, &global[..32]); + Ok(()) } +/// Writes 32-bytes of global state. pub fn set_global_state_bytes32(mut env: WasmEnvMut, idx: u32, src_ptr: GuestPtr) -> MaybeEscape { - ready_hostio(env.data_mut())?; - let (mem, mut state) = jit_env(&mut env); - caller_env::set_global_state_bytes32(&mem, &mut state, idx, src_ptr).map_err(Escape::HostIO) + let (mem, exec) = env.jit_env(); + ready_hostio(exec)?; + + let slice = mem.read_slice(src_ptr, 32); + let slice = &slice.try_into().unwrap(); + match exec.large_globals.get_mut(idx as usize) { + Some(global) => *global = *slice, + None => return Escape::hostio("global write oob in wavmio.setGlobalStateBytes32"), + }; + Ok(()) } +/// Reads 8-bytes of global state pub fn get_global_state_u64(mut env: WasmEnvMut, idx: u32) -> Result { - ready_hostio(env.data_mut())?; - let (_mem, state) = jit_env(&mut env); - caller_env::get_global_state_u64(&state, idx).map_err(Escape::HostIO) + let (_, exec) = env.jit_env(); + ready_hostio(exec)?; + + match exec.small_globals.get(idx as usize) { + Some(global) => Ok(*global), + None => Escape::hostio("global read out of bounds in wavmio.getGlobalStateU64"), + } } +/// Writes 8-bytes of global state pub fn set_global_state_u64(mut env: WasmEnvMut, idx: u32, val: u64) -> MaybeEscape { - ready_hostio(env.data_mut())?; - let (_mem, mut state) = jit_env(&mut env); - caller_env::set_global_state_u64(&mut state, idx, val).map_err(Escape::HostIO) + let (_, exec) = env.jit_env(); + ready_hostio(exec)?; + + match exec.small_globals.get_mut(idx as usize) { + Some(global) => *global = val, + None => return Escape::hostio("global write out of bounds in wavmio.setGlobalStateU64"), + } + Ok(()) } +/// Reads an inbox message. pub fn read_inbox_message( mut env: WasmEnvMut, msg_num: u64, offset: u32, out_ptr: GuestPtr, ) -> Result { - ready_hostio(env.data_mut())?; - let (mut mem, state) = jit_env(&mut env); - caller_env::read_inbox_message(&mut mem, &state, msg_num, offset, out_ptr) - .map_err(Escape::HostIO) + let (mut mem, exec) = env.jit_env(); + ready_hostio(exec)?; + + let message = match exec.sequencer_messages.get(&msg_num) { + Some(message) => message, + None => return Escape::hostio(format!("missing sequencer inbox message {msg_num}")), + }; + let offset = offset as usize; + let len = std::cmp::min(32, message.len().saturating_sub(offset)); + let read = message.get(offset..(offset + len)).unwrap_or_default(); + mem.write_slice(out_ptr, read); + Ok(read.len() as u32) } +/// Reads a delayed inbox message. pub fn read_delayed_inbox_message( mut env: WasmEnvMut, msg_num: u64, offset: u32, out_ptr: GuestPtr, ) -> Result { - ready_hostio(env.data_mut())?; - let (mut mem, state) = jit_env(&mut env); - caller_env::read_delayed_inbox_message(&mut mem, &state, msg_num, offset, out_ptr) - .map_err(Escape::HostIO) + let (mut mem, exec) = env.jit_env(); + ready_hostio(exec)?; + + let message = match exec.delayed_messages.get(&msg_num) { + Some(message) => message, + None => return Escape::hostio(format!("missing delayed inbox message {msg_num}")), + }; + let offset = offset as usize; + let len = std::cmp::min(32, message.len().saturating_sub(offset)); + let read = message.get(offset..(offset + len)).unwrap_or_default(); + mem.write_slice(out_ptr, read); + Ok(read.len() as u32) } +/// Retrieves the preimage of the given hash. #[deprecated] // we're just keeping this around until we no longer need to validate old replay binaries pub fn resolve_keccak_preimage( env: WasmEnvMut, @@ -90,7 +135,7 @@ pub fn resolve_typed_preimage( ) } -fn resolve_preimage_impl( +pub fn resolve_preimage_impl( mut env: WasmEnvMut, preimage_type: u8, hash_ptr: GuestPtr, @@ -98,48 +143,63 @@ fn resolve_preimage_impl( out_ptr: GuestPtr, name: &str, ) -> Result { - ready_hostio(env.data_mut())?; + let (mut mem, exec) = env.jit_env(); + let offset = offset as usize; + + let Ok(preimage_type) = preimage_type.try_into() else { + eprintln!("Go trying to resolve pre image with unknown type {preimage_type}"); + return Ok(0); + }; + + macro_rules! error { + ($text:expr $(,$args:expr)*) => {{ + let text = format!($text $(,$args)*); + return Escape::hostio(&text) + }}; + } + + let hash = mem.read_bytes32(hash_ptr); + + let Some(preimage) = exec + .preimages + .get(&preimage_type) + .and_then(|m| m.get(&hash)) + else { + let hash_hex = hex::encode(hash); + error!("Missing requested preimage for hash {hash_hex} in {name}") + }; #[cfg(debug_assertions)] { - use crate::state::jit_env; use arbutil::PreimageType; use sha2::Sha256; use sha3::{Digest, Keccak256}; - let (mut mem, state) = jit_env(&mut env); - let hash = mem.read_bytes32(hash_ptr); - - let Ok(preimage_type) = preimage_type.try_into() else { - eprintln!("Go trying to resolve pre image with unknown type {preimage_type}"); - return Ok(0); + // Check if preimage rehashes to the provided hash. Exclude blob preimages + let calculated_hash: [u8; 32] = match preimage_type { + PreimageType::Keccak256 => Keccak256::digest(preimage).into(), + PreimageType::Sha2_256 => Sha256::digest(preimage).into(), + PreimageType::EthVersionedHash => *hash, + PreimageType::DACertificate => *hash, // Can't verify DACertificate hash, just accept it }; - - if let Some(preimage) = state.0 - .preimages - .get(&preimage_type) - .and_then(|m| m.get(&hash)) - { - let calculated_hash: [u8; 32] = match preimage_type { - PreimageType::Keccak256 => Keccak256::digest(preimage).into(), - PreimageType::Sha2_256 => Sha256::digest(preimage).into(), - PreimageType::EthVersionedHash => *hash, - PreimageType::DACertificate => *hash, - }; - if calculated_hash != *hash { - return Escape::hostio(format!( - "Calculated hash {} of preimage {} does not match provided hash {}", - hex::encode(calculated_hash), - hex::encode(preimage), - hex::encode(*hash) - )); - } + if calculated_hash != *hash { + error!( + "Calculated hash {} of preimage {} does not match provided hash {}", + hex::encode(calculated_hash), + hex::encode(preimage), + hex::encode(*hash) + ); } } - let (mut mem, state) = jit_env(&mut env); - caller_env::resolve_preimage(&mut mem, &state, preimage_type, hash_ptr, offset, out_ptr, name) - .map_err(Escape::HostIO) + if offset % 32 != 0 { + error!("bad offset {offset} in {name}") + }; + + let len = std::cmp::min(32, preimage.len().saturating_sub(offset)); + let read = preimage.get(offset..(offset + len)).unwrap_or_default(); + mem.write_slice(out_ptr, read); + Ok(read.len() as u32) } pub fn validate_certificate( @@ -147,8 +207,24 @@ pub fn validate_certificate( preimage_type: u8, hash_ptr: GuestPtr, ) -> Result { - let (mem, state) = jit_env(&mut env); - Ok(caller_env::validate_certificate(&mem, &state, preimage_type, hash_ptr)) + let (mut mem, exec) = env.jit_env(); + let hash = mem.read_bytes32(hash_ptr); + + let Ok(preimage_type) = preimage_type.try_into() else { + eprintln!( + "Go trying to validate certificate for preimage with unknown type {preimage_type}" + ); + return Ok(0); + }; + + // Check if preimage exists + let exists = exec + .preimages + .get(&preimage_type) + .and_then(|m| m.get(&hash)) + .is_some(); + + Ok(if exists { 1 } else { 0 }) } fn ready_hostio(env: &mut WasmEnv) -> MaybeEscape { From 473064f99426a9af1f17f4775c742bb8b0e97f6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Wed, 4 Mar 2026 12:51:57 +0100 Subject: [PATCH 062/189] reuse caller-env in jit --- crates/jit/src/caller_env.rs | 74 +++++++++++++++- crates/jit/src/wavmio.rs | 158 ++++++++++++----------------------- 2 files changed, 124 insertions(+), 108 deletions(-) diff --git a/crates/jit/src/caller_env.rs b/crates/jit/src/caller_env.rs index a30662049fb..fe3b49ec3c2 100644 --- a/crates/jit/src/caller_env.rs +++ b/crates/jit/src/caller_env.rs @@ -2,8 +2,8 @@ // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md use crate::machine::{WasmEnv, WasmEnvMut}; -use arbutil::{Bytes20, Bytes32}; -use caller_env::{ExecEnv, GuestPtr, MemAccess}; +use arbutil::{Bytes20, Bytes32, PreimageType}; +use caller_env::{wavmio::WavmState, ExecEnv, GuestPtr, MemAccess}; use rand::RngCore; use std::mem::{self, MaybeUninit}; use wasmer::{Memory, MemoryView, StoreMut, WasmPtr}; @@ -132,3 +132,73 @@ impl ExecEnv for JitExecEnv<'_> { } } } + +impl ExecEnv for WasmEnv { + fn advance_time(&mut self, ns: u64) { + self.go_state.time += ns; + } + + fn get_time(&self) -> u64 { + self.go_state.time + } + + fn next_rand_u32(&mut self) -> u32 { + self.go_state.rng.next_u32() + } + + fn print_string(&mut self, bytes: &[u8]) { + match String::from_utf8(bytes.to_vec()) { + Ok(s) => eprintln!("JIT: WASM says: {s}"), + Err(e) => { + let bytes = e.as_bytes(); + eprintln!("Go string {} is not valid utf8: {e:?}", hex::encode(bytes)); + } + } + } +} + +impl WavmState for WasmEnv { + fn get_u64_global(&self, idx: usize) -> Option { + self.small_globals.get(idx).copied() + } + + fn set_u64_global(&mut self, idx: usize, val: u64) -> bool { + match self.small_globals.get_mut(idx) { + Some(g) => { + *g = val; + true + } + None => false, + } + } + + fn get_bytes32_global(&self, idx: usize) -> Option<&[u8; 32]> { + self.large_globals.get(idx).map(|b| &b.0) + } + + fn set_bytes32_global(&mut self, idx: usize, val: [u8; 32]) -> bool { + match self.large_globals.get_mut(idx) { + Some(g) => { + *g = val.into(); + true + } + None => false, + } + } + + fn get_sequencer_message(&self, num: u64) -> Option<&[u8]> { + self.sequencer_messages.get(&num).map(|v| v.as_slice()) + } + + fn get_delayed_message(&self, num: u64) -> Option<&[u8]> { + self.delayed_messages.get(&num).map(|v| v.as_slice()) + } + + fn get_preimage(&self, preimage_type: u8, hash: &[u8; 32]) -> Option<&[u8]> { + let pt: PreimageType = preimage_type.try_into().ok()?; + self.preimages + .get(&pt) + .and_then(|m| m.get(&Bytes32(*hash))) + .map(|v| v.as_slice()) + } +} diff --git a/crates/jit/src/wavmio.rs b/crates/jit/src/wavmio.rs index 97d07e4e2ac..5aee97a9fed 100644 --- a/crates/jit/src/wavmio.rs +++ b/crates/jit/src/wavmio.rs @@ -6,7 +6,7 @@ use crate::{ machine::{Escape, MaybeEscape, WasmEnv, WasmEnvMut}, }; use arbutil::Color; -use caller_env::{GuestPtr, MemAccess}; +use caller_env::GuestPtr; use std::{ io, io::{BufReader, BufWriter, ErrorKind}, @@ -20,49 +20,30 @@ use validation::transfer::receive_validation_input; pub fn get_global_state_bytes32(mut env: WasmEnvMut, idx: u32, out_ptr: GuestPtr) -> MaybeEscape { let (mut mem, exec) = env.jit_env(); ready_hostio(exec)?; - - let Some(global) = exec.large_globals.get(idx as usize) else { - return Escape::hostio("global read out of bounds in wavmio.getGlobalStateBytes32"); - }; - mem.write_slice(out_ptr, &global[..32]); - Ok(()) + caller_env::wavmio::get_global_state_bytes32(&mut mem, exec, idx, out_ptr) + .map_err(Escape::HostIO) } /// Writes 32-bytes of global state. pub fn set_global_state_bytes32(mut env: WasmEnvMut, idx: u32, src_ptr: GuestPtr) -> MaybeEscape { let (mem, exec) = env.jit_env(); ready_hostio(exec)?; - - let slice = mem.read_slice(src_ptr, 32); - let slice = &slice.try_into().unwrap(); - match exec.large_globals.get_mut(idx as usize) { - Some(global) => *global = *slice, - None => return Escape::hostio("global write oob in wavmio.setGlobalStateBytes32"), - }; - Ok(()) + caller_env::wavmio::set_global_state_bytes32(&mem, exec, idx, src_ptr) + .map_err(Escape::HostIO) } /// Reads 8-bytes of global state pub fn get_global_state_u64(mut env: WasmEnvMut, idx: u32) -> Result { let (_, exec) = env.jit_env(); ready_hostio(exec)?; - - match exec.small_globals.get(idx as usize) { - Some(global) => Ok(*global), - None => Escape::hostio("global read out of bounds in wavmio.getGlobalStateU64"), - } + caller_env::wavmio::get_global_state_u64(exec, idx).map_err(Escape::HostIO) } /// Writes 8-bytes of global state pub fn set_global_state_u64(mut env: WasmEnvMut, idx: u32, val: u64) -> MaybeEscape { let (_, exec) = env.jit_env(); ready_hostio(exec)?; - - match exec.small_globals.get_mut(idx as usize) { - Some(global) => *global = val, - None => return Escape::hostio("global write out of bounds in wavmio.setGlobalStateU64"), - } - Ok(()) + caller_env::wavmio::set_global_state_u64(exec, idx, val).map_err(Escape::HostIO) } /// Reads an inbox message. @@ -74,16 +55,8 @@ pub fn read_inbox_message( ) -> Result { let (mut mem, exec) = env.jit_env(); ready_hostio(exec)?; - - let message = match exec.sequencer_messages.get(&msg_num) { - Some(message) => message, - None => return Escape::hostio(format!("missing sequencer inbox message {msg_num}")), - }; - let offset = offset as usize; - let len = std::cmp::min(32, message.len().saturating_sub(offset)); - let read = message.get(offset..(offset + len)).unwrap_or_default(); - mem.write_slice(out_ptr, read); - Ok(read.len() as u32) + caller_env::wavmio::read_inbox_message(&mut mem, exec, msg_num, offset, out_ptr) + .map_err(Escape::HostIO) } /// Reads a delayed inbox message. @@ -95,16 +68,8 @@ pub fn read_delayed_inbox_message( ) -> Result { let (mut mem, exec) = env.jit_env(); ready_hostio(exec)?; - - let message = match exec.delayed_messages.get(&msg_num) { - Some(message) => message, - None => return Escape::hostio(format!("missing delayed inbox message {msg_num}")), - }; - let offset = offset as usize; - let len = std::cmp::min(32, message.len().saturating_sub(offset)); - let read = message.get(offset..(offset + len)).unwrap_or_default(); - mem.write_slice(out_ptr, read); - Ok(read.len() as u32) + caller_env::wavmio::read_delayed_inbox_message(&mut mem, exec, msg_num, offset, out_ptr) + .map_err(Escape::HostIO) } /// Retrieves the preimage of the given hash. @@ -144,62 +109,54 @@ pub fn resolve_preimage_impl( name: &str, ) -> Result { let (mut mem, exec) = env.jit_env(); - let offset = offset as usize; + ready_hostio(exec)?; - let Ok(preimage_type) = preimage_type.try_into() else { + if TryInto::::try_into(preimage_type).is_err() { eprintln!("Go trying to resolve pre image with unknown type {preimage_type}"); return Ok(0); - }; - - macro_rules! error { - ($text:expr $(,$args:expr)*) => {{ - let text = format!($text $(,$args)*); - return Escape::hostio(&text) - }}; } - let hash = mem.read_bytes32(hash_ptr); - - let Some(preimage) = exec - .preimages - .get(&preimage_type) - .and_then(|m| m.get(&hash)) - else { - let hash_hex = hex::encode(hash); - error!("Missing requested preimage for hash {hash_hex} in {name}") - }; - #[cfg(debug_assertions)] { use arbutil::PreimageType; + use caller_env::MemAccess; use sha2::Sha256; use sha3::{Digest, Keccak256}; - // Check if preimage rehashes to the provided hash. Exclude blob preimages - let calculated_hash: [u8; 32] = match preimage_type { - PreimageType::Keccak256 => Keccak256::digest(preimage).into(), - PreimageType::Sha2_256 => Sha256::digest(preimage).into(), - PreimageType::EthVersionedHash => *hash, - PreimageType::DACertificate => *hash, // Can't verify DACertificate hash, just accept it - }; - if calculated_hash != *hash { - error!( - "Calculated hash {} of preimage {} does not match provided hash {}", - hex::encode(calculated_hash), - hex::encode(preimage), - hex::encode(*hash) - ); + let hash: [u8; 32] = mem.read_fixed(hash_ptr); + let preimage_type: PreimageType = preimage_type.try_into().unwrap(); + if let Some(preimage) = exec + .preimages + .get(&preimage_type) + .and_then(|m| m.get(&arbutil::Bytes32(hash))) + { + let calculated_hash: [u8; 32] = match preimage_type { + PreimageType::Keccak256 => Keccak256::digest(preimage).into(), + PreimageType::Sha2_256 => Sha256::digest(preimage).into(), + PreimageType::EthVersionedHash => hash, + PreimageType::DACertificate => hash, + }; + if calculated_hash != hash { + return Escape::hostio(format!( + "Calculated hash {} of preimage {} does not match provided hash {}", + hex::encode(calculated_hash), + hex::encode(preimage), + hex::encode(hash) + )); + } } } - if offset % 32 != 0 { - error!("bad offset {offset} in {name}") - }; - - let len = std::cmp::min(32, preimage.len().saturating_sub(offset)); - let read = preimage.get(offset..(offset + len)).unwrap_or_default(); - mem.write_slice(out_ptr, read); - Ok(read.len() as u32) + caller_env::wavmio::resolve_preimage( + &mut mem, + exec, + preimage_type, + hash_ptr, + offset, + out_ptr, + name, + ) + .map_err(Escape::HostIO) } pub fn validate_certificate( @@ -207,24 +164,13 @@ pub fn validate_certificate( preimage_type: u8, hash_ptr: GuestPtr, ) -> Result { - let (mut mem, exec) = env.jit_env(); - let hash = mem.read_bytes32(hash_ptr); - - let Ok(preimage_type) = preimage_type.try_into() else { - eprintln!( - "Go trying to validate certificate for preimage with unknown type {preimage_type}" - ); - return Ok(0); - }; - - // Check if preimage exists - let exists = exec - .preimages - .get(&preimage_type) - .and_then(|m| m.get(&hash)) - .is_some(); - - Ok(if exists { 1 } else { 0 }) + let (mem, exec) = env.jit_env(); + Ok(caller_env::wavmio::validate_certificate( + &mem, + exec, + preimage_type, + hash_ptr, + )) } fn ready_hostio(env: &mut WasmEnv) -> MaybeEscape { From aaa318ab1f7383433f8cfd52ace35c01f1c42232 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Wed, 4 Mar 2026 13:08:20 +0100 Subject: [PATCH 063/189] rename interface to WavmIo --- crates/caller-env/src/wavmio.rs | 34 ++++++++++++++++----------------- crates/jit/src/caller_env.rs | 4 ++-- sp1-crates/program/src/state.rs | 6 +++--- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/crates/caller-env/src/wavmio.rs b/crates/caller-env/src/wavmio.rs index b5bd213c235..10a4bf7dbe9 100644 --- a/crates/caller-env/src/wavmio.rs +++ b/crates/caller-env/src/wavmio.rs @@ -7,7 +7,7 @@ use alloc::format; use core::cmp::min; /// Trait for accessing wavmio host state (globals, inbox, preimages). -pub trait WavmState: ExecEnv { +pub trait WavmIo: ExecEnv { fn get_u64_global(&self, idx: usize) -> Option; fn set_u64_global(&mut self, idx: usize, val: u64) -> bool; fn get_bytes32_global(&self, idx: usize) -> Option<&[u8; 32]>; @@ -20,11 +20,11 @@ pub trait WavmState: ExecEnv { /// Reads 32-bytes of global state and writes to guest memory. pub fn get_global_state_bytes32( mem: &mut impl MemAccess, - state: &impl WavmState, + io: &impl WavmIo, idx: u32, out_ptr: GuestPtr, ) -> Result<(), String> { - let Some(global) = state.get_bytes32_global(idx as usize) else { + let Some(global) = io.get_bytes32_global(idx as usize) else { return Err("global read out of bounds in wavmio.getGlobalStateBytes32".into()); }; mem.write_slice(out_ptr, &global[..]); @@ -34,12 +34,12 @@ pub fn get_global_state_bytes32( /// Reads 32-bytes from guest memory and writes to global state. pub fn set_global_state_bytes32( mem: &impl MemAccess, - state: &mut impl WavmState, + io: &mut impl WavmIo, idx: u32, src_ptr: GuestPtr, ) -> Result<(), String> { let val = mem.read_fixed(src_ptr); - if !state.set_bytes32_global(idx as usize, val) { + if !io.set_bytes32_global(idx as usize, val) { return Err("global write oob in wavmio.setGlobalStateBytes32".into()); } Ok(()) @@ -47,10 +47,10 @@ pub fn set_global_state_bytes32( /// Reads 8-bytes of global state. pub fn get_global_state_u64( - state: &impl WavmState, + io: &impl WavmIo, idx: u32, ) -> Result { - match state.get_u64_global(idx as usize) { + match io.get_u64_global(idx as usize) { Some(val) => Ok(val), None => Err("global read out of bounds in wavmio.getGlobalStateU64".into()), } @@ -58,11 +58,11 @@ pub fn get_global_state_u64( /// Writes 8-bytes of global state. pub fn set_global_state_u64( - state: &mut impl WavmState, + io: &mut impl WavmIo, idx: u32, val: u64, ) -> Result<(), String> { - if !state.set_u64_global(idx as usize, val) { + if !io.set_u64_global(idx as usize, val) { return Err("global write out of bounds in wavmio.setGlobalStateU64".into()); } Ok(()) @@ -71,12 +71,12 @@ pub fn set_global_state_u64( /// Reads up to 32 bytes of a sequencer inbox message at the given offset. pub fn read_inbox_message( mem: &mut impl MemAccess, - state: &impl WavmState, + io: &impl WavmIo, msg_num: u64, offset: u32, out_ptr: GuestPtr, ) -> Result { - let message = match state.get_sequencer_message(msg_num) { + let message = match io.get_sequencer_message(msg_num) { Some(message) => message, None => return Err(format!("missing sequencer inbox message {msg_num}")), }; @@ -90,12 +90,12 @@ pub fn read_inbox_message( /// Reads up to 32 bytes of a delayed inbox message at the given offset. pub fn read_delayed_inbox_message( mem: &mut impl MemAccess, - state: &impl WavmState, + io: &impl WavmIo, msg_num: u64, offset: u32, out_ptr: GuestPtr, ) -> Result { - let message = match state.get_delayed_message(msg_num) { + let message = match io.get_delayed_message(msg_num) { Some(message) => message, None => return Err(format!("missing delayed inbox message {msg_num}")), }; @@ -109,7 +109,7 @@ pub fn read_delayed_inbox_message( /// Looks up a preimage by type and hash, reads up to 32 bytes at an aligned offset. pub fn resolve_preimage( mem: &mut impl MemAccess, - state: &impl WavmState, + io: &impl WavmIo, preimage_type: u8, hash_ptr: GuestPtr, offset: u32, @@ -119,7 +119,7 @@ pub fn resolve_preimage( let hash = mem.read_fixed(hash_ptr); let offset = offset as usize; - let Some(preimage) = state.get_preimage(preimage_type, &hash) else { + let Some(preimage) = io.get_preimage(preimage_type, &hash) else { let hash_hex = hex::encode(hash); return Err(format!( "Missing requested preimage for hash {hash_hex} in {name}" @@ -139,12 +139,12 @@ pub fn resolve_preimage( /// Returns 1 if a preimage exists for the given type and hash, 0 otherwise. pub fn validate_certificate( mem: &impl MemAccess, - state: &impl WavmState, + io: &impl WavmIo, preimage_type: u8, hash_ptr: GuestPtr, ) -> u8 { let hash = mem.read_fixed(hash_ptr); - match state.get_preimage(preimage_type, &hash) { + match io.get_preimage(preimage_type, &hash) { Some(_) => 1, None => 0, } diff --git a/crates/jit/src/caller_env.rs b/crates/jit/src/caller_env.rs index fe3b49ec3c2..99be7ff6626 100644 --- a/crates/jit/src/caller_env.rs +++ b/crates/jit/src/caller_env.rs @@ -3,7 +3,7 @@ use crate::machine::{WasmEnv, WasmEnvMut}; use arbutil::{Bytes20, Bytes32, PreimageType}; -use caller_env::{wavmio::WavmState, ExecEnv, GuestPtr, MemAccess}; +use caller_env::{wavmio::WavmIo, ExecEnv, GuestPtr, MemAccess}; use rand::RngCore; use std::mem::{self, MaybeUninit}; use wasmer::{Memory, MemoryView, StoreMut, WasmPtr}; @@ -157,7 +157,7 @@ impl ExecEnv for WasmEnv { } } -impl WavmState for WasmEnv { +impl WavmIo for WasmEnv { fn get_u64_global(&self, idx: usize) -> Option { self.small_globals.get(idx).copied() } diff --git a/sp1-crates/program/src/state.rs b/sp1-crates/program/src/state.rs index a0813bb9af6..f132f50ff55 100644 --- a/sp1-crates/program/src/state.rs +++ b/sp1-crates/program/src/state.rs @@ -1,7 +1,7 @@ // Copyright 2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md -use caller_env::wavmio::WavmState; +use caller_env::wavmio::WavmIo; use caller_env::{ExecEnv, GuestPtr}; use rand::RngCore; use wasmer::FunctionEnvMut; @@ -9,7 +9,7 @@ use wasmer::FunctionEnvMut; use crate::memory::Sp1MemAccess; use crate::replay::CustomEnvData; -/// Newtype wrapper to implement WavmState and ExecEnv over CustomEnvData. +/// Newtype wrapper to implement WavmIo and ExecEnv for CustomEnvData. pub(crate) struct Sp1State<'a>(pub &'a mut CustomEnvData); impl ExecEnv for Sp1State<'_> { @@ -30,7 +30,7 @@ impl ExecEnv for Sp1State<'_> { } } -impl WavmState for Sp1State<'_> { +impl WavmIo for Sp1State<'_> { fn get_u64_global(&self, idx: usize) -> Option { self.0.input().small_globals.get(idx).copied() } From 41f5fc7ad655e85ae2c90f216bd324bd5a417149 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Wed, 4 Mar 2026 13:09:49 +0100 Subject: [PATCH 064/189] Do not extend ExecEnv --- crates/caller-env/src/wavmio.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/caller-env/src/wavmio.rs b/crates/caller-env/src/wavmio.rs index 10a4bf7dbe9..5cdaf1975ca 100644 --- a/crates/caller-env/src/wavmio.rs +++ b/crates/caller-env/src/wavmio.rs @@ -1,13 +1,13 @@ // Copyright 2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md -use crate::{ExecEnv, GuestPtr, MemAccess}; +use crate::{GuestPtr, MemAccess}; use alloc::string::String; use alloc::format; use core::cmp::min; /// Trait for accessing wavmio host state (globals, inbox, preimages). -pub trait WavmIo: ExecEnv { +pub trait WavmIo { fn get_u64_global(&self, idx: usize) -> Option; fn set_u64_global(&mut self, idx: usize, val: u64) -> bool; fn get_bytes32_global(&self, idx: usize) -> Option<&[u8; 32]>; From 4978082036f555a1ff6c97f5c670f793f6de8249 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Wed, 4 Mar 2026 13:12:44 +0100 Subject: [PATCH 065/189] update doc --- crates/caller-env/src/wavmio.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/caller-env/src/wavmio.rs b/crates/caller-env/src/wavmio.rs index 5cdaf1975ca..2ba9855f7fc 100644 --- a/crates/caller-env/src/wavmio.rs +++ b/crates/caller-env/src/wavmio.rs @@ -6,7 +6,7 @@ use alloc::string::String; use alloc::format; use core::cmp::min; -/// Trait for accessing wavmio host state (globals, inbox, preimages). +/// Read validation inputs and set outputs for the `wavmio` host functions. pub trait WavmIo { fn get_u64_global(&self, idx: usize) -> Option; fn set_u64_global(&mut self, idx: usize, val: u64) -> bool; From 9bd0b95ad0edcfa8d9a4ef75ce99bd5f90966ba8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Wed, 4 Mar 2026 13:19:48 +0100 Subject: [PATCH 066/189] remove ExecEnv for WasmEnv --- crates/jit/src/caller_env.rs | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/crates/jit/src/caller_env.rs b/crates/jit/src/caller_env.rs index 99be7ff6626..36f492b8669 100644 --- a/crates/jit/src/caller_env.rs +++ b/crates/jit/src/caller_env.rs @@ -133,30 +133,6 @@ impl ExecEnv for JitExecEnv<'_> { } } -impl ExecEnv for WasmEnv { - fn advance_time(&mut self, ns: u64) { - self.go_state.time += ns; - } - - fn get_time(&self) -> u64 { - self.go_state.time - } - - fn next_rand_u32(&mut self) -> u32 { - self.go_state.rng.next_u32() - } - - fn print_string(&mut self, bytes: &[u8]) { - match String::from_utf8(bytes.to_vec()) { - Ok(s) => eprintln!("JIT: WASM says: {s}"), - Err(e) => { - let bytes = e.as_bytes(); - eprintln!("Go string {} is not valid utf8: {e:?}", hex::encode(bytes)); - } - } - } -} - impl WavmIo for WasmEnv { fn get_u64_global(&self, idx: usize) -> Option { self.small_globals.get(idx).copied() From fe287597f78a3ea33c78fe68034f2a14da3a1933 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Wed, 4 Mar 2026 13:22:18 +0100 Subject: [PATCH 067/189] more concise --- crates/jit/src/caller_env.rs | 20 ++++++-------------- sp1-crates/program/src/state.rs | 20 ++++++-------------- 2 files changed, 12 insertions(+), 28 deletions(-) diff --git a/crates/jit/src/caller_env.rs b/crates/jit/src/caller_env.rs index 36f492b8669..1f9d0cac018 100644 --- a/crates/jit/src/caller_env.rs +++ b/crates/jit/src/caller_env.rs @@ -139,13 +139,9 @@ impl WavmIo for WasmEnv { } fn set_u64_global(&mut self, idx: usize, val: u64) -> bool { - match self.small_globals.get_mut(idx) { - Some(g) => { - *g = val; - true - } - None => false, - } + let Some(g) = self.small_globals.get_mut(idx) else { return false }; + *g = val; + true } fn get_bytes32_global(&self, idx: usize) -> Option<&[u8; 32]> { @@ -153,13 +149,9 @@ impl WavmIo for WasmEnv { } fn set_bytes32_global(&mut self, idx: usize, val: [u8; 32]) -> bool { - match self.large_globals.get_mut(idx) { - Some(g) => { - *g = val.into(); - true - } - None => false, - } + let Some(g) = self.large_globals.get_mut(idx) else { return false }; + *g = val.into(); + true } fn get_sequencer_message(&self, num: u64) -> Option<&[u8]> { diff --git a/sp1-crates/program/src/state.rs b/sp1-crates/program/src/state.rs index f132f50ff55..ae52de313c3 100644 --- a/sp1-crates/program/src/state.rs +++ b/sp1-crates/program/src/state.rs @@ -36,13 +36,9 @@ impl WavmIo for Sp1State<'_> { } fn set_u64_global(&mut self, idx: usize, val: u64) -> bool { - match self.0.input_mut().small_globals.get_mut(idx) { - Some(g) => { - *g = val; - true - } - None => false, - } + let Some(g) = self.0.input_mut().small_globals.get_mut(idx) else { return false }; + *g = val; + true } fn get_bytes32_global(&self, idx: usize) -> Option<&[u8; 32]> { @@ -50,13 +46,9 @@ impl WavmIo for Sp1State<'_> { } fn set_bytes32_global(&mut self, idx: usize, val: [u8; 32]) -> bool { - match self.0.input_mut().large_globals.get_mut(idx) { - Some(g) => { - *g = val; - true - } - None => false, - } + let Some(g) = self.0.input_mut().large_globals.get_mut(idx) else { return false }; + *g = val; + true } fn get_sequencer_message(&self, num: u64) -> Option<&[u8]> { From a6ce00488b9878f41723063674154aede10983a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Wed, 4 Mar 2026 13:42:44 +0100 Subject: [PATCH 068/189] Remove unnecessary impl --- sp1-crates/program/src/state.rs | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/sp1-crates/program/src/state.rs b/sp1-crates/program/src/state.rs index ae52de313c3..39eec226caa 100644 --- a/sp1-crates/program/src/state.rs +++ b/sp1-crates/program/src/state.rs @@ -12,24 +12,6 @@ use crate::replay::CustomEnvData; /// Newtype wrapper to implement WavmIo and ExecEnv for CustomEnvData. pub(crate) struct Sp1State<'a>(pub &'a mut CustomEnvData); -impl ExecEnv for Sp1State<'_> { - fn advance_time(&mut self, ns: u64) { - self.0.time += ns; - } - - fn get_time(&self) -> u64 { - self.0.time - } - - fn next_rand_u32(&mut self) -> u32 { - self.0.pcg.next_u32() - } - - fn print_string(&mut self, bytes: &[u8]) { - crate::platform::print_string(2, bytes); - } -} - impl WavmIo for Sp1State<'_> { fn get_u64_global(&self, idx: usize) -> Option { self.0.input().small_globals.get(idx).copied() From 149e11a05be3e51a60bc1fca729f98114913d243 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Wed, 4 Mar 2026 14:06:08 +0100 Subject: [PATCH 069/189] remove newtype --- sp1-crates/program/src/imports/wavmio.rs | 22 +++++++++--------- sp1-crates/program/src/state.rs | 29 ++++++++++-------------- 2 files changed, 23 insertions(+), 28 deletions(-) diff --git a/sp1-crates/program/src/imports/wavmio.rs b/sp1-crates/program/src/imports/wavmio.rs index 0943877091c..4d8b63e2f7d 100644 --- a/sp1-crates/program/src/imports/wavmio.rs +++ b/sp1-crates/program/src/imports/wavmio.rs @@ -10,47 +10,47 @@ use wasmer::{FunctionEnvMut, MemoryView}; pub fn get_global_state_bytes32(mut ctx: FunctionEnvMut, idx: u32, out_ptr: Ptr) -> MaybeEscape { let (mut mem, state) = sp1_env(&mut ctx); - caller_env::get_global_state_bytes32(&mut mem, &state, idx, gp(out_ptr)).map_err(Escape::Logical) + caller_env::get_global_state_bytes32(&mut mem, state, idx, gp(out_ptr)).map_err(Escape::Logical) } pub fn set_global_state_bytes32(mut ctx: FunctionEnvMut, idx: u32, src_ptr: Ptr) -> MaybeEscape { - let (mem, mut state) = sp1_env(&mut ctx); - caller_env::set_global_state_bytes32(&mem, &mut state, idx, gp(src_ptr)).map_err(Escape::Logical) + let (mem, state) = sp1_env(&mut ctx); + caller_env::set_global_state_bytes32(&mem, state, idx, gp(src_ptr)).map_err(Escape::Logical) } pub fn get_global_state_u64(mut ctx: FunctionEnvMut, idx: u32) -> Result { let (_mem, state) = sp1_env(&mut ctx); - caller_env::get_global_state_u64(&state, idx).map_err(Escape::Logical) + caller_env::get_global_state_u64(state, idx).map_err(Escape::Logical) } pub fn set_global_state_u64(mut ctx: FunctionEnvMut, idx: u32, val: u64) -> MaybeEscape { - let (_mem, mut state) = sp1_env(&mut ctx); - caller_env::set_global_state_u64(&mut state, idx, val).map_err(Escape::Logical) + let (_mem, state) = sp1_env(&mut ctx); + caller_env::set_global_state_u64(state, idx, val).map_err(Escape::Logical) } pub fn read_inbox_message(mut ctx: FunctionEnvMut, msg_num: u64, offset: u32, out_ptr: Ptr) -> Result { let (mut mem, state) = sp1_env(&mut ctx); - caller_env::read_inbox_message(&mut mem, &state, msg_num, offset, gp(out_ptr)).map_err(Escape::Logical) + caller_env::read_inbox_message(&mut mem, state, msg_num, offset, gp(out_ptr)).map_err(Escape::Logical) } pub fn read_delayed_inbox_message(mut ctx: FunctionEnvMut, msg_num: u64, offset: u32, out_ptr: Ptr) -> Result { let (mut mem, state) = sp1_env(&mut ctx); - caller_env::read_delayed_inbox_message(&mut mem, &state, msg_num, offset, gp(out_ptr)).map_err(Escape::Logical) + caller_env::read_delayed_inbox_message(&mut mem, state, msg_num, offset, gp(out_ptr)).map_err(Escape::Logical) } pub fn resolve_keccak_preimage(mut ctx: FunctionEnvMut, hash_ptr: Ptr, offset: u32, out_ptr: Ptr) -> Result { let (mut mem, state) = sp1_env(&mut ctx); - caller_env::resolve_preimage(&mut mem, &state, 0, gp(hash_ptr), offset, gp(out_ptr), "wavmio.ResolvePreImage").map_err(Escape::Logical) + caller_env::resolve_preimage(&mut mem, state, 0, gp(hash_ptr), offset, gp(out_ptr), "wavmio.ResolvePreImage").map_err(Escape::Logical) } pub fn resolve_typed_preimage(mut ctx: FunctionEnvMut, preimage_type: u8, hash_ptr: Ptr, offset: u32, out_ptr: Ptr) -> Result { let (mut mem, state) = sp1_env(&mut ctx); - caller_env::resolve_preimage(&mut mem, &state, preimage_type, gp(hash_ptr), offset, gp(out_ptr), "wavmio.ResolveTypedPreimage").map_err(Escape::Logical) + caller_env::resolve_preimage(&mut mem, state, preimage_type, gp(hash_ptr), offset, gp(out_ptr), "wavmio.ResolveTypedPreimage").map_err(Escape::Logical) } pub fn validate_certificate(mut ctx: FunctionEnvMut, preimage_type: u8, hash_ptr: Ptr) -> Result { let (mem, state) = sp1_env(&mut ctx); - Ok(caller_env::validate_certificate(&mem, &state, preimage_type, gp(hash_ptr))) + Ok(caller_env::validate_certificate(&mem, state, preimage_type, gp(hash_ptr))) } // Greedy preimage resolution — kept separate, will be refactored independently. diff --git a/sp1-crates/program/src/state.rs b/sp1-crates/program/src/state.rs index 39eec226caa..0a4401cd430 100644 --- a/sp1-crates/program/src/state.rs +++ b/sp1-crates/program/src/state.rs @@ -2,48 +2,43 @@ // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md use caller_env::wavmio::WavmIo; -use caller_env::{ExecEnv, GuestPtr}; -use rand::RngCore; +use caller_env::GuestPtr; use wasmer::FunctionEnvMut; use crate::memory::Sp1MemAccess; use crate::replay::CustomEnvData; -/// Newtype wrapper to implement WavmIo and ExecEnv for CustomEnvData. -pub(crate) struct Sp1State<'a>(pub &'a mut CustomEnvData); - -impl WavmIo for Sp1State<'_> { +impl WavmIo for CustomEnvData { fn get_u64_global(&self, idx: usize) -> Option { - self.0.input().small_globals.get(idx).copied() + self.input().small_globals.get(idx).copied() } fn set_u64_global(&mut self, idx: usize, val: u64) -> bool { - let Some(g) = self.0.input_mut().small_globals.get_mut(idx) else { return false }; + let Some(g) = self.input_mut().small_globals.get_mut(idx) else { return false }; *g = val; true } fn get_bytes32_global(&self, idx: usize) -> Option<&[u8; 32]> { - self.0.input().large_globals.get(idx) + self.input().large_globals.get(idx) } fn set_bytes32_global(&mut self, idx: usize, val: [u8; 32]) -> bool { - let Some(g) = self.0.input_mut().large_globals.get_mut(idx) else { return false }; + let Some(g) = self.input_mut().large_globals.get_mut(idx) else { return false }; *g = val; true } fn get_sequencer_message(&self, num: u64) -> Option<&[u8]> { - self.0.input().sequencer_messages.get(&num).map(|v| v.as_slice()) + self.input().sequencer_messages.get(&num).map(|v| v.as_slice()) } fn get_delayed_message(&self, num: u64) -> Option<&[u8]> { - self.0.input().delayed_messages.get(&num).map(|v| v.as_slice()) + self.input().delayed_messages.get(&num).map(|v| v.as_slice()) } fn get_preimage(&self, preimage_type: u8, hash: &[u8; 32]) -> Option<&[u8]> { - self.0 - .input() + self.input() .preimages .get(&preimage_type) .and_then(|m| m.get(hash)) @@ -51,13 +46,13 @@ impl WavmIo for Sp1State<'_> { } } -/// Extracts (Sp1MemAccess, Sp1State) from a FunctionEnvMut in place. +/// Extracts (Sp1MemAccess, &mut CustomEnvData) from a FunctionEnvMut in place. pub(crate) fn sp1_env<'a>( ctx: &'a mut FunctionEnvMut<'_, CustomEnvData>, -) -> (Sp1MemAccess<'a>, Sp1State<'a>) { +) -> (Sp1MemAccess<'a>, &'a mut CustomEnvData) { let memory = ctx.data().memory.clone().unwrap(); let (data, store) = ctx.data_and_store_mut(); - (Sp1MemAccess { memory, store }, Sp1State(data)) + (Sp1MemAccess { memory, store }, data) } /// Converts a wasmer `Ptr` (WasmPtr) to a caller-env `GuestPtr`. From c517c11ac0f1dc459a772f97b55f49ccf42cf66a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Wed, 4 Mar 2026 14:21:49 +0100 Subject: [PATCH 070/189] fmt --- crates/caller-env/src/wavmio.rs | 13 +++---------- crates/jit/src/caller_env.rs | 8 ++++++-- crates/jit/src/wavmio.rs | 3 +-- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/crates/caller-env/src/wavmio.rs b/crates/caller-env/src/wavmio.rs index 2ba9855f7fc..ff065505057 100644 --- a/crates/caller-env/src/wavmio.rs +++ b/crates/caller-env/src/wavmio.rs @@ -2,8 +2,8 @@ // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md use crate::{GuestPtr, MemAccess}; -use alloc::string::String; use alloc::format; +use alloc::string::String; use core::cmp::min; /// Read validation inputs and set outputs for the `wavmio` host functions. @@ -46,10 +46,7 @@ pub fn set_global_state_bytes32( } /// Reads 8-bytes of global state. -pub fn get_global_state_u64( - io: &impl WavmIo, - idx: u32, -) -> Result { +pub fn get_global_state_u64(io: &impl WavmIo, idx: u32) -> Result { match io.get_u64_global(idx as usize) { Some(val) => Ok(val), None => Err("global read out of bounds in wavmio.getGlobalStateU64".into()), @@ -57,11 +54,7 @@ pub fn get_global_state_u64( } /// Writes 8-bytes of global state. -pub fn set_global_state_u64( - io: &mut impl WavmIo, - idx: u32, - val: u64, -) -> Result<(), String> { +pub fn set_global_state_u64(io: &mut impl WavmIo, idx: u32, val: u64) -> Result<(), String> { if !io.set_u64_global(idx as usize, val) { return Err("global write out of bounds in wavmio.setGlobalStateU64".into()); } diff --git a/crates/jit/src/caller_env.rs b/crates/jit/src/caller_env.rs index 1f9d0cac018..d6affc3253e 100644 --- a/crates/jit/src/caller_env.rs +++ b/crates/jit/src/caller_env.rs @@ -139,7 +139,9 @@ impl WavmIo for WasmEnv { } fn set_u64_global(&mut self, idx: usize, val: u64) -> bool { - let Some(g) = self.small_globals.get_mut(idx) else { return false }; + let Some(g) = self.small_globals.get_mut(idx) else { + return false; + }; *g = val; true } @@ -149,7 +151,9 @@ impl WavmIo for WasmEnv { } fn set_bytes32_global(&mut self, idx: usize, val: [u8; 32]) -> bool { - let Some(g) = self.large_globals.get_mut(idx) else { return false }; + let Some(g) = self.large_globals.get_mut(idx) else { + return false; + }; *g = val.into(); true } diff --git a/crates/jit/src/wavmio.rs b/crates/jit/src/wavmio.rs index 5aee97a9fed..f8c9b76326a 100644 --- a/crates/jit/src/wavmio.rs +++ b/crates/jit/src/wavmio.rs @@ -28,8 +28,7 @@ pub fn get_global_state_bytes32(mut env: WasmEnvMut, idx: u32, out_ptr: GuestPtr pub fn set_global_state_bytes32(mut env: WasmEnvMut, idx: u32, src_ptr: GuestPtr) -> MaybeEscape { let (mem, exec) = env.jit_env(); ready_hostio(exec)?; - caller_env::wavmio::set_global_state_bytes32(&mem, exec, idx, src_ptr) - .map_err(Escape::HostIO) + caller_env::wavmio::set_global_state_bytes32(&mem, exec, idx, src_ptr).map_err(Escape::HostIO) } /// Reads 8-bytes of global state From 4af3e19fa7a2dd73c753371dd6d7d7a9711606c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Thu, 5 Mar 2026 10:57:44 +0100 Subject: [PATCH 071/189] Add 0x prefix in wasi-stub --- sp1-crates/program/src/imports/wasi_stub.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sp1-crates/program/src/imports/wasi_stub.rs b/sp1-crates/program/src/imports/wasi_stub.rs index 18af7ff4c56..72af5b85c48 100644 --- a/sp1-crates/program/src/imports/wasi_stub.rs +++ b/sp1-crates/program/src/imports/wasi_stub.rs @@ -20,7 +20,7 @@ pub fn proc_exit(mut ctx: FunctionEnvMut, code: u32) { platform::print_string( 1, format!( - "Validation succeeds with hash {}", + "Validation succeeds with hash 0x{}", hex::encode(data.input().large_globals[0]) ) .as_bytes(), From 6c0e40cf6207451df76d1268b7790ce25219d45b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Thu, 5 Mar 2026 13:54:47 +0100 Subject: [PATCH 072/189] JIT: simplify wrap! macro a bit --- crates/jit/src/wasip1_stub.rs | 68 +++++++++++++++++------------------ 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/crates/jit/src/wasip1_stub.rs b/crates/jit/src/wasip1_stub.rs index 1f6005135f8..a5f7ed9a401 100644 --- a/crates/jit/src/wasip1_stub.rs +++ b/crates/jit/src/wasip1_stub.rs @@ -12,9 +12,9 @@ pub fn proc_exit(mut _env: WasmEnvMut, code: u32) -> Result<(), Escape> { } macro_rules! wrap { - ($(fn $func_name:ident ($($arg_name:ident : $arg_type:ty),* ) -> $return_type:ty);*) => { + ($(fn $func_name:ident ($($arg_name:ident : $arg_type:ty),* ));*) => { $( - pub fn $func_name(mut src: WasmEnvMut, $($arg_name : $arg_type),*) -> Result<$return_type, Escape> { + pub fn $func_name(mut src: WasmEnvMut, $($arg_name : $arg_type),*) -> Result { let (mut mem, wenv) = src.jit_env(); Ok(caller_env::wasip1_stub::$func_name(&mut mem, &mut JitExecEnv { wenv }, $($arg_name),*)) @@ -28,21 +28,21 @@ wrap! { clock_id: u32, precision: u64, time_ptr: GuestPtr - ) -> Errno; + ); - fn random_get(buf: GuestPtr, len: u32) -> Errno; + fn random_get(buf: GuestPtr, len: u32); - fn environ_get(a: GuestPtr, b: GuestPtr) -> Errno; - fn environ_sizes_get(length_ptr: GuestPtr, data_size_ptr: GuestPtr) -> Errno; + fn environ_get(a: GuestPtr, b: GuestPtr); + fn environ_sizes_get(length_ptr: GuestPtr, data_size_ptr: GuestPtr); - fn fd_read(a: u32, b: u32, c: u32, d: u32) -> Errno; - fn fd_close(fd: u32) -> Errno; + fn fd_read(a: u32, b: u32, c: u32, d: u32); + fn fd_close(fd: u32); fn fd_write( fd: u32, iovecs_ptr: GuestPtr, iovecs_len: u32, ret_ptr: GuestPtr - ) -> Errno; + ); fn fd_readdir( fd: u32, @@ -50,18 +50,18 @@ wrap! { b: u32, c: u64, d: u32 - ) -> Errno; + ); - fn fd_sync(a: u32) -> Errno; + fn fd_sync(a: u32); fn fd_seek( fd: u32, offset: u64, whence: u8, filesize: u32 - ) -> Errno; + ); - fn fd_datasync(_fd: u32) -> Errno; + fn fd_datasync(_fd: u32); fn path_open( a: u32, @@ -73,19 +73,19 @@ wrap! { g: u64, h: u32, i: u32 - ) -> Errno; + ); fn path_create_directory( a: u32, b: u32, c: u32 - ) -> Errno; + ); fn path_remove_directory( a: u32, b: u32, c: u32 - ) -> Errno; + ); fn path_readlink( a: u32, @@ -94,7 +94,7 @@ wrap! { d: u32, e: u32, f: u32 - ) -> Errno; + ); fn path_rename( a: u32, @@ -103,7 +103,7 @@ wrap! { d: u32, e: u32, f: u32 - ) -> Errno; + ); fn path_filestat_get( a: u32, @@ -111,15 +111,15 @@ wrap! { c: u32, d: u32, e: u32 - ) -> Errno; + ); - fn path_unlink_file(a: u32, b: u32, c: u32) -> Errno; + fn path_unlink_file(a: u32, b: u32, c: u32); - fn fd_prestat_get(a: u32, b: u32) -> Errno; - fn fd_prestat_dir_name(a: u32, b: u32, c: u32) -> Errno; + fn fd_prestat_get(a: u32, b: u32); + fn fd_prestat_dir_name(a: u32, b: u32, c: u32); - fn fd_filestat_get(fd: u32, _filestat: u32) -> Errno; - fn fd_filestat_set_size(fd: u32, size: u64) -> Errno; + fn fd_filestat_get(fd: u32, _filestat: u32); + fn fd_filestat_set_size(fd: u32, size: u64); fn fd_pread( fd: u32, @@ -127,7 +127,7 @@ wrap! { b: u32, c: u64, d: u32 - ) -> Errno; + ); fn fd_pwrite( fd: u32, @@ -135,22 +135,22 @@ wrap! { b: u32, c: u64, d: u32 - ) -> Errno; + ); - fn sock_accept(_fd: u32, a: u32, b: u32) -> Errno; - fn sock_shutdown(a: u32, b: u32) -> Errno; + fn sock_accept(_fd: u32, a: u32, b: u32); + fn sock_shutdown(a: u32, b: u32); - fn sched_yield() -> Errno; + fn sched_yield(); fn args_sizes_get( length_ptr: GuestPtr, data_size_ptr: GuestPtr - ) -> Errno; + ); - fn args_get(argv_buf: GuestPtr, data_buf: GuestPtr) -> Errno; + fn args_get(argv_buf: GuestPtr, data_buf: GuestPtr); - fn fd_fdstat_get(a: u32, b: u32) -> Errno; - fn fd_fdstat_set_flags(a: u32, b: u32) -> Errno; + fn fd_fdstat_get(a: u32, b: u32); + fn fd_fdstat_set_flags(a: u32, b: u32); // we always simulate a timeout fn poll_oneoff( @@ -158,5 +158,5 @@ wrap! { out_evt: GuestPtr, nsubscriptions: u32, nevents_ptr: GuestPtr - ) -> Errno + ) } From 45595f8ba2193c3913be5ad5f2cf50029878cf4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Thu, 5 Mar 2026 14:02:11 +0100 Subject: [PATCH 073/189] JIT: make wrap! macro work per function --- crates/jit/src/wasip1_stub.rs | 182 +++++++--------------------------- 1 file changed, 37 insertions(+), 145 deletions(-) diff --git a/crates/jit/src/wasip1_stub.rs b/crates/jit/src/wasip1_stub.rs index a5f7ed9a401..ed7dd68347a 100644 --- a/crates/jit/src/wasip1_stub.rs +++ b/crates/jit/src/wasip1_stub.rs @@ -12,151 +12,43 @@ pub fn proc_exit(mut _env: WasmEnvMut, code: u32) -> Result<(), Escape> { } macro_rules! wrap { - ($(fn $func_name:ident ($($arg_name:ident : $arg_type:ty),* ));*) => { - $( - pub fn $func_name(mut src: WasmEnvMut, $($arg_name : $arg_type),*) -> Result { - let (mut mem, wenv) = src.jit_env(); - - Ok(caller_env::wasip1_stub::$func_name(&mut mem, &mut JitExecEnv { wenv }, $($arg_name),*)) - } - )* + (fn $func_name:ident ($($arg_name:ident : $arg_type:ty),* $(,)?)) => { + pub fn $func_name(mut src: WasmEnvMut, $($arg_name : $arg_type),*) -> Result { + let (mut mem, wenv) = src.jit_env(); + Ok(caller_env::wasip1_stub::$func_name(&mut mem, &mut JitExecEnv { wenv }, $($arg_name),*)) + } }; } -wrap! { - fn clock_time_get( - clock_id: u32, - precision: u64, - time_ptr: GuestPtr - ); - - fn random_get(buf: GuestPtr, len: u32); - - fn environ_get(a: GuestPtr, b: GuestPtr); - fn environ_sizes_get(length_ptr: GuestPtr, data_size_ptr: GuestPtr); - - fn fd_read(a: u32, b: u32, c: u32, d: u32); - fn fd_close(fd: u32); - fn fd_write( - fd: u32, - iovecs_ptr: GuestPtr, - iovecs_len: u32, - ret_ptr: GuestPtr - ); - - fn fd_readdir( - fd: u32, - a: u32, - b: u32, - c: u64, - d: u32 - ); - - fn fd_sync(a: u32); - - fn fd_seek( - fd: u32, - offset: u64, - whence: u8, - filesize: u32 - ); - - fn fd_datasync(_fd: u32); - - fn path_open( - a: u32, - b: u32, - c: u32, - d: u32, - e: u32, - f: u64, - g: u64, - h: u32, - i: u32 - ); - - fn path_create_directory( - a: u32, - b: u32, - c: u32 - ); - - fn path_remove_directory( - a: u32, - b: u32, - c: u32 - ); - - fn path_readlink( - a: u32, - b: u32, - c: u32, - d: u32, - e: u32, - f: u32 - ); - - fn path_rename( - a: u32, - b: u32, - c: u32, - d: u32, - e: u32, - f: u32 - ); - - fn path_filestat_get( - a: u32, - b: u32, - c: u32, - d: u32, - e: u32 - ); - - fn path_unlink_file(a: u32, b: u32, c: u32); - - fn fd_prestat_get(a: u32, b: u32); - fn fd_prestat_dir_name(a: u32, b: u32, c: u32); - - fn fd_filestat_get(fd: u32, _filestat: u32); - fn fd_filestat_set_size(fd: u32, size: u64); - - fn fd_pread( - fd: u32, - a: u32, - b: u32, - c: u64, - d: u32 - ); - - fn fd_pwrite( - fd: u32, - a: u32, - b: u32, - c: u64, - d: u32 - ); - - fn sock_accept(_fd: u32, a: u32, b: u32); - fn sock_shutdown(a: u32, b: u32); - - fn sched_yield(); - - fn args_sizes_get( - length_ptr: GuestPtr, - data_size_ptr: GuestPtr - ); - - fn args_get(argv_buf: GuestPtr, data_buf: GuestPtr); - - fn fd_fdstat_get(a: u32, b: u32); - fn fd_fdstat_set_flags(a: u32, b: u32); - - // we always simulate a timeout - fn poll_oneoff( - in_subs: GuestPtr, - out_evt: GuestPtr, - nsubscriptions: u32, - nevents_ptr: GuestPtr - ) -} +wrap!(fn clock_time_get(clock_id: u32, precision: u64, time_ptr: GuestPtr)); +wrap!(fn random_get(buf: GuestPtr, len: u32)); +wrap!(fn environ_get(a: GuestPtr, b: GuestPtr)); +wrap!(fn environ_sizes_get(length_ptr: GuestPtr, data_size_ptr: GuestPtr)); +wrap!(fn fd_read(a: u32, b: u32, c: u32, d: u32)); +wrap!(fn fd_close(fd: u32)); +wrap!(fn fd_write(fd: u32, iovecs_ptr: GuestPtr, iovecs_len: u32, ret_ptr: GuestPtr)); +wrap!(fn fd_readdir(fd: u32, a: u32, b: u32, c: u64, d: u32)); +wrap!(fn fd_sync(a: u32)); +wrap!(fn fd_seek(fd: u32, offset: u64, whence: u8, filesize: u32)); +wrap!(fn fd_datasync(_fd: u32)); +wrap!(fn path_open(a: u32, b: u32, c: u32, d: u32, e: u32, f: u64, g: u64, h: u32, i: u32)); +wrap!(fn path_create_directory(a: u32, b: u32, c: u32)); +wrap!(fn path_remove_directory(a: u32, b: u32, c: u32)); +wrap!(fn path_readlink(a: u32, b: u32, c: u32, d: u32, e: u32, f: u32)); +wrap!(fn path_rename(a: u32, b: u32, c: u32, d: u32, e: u32, f: u32)); +wrap!(fn path_filestat_get(a: u32, b: u32, c: u32, d: u32, e: u32)); +wrap!(fn path_unlink_file(a: u32, b: u32, c: u32)); +wrap!(fn fd_prestat_get(a: u32, b: u32)); +wrap!(fn fd_prestat_dir_name(a: u32, b: u32, c: u32)); +wrap!(fn fd_filestat_get(fd: u32, _filestat: u32)); +wrap!(fn fd_filestat_set_size(fd: u32, size: u64)); +wrap!(fn fd_pread(fd: u32, a: u32, b: u32, c: u64, d: u32)); +wrap!(fn fd_pwrite(fd: u32, a: u32, b: u32, c: u64, d: u32)); +wrap!(fn sock_accept(_fd: u32, a: u32, b: u32)); +wrap!(fn sock_shutdown(a: u32, b: u32)); +wrap!(fn sched_yield()); +wrap!(fn args_sizes_get(length_ptr: GuestPtr, data_size_ptr: GuestPtr)); +wrap!(fn args_get(argv_buf: GuestPtr, data_buf: GuestPtr)); +wrap!(fn fd_fdstat_get(a: u32, b: u32)); +wrap!(fn fd_fdstat_set_flags(a: u32, b: u32)); +wrap!(fn poll_oneoff(in_subs: GuestPtr, out_evt: GuestPtr, nsubscriptions: u32, nevents_ptr: GuestPtr)); From fce70dc40b6c66c7c884de2bae85220b9ce5a60b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Thu, 5 Mar 2026 15:00:23 +0100 Subject: [PATCH 074/189] caller-env: make Errno inner field pub --- crates/caller-env/src/wasip1_stub.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/caller-env/src/wasip1_stub.rs b/crates/caller-env/src/wasip1_stub.rs index bc0b3b27422..37d36d2600b 100644 --- a/crates/caller-env/src/wasip1_stub.rs +++ b/crates/caller-env/src/wasip1_stub.rs @@ -10,7 +10,7 @@ use crate::{ExecEnv, GuestPtr, MemAccess}; #[repr(transparent)] -pub struct Errno(pub(crate) u16); +pub struct Errno(pub u16); pub const ERRNO_SUCCESS: Errno = Errno(0); pub const ERRNO_BADF: Errno = Errno(8); From 21ee8d2f82355bb938a52bcea9e2994358e5410f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Thu, 5 Mar 2026 15:13:09 +0100 Subject: [PATCH 075/189] Reuse codes from caller-env --- sp1-crates/program/src/imports/wasi_stub.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sp1-crates/program/src/imports/wasi_stub.rs b/sp1-crates/program/src/imports/wasi_stub.rs index 72af5b85c48..2f4d3fc749b 100644 --- a/sp1-crates/program/src/imports/wasi_stub.rs +++ b/sp1-crates/program/src/imports/wasi_stub.rs @@ -9,9 +9,9 @@ use wasmer::FunctionEnvMut; pub type Errno = u16; -pub const ERRNO_SUCCESS: Errno = 0; -pub const ERRNO_BADF: Errno = 8; -pub const ERRNO_INVAL: Errno = 28; +pub const ERRNO_SUCCESS: Errno = caller_env::wasip1_stub::ERRNO_SUCCESS.0; +pub const ERRNO_BADF: Errno = caller_env::wasip1_stub::ERRNO_BADF.0; +pub const ERRNO_INVAL: Errno = caller_env::wasip1_stub::ERRNO_INVAL.0; pub fn proc_exit(mut ctx: FunctionEnvMut, code: u32) { let (data, _store) = ctx.data_and_store_mut(); From a29d7e7411554f28297b430cb81ceac4cbd085ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Thu, 5 Mar 2026 15:15:27 +0100 Subject: [PATCH 076/189] impl ExecEnv for CustomEnvData --- sp1-crates/program/src/state.rs | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/sp1-crates/program/src/state.rs b/sp1-crates/program/src/state.rs index 0a4401cd430..b08fbf92e7d 100644 --- a/sp1-crates/program/src/state.rs +++ b/sp1-crates/program/src/state.rs @@ -2,12 +2,31 @@ // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md use caller_env::wavmio::WavmIo; -use caller_env::GuestPtr; +use caller_env::{ExecEnv, GuestPtr}; +use rand::RngCore; use wasmer::FunctionEnvMut; use crate::memory::Sp1MemAccess; use crate::replay::CustomEnvData; +impl ExecEnv for CustomEnvData { + fn advance_time(&mut self, ns: u64) { + self.time += ns; + } + + fn get_time(&self) -> u64 { + self.time + } + + fn next_rand_u32(&mut self) -> u32 { + self.pcg.next_u32() + } + + fn print_string(&mut self, bytes: &[u8]) { + crate::platform::print_string(1, bytes); + } +} + impl WavmIo for CustomEnvData { fn get_u64_global(&self, idx: usize) -> Option { self.input().small_globals.get(idx).copied() From dfbab75135d497bf3634b345ea0ac13563432521 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Thu, 5 Mar 2026 15:25:35 +0100 Subject: [PATCH 077/189] SP1: delegate implementation to caller-env with a wrap macro --- sp1-crates/program/src/imports/wasi_stub.rs | 362 +++----------------- 1 file changed, 44 insertions(+), 318 deletions(-) diff --git a/sp1-crates/program/src/imports/wasi_stub.rs b/sp1-crates/program/src/imports/wasi_stub.rs index 2f4d3fc749b..88deb09c0ef 100644 --- a/sp1-crates/program/src/imports/wasi_stub.rs +++ b/sp1-crates/program/src/imports/wasi_stub.rs @@ -1,18 +1,8 @@ -//! WASI stubs -//! -//! The code used here is heavily borrowed from nitro's own WASI stubs: -//! https://github.com/OffchainLabs/nitro/blob/c858ed93a5a4fd81908277d94fb72974058a3615/arbitrator/caller-env/src/wasip1_stub.rs +//! WASI stubs — thin wrappers delegating to caller_env::wasip1_stub. -use crate::{Escape, Ptr, platform, read_slice, replay::CustomEnvData}; -use rand::RngCore; +use crate::{Ptr, platform, replay::CustomEnvData, state::{gp, sp1_env}}; use wasmer::FunctionEnvMut; -pub type Errno = u16; - -pub const ERRNO_SUCCESS: Errno = caller_env::wasip1_stub::ERRNO_SUCCESS.0; -pub const ERRNO_BADF: Errno = caller_env::wasip1_stub::ERRNO_BADF.0; -pub const ERRNO_INVAL: Errno = caller_env::wasip1_stub::ERRNO_INVAL.0; - pub fn proc_exit(mut ctx: FunctionEnvMut, code: u32) { let (data, _store) = ctx.data_and_store_mut(); @@ -30,310 +20,46 @@ pub fn proc_exit(mut ctx: FunctionEnvMut, code: u32) { platform::exit(code); } -pub fn args_sizes_get( - mut ctx: FunctionEnvMut, - argc: Ptr, - argv_buf_size: Ptr, -) -> Result { - let (data, store) = ctx.data_and_store_mut(); - let memory = data.memory.clone().unwrap().view(&store); - - argc.write(&memory, 1)?; - argv_buf_size.write(&memory, 4)?; - - Ok(ERRNO_SUCCESS) -} - -pub fn args_get( - mut ctx: FunctionEnvMut, - argv_buf: Ptr, - data_buf: Ptr, -) -> Result { - let (data, store) = ctx.data_and_store_mut(); - let memory = data.memory.clone().unwrap().view(&store); - - let data_buf = data_buf.deref(&memory); - - argv_buf.write(&memory, data_buf.offset() as u32)?; - data_buf.write(0x6E6962)?; // "bin\0" - - Ok(ERRNO_SUCCESS) -} - -pub fn environ_sizes_get( - mut ctx: FunctionEnvMut, - length_ptr: Ptr, - data_size_ptr: Ptr, -) -> Result { - let (data, store) = ctx.data_and_store_mut(); - let memory = data.memory.clone().unwrap().view(&store); - - length_ptr.write(&memory, 0)?; - data_size_ptr.write(&memory, 0)?; - - Ok(ERRNO_SUCCESS) -} - -pub fn environ_get(_ctx: FunctionEnvMut, _: Ptr, _: Ptr) -> Errno { - ERRNO_SUCCESS -} - -pub fn fd_write( - mut ctx: FunctionEnvMut, - fd: u32, - iovecs_ptr: Ptr, - iovecs_len: u32, - ret_ptr: Ptr, -) -> Result { - if fd != 1 && fd != 2 { - return Ok(ERRNO_BADF); - } - - let (data, store) = ctx.data_and_store_mut(); - let memory = data.memory.clone().unwrap().view(&store); - - let mut size = 0; - for i in 0..iovecs_len { - let ptr = iovecs_ptr.add_offset((i * 2).into()).unwrap(); - let len = ptr.add_offset(1).unwrap().read(&memory)?; - let ptr = Ptr::new(ptr.read(&memory)?); - let data = read_slice(ptr, len as usize, &memory)?; - - platform::print_string(fd, &data); - - size += len; - } - - ret_ptr.write(&memory, size)?; - Ok(ERRNO_SUCCESS) -} - -pub fn fd_close(_ctx: FunctionEnvMut, _fd: u32) -> Errno { - ERRNO_BADF -} - -pub fn fd_read(_ctx: FunctionEnvMut, _: u32, _: u32, _: u32, _: u32) -> Errno { - ERRNO_BADF -} - -pub fn fd_readdir( - _ctx: FunctionEnvMut, - _fd: u32, - _: u32, - _: u32, - _: u64, - _: u32, -) -> Errno { - ERRNO_BADF -} - -pub fn fd_sync(_ctx: FunctionEnvMut, _: u32) -> Errno { - ERRNO_SUCCESS -} - -pub fn fd_seek(_ctx: FunctionEnvMut, _: u32, _: u64, _: u32, _: u32) -> Errno { - ERRNO_BADF -} - -pub fn fd_datasync(_ctx: FunctionEnvMut, _: u32) -> Errno { - ERRNO_BADF -} - -pub fn fd_prestat_get(_ctx: FunctionEnvMut, _: u32, _: u32) -> Errno { - ERRNO_BADF -} - -pub fn fd_prestat_dir_name(_ctx: FunctionEnvMut, _: u32, _: u32, _: u32) -> Errno { - ERRNO_BADF -} - -pub fn fd_filestat_get(_ctx: FunctionEnvMut, _: u32, _: u32) -> Errno { - ERRNO_BADF -} - -pub fn fd_filestat_set_size(_ctx: FunctionEnvMut, _: u32, _: u64) -> Errno { - ERRNO_BADF -} - -pub fn fd_pread( - _ctx: FunctionEnvMut, - _fd: u32, - _: u32, - _: u32, - _: u64, - _: u32, -) -> Errno { - ERRNO_BADF -} - -pub fn fd_pwrite( - _ctx: FunctionEnvMut, - _fd: u32, - _: u32, - _: u32, - _: u64, - _: u32, -) -> Errno { - ERRNO_BADF -} - -pub fn fd_fdstat_get(_ctx: FunctionEnvMut, _: u32, _: u32) -> Errno { - ERRNO_INVAL -} - -pub fn fd_fdstat_set_flags(_ctx: FunctionEnvMut, _: u32, _: u32) -> Errno { - ERRNO_INVAL -} - -const TIME_INTERVAL: u64 = 10_000_000; - -pub fn clock_time_get( - mut ctx: FunctionEnvMut, - _clock_id: u32, - _precision: u64, - time_ptr: Ptr, -) -> Result { - let (data, store) = ctx.data_and_store_mut(); - let memory = data.memory.clone().unwrap().view(&store); - - data.time += TIME_INTERVAL; - time_ptr.cast::().write(&memory, data.time)?; - - Ok(ERRNO_SUCCESS) -} - -pub fn random_get( - mut ctx: FunctionEnvMut, - mut buf: Ptr, - mut len: u32, -) -> Result { - let (data, store) = ctx.data_and_store_mut(); - let memory = data.memory.clone().unwrap().view(&store); - - while len >= 4 { - let next_rand = data.pcg.next_u32(); - buf.write(&memory, next_rand)?; - buf = buf.add_offset(1).unwrap(); - len -= 4; - } - if len > 0 { - let mut rem = data.pcg.next_u32(); - let mut buf = buf.cast::(); - - for _ in 0..len { - buf.write(&memory, rem as u8)?; - buf = buf.add_offset(1).unwrap(); - rem >>= 8; - } - } - Ok(ERRNO_SUCCESS) -} - -pub fn poll_oneoff( - mut ctx: FunctionEnvMut, - in_subs: Ptr, - out_evt: Ptr, - num_subscriptions: u32, - num_events_ptr: Ptr, -) -> Result { - let (data, store) = ctx.data_and_store_mut(); - let memory = data.memory.clone().unwrap().view(&store); - - data.time += TIME_INTERVAL; - - const SUBSCRIPTION_SIZE: u32 = 48; - for index in 0..num_subscriptions { - let subs_base = in_subs - .cast::() - .add_offset(SUBSCRIPTION_SIZE * index) - .unwrap(); - let subs_type = subs_base - .add_offset(8) - .unwrap() - .cast::() - .read(&memory)?; - if subs_type != 0 { - continue; +macro_rules! wrap { + (fn $name:ident($($arg:ident: $ty:tt),* $(,)?)) => { + pub fn $name(mut src: FunctionEnvMut, $($arg: $ty),*) -> u16 { + let (mut mem, state) = sp1_env(&mut src); + caller_env::wasip1_stub::$name(&mut mem, state, $(wrap!(@conv $arg $ty)),*).0 } - let user_data = subs_base.cast::().read(&memory)?; - out_evt.write(&memory, user_data)?; - out_evt.add_offset(2).unwrap().write(&memory, subs_type)?; - num_events_ptr.write(&memory, 1)?; - return Ok(ERRNO_SUCCESS); - } - Ok(ERRNO_INVAL) -} - -pub fn sched_yield(_ctx: FunctionEnvMut) -> Errno { - ERRNO_SUCCESS -} - -pub fn path_open( - _ctx: FunctionEnvMut, - _: u32, - _: u32, - _: u32, - _: u32, - _: u32, - _: u64, - _: u64, - _: u32, - _: u32, -) -> Errno { - ERRNO_BADF -} - -pub fn path_create_directory(_ctx: FunctionEnvMut, _: u32, _: u32, _: u32) -> Errno { - ERRNO_BADF -} - -pub fn path_remove_directory(_ctx: FunctionEnvMut, _: u32, _: u32, _: u32) -> Errno { - ERRNO_BADF -} - -pub fn path_readlink( - _ctx: FunctionEnvMut, - _: u32, - _: u32, - _: u32, - _: u32, - _: u32, - _: u32, -) -> Errno { - ERRNO_BADF -} - -pub fn path_rename( - _ctx: FunctionEnvMut, - _: u32, - _: u32, - _: u32, - _: u32, - _: u32, - _: u32, -) -> Errno { - ERRNO_BADF -} - -pub fn path_filestat_get( - _ctx: FunctionEnvMut, - _: u32, - _: u32, - _: u32, - _: u32, - _: u32, -) -> Errno { - ERRNO_BADF -} - -pub fn path_unlink_file(_ctx: FunctionEnvMut, _: u32, _: u32, _: u32) -> Errno { - ERRNO_BADF -} - -pub fn sock_accept(_ctx: FunctionEnvMut, _: u32, _: u32, _: u32) -> Errno { - ERRNO_BADF -} - -pub fn sock_shutdown(_ctx: FunctionEnvMut, _: u32, _: u32) -> Errno { - ERRNO_BADF -} + }; + (@conv $arg:ident Ptr) => { gp($arg) }; + (@conv $arg:ident $ty:tt) => { $arg }; +} + +wrap!(fn clock_time_get(_clock_id: u32, _precision: u64, time_ptr: Ptr)); +wrap!(fn random_get(buf: Ptr, len: u32)); +wrap!(fn environ_get(a: Ptr, b: Ptr)); +wrap!(fn environ_sizes_get(length_ptr: Ptr, data_size_ptr: Ptr)); +wrap!(fn fd_read(a: u32, b: u32, c: u32, d: u32)); +wrap!(fn fd_close(fd: u32)); +wrap!(fn fd_write(fd: u32, iovecs_ptr: Ptr, iovecs_len: u32, ret_ptr: Ptr)); +wrap!(fn fd_readdir(fd: u32, a: u32, b: u32, c: u64, d: u32)); +wrap!(fn fd_sync(a: u32)); +wrap!(fn fd_seek(fd: u32, offset: u64, whence: u8, filesize: u32)); +wrap!(fn fd_datasync(_fd: u32)); +wrap!(fn path_open(a: u32, b: u32, c: u32, d: u32, e: u32, f: u64, g: u64, h: u32, i: u32)); +wrap!(fn path_create_directory(a: u32, b: u32, c: u32)); +wrap!(fn path_remove_directory(a: u32, b: u32, c: u32)); +wrap!(fn path_readlink(a: u32, b: u32, c: u32, d: u32, e: u32, f: u32)); +wrap!(fn path_rename(a: u32, b: u32, c: u32, d: u32, e: u32, f: u32)); +wrap!(fn path_filestat_get(a: u32, b: u32, c: u32, d: u32, e: u32)); +wrap!(fn path_unlink_file(a: u32, b: u32, c: u32)); +wrap!(fn fd_prestat_get(a: u32, b: u32)); +wrap!(fn fd_prestat_dir_name(a: u32, b: u32, c: u32)); +wrap!(fn fd_filestat_get(fd: u32, _filestat: u32)); +wrap!(fn fd_filestat_set_size(fd: u32, size: u64)); +wrap!(fn fd_pread(fd: u32, a: u32, b: u32, c: u64, d: u32)); +wrap!(fn fd_pwrite(fd: u32, a: u32, b: u32, c: u64, d: u32)); +wrap!(fn sock_accept(_fd: u32, a: u32, b: u32)); +wrap!(fn sock_shutdown(a: u32, b: u32)); +wrap!(fn sched_yield()); +wrap!(fn args_sizes_get(length_ptr: Ptr, data_size_ptr: Ptr)); +wrap!(fn args_get(argv_buf: Ptr, data_buf: Ptr)); +wrap!(fn fd_fdstat_get(a: u32, b: u32)); +wrap!(fn fd_fdstat_set_flags(a: u32, b: u32)); +wrap!(fn poll_oneoff(in_subs: Ptr, out_evt: Ptr, nsubscriptions: u32, nevents_ptr: Ptr)); From 9f17964054f09923435516d5da6c2b6520262d14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 10 Mar 2026 10:41:01 +0100 Subject: [PATCH 078/189] Remove external brotli fork dependency. Reuse caller-env implementation in SP1 --- sp1-crates/Cargo.lock | 33 +------ sp1-crates/Cargo.toml | 2 +- sp1-crates/program/src/imports/arbcompress.rs | 91 ++++++------------- 3 files changed, 33 insertions(+), 93 deletions(-) diff --git a/sp1-crates/Cargo.lock b/sp1-crates/Cargo.lock index 5d5cab059e2..e7cd66213e9 100644 --- a/sp1-crates/Cargo.lock +++ b/sp1-crates/Cargo.lock @@ -49,21 +49,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "alloc-no-stdlib" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" - -[[package]] -name = "alloc-stdlib" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" -dependencies = [ - "alloc-no-stdlib", -] - [[package]] name = "allocator-api2" version = "0.2.21" @@ -519,22 +504,10 @@ dependencies = [ [[package]] name = "brotli" -version = "8.0.1" -source = "git+https://github.com/wakabat/rust-brotli?rev=37b6403#37b6403c1075625e15b9355bcedf8b20232bc6c2" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", - "brotli-decompressor", -] - -[[package]] -name = "brotli-decompressor" -version = "5.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03" +version = "0.1.0" dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", + "lazy_static", + "num_enum 0.7.5", ] [[package]] diff --git a/sp1-crates/Cargo.toml b/sp1-crates/Cargo.toml index 65e03a6b05b..48c85c7d6e3 100644 --- a/sp1-crates/Cargo.toml +++ b/sp1-crates/Cargo.toml @@ -5,6 +5,7 @@ members = ["program", "builder", "stylus-compiler-program", "prover", "runner"] [workspace.dependencies] arbutil = { path = "../crates/arbutil" } +brotli = { path = "../crates/brotli" } caller-env = { path = "../crates/caller-env", default-features = false } prover = { path = "prover", default-features = false, features = ["sp1"] } validation = { path = "../crates/validation", default-features = false } @@ -41,7 +42,6 @@ tokio = { version = "1.42.0" } tracing = { version = "0.1.40" } wasmparser = { version = "0.224.0" } -brotli = { git = "https://github.com/wakabat/rust-brotli", rev = "37b6403" } secp256k1 = { git = "https://github.com/sp1-patches/rust-secp256k1", tag = "patch-0.29.1-sp1-6.0.0", features = ["recovery", "global-context"] } tiny-keccak = { git = "https://github.com/sp1-patches/tiny-keccak", tag = "patch-2.0.2-sp1-6.0.0", features = ["keccak"] } wasmer = { git = "https://github.com/wakabat/official-wasmer", rev = "e065880", default-features = false, features = ["sys", "compiler", "singlepass", "wasmparser"] } diff --git a/sp1-crates/program/src/imports/arbcompress.rs b/sp1-crates/program/src/imports/arbcompress.rs index e81d5bc5696..de569a41710 100644 --- a/sp1-crates/program/src/imports/arbcompress.rs +++ b/sp1-crates/program/src/imports/arbcompress.rs @@ -1,21 +1,10 @@ //! This module implements arbcompression functions required by Arbitrum. -//! It is based on: -//! https://github.com/OffchainLabs/nitro/blob/d2dba175c037c47e68cf3038f0d4b06b54983644/arbitrator/caller-env/src/brotli/mod.rs -//! But a pure Rust brotli implementation is used instead of the C++ FFI one. -//! We have verified (in a small scale) that the 2 brotli implementations generate -//! the same bytes in both compression and decompression. -use crate::{Escape, Ptr, read_slice, replay::CustomEnvData}; -use brotli::{Allocator, CompressorWriter, Decompressor, HeapAlloc, SliceWrapperMut}; -use std::io::{Cursor, Read, Write}; +use crate::state::{gp, sp1_env}; +use crate::{Escape, Ptr, replay::CustomEnvData}; +use brotli::Dictionary; use wasmer::FunctionEnvMut; -const STYLUS_DICTIONARY: &[u8] = - include_bytes!("../../../../crates/brotli/src/dicts/stylus-program-11.lz"); - -// Following Arbitrum's convention -pub const BROTLI_SUCCESS: u32 = 1; - pub fn brotli_compress( mut ctx: FunctionEnvMut, in_buf_ptr: Ptr, @@ -26,27 +15,20 @@ pub fn brotli_compress( window_size: u32, dictionary: u8, ) -> Result { - let (data, store) = ctx.data_and_store_mut(); - let memory = data.memory.clone().unwrap().view(&store); - - let input = read_slice(in_buf_ptr, in_buf_len as usize, &memory)?; - let mut output = vec![]; - { - let mut writer = CompressorWriter::new(&mut output, 4096, level, window_size); - match dictionary { - 0 => (), // Empty dictionary - 1 => writer.set_custom_dictionary(STYLUS_DICTIONARY), - _ => panic!("Unknown dictionary value: {dictionary}"), - } - writer.write_all(&input)?; - } - let out_len = out_len_ptr.read(&memory)?; - assert!(output.len() <= out_len as usize); - - memory.write(out_buf_ptr.offset() as u64, &output)?; - out_len_ptr.write(&memory, output.len() as u32)?; - - Ok(BROTLI_SUCCESS) + let (mut mem, state) = sp1_env(&mut ctx); + let dictionary = Dictionary::try_from(dictionary).expect("unknown dictionary"); + Ok(caller_env::brotli::brotli_compress( + &mut mem, + state, + gp(in_buf_ptr), + in_buf_len, + gp(out_buf_ptr), + gp(out_len_ptr), + level, + window_size, + dictionary, + ) + .into()) } pub fn brotli_decompress( @@ -57,31 +39,16 @@ pub fn brotli_decompress( out_len_ptr: Ptr, dictionary: u8, ) -> Result { - // Keep the allocator alive for the duration of this method - let mut allocator = HeapAlloc::default(); - - let (data, store) = ctx.data_and_store_mut(); - let memory = data.memory.clone().unwrap().view(&store); - - let input = read_slice(in_buf_ptr, in_buf_len as usize, &memory)?; - let mut decompressor = match dictionary { - 0 => Decompressor::new(Cursor::new(input), 4096), - 1 => { - // This is slow(requires copying for every operation), but it might work now. - let mut buffer = allocator.alloc_cell(STYLUS_DICTIONARY.len()); - buffer.slice_mut().copy_from_slice(STYLUS_DICTIONARY); - Decompressor::new_with_custom_dict(Cursor::new(input), 4096, buffer) - } - _ => panic!("Unknown dictionary value: {dictionary}"), - }; - let mut output = vec![]; - decompressor.read_to_end(&mut output)?; - - let out_len = out_len_ptr.read(&memory)?; - assert!(output.len() <= out_len as usize); - - memory.write(out_buf_ptr.offset() as u64, &output)?; - out_len_ptr.write(&memory, output.len() as u32)?; - - Ok(BROTLI_SUCCESS) + let (mut mem, state) = sp1_env(&mut ctx); + let dictionary = Dictionary::try_from(dictionary).expect("unknown dictionary"); + Ok(caller_env::brotli::brotli_decompress( + &mut mem, + state, + gp(in_buf_ptr), + in_buf_len, + gp(out_buf_ptr), + gp(out_len_ptr), + dictionary, + ) + .into()) } From 5d4e165a886261308c908cc1a3b46745d4a111ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 10 Mar 2026 10:49:11 +0100 Subject: [PATCH 079/189] Avoid direct dependency in program --- sp1-crates/Cargo.lock | 1 - sp1-crates/program/Cargo.toml | 3 +-- sp1-crates/program/src/imports/arbcompress.rs | 7 ++----- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/sp1-crates/Cargo.lock b/sp1-crates/Cargo.lock index e7cd66213e9..90a197e8e65 100644 --- a/sp1-crates/Cargo.lock +++ b/sp1-crates/Cargo.lock @@ -3753,7 +3753,6 @@ name = "program" version = "0.1.0" dependencies = [ "arbutil", - "brotli", "bytes", "caller-env", "corosensei", diff --git a/sp1-crates/program/Cargo.toml b/sp1-crates/program/Cargo.toml index fa012b4803e..67986bba44a 100644 --- a/sp1-crates/program/Cargo.toml +++ b/sp1-crates/program/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" edition = "2024" [dependencies] -caller-env = { workspace = true } +caller-env = { workspace = true, features = ["brotli"] } sp1-zkvm = { workspace = true } wasmer = { workspace = true } wasmer-types = { workspace = true } @@ -13,7 +13,6 @@ wasmer-vm = { workspace = true } prover = { workspace = true, features = ["native"] } arbutil = { workspace = true } -brotli = { workspace = true } bytes = { workspace = true } corosensei = { workspace = true } eyre = { workspace = true } diff --git a/sp1-crates/program/src/imports/arbcompress.rs b/sp1-crates/program/src/imports/arbcompress.rs index de569a41710..72df26db46f 100644 --- a/sp1-crates/program/src/imports/arbcompress.rs +++ b/sp1-crates/program/src/imports/arbcompress.rs @@ -2,7 +2,6 @@ use crate::state::{gp, sp1_env}; use crate::{Escape, Ptr, replay::CustomEnvData}; -use brotli::Dictionary; use wasmer::FunctionEnvMut; pub fn brotli_compress( @@ -16,7 +15,6 @@ pub fn brotli_compress( dictionary: u8, ) -> Result { let (mut mem, state) = sp1_env(&mut ctx); - let dictionary = Dictionary::try_from(dictionary).expect("unknown dictionary"); Ok(caller_env::brotli::brotli_compress( &mut mem, state, @@ -26,7 +24,7 @@ pub fn brotli_compress( gp(out_len_ptr), level, window_size, - dictionary, + dictionary.try_into().expect("unknown dictionary"), ) .into()) } @@ -40,7 +38,6 @@ pub fn brotli_decompress( dictionary: u8, ) -> Result { let (mut mem, state) = sp1_env(&mut ctx); - let dictionary = Dictionary::try_from(dictionary).expect("unknown dictionary"); Ok(caller_env::brotli::brotli_decompress( &mut mem, state, @@ -48,7 +45,7 @@ pub fn brotli_decompress( in_buf_len, gp(out_buf_ptr), gp(out_len_ptr), - dictionary, + dictionary.try_into().expect("unknown dictionary"), ) .into()) } From 3143fa97568cd3fa648e0e552fa3c39fcd1e6807 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 10 Mar 2026 11:04:57 +0100 Subject: [PATCH 080/189] Remove `decompress-user-wasm` feature in validation - decompress user wasm unconditionally --- crates/validation/Cargo.toml | 6 +----- crates/validation/src/lib.rs | 15 +++------------ sp1-crates/Cargo.lock | 2 ++ sp1-crates/prover/src/binary_input.rs | 12 +----------- 4 files changed, 7 insertions(+), 28 deletions(-) diff --git a/crates/validation/Cargo.toml b/crates/validation/Cargo.toml index a7518ef05e4..01890c463b1 100644 --- a/crates/validation/Cargo.toml +++ b/crates/validation/Cargo.toml @@ -11,11 +11,7 @@ rust-version.workspace = true [dependencies] arbutil = { workspace = true } -brotli = { workspace = true, optional = true } +brotli = { workspace = true } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } serde_with = { workspace = true, features = ["base64"] } - -[features] -default = ["decompress-user-wasm"] -decompress-user-wasm = ["brotli"] diff --git a/crates/validation/src/lib.rs b/crates/validation/src/lib.rs index 7d0a08b83cd..fe0b312f219 100644 --- a/crates/validation/src/lib.rs +++ b/crates/validation/src/lib.rs @@ -48,13 +48,9 @@ pub struct BatchInfo { pub data: Vec, } -/// `UserWasm` is a wrapper around `Vec` +/// `UserWasm` is a wrapper around `Vec`. It contains `brotli`-decompressed wasm module. /// -/// If the `decompress-user-wasm` feature is on, it contains `brotli`-decompressed wasm module. -/// Otherwise, it contains the compressed wasm module as-is, and the caller is responsible for decompressing it before use. -/// -/// Note: The wrapped `Vec` is already `Base64` decoded before -/// `from(Vec)` is called by `serde`. +/// Note: The wrapped `Vec` is already `Base64` decoded before `from(Vec)` is called by `serde`. #[derive(Clone, Debug, PartialEq, Eq)] pub struct UserWasm(Vec); @@ -72,15 +68,10 @@ impl AsRef<[u8]> for UserWasm { } impl TryFrom> for UserWasm { - #[cfg(feature = "decompress-user-wasm")] type Error = brotli::BrotliStatus; - #[cfg(not(feature = "decompress-user-wasm"))] - type Error = (); fn try_from(data: Vec) -> Result { - #[cfg(feature = "decompress-user-wasm")] - let data = brotli::decompress(&data, brotli::Dictionary::Empty)?; - Ok(Self(data)) + Ok(Self(brotli::decompress(&data, brotli::Dictionary::Empty)?)) } } diff --git a/sp1-crates/Cargo.lock b/sp1-crates/Cargo.lock index 90a197e8e65..1af7e5364f7 100644 --- a/sp1-crates/Cargo.lock +++ b/sp1-crates/Cargo.lock @@ -581,6 +581,7 @@ checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" name = "caller-env" version = "0.1.0" dependencies = [ + "brotli", "hex", "k256 0.13.4 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.8.5", @@ -6734,6 +6735,7 @@ name = "validation" version = "0.1.0" dependencies = [ "arbutil", + "brotli", "serde", "serde_json", "serde_with", diff --git a/sp1-crates/prover/src/binary_input.rs b/sp1-crates/prover/src/binary_input.rs index e321910b62e..c5b6d3d1e67 100644 --- a/sp1-crates/prover/src/binary_input.rs +++ b/sp1-crates/prover/src/binary_input.rs @@ -23,22 +23,12 @@ pub struct Input { // SP1 has additional alignment requirements, we have to decompress the data // into aligned bytes pub fn decompress_aligned(user_wasm: &UserWasm) -> ModuleAsm { - // brotli-decompress the data first, since the `validation.decompress_user_wasm` feature is not - // enabled - C-binded brotli used in `validation` is not supported in SP1. - let data = { - let mut decompressor = - brotli::Decompressor::new(std::io::Cursor::new(user_wasm.as_vec()), 4096); - let mut result = vec![]; - decompressor - .read_to_end(&mut result) - .expect("decompressing"); - result - }; // This is less ideal but until one of the following happens, we // will have to stick with it: // * Allocator allocates aligned memory // * Bytes add alignment options // * Wasmer's Module does not simply accept `IntoBytes` trait. + let data = user_wasm.as_vec(); let mut buffer = BytesMut::zeroed(data.len() + 7); let p = buffer.as_ptr() as usize; let aligned_p = (p + 7) / 8 * 8; From a1a3e9d346bc611f2be49f192ded52f482d24d6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 10 Mar 2026 11:11:34 +0100 Subject: [PATCH 081/189] Add CMake patch for brotli. Add new steps to the build.sh --- sp1-crates/brotli_cmake_patch.txt | 438 ++++++++++++++++++++++++++++++ sp1-crates/build.sh | 32 +++ 2 files changed, 470 insertions(+) create mode 100644 sp1-crates/brotli_cmake_patch.txt diff --git a/sp1-crates/brotli_cmake_patch.txt b/sp1-crates/brotli_cmake_patch.txt new file mode 100644 index 00000000000..f23c882cc9f --- /dev/null +++ b/sp1-crates/brotli_cmake_patch.txt @@ -0,0 +1,438 @@ +# Ubuntu 12.04 LTS has CMake 2.8.7, and is an important target since +# several CI services, such as Travis and Drone, use it. Solaris 11 +# has 2.8.6, and it's not difficult to support if you already have to +# support 2.8.7. +cmake_minimum_required(VERSION 2.8.6) + +# Since this project's version is loaded from other files, this policy +# will help suppress the warning generated by cmake. +# This policy is set because we can't provide "VERSION" in "project" command. +# Use `cmake --help-policy CMP0048` for more information. +cmake_policy(SET CMP0048 NEW) +project(brotli C) + +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + message(STATUS "Setting build type to Release as none was specified.") + set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build." FORCE) +else() + message(STATUS "Build type is '${CMAKE_BUILD_TYPE}'") +endif() + +include(CheckCSourceCompiles) +check_c_source_compiles( + "#if defined(__EMSCRIPTEN__) + int main() {return 0;} + #endif" + BROTLI_EMSCRIPTEN +) +if (BROTLI_EMSCRIPTEN) + message("-- Compiler is EMSCRIPTEN") +else() + message("-- Compiler is not EMSCRIPTEN") +endif() + +check_c_source_compiles( + "#if defined(__riscv) + int main() {return 0;} + #endif" + BROTLI_RISCV +) +if (BROTLI_RISCV) + message("-- Compiler is RISC-V") +endif() + +# If Brotli is being bundled in another project, we don't want to +# install anything. However, we want to let people override this, so +# we'll use the BROTLI_BUNDLED_MODE variable to let them do that; just +# set it to OFF in your project before you add_subdirectory(brotli). +get_directory_property(BROTLI_PARENT_DIRECTORY PARENT_DIRECTORY) +if(NOT DEFINED BROTLI_BUNDLED_MODE) + # Bundled mode hasn't been set one way or the other, set the default + # depending on whether or not we are the top-level project. + if(BROTLI_PARENT_DIRECTORY) + set(BROTLI_BUNDLED_MODE ON) + else() + set(BROTLI_BUNDLED_MODE OFF) + endif() +endif() +mark_as_advanced(BROTLI_BUNDLED_MODE) + +include(GNUInstallDirs) + +# Parse version information from common/version.h. Normally we would +# define these values here and write them out to configuration file(s) +# (i.e., config.h), but in this case we parse them from +# common/version.h to be less intrusive. +function(hex_to_dec HEXADECIMAL DECIMAL) + string(TOUPPER "${HEXADECIMAL}" _tail) + set(_decimal 0) + string(LENGTH "${_tail}" _tail_length) + while (_tail_length GREATER 0) + math(EXPR _decimal "${_decimal} * 16") + string(SUBSTRING "${_tail}" 0 1 _digit) + string(SUBSTRING "${_tail}" 1 -1 _tail) + if (_digit STREQUAL "A") + math(EXPR _decimal "${_decimal} + 10") + elseif (_digit STREQUAL "B") + math(EXPR _decimal "${_decimal} + 11") + elseif (_digit STREQUAL "C") + math(EXPR _decimal "${_decimal} + 12") + elseif (_digit STREQUAL "D") + math(EXPR _decimal "${_decimal} + 13") + elseif (_digit STREQUAL "E") + math(EXPR _decimal "${_decimal} + 14") + elseif (_digit STREQUAL "F") + math(EXPR _decimal "${_decimal} + 15") + else() + math(EXPR _decimal "${_decimal} + ${_digit}") + endif() + string(LENGTH "${_tail}" _tail_length) + endwhile() + set(${DECIMAL} ${_decimal} PARENT_SCOPE) +endfunction(hex_to_dec) + +# Version information +file(STRINGS "c/common/version.h" _brotli_version_line REGEX "^#define BROTLI_VERSION (0x[0-9a-fA-F]+)$") +string(REGEX REPLACE "^#define BROTLI_VERSION 0x([0-9a-fA-F]+)$" "\\1" _brotli_version_hex "${_brotli_version_line}") +hex_to_dec("${_brotli_version_hex}" _brotli_version) +math(EXPR BROTLI_VERSION_MAJOR "${_brotli_version} >> 24") +math(EXPR BROTLI_VERSION_MINOR "(${_brotli_version} >> 12) & 4095") +math(EXPR BROTLI_VERSION_PATCH "${_brotli_version} & 4095") +set(BROTLI_VERSION "${BROTLI_VERSION_MAJOR}.${BROTLI_VERSION_MINOR}.${BROTLI_VERSION_PATCH}") +mark_as_advanced(BROTLI_VERSION BROTLI_VERSION_MAJOR BROTLI_VERSION_MINOR BROTLI_VERSION_PATCH) + +# ABI Version information +file(STRINGS "c/common/version.h" _brotli_abi_info_line REGEX "^#define BROTLI_ABI_VERSION (0x[0-9a-fA-F]+)$") +string(REGEX REPLACE "^#define BROTLI_ABI_VERSION 0x([0-9a-fA-F]+)$" "\\1" _brotli_abi_info_hex "${_brotli_abi_info_line}") +hex_to_dec("${_brotli_abi_info_hex}" _brotli_abi_info) +math(EXPR BROTLI_ABI_CURRENT "${_brotli_abi_info} >> 24") +math(EXPR BROTLI_ABI_REVISION "(${_brotli_abi_info} >> 12) & 4095") +math(EXPR BROTLI_ABI_AGE "${_brotli_abi_info} & 4095") +math(EXPR BROTLI_ABI_COMPATIBILITY "${BROTLI_ABI_CURRENT} - ${BROTLI_ABI_AGE}") +mark_as_advanced(BROTLI_ABI_CURRENT BROTLI_ABI_REVISION BROTLI_ABI_AGE BROTLI_ABI_COMPATIBILITY) + +if (ENABLE_SANITIZER) + set(CMAKE_C_FLAGS " ${CMAKE_C_FLAGS} -fsanitize=${ENABLE_SANITIZER}") + set(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} -fsanitize=${ENABLE_SANITIZER}") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=${ENABLE_SANITIZER}") + + # By default, brotli depends on undefined behavior, but setting + # BROTLI_BUILD_PORTABLE should result in a build which does not. + if(ENABLE_SANITIZER STREQUAL "undefined") + add_definitions(-DBROTLI_BUILD_PORTABLE) + endif() +endif () + +include(CheckFunctionExists) +set(LIBM_LIBRARY) +CHECK_FUNCTION_EXISTS(log2 LOG2_RES) +if(NOT LOG2_RES) + set(orig_req_libs "${CMAKE_REQUIRED_LIBRARIES}") + set(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES};m") + CHECK_FUNCTION_EXISTS(log2 LOG2_LIBM_RES) + if(LOG2_LIBM_RES) + set(LIBM_LIBRARY "m") + add_definitions(-DBROTLI_HAVE_LOG2=1) + else() + add_definitions(-DBROTLI_HAVE_LOG2=0) + endif() + + set(CMAKE_REQUIRED_LIBRARIES "${orig_req_libs}") + unset(LOG2_LIBM_RES) + unset(orig_req_libs) +else() + add_definitions(-DBROTLI_HAVE_LOG2=1) +endif() +unset(LOG2_RES) + +set(BROTLI_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/c/include") +mark_as_advanced(BROTLI_INCLUDE_DIRS) + +set(BROTLI_LIBRARIES_CORE brotlienc brotlidec brotlicommon) +set(BROTLI_LIBRARIES ${BROTLI_LIBRARIES_CORE} ${LIBM_LIBRARY}) +mark_as_advanced(BROTLI_LIBRARIES) + +set(BROTLI_LIBRARIES_CORE_STATIC brotlienc-static brotlidec-static brotlicommon-static) +set(BROTLI_LIBRARIES_STATIC ${BROTLI_LIBRARIES_CORE_STATIC} ${LIBM_LIBRARY}) +mark_as_advanced(BROTLI_LIBRARIES_STATIC) + +if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") + add_definitions(-DOS_LINUX) +elseif(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") + add_definitions(-DOS_FREEBSD) +elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + add_definitions(-DOS_MACOSX) +endif() + +function(transform_sources_list INPUT_FILE OUTPUT_FILE) + file(READ ${INPUT_FILE} TEXT) + string(REGEX REPLACE "\\\\\n" "~continuation~" TEXT ${TEXT}) + string(REGEX REPLACE "([a-zA-Z_][a-zA-Z0-9_]*)[\t ]*=[\t ]*([^\n]*)" "SET(\\1 \\2)" TEXT ${TEXT}) + string(REPLACE "~continuation~" "\n" TEXT ${TEXT}) + file(WRITE ${OUTPUT_FILE} ${TEXT}) +endfunction() + +transform_sources_list("scripts/sources.lst" "${CMAKE_CURRENT_BINARY_DIR}/sources.lst.cmake") +include("${CMAKE_CURRENT_BINARY_DIR}/sources.lst.cmake") + +if(BROTLI_EMSCRIPTEN OR BROTLI_RISCV) + set(BROTLI_SHARED_LIBS "") +else() + set(BROTLI_SHARED_LIBS brotlicommon brotlidec brotlienc) + add_library(brotlicommon SHARED ${BROTLI_COMMON_C}) + add_library(brotlidec SHARED ${BROTLI_DEC_C}) + add_library(brotlienc SHARED ${BROTLI_ENC_C}) +endif() + +set(BROTLI_STATIC_LIBS brotlicommon-static brotlidec-static brotlienc-static) +add_library(brotlicommon-static STATIC ${BROTLI_COMMON_C}) +add_library(brotlidec-static STATIC ${BROTLI_DEC_C}) +add_library(brotlienc-static STATIC ${BROTLI_ENC_C}) + +# Older CMake versions does not understand INCLUDE_DIRECTORIES property. +include_directories(${BROTLI_INCLUDE_DIRS}) + +foreach(lib IN LISTS BROTLI_SHARED_LIBS) + target_compile_definitions(${lib} PUBLIC "BROTLI_SHARED_COMPILATION" ) + string(TOUPPER "${lib}" LIB) + set_target_properties (${lib} PROPERTIES DEFINE_SYMBOL "${LIB}_SHARED_COMPILATION") +endforeach() + +foreach(lib IN LISTS BROTLI_SHARED_LIBS BROTLI_STATIC_LIBS) + target_link_libraries(${lib} ${LIBM_LIBRARY}) + set_property(TARGET ${lib} APPEND PROPERTY INCLUDE_DIRECTORIES ${BROTLI_INCLUDE_DIRS}) + set_target_properties(${lib} PROPERTIES + VERSION "${BROTLI_ABI_COMPATIBILITY}.${BROTLI_ABI_AGE}.${BROTLI_ABI_REVISION}" + SOVERSION "${BROTLI_ABI_COMPATIBILITY}") + if(NOT BROTLI_EMSCRIPTEN) + set_target_properties(${lib} PROPERTIES POSITION_INDEPENDENT_CODE TRUE) + endif() + set_property(TARGET ${lib} APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${BROTLI_INCLUDE_DIRS}") +endforeach() + +if(NOT (BROTLI_EMSCRIPTEN AND BROTLI_RISCV)) +target_link_libraries(brotlidec brotlicommon) +target_link_libraries(brotlienc brotlicommon) +endif() + +target_link_libraries(brotlidec-static brotlicommon-static) +target_link_libraries(brotlienc-static brotlicommon-static) + +# For projects stuck on older versions of CMake, this will set the +# BROTLI_INCLUDE_DIRS and BROTLI_LIBRARIES variables so they still +# have a relatively easy way to use Brotli: +# +# include_directories(${BROTLI_INCLUDE_DIRS}) +# target_link_libraries(foo ${BROTLI_LIBRARIES}) +if(BROTLI_PARENT_DIRECTORY) + set(BROTLI_INCLUDE_DIRS "${BROTLI_INCLUDE_DIRS}" PARENT_SCOPE) + set(BROTLI_LIBRARIES "${BROTLI_LIBRARIES}" PARENT_SCOPE) +endif() + +# Build the brotli executable +if(NOT BROTLI_RISCV) + add_executable(brotli ${BROTLI_CLI_C}) + target_link_libraries(brotli ${BROTLI_LIBRARIES_STATIC}) +endif() + +# Installation +if(NOT BROTLI_BUNDLED_MODE) + if(NOT BROTLI_RISCV) + install( + TARGETS brotli + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + ) + endif() + + if(NOT (BROTLI_EMSCRIPTEN AND BROTLI_RISCV)) + install( + TARGETS ${BROTLI_LIBRARIES_CORE} + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + ) + endif() # BROTLI_EMSCRIPTEN + + install( + TARGETS ${BROTLI_LIBRARIES_CORE_STATIC} + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + ) + + install( + DIRECTORY ${BROTLI_INCLUDE_DIRS}/brotli + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" + ) +endif() # BROTLI_BUNDLED_MODE + +# Tests + +# If we're targeting Windows but not running on Windows, we need Wine +# to run the tests... +if(NOT BROTLI_DISABLE_TESTS) + if(WIN32 AND NOT CMAKE_HOST_WIN32) + find_program(BROTLI_WRAPPER NAMES wine) + + if(NOT BROTLI_WRAPPER) + message(STATUS "wine not found, disabling tests") + set(BROTLI_DISABLE_TESTS TRUE) + endif() + endif() +endif() + +# If our compiler is a cross-compiler that we know about (arm/aarch64), +# then we need to use qemu to execute the tests. +if(NOT BROTLI_DISABLE_TESTS) + if ("${CMAKE_C_COMPILER}" MATCHES "^.*/arm-linux-gnueabihf-.*$") + message(STATUS "Detected arm-linux-gnueabihf cross-compilation") + set(BROTLI_WRAPPER "qemu-arm") + set(BROTLI_WRAPPER_LD_PREFIX "/usr/arm-linux-gnueabihf") + endif() + + if ("${CMAKE_C_COMPILER}" MATCHES "^.*/arm-linux-gnueabi-.*$") + message(STATUS "Detected arm-linux-gnueabi cross-compilation") + set(BROTLI_WRAPPER "qemu-arm") + set(BROTLI_WRAPPER_LD_PREFIX "/usr/arm-linux-gnueabi") + endif() + + if ("${CMAKE_C_COMPILER}" MATCHES "^.*/aarch64-linux-gnu-.*$") + message(STATUS "Detected aarch64-linux-gnu cross-compilation") + set(BROTLI_WRAPPER "qemu-aarch64") + set(BROTLI_WRAPPER_LD_PREFIX "/usr/aarch64-linux-gnu") + endif() +endif() + +if(NOT BROTLI_DISABLE_TESTS) + include(CTest) + enable_testing() + + set(ROUNDTRIP_INPUTS + tests/testdata/alice29.txt + tests/testdata/asyoulik.txt + tests/testdata/lcet10.txt + tests/testdata/plrabn12.txt + c/enc/encode.c + c/common/dictionary.h + c/dec/decode.c) + + foreach(INPUT ${ROUNDTRIP_INPUTS}) + get_filename_component(OUTPUT_NAME "${INPUT}" NAME) + + set(OUTPUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_NAME}") + set(INPUT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/${INPUT}") + + if (EXISTS "${INPUT_FILE}") + foreach(quality 1 6 9 11) + add_test(NAME "${BROTLI_TEST_PREFIX}roundtrip/${INPUT}/${quality}" + COMMAND "${CMAKE_COMMAND}" + -DBROTLI_WRAPPER=${BROTLI_WRAPPER} + -DBROTLI_WRAPPER_LD_PREFIX=${BROTLI_WRAPPER_LD_PREFIX} + -DBROTLI_CLI=$ + -DQUALITY=${quality} + -DINPUT=${INPUT_FILE} + -DOUTPUT=${OUTPUT_FILE}.${quality} + -P ${CMAKE_CURRENT_SOURCE_DIR}/tests/run-roundtrip-test.cmake) + endforeach() + else() + message(WARNING "Test file ${INPUT} does not exist.") + endif() + endforeach() + + file(GLOB_RECURSE + COMPATIBILITY_INPUTS + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + tests/testdata/*.compressed*) + + foreach(INPUT ${COMPATIBILITY_INPUTS}) + add_test(NAME "${BROTLI_TEST_PREFIX}compatibility/${INPUT}" + COMMAND "${CMAKE_COMMAND}" + -DBROTLI_WRAPPER=${BROTLI_WRAPPER} + -DBROTLI_WRAPPER_LD_PREFIX=${BROTLI_WRAPPER_LD_PREFIX} + -DBROTLI_CLI=$ + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/${INPUT} + -P ${CMAKE_CURRENT_SOURCE_DIR}/tests/run-compatibility-test.cmake) + endforeach() +endif() + +# Generate a pkg-config files + +function(generate_pkg_config_path outvar path) + string(LENGTH "${path}" path_length) + + set(path_args ${ARGV}) + list(REMOVE_AT path_args 0 1) + list(LENGTH path_args path_args_remaining) + + set("${outvar}" "${path}") + + while(path_args_remaining GREATER 1) + list(GET path_args 0 name) + list(GET path_args 1 value) + + get_filename_component(value_full "${value}" ABSOLUTE) + string(LENGTH "${value}" value_length) + + if(path_length EQUAL value_length AND path STREQUAL value) + set("${outvar}" "\${${name}}") + break() + elseif(path_length GREATER value_length) + # We might be in a subdirectory of the value, but we have to be + # careful about a prefix matching but not being a subdirectory + # (for example, /usr/lib64 is not a subdirectory of /usr/lib). + # We'll do this by making sure the next character is a directory + # separator. + string(SUBSTRING "${path}" ${value_length} 1 sep) + if(sep STREQUAL "/") + string(SUBSTRING "${path}" 0 ${value_length} s) + if(s STREQUAL value) + string(SUBSTRING "${path}" "${value_length}" -1 suffix) + set("${outvar}" "\${${name}}${suffix}") + break() + endif() + endif() + endif() + + list(REMOVE_AT path_args 0 1) + list(LENGTH path_args path_args_remaining) + endwhile() + + set("${outvar}" "${${outvar}}" PARENT_SCOPE) +endfunction(generate_pkg_config_path) + +function(transform_pc_file INPUT_FILE OUTPUT_FILE VERSION) + file(READ ${INPUT_FILE} TEXT) + + set(PREFIX "${CMAKE_INSTALL_PREFIX}") + string(REGEX REPLACE "@prefix@" "${PREFIX}" TEXT ${TEXT}) + string(REGEX REPLACE "@exec_prefix@" "${PREFIX}" TEXT ${TEXT}) + + generate_pkg_config_path(LIBDIR "${CMAKE_INSTALL_FULL_LIBDIR}" prefix "${PREFIX}") + string(REGEX REPLACE "@libdir@" "${LIBDIR}" TEXT ${TEXT}) + + generate_pkg_config_path(INCLUDEDIR "${CMAKE_INSTALL_FULL_INCLUDEDIR}" prefix "${PREFIX}") + string(REGEX REPLACE "@includedir@" "${INCLUDEDIR}" TEXT ${TEXT}) + + string(REGEX REPLACE "@PACKAGE_VERSION@" "${VERSION}" TEXT ${TEXT}) + + file(WRITE ${OUTPUT_FILE} ${TEXT}) +endfunction() + +transform_pc_file("scripts/libbrotlicommon.pc.in" "${CMAKE_CURRENT_BINARY_DIR}/libbrotlicommon.pc" "${BROTLI_VERSION}") + +transform_pc_file("scripts/libbrotlidec.pc.in" "${CMAKE_CURRENT_BINARY_DIR}/libbrotlidec.pc" "${BROTLI_VERSION}") + +transform_pc_file("scripts/libbrotlienc.pc.in" "${CMAKE_CURRENT_BINARY_DIR}/libbrotlienc.pc" "${BROTLI_VERSION}") + +if(NOT BROTLI_BUNDLED_MODE) + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libbrotlicommon.pc" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libbrotlidec.pc" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libbrotlienc.pc" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") +endif() # BROTLI_BUNDLED_MODE + +if (ENABLE_COVERAGE STREQUAL "yes") + SETUP_TARGET_FOR_COVERAGE(coverage test coverage) +endif () diff --git a/sp1-crates/build.sh b/sp1-crates/build.sh index 89340f4213f..7f2684a1399 100755 --- a/sp1-crates/build.sh +++ b/sp1-crates/build.sh @@ -6,6 +6,38 @@ SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" export TOP=$SCRIPT_DIR/.. cd "$TOP" + +# Download RISC-V C toolchain if needed +PARENT_DIR="" +if [ ! -d "$HOME/.sp1/riscv" ]; then + # Force reinstallation of sp1up, so we can pickup latest sp1up updates for rv64im toolchain + curl -L https://sp1up.succinct.xyz | bash + $HOME/.sp1/bin/sp1up -c + + echo "Testing riscv64-unknown-elf-gcc..." + $HOME/.sp1/riscv/bin/riscv64-unknown-elf-gcc --version +fi + +# Build brotli for SP1 +cp sp1-crates/brotli_cmake_patch.txt brotli/CMakeLists.txt +rm -rf target/build-sp1/brotli target/lib-sp1 +mkdir -p target/build-sp1/brotli +cd target/build-sp1/brotli +cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \ + -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY \ + -DCMAKE_SYSTEM_NAME=Generic \ + -DCMAKE_C_COMPILER=$HOME/.sp1/riscv/bin/riscv64-unknown-elf-gcc \ + -DCMAKE_C_FLAGS="-march=rv64im -mabi=lp64 -DBROTLI_BUILD_PORTABLE -mcmodel=medany -ffunction-sections -fdata-sections -fPIC" \ + -DCMAKE_AR=$HOME/.sp1/riscv/bin/riscv64-unknown-elf-ar \ + -DCMAKE_RANLIB=$HOME/.sp1/riscv/bin/riscv64-unknown-elf-ranlib \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=$TOP/target/lib-sp1 \ + -DBROTLI_DISABLE_TESTS=ON \ + $TOP/brotli +make +make install +cd $TOP + # Build nitro dependencies make build-replay-env test-go-deps rm -rf target/sp1 From f1f13d40ccd4069850f3b97c48404f253d2ff1ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 10 Mar 2026 11:20:56 +0100 Subject: [PATCH 082/189] Add new path discovery to brotli build script --- crates/brotli/build.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/brotli/build.rs b/crates/brotli/build.rs index 1f0913491cc..700f74d9565 100644 --- a/crates/brotli/build.rs +++ b/crates/brotli/build.rs @@ -9,6 +9,8 @@ fn main() { if target_arch.contains("wasm32") { println!("cargo:rustc-link-search=target/lib-wasm/"); + } else if target_arch.contains("riscv64") { + println!("cargo:rustc-link-search=../../target/lib-sp1/lib"); } else { println!("cargo:rustc-link-search=target/lib/"); println!("cargo:rustc-link-search=../../target/lib/"); From e89017d5a9d8612ad87f15fa36dabd0b4b41d8ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 10 Mar 2026 11:34:36 +0100 Subject: [PATCH 083/189] Add exports for memory management in C brotli --- sp1-crates/program/src/main.rs | 111 +++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/sp1-crates/program/src/main.rs b/sp1-crates/program/src/main.rs index 90ee5171dc9..ab375c647e3 100644 --- a/sp1-crates/program/src/main.rs +++ b/sp1-crates/program/src/main.rs @@ -25,3 +25,114 @@ pub extern "C" fn __negdf2(_x: f64) -> f64 { pub extern "C" fn __negsf2(_x: f32) -> f32 { todo!() } + +// The following code provides adapter functions, so the brotli implementation +// in C can rely on Rust for memory management. + +// Use `alloc::` instead of `std::` if you are in a `#![no_std]` environment. +use std::alloc::{alloc, alloc_zeroed, dealloc, realloc as rust_realloc, Layout}; +use std::ptr; + +// Alignment and header size (use 16 for 64-bit systems or SIMD requirements) +const ALIGN: usize = 8; +const HEADER_SIZE: usize = 8; + +/// void* malloc(size_t size) +#[unsafe(no_mangle)] +pub unsafe extern "C" fn malloc(size: usize) -> *mut u8 { + if size == 0 { + return ptr::null_mut(); + } + + let total_size = size + HEADER_SIZE; + let layout = Layout::from_size_align_unchecked(total_size, ALIGN); + let ptr = alloc(layout); + + if ptr.is_null() { + return ptr::null_mut(); + } + + *(ptr as *mut usize) = size; + ptr.add(HEADER_SIZE) +} + +/// void* calloc(size_t nmemb, size_t size) +#[unsafe(no_mangle)] +pub unsafe extern "C" fn calloc(nmemb: usize, size: usize) -> *mut u8 { + let req_size = match nmemb.checked_mul(size) { + Some(s) => s, + None => return ptr::null_mut(), + }; + + if req_size == 0 { + return ptr::null_mut(); + } + + let total_size = req_size + HEADER_SIZE; + let layout = Layout::from_size_align_unchecked(total_size, ALIGN); + let ptr = alloc_zeroed(layout); + + if ptr.is_null() { + return ptr::null_mut(); + } + + *(ptr as *mut usize) = req_size; + ptr.add(HEADER_SIZE) +} + +/// void* realloc(void* ptr, size_t size) +#[unsafe(no_mangle)] +pub unsafe extern "C" fn realloc(ptr: *mut u8, size: usize) -> *mut u8 { + // C standard: realloc(NULL, size) is identical to malloc(size) + if ptr.is_null() { + return malloc(size); + } + + // C standard: realloc(ptr, 0) is identical to free(ptr) + if size == 0 { + free(ptr); + return ptr::null_mut(); + } + + let header_ptr = ptr.sub(HEADER_SIZE); + let old_size = *(header_ptr as *const usize); + + let old_total_size = old_size + HEADER_SIZE; + let new_total_size = size + HEADER_SIZE; + + let layout = Layout::from_size_align_unchecked(old_total_size, ALIGN); + + let new_header_ptr = rust_realloc(header_ptr, layout, new_total_size); + if new_header_ptr.is_null() { + return ptr::null_mut(); // Original block is left untouched on failure + } + + // Update the header with the new requested size + *(new_header_ptr as *mut usize) = size; + + new_header_ptr.add(HEADER_SIZE) +} + +/// void free(void* ptr) +#[unsafe(no_mangle)] +pub unsafe extern "C" fn free(ptr: *mut u8) { + if ptr.is_null() { + return; + } + + let header_ptr = ptr.sub(HEADER_SIZE); + let size = *(header_ptr as *const usize); + + let total_size = size + HEADER_SIZE; + let layout = Layout::from_size_align_unchecked(total_size, ALIGN); + + dealloc(header_ptr, layout); +} + +/// void exit(int status) +#[unsafe(no_mangle)] +pub extern "C" fn exit(status: i32) -> ! { + // For embedded no_std, you will likely replace this with a panic + // or a hardware-specific halt/reset routine. + std::process::exit(status); +} From 1e886f0cd45dac7fcc6057da065f67ab0adb56f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 10 Mar 2026 11:48:10 +0100 Subject: [PATCH 084/189] Shell lint --- sp1-crates/build.sh | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/sp1-crates/build.sh b/sp1-crates/build.sh index 7f2684a1399..c61b47a1245 100755 --- a/sp1-crates/build.sh +++ b/sp1-crates/build.sh @@ -8,14 +8,13 @@ export TOP=$SCRIPT_DIR/.. cd "$TOP" # Download RISC-V C toolchain if needed -PARENT_DIR="" if [ ! -d "$HOME/.sp1/riscv" ]; then # Force reinstallation of sp1up, so we can pickup latest sp1up updates for rv64im toolchain curl -L https://sp1up.succinct.xyz | bash - $HOME/.sp1/bin/sp1up -c + "$HOME"/.sp1/bin/sp1up -c echo "Testing riscv64-unknown-elf-gcc..." - $HOME/.sp1/riscv/bin/riscv64-unknown-elf-gcc --version + "$HOME"/.sp1/riscv/bin/riscv64-unknown-elf-gcc --version fi # Build brotli for SP1 @@ -26,17 +25,17 @@ cd target/build-sp1/brotli cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \ -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY \ -DCMAKE_SYSTEM_NAME=Generic \ - -DCMAKE_C_COMPILER=$HOME/.sp1/riscv/bin/riscv64-unknown-elf-gcc \ + -DCMAKE_C_COMPILER="$HOME"/.sp1/riscv/bin/riscv64-unknown-elf-gcc \ -DCMAKE_C_FLAGS="-march=rv64im -mabi=lp64 -DBROTLI_BUILD_PORTABLE -mcmodel=medany -ffunction-sections -fdata-sections -fPIC" \ - -DCMAKE_AR=$HOME/.sp1/riscv/bin/riscv64-unknown-elf-ar \ - -DCMAKE_RANLIB=$HOME/.sp1/riscv/bin/riscv64-unknown-elf-ranlib \ + -DCMAKE_AR="$HOME"/.sp1/riscv/bin/riscv64-unknown-elf-ar \ + -DCMAKE_RANLIB="$HOME"/.sp1/riscv/bin/riscv64-unknown-elf-ranlib \ -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_INSTALL_PREFIX=$TOP/target/lib-sp1 \ + -DCMAKE_INSTALL_PREFIX="$TOP"/target/lib-sp1 \ -DBROTLI_DISABLE_TESTS=ON \ - $TOP/brotli + "$TOP"/brotli make make install -cd $TOP +cd "$TOP" # Build nitro dependencies make build-replay-env test-go-deps From c189f3494815b121fc3d49a9c8857699d7cfffcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 10 Mar 2026 17:05:19 +0100 Subject: [PATCH 085/189] Target paths --- sp1-crates/prover/src/lib.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sp1-crates/prover/src/lib.rs b/sp1-crates/prover/src/lib.rs index 5a9499d2339..4c01f2e4b06 100644 --- a/sp1-crates/prover/src/lib.rs +++ b/sp1-crates/prover/src/lib.rs @@ -1,23 +1,23 @@ -//! Ideally, we should just use arbitrator/prover. This crate has no +//! Ideally, we should just use crates/prover. This crate has no //! reason to exist. But at the moment, nitro uses wasmer 4.x, while SP1 //! requires wasmer 6.1.x. The 2 wasmer versions are hardly compatible. //! On the other hand, we would want to borrow common definitions in -//! arbitrator/prover so we don't have to define them twice. +//! crates/prover so we don't have to define them twice. //! This crate serves as a workaround till we can upgrade wasmer in nitro. #![allow(unexpected_cfgs)] #[cfg(feature = "native")] -#[path = "../../../arbitrator/prover/src/binary.rs"] +#[path = "../../../crates/prover/src/binary.rs"] pub mod binary; #[cfg(feature = "native")] -#[path = "../../../arbitrator/prover/src/programs/mod.rs"] +#[path = "../../../crates/prover/src/programs/mod.rs"] pub mod programs; #[cfg(feature = "native")] -#[path = "../../../arbitrator/prover/src/value.rs"] +#[path = "../../../crates/prover/src/value.rs"] pub mod value; #[cfg(feature = "native")] -#[path = "../../../arbitrator/arbutil/src/operator.rs"] +#[path = "../../../crates/arbutil/src/operator.rs"] pub mod operator; pub mod binary_input; From 803d286499954f2f92c2f20a1ba76240ca412068 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 10 Mar 2026 17:05:25 +0100 Subject: [PATCH 086/189] Migrate binary.rs --- arbitrator/prover/src/binary.rs | 750 -------------------------------- crates/prover/src/binary.rs | 18 + 2 files changed, 18 insertions(+), 750 deletions(-) delete mode 100644 arbitrator/prover/src/binary.rs diff --git a/arbitrator/prover/src/binary.rs b/arbitrator/prover/src/binary.rs deleted file mode 100644 index 2dd269371fc..00000000000 --- a/arbitrator/prover/src/binary.rs +++ /dev/null @@ -1,750 +0,0 @@ -// Copyright 2021-2024, Offchain Labs, Inc. -// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md - -use crate::{ - programs::{ - FuncMiddleware, Middleware, ModuleMod, STYLUS_ENTRY_POINT, StylusData, - config::CompileConfig, counter::Counter, depth::DepthChecker, dynamic::DynamicMeter, - heap::HeapBound, meter::Meter, start::StartMover, - }, - value::{ArbValueType, FunctionType, IntegerValType, Value}, -}; -use arbutil::{ - Bytes32, Color, DebugColor, evm::ARBOS_VERSION_STYLUS_CHARGING_FIXES, math::SaturatingSum, -}; -use eyre::{Result, WrapErr, bail, ensure, eyre}; -use fnv::{FnvHashMap as HashMap, FnvHashSet as HashSet}; -use nom::{ - branch::alt, - bytes::complete::tag, - combinator::{all_consuming, map, value}, - sequence::{preceded, tuple}, -}; -use serde::{Deserialize, Serialize}; -use std::{convert::TryInto, fmt::Debug, hash::Hash, mem, path::Path, str::FromStr}; -use wasmer_types::{ExportIndex, FunctionIndex, LocalFunctionIndex, entity::EntityRef}; -use wasmparser::{ - Data, Element, ExternalKind, MemoryType, Name, NameSectionReader, Naming, Operator, Parser, - Payload, TableType, TypeRef, ValType, Validator, WasmFeatures, -}; - -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -pub enum FloatType { - F32, - F64, -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -pub enum FloatUnOp { - Abs, - Neg, - Ceil, - Floor, - Trunc, - Nearest, - Sqrt, -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -pub enum FloatBinOp { - Add, - Sub, - Mul, - Div, - Min, - Max, - CopySign, -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -pub enum FloatRelOp { - Eq, - Ne, - Lt, - Gt, - Le, - Ge, -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -pub enum FloatInstruction { - UnOp(FloatType, FloatUnOp), - BinOp(FloatType, FloatBinOp), - RelOp(FloatType, FloatRelOp), - /// The bools represent (saturating, signed) - TruncIntOp(IntegerValType, FloatType, bool, bool), - ConvertIntOp(FloatType, IntegerValType, bool), - F32DemoteF64, - F64PromoteF32, -} - -impl FloatInstruction { - pub fn signature(&self) -> FunctionType { - match *self { - FloatInstruction::UnOp(t, _) => FunctionType::new([t.into()], [t.into()]), - FloatInstruction::BinOp(t, _) => FunctionType::new([t.into(); 2], [t.into()]), - FloatInstruction::RelOp(t, _) => FunctionType::new([t.into(); 2], [ArbValueType::I32]), - FloatInstruction::TruncIntOp(i, f, ..) => FunctionType::new([f.into()], [i.into()]), - FloatInstruction::ConvertIntOp(f, i, _) => FunctionType::new([i.into()], [f.into()]), - FloatInstruction::F32DemoteF64 => { - FunctionType::new([ArbValueType::F64], [ArbValueType::F32]) - } - FloatInstruction::F64PromoteF32 => { - FunctionType::new([ArbValueType::F32], [ArbValueType::F64]) - } - } - } -} - -impl FromStr for FloatInstruction { - type Err = String; - - fn from_str(s: &str) -> Result { - type IResult<'a, T> = nom::IResult<&'a str, T, nom::error::Error<&'a str>>; - - fn parse_fp_type(s: &str) -> IResult<'_, FloatType> { - alt(( - value(FloatType::F32, tag("f32")), - value(FloatType::F64, tag("f64")), - ))(s) - } - - fn parse_signedness(s: &str) -> IResult<'_, bool> { - alt((value(true, tag("s")), value(false, tag("u"))))(s) - } - - fn parse_int_type(s: &str) -> IResult<'_, IntegerValType> { - alt(( - value(IntegerValType::I32, tag("i32")), - value(IntegerValType::I64, tag("i64")), - ))(s) - } - - fn parse_un_op(s: &str) -> IResult<'_, FloatUnOp> { - alt(( - value(FloatUnOp::Abs, tag("abs")), - value(FloatUnOp::Neg, tag("neg")), - value(FloatUnOp::Ceil, tag("ceil")), - value(FloatUnOp::Floor, tag("floor")), - value(FloatUnOp::Trunc, tag("trunc")), - value(FloatUnOp::Nearest, tag("nearest")), - value(FloatUnOp::Sqrt, tag("sqrt")), - ))(s) - } - - fn parse_bin_op(s: &str) -> IResult<'_, FloatBinOp> { - alt(( - value(FloatBinOp::Add, tag("add")), - value(FloatBinOp::Sub, tag("sub")), - value(FloatBinOp::Mul, tag("mul")), - value(FloatBinOp::Div, tag("div")), - value(FloatBinOp::Min, tag("min")), - value(FloatBinOp::Max, tag("max")), - value(FloatBinOp::CopySign, tag("copysign")), - ))(s) - } - - fn parse_rel_op(s: &str) -> IResult<'_, FloatRelOp> { - alt(( - value(FloatRelOp::Eq, tag("eq")), - value(FloatRelOp::Ne, tag("ne")), - value(FloatRelOp::Lt, tag("lt")), - value(FloatRelOp::Gt, tag("gt")), - value(FloatRelOp::Le, tag("le")), - value(FloatRelOp::Ge, tag("ge")), - ))(s) - } - - let inst = alt(( - map( - all_consuming(tuple((parse_fp_type, tag("_"), parse_un_op))), - |(t, _, o)| FloatInstruction::UnOp(t, o), - ), - map( - all_consuming(tuple((parse_fp_type, tag("_"), parse_bin_op))), - |(t, _, o)| FloatInstruction::BinOp(t, o), - ), - map( - all_consuming(tuple((parse_fp_type, tag("_"), parse_rel_op))), - |(t, _, o)| FloatInstruction::RelOp(t, o), - ), - map( - all_consuming(tuple(( - parse_int_type, - alt(( - value(true, tag("_trunc_sat_")), - value(false, tag("_trunc_")), - )), - parse_fp_type, - tag("_"), - parse_signedness, - ))), - |(i, sat, f, _, s)| FloatInstruction::TruncIntOp(i, f, sat, s), - ), - map( - all_consuming(tuple(( - parse_fp_type, - tag("_convert_"), - parse_int_type, - tag("_"), - parse_signedness, - ))), - |(f, _, i, _, s)| FloatInstruction::ConvertIntOp(f, i, s), - ), - value( - FloatInstruction::F32DemoteF64, - all_consuming(tag("f32_demote_f64")), - ), - value( - FloatInstruction::F64PromoteF32, - all_consuming(tag("f64_promote_f32")), - ), - )); - - let res = preceded(tag("wavm__"), inst)(s); - - res.map(|(_, i)| i).map_err(|e| e.to_string()) - } -} - -pub fn op_as_const(op: Operator) -> Result { - match op { - Operator::I32Const { value } => Ok(Value::I32(value as u32)), - Operator::I64Const { value } => Ok(Value::I64(value as u64)), - Operator::F32Const { value } => Ok(Value::F32(f32::from_bits(value.bits()))), - Operator::F64Const { value } => Ok(Value::F64(f64::from_bits(value.bits()))), - _ => bail!("Opcode is not a constant"), - } -} - -#[derive(Clone, Debug, Default)] -pub struct FuncImport<'a> { - pub offset: u32, - pub module: &'a str, - pub name: &'a str, -} - -/// This enum primarily exists because wasmer's ExternalKind doesn't impl these derived functions -#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)] -pub enum ExportKind { - Func, - Table, - Memory, - Global, - Tag, -} - -impl From for ExportKind { - fn from(kind: ExternalKind) -> Self { - use ExternalKind as E; - match kind { - E::Func => Self::Func, - E::Table => Self::Table, - E::Memory => Self::Memory, - E::Global => Self::Global, - E::Tag => Self::Tag, - } - } -} - -impl From for ExportKind { - fn from(value: ExportIndex) -> Self { - use ExportIndex as E; - match value { - E::Function(_) => Self::Func, - E::Table(_) => Self::Table, - E::Memory(_) => Self::Memory, - E::Global(_) => Self::Global, - #[cfg(feature = "sp1")] - E::Tag(_) => Self::Tag, - } - } -} - -#[derive(Clone, Debug, Default)] -pub struct Code<'a> { - pub locals: Vec, - pub expr: Vec>, -} - -#[derive(Clone, Debug)] -pub struct Local { - pub index: u32, - pub value: ArbValueType, -} - -#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] -pub struct NameCustomSection { - pub module: String, - pub functions: HashMap, -} - -pub type ExportMap = HashMap; - -#[derive(Clone, Default)] -pub struct WasmBinary<'a> { - pub types: Vec, - pub imports: Vec>, - /// Maps *local* function indices to global type signatures. - pub functions: Vec, - pub tables: Vec, - pub memories: Vec, - pub globals: Vec, - pub exports: ExportMap, - pub start: Option, - pub elements: Vec>, - pub codes: Vec>, - pub datas: Vec>, - pub names: NameCustomSection, - /// The source wasm, if known. - pub wasm: Option<&'a [u8]>, - /// Consensus data used to make module hashes unique. - pub extra_data: Vec, -} - -pub fn parse<'a>(input: &'a [u8], path: &'_ Path) -> Result> { - #[cfg(not(feature = "sp1"))] - let features = WasmFeatures { - mutable_global: true, - saturating_float_to_int: true, - sign_extension: true, - reference_types: false, - multi_value: true, - bulk_memory: true, // not all ops supported yet - simd: false, - relaxed_simd: false, - threads: false, - tail_call: false, - floats: true, - multi_memory: false, - exceptions: false, - memory64: false, - extended_const: false, - component_model: false, - function_references: false, - memory_control: false, - gc: false, - component_model_values: false, - component_model_nested_names: false, - }; - #[cfg(feature = "sp1")] - let features = { - let mut features = WasmFeatures::empty(); - features.set(WasmFeatures::MUTABLE_GLOBAL, true); - features.set(WasmFeatures::SATURATING_FLOAT_TO_INT, true); - features.set(WasmFeatures::SIGN_EXTENSION, true); - features.set(WasmFeatures::MULTI_VALUE, true); - features.set(WasmFeatures::BULK_MEMORY, true); // not all ops supported yet - features.set(WasmFeatures::FLOATS, true); - features - }; - Validator::new_with_features(features) - .validate_all(input) - .wrap_err_with(|| eyre!("failed to validate {}", path.to_string_lossy().red()))?; - - let mut binary = WasmBinary { - wasm: Some(input), - ..Default::default() - }; - let sections: Vec<_> = Parser::new(0).parse_all(input).collect::>()?; - - for section in sections { - use Payload::*; - - macro_rules! process { - ($dest:expr, $source:expr) => {{ - for item in $source.into_iter() { - $dest.push(item?.into()) - } - }}; - } - - match section { - TypeSection(type_section) => { - for func in type_section.into_iter_err_on_gc_types() { - binary.types.push(func?.try_into()?); - } - } - CodeSectionEntry(codes) => { - let mut code = Code::default(); - let mut locals = codes.get_locals_reader()?; - let mut ops = codes.get_operators_reader()?; - let mut index = 0; - - for _ in 0..locals.get_count() { - let (count, value) = locals.read()?; - for _ in 0..count { - code.locals.push(Local { - index, - value: value.try_into()?, - }); - index += 1; - } - } - while !ops.eof() { - code.expr.push(ops.read()?); - } - - binary.codes.push(code); - } - GlobalSection(globals) => { - for global in globals { - let mut init = global?.init_expr.get_operators_reader(); - - let value = match (init.read()?, init.read()?, init.eof()) { - (op, Operator::End, true) => op_as_const(op)?, - _ => bail!("Non-constant global initializer"), - }; - binary.globals.push(value); - } - } - ImportSection(imports) => { - for import in imports { - let import = import?; - let TypeRef::Func(offset) = import.ty else { - bail!("unsupported import kind {:?}", import) - }; - let import = FuncImport { - offset, - module: import.module, - name: import.name, - }; - binary.imports.push(import); - } - } - ExportSection(exports) => { - use ExternalKind as E; - for export in exports { - let export = export?; - let name = export.name.to_owned(); - let kind = export.kind; - if let E::Func = kind { - let index = export.index; - let name = || name.clone(); - binary.names.functions.entry(index).or_insert_with(name); - } - binary.exports.insert(name, (export.index, kind.into())); - } - } - FunctionSection(functions) => process!(binary.functions, functions), - TableSection(tables) => { - for table in tables { - binary.tables.push(table?.ty); - } - } - MemorySection(memories) => process!(binary.memories, memories), - StartSection { func, .. } => binary.start = Some(func), - ElementSection(elements) => process!(binary.elements, elements), - DataSection(datas) => process!(binary.datas, datas), - CodeSectionStart { .. } => {} - CustomSection(reader) => { - if reader.name() != "name" { - continue; - } - - // CHECK: maybe reader.data_offset() - #[cfg(not(feature = "sp1"))] - let name_reader = NameSectionReader::new(reader.data(), 0); - #[cfg(feature = "sp1")] - let name_reader = - NameSectionReader::new(wasmparser::BinaryReader::new(reader.data(), 0)); - - for name in name_reader { - match name? { - Name::Module { name, .. } => binary.names.module = name.to_owned(), - Name::Function(namemap) => { - for naming in namemap { - let Naming { index, name } = naming?; - binary.names.functions.insert(index, name.to_owned()); - } - } - _ => {} - } - } - } - Version { num, .. } => ensure!(num == 1, "wasm format version not supported {num}"), - UnknownSection { id, .. } => bail!("unsupported unknown section type {id}"), - End(_) => {} - x => bail!("unsupported section type {:?}", x), - } - } - - // reject the module if it imports the same func with inconsistent signatures - let mut imports = HashMap::default(); - for import in &binary.imports { - let offset = import.offset; - let module = import.module; - let name = import.name; - - let key = (module, name); - if let Some(prior) = imports.insert(key, offset) { - if prior != offset { - let name = name.debug_red(); - bail!("inconsistent imports for {} {name}", module.red()); - } - } - } - - // reject the module if it re-exports an import with the same name - let mut exports = HashSet::default(); - for export in binary.exports.keys() { - let export = export.rsplit("__").take(1); - exports.extend(export); - } - for import in &binary.imports { - let name = import.name; - if exports.contains(name) { - bail!("binary exports an import with the same name {}", name.red()); - } - } - - // reject the module if it imports or exports reserved symbols - let reserved = |x: &&str| x.starts_with("stylus"); - if let Some(name) = exports.into_iter().find(reserved) { - bail!("binary exports reserved symbol {}", name.red()) - } - if let Some(name) = binary.imports.iter().map(|x| x.name).find(reserved) { - bail!("binary imports reserved symbol {}", name.red()) - } - - // if no module name was given, make a best-effort guess with the file path - if binary.names.module.is_empty() { - binary.names.module = match path.file_name() { - Some(os_str) => os_str.to_string_lossy().into(), - None => path.to_string_lossy().into(), - }; - } - Ok(binary) -} - -impl Debug for WasmBinary<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("WasmBinary") - .field("types", &self.types) - .field("imports", &self.imports) - .field("functions", &self.functions) - .field("tables", &self.tables) - .field("memories", &self.memories) - .field("globals", &self.globals) - .field("exports", &self.exports) - .field("start", &self.start) - .field("elements", &format!("<{} elements>", self.elements.len())) - .field("codes", &self.codes) - .field("datas", &self.datas) - .field("names", &self.names) - .finish() - } -} - -impl<'a> WasmBinary<'a> { - /// Instruments a user wasm, producing a version bounded via configurable instrumentation. - pub fn instrument( - &mut self, - compile: &CompileConfig, - codehash: &Bytes32, - ) -> Result { - let start = StartMover::new(compile.debug.debug_info); - let meter = Meter::new(&compile.pricing); - let dygas = DynamicMeter::new(&compile.pricing); - let depth = DepthChecker::new(compile.bounds); - let bound = HeapBound::new(compile.bounds); - - start.update_module(self)?; - meter.update_module(self)?; - dygas.update_module(self)?; - depth.update_module(self)?; - bound.update_module(self)?; - - let count = compile.debug.count_ops.then(Counter::new); - if let Some(count) = &count { - count.update_module(self)?; - } - - for (index, code) in self.codes.iter_mut().enumerate() { - let index = LocalFunctionIndex::from_u32(index as u32); - let locals: Vec = code.locals.iter().map(|x| x.value.into()).collect(); - - let mut build = mem::take(&mut code.expr); - let mut input = Vec::with_capacity(build.len()); - - /// this macro exists since middlewares aren't sized (can't use a vec without boxes) - macro_rules! apply { - ($middleware:expr) => { - let mut mid = Middleware::::instrument(&$middleware, index)?; - mid.locals_info(&locals); - - mem::swap(&mut build, &mut input); - - for op in input.drain(..) { - mid.feed(op, &mut build) - .wrap_err_with(|| format!("{} failure", mid.name()))? - } - }; - } - - // add the instrumentation in the order of application - // note: this must be consistent with native execution - apply!(start); - apply!(meter); - apply!(dygas); - apply!(depth); - apply!(bound); - - if let Some(count) = &count { - apply!(*count); - } - - code.expr = build; - } - - let wasm = self.wasm.take().unwrap(); - self.extra_data.extend(*codehash); - self.extra_data.extend(compile.version.to_be_bytes()); - - // 4GB maximum implies `footprint` fits in a u16 - let footprint = self.memory_info()?.min.0 as u16; - - // check the entrypoint - let ty = FunctionType::new([ArbValueType::I32], [ArbValueType::I32]); - let user_main = self.check_func(STYLUS_ENTRY_POINT, ty)?; - - // predict costs - let funcs = self.codes.len() as u64; - let globals = self.globals.len() as u64; - let wasm_len = wasm.len() as u64; - - let data_len: u64 = self.datas.iter().map(|x| x.range.len() as u64).sum(); - let elem_len: u64 = self.elements.iter().map(|x| x.range.len() as u64).sum(); - let data_len = data_len + elem_len; - - let mut type_len = 0; - for index in &self.functions { - let ty = &self.types[*index as usize]; - type_len += (ty.inputs.len() + ty.outputs.len()) as u64; - } - - let mut asm_estimate: u64 = 512000; - asm_estimate = asm_estimate.saturating_add(funcs.saturating_mul(996829) / 1000); - asm_estimate = asm_estimate.saturating_add(type_len.saturating_mul(11416) / 1000); - asm_estimate = asm_estimate.saturating_add(wasm_len.saturating_mul(62628) / 10000); - - let mut cached_init: u64 = 0; - cached_init = cached_init.saturating_add(funcs.saturating_mul(13420) / 100_000); - cached_init = cached_init.saturating_add(type_len.saturating_mul(89) / 100_000); - cached_init = cached_init.saturating_add(wasm_len.saturating_mul(122) / 100_000); - cached_init = cached_init.saturating_add(globals.saturating_mul(1628) / 1000); - cached_init = cached_init.saturating_add(data_len.saturating_mul(75244) / 100_000); - cached_init = cached_init.saturating_add(footprint as u64 * 5); - - let mut init: u64 = 0; - if compile.version == 1 { - init = cached_init; // in version 1 cached cost is part of init cost - } - init = init.saturating_add(funcs.saturating_mul(8252) / 1000); - init = init.saturating_add(type_len.saturating_mul(1059) / 1000); - init = init.saturating_add(wasm_len.saturating_mul(1286) / 10_000); - - let [ink_left, ink_status] = meter.globals(); - let depth_left = depth.globals(); - Ok(StylusData { - ink_left: ink_left.as_u32(), - ink_status: ink_status.as_u32(), - depth_left: depth_left.as_u32(), - init_cost: init.try_into().wrap_err("init cost too high")?, - cached_init_cost: cached_init.try_into().wrap_err("cached cost too high")?, - asm_estimate: asm_estimate.try_into().wrap_err("asm estimate too large")?, - footprint, - user_main, - }) - } - - /// Parses and instruments a user wasm - pub fn parse_user( - wasm: &'a [u8], - arbos_version_for_gas: u64, - page_limit: u16, - compile: &CompileConfig, - codehash: &Bytes32, - ) -> Result<(WasmBinary<'a>, StylusData)> { - let mut bin = parse(wasm, Path::new("user"))?; - let stylus_data = bin.instrument(compile, codehash)?; - - let Some(memory) = bin.memories.first() else { - bail!("missing memory with export name \"memory\"") - }; - let pages = memory.initial; - - // ensure the wasm fits within the remaining amount of memory - if pages > page_limit.into() { - let limit = page_limit.red(); - bail!("memory exceeds limit: {} > {limit}", pages.red()); - } - - // not strictly necessary, but anti-DoS limits and extra checks in case of bugs - macro_rules! limit { - ($limit:expr, $count:expr, $name:expr) => { - if $count > $limit { - bail!("too many wasm {}: {} > {}", $name, $count, $limit); - } - }; - } - limit!(1, bin.memories.len(), "memories"); - limit!(128, bin.datas.len(), "datas"); - limit!(128, bin.elements.len(), "elements"); - limit!(1024, bin.exports.len(), "exports"); - limit!(4096, bin.codes.len(), "functions"); - limit!(32768, bin.globals.len(), "globals"); - for code in &bin.codes { - limit!(348, code.locals.len(), "locals"); - limit!(65536, code.expr.len(), "opcodes in func body"); - } - - if arbos_version_for_gas >= ARBOS_VERSION_STYLUS_CHARGING_FIXES { - limit!(513, bin.imports.len(), "imports") - } - - let table_entries = bin.tables.iter().map(|x| x.initial).saturating_sum(); - limit!(4096, table_entries, "table entries"); - - let elem_entries = bin.elements.iter().map(|x| x.range.len()).saturating_sum(); - limit!(4096, elem_entries, "element entries"); - - let max_len = 512; - macro_rules! too_long { - ($name:expr, $len:expr) => { - bail!( - "wasm {} too long: {} > {}", - $name.red(), - $len.red(), - max_len.red() - ) - }; - } - if let Some((name, _)) = bin.exports.iter().find(|(name, _)| name.len() > max_len) { - too_long!("name", name.len()) - } - if bin.names.module.len() > max_len { - too_long!("module name", bin.names.module.len()) - } - if bin.start.is_some() { - bail!("wasm start functions not allowed"); - } - Ok((bin, stylus_data)) - } - - /// Ensures a func exists and has the right type. - fn check_func(&self, name: &str, ty: FunctionType) -> Result { - let Some(&(func, kind)) = self.exports.get(name) else { - bail!("missing export with name {}", name.red()); - }; - if kind != ExportKind::Func { - let kind = kind.debug_red(); - bail!("export {} must be a function but is a {kind}", name.red()); - } - let func_ty = self.get_function(FunctionIndex::new(func.try_into()?))?; - if func_ty != ty { - bail!("wrong type for {}: {}", name.red(), func_ty.red()); - } - Ok(func) - } -} diff --git a/crates/prover/src/binary.rs b/crates/prover/src/binary.rs index 808dc206db7..498e305371d 100644 --- a/crates/prover/src/binary.rs +++ b/crates/prover/src/binary.rs @@ -255,6 +255,8 @@ impl From for ExportKind { E::Table(_) => Self::Table, E::Memory(_) => Self::Memory, E::Global(_) => Self::Global, + #[cfg(feature = "sp1")] + E::Tag(_) => Self::Tag, } } } @@ -301,6 +303,7 @@ pub struct WasmBinary<'a> { } pub fn parse<'a>(input: &'a [u8], path: &'_ Path) -> Result> { + #[cfg(not(feature = "sp1"))] let features = WasmFeatures { mutable_global: true, saturating_float_to_int: true, @@ -324,6 +327,17 @@ pub fn parse<'a>(input: &'a [u8], path: &'_ Path) -> Result> { component_model_values: false, component_model_nested_names: false, }; + #[cfg(feature = "sp1")] + let features = { + let mut features = WasmFeatures::empty(); + features.set(WasmFeatures::MUTABLE_GLOBAL, true); + features.set(WasmFeatures::SATURATING_FLOAT_TO_INT, true); + features.set(WasmFeatures::SIGN_EXTENSION, true); + features.set(WasmFeatures::MULTI_VALUE, true); + features.set(WasmFeatures::BULK_MEMORY, true); // not all ops supported yet + features.set(WasmFeatures::FLOATS, true); + features + }; Validator::new_with_features(features) .validate_all(input) .wrap_err_with(|| eyre!("failed to validate {}", path.to_string_lossy().red()))?; @@ -429,7 +443,11 @@ pub fn parse<'a>(input: &'a [u8], path: &'_ Path) -> Result> { } // CHECK: maybe reader.data_offset() + #[cfg(not(feature = "sp1"))] let name_reader = NameSectionReader::new(reader.data(), 0); + #[cfg(feature = "sp1")] + let name_reader = + NameSectionReader::new(wasmparser::BinaryReader::new(reader.data(), 0)); for name in name_reader { match name? { From 80a50fb60169ccea4e9449d4507232c64afc9b31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 10 Mar 2026 17:08:07 +0100 Subject: [PATCH 087/189] Migrate config.rs --- arbitrator/prover/src/programs/config.rs | 234 ----------------------- crates/prover/src/programs/config.rs | 9 +- 2 files changed, 6 insertions(+), 237 deletions(-) delete mode 100644 arbitrator/prover/src/programs/config.rs diff --git a/arbitrator/prover/src/programs/config.rs b/arbitrator/prover/src/programs/config.rs deleted file mode 100644 index 79df3b605a2..00000000000 --- a/arbitrator/prover/src/programs/config.rs +++ /dev/null @@ -1,234 +0,0 @@ -// Copyright 2022-2023, Offchain Labs, Inc. -// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md - -#![allow(clippy::field_reassign_with_default)] - -use crate::{programs::meter, value::FunctionType}; -use arbutil::evm::api::{Gas, Ink}; -use derivative::Derivative; -use fnv::FnvHashMap as HashMap; -use std::fmt::Debug; -use wasmer_types::{Pages, SignatureIndex, WASM_PAGE_SIZE}; -use wasmparser::Operator; - -#[cfg(feature = "native")] -use { - super::{ - MiddlewareWrapper, counter::Counter, depth::DepthChecker, dynamic::DynamicMeter, - heap::HeapBound, meter::Meter, start::StartMover, - }, - std::sync::Arc, -}; - -#[derive(Clone, Copy, Debug)] -#[repr(C)] -pub struct StylusConfig { - /// Version the program was compiled against - pub version: u16, - /// The maximum size of the stack, measured in words - pub max_depth: u32, - /// Pricing parameters supplied at runtime - pub pricing: PricingParams, -} - -#[derive(Clone, Copy, Debug)] -#[repr(C)] -pub struct PricingParams { - /// The price of ink, measured in bips of an evm gas - pub ink_price: u32, -} - -impl Default for StylusConfig { - fn default() -> Self { - Self { - version: 0, - max_depth: u32::MAX, - pricing: PricingParams::default(), - } - } -} - -impl Default for PricingParams { - fn default() -> Self { - Self { ink_price: 1 } - } -} - -impl StylusConfig { - pub const fn new(version: u16, max_depth: u32, ink_price: u32) -> Self { - let pricing = PricingParams::new(ink_price); - Self { - version, - max_depth, - pricing, - } - } -} - -#[allow(clippy::inconsistent_digit_grouping)] -impl PricingParams { - pub const fn new(ink_price: u32) -> Self { - Self { ink_price } - } - - pub fn gas_to_ink(&self, gas: Gas) -> Ink { - Ink(gas.0.saturating_mul(self.ink_price.into())) - } - - pub fn ink_to_gas(&self, ink: Ink) -> Gas { - Gas(ink.0 / self.ink_price as u64) // ink_price is never 0 - } -} - -pub type SigMap = HashMap; -pub type OpCosts = fn(&Operator, &SigMap) -> u64; - -#[derive(Clone, Debug, Default)] -pub struct CompileConfig { - /// Version of the compiler to use - pub version: u16, - /// Pricing parameters used for metering - pub pricing: CompilePricingParams, - /// Memory bounds - pub bounds: CompileMemoryParams, - /// Debug parameters for test chains - pub debug: CompileDebugParams, -} - -#[derive(Clone, Copy, Debug)] -pub struct CompileMemoryParams { - /// The maximum number of pages a program may start with - pub heap_bound: Pages, - /// The maximum size of a stack frame, measured in words - pub max_frame_size: u32, - /// The maximum number of overlapping value lifetimes in a frame - pub max_frame_contention: u16, -} - -#[derive(Clone, Derivative)] -#[derivative(Debug)] -pub struct CompilePricingParams { - /// Associates opcodes to their ink costs - #[derivative(Debug = "ignore")] - pub costs: OpCosts, - /// Cost of checking the amount of ink left. - pub ink_header_cost: u64, - /// Per-byte `MemoryFill` cost - pub memory_fill_ink: u64, - /// Per-byte `MemoryCopy` cost - pub memory_copy_ink: u64, -} - -#[derive(Clone, Debug, Default)] -pub struct CompileDebugParams { - /// Allow debug functions - pub debug_funcs: bool, - /// Retain debug info - pub debug_info: bool, - /// Add instrumentation to count the number of times each kind of opcode is executed - pub count_ops: bool, -} - -impl Default for CompilePricingParams { - fn default() -> Self { - Self { - costs: |_, _| 0, - ink_header_cost: 0, - memory_fill_ink: 0, - memory_copy_ink: 0, - } - } -} - -impl Default for CompileMemoryParams { - fn default() -> Self { - Self { - heap_bound: Pages(u32::MAX / WASM_PAGE_SIZE as u32), - max_frame_size: u32::MAX, - max_frame_contention: u16::MAX, - } - } -} - -impl CompileConfig { - pub fn version(version: u16, debug_chain: bool) -> Self { - let mut config = Self::default(); - config.version = version; - config.debug.debug_funcs = debug_chain; - config.debug.debug_info = debug_chain; - - match version { - 0 => {} - 1 | 2 => { - config.bounds.heap_bound = Pages(128); // 8 mb - config.bounds.max_frame_size = 10 * 1024; - config.bounds.max_frame_contention = 4096; - config.pricing = CompilePricingParams { - costs: meter::pricing_v1, - ink_header_cost: 2450, - memory_fill_ink: 800 / 8, - memory_copy_ink: 800 / 8, - }; - } - _ => panic!("no config exists for Stylus version {version}"), - } - - config - } -} - -#[cfg(all(feature = "native", not(feature = "sp1")))] -use { - wasmer::{Cranelift, CraneliftOptLevel, Engine, Store, Target}, - wasmer_compiler_singlepass::Singlepass, -}; - -#[cfg(all(feature = "native", not(feature = "sp1")))] -impl CompileConfig { - fn engine_type(&self, target: Target, cranelift: bool) -> Engine { - use wasmer::sys::EngineBuilder; - - let mut wasmer_config: Box = match cranelift { - true => { - let mut wasmer_config = Cranelift::new(); - wasmer_config.opt_level(CraneliftOptLevel::Speed); - Box::new(wasmer_config) - } - false => Box::new(Singlepass::new()), - }; - wasmer_config.canonicalize_nans(true); - wasmer_config.enable_verifier(); - - let start = MiddlewareWrapper::new(StartMover::new(self.debug.debug_info)); - let meter = MiddlewareWrapper::new(Meter::new(&self.pricing)); - let dygas = MiddlewareWrapper::new(DynamicMeter::new(&self.pricing)); - let depth = MiddlewareWrapper::new(DepthChecker::new(self.bounds)); - let bound = MiddlewareWrapper::new(HeapBound::new(self.bounds)); - - // add the instrumentation in the order of application - // note: this must be consistent with the prover - wasmer_config.push_middleware(Arc::new(start)); - wasmer_config.push_middleware(Arc::new(meter)); - wasmer_config.push_middleware(Arc::new(dygas)); - wasmer_config.push_middleware(Arc::new(depth)); - wasmer_config.push_middleware(Arc::new(bound)); - - if self.debug.count_ops { - let counter = Counter::new(); - wasmer_config.push_middleware(Arc::new(MiddlewareWrapper::new(counter))); - } - - EngineBuilder::new(wasmer_config) - .set_target(Some(target)) - .into() - } - - // cranelift only matters for compilation and not usually needed - pub fn engine(&self, target: Target) -> Engine { - self.engine_type(target, true) - } - - pub fn store(&self, target: Target, cranelift: bool) -> Store { - Store::new(self.engine_type(target, cranelift)) - } -} diff --git a/crates/prover/src/programs/config.rs b/crates/prover/src/programs/config.rs index ddd454783be..8fe7365763a 100644 --- a/crates/prover/src/programs/config.rs +++ b/crates/prover/src/programs/config.rs @@ -18,6 +18,9 @@ use { meter::Meter, start::StartMover, MiddlewareWrapper, }, std::sync::Arc, +}; +#[cfg(all(feature = "native", not(feature = "sp1")))] +use { wasmer::{Cranelift, CraneliftOptLevel, Engine, Store, Target}, wasmer_compiler_singlepass::Singlepass, }; @@ -178,7 +181,7 @@ impl CompileConfig { config } - #[cfg(feature = "native")] + #[cfg(all(feature = "native", not(feature = "sp1")))] fn engine_type(&self, target: Target, cranelift: bool) -> Engine { use wasmer::sys::EngineBuilder; @@ -217,13 +220,13 @@ impl CompileConfig { .into() } - #[cfg(feature = "native")] + #[cfg(all(feature = "native", not(feature = "sp1")))] // cranelift only matters for compilation and not usually needed pub fn engine(&self, target: Target) -> Engine { self.engine_type(target, true) } - #[cfg(feature = "native")] + #[cfg(all(feature = "native", not(feature = "sp1")))] pub fn store(&self, target: Target, cranelift: bool) -> Store { Store::new(self.engine_type(target, cranelift)) } From fbc43edf1d53c27b4edf9b156ea869aa15aab275 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 10 Mar 2026 17:09:30 +0100 Subject: [PATCH 088/189] Migrate counter.rs --- arbitrator/prover/src/programs/counter.rs | 158 ---------------------- crates/prover/src/programs/counter.rs | 5 + 2 files changed, 5 insertions(+), 158 deletions(-) delete mode 100644 arbitrator/prover/src/programs/counter.rs diff --git a/arbitrator/prover/src/programs/counter.rs b/arbitrator/prover/src/programs/counter.rs deleted file mode 100644 index 95fce3f5e6f..00000000000 --- a/arbitrator/prover/src/programs/counter.rs +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright 2021-2023, Offchain Labs, Inc. -// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md - -use super::{FuncMiddleware, Middleware, ModuleMod}; - -#[cfg(feature = "sp1")] -use crate::operator::{OperatorCode, OperatorInfo}; -#[cfg(not(feature = "sp1"))] -use arbutil::operator::{OperatorCode, OperatorInfo}; -use eyre::{Result, eyre}; -use fnv::FnvHashMap as HashMap; -use lazy_static::lazy_static; -use parking_lot::Mutex; -use std::collections::BTreeMap; -use std::{clone::Clone, fmt::Debug, sync::Arc}; -use wasmer_types::{GlobalIndex, GlobalInit, LocalFunctionIndex, Type}; -use wasmparser::Operator; - -lazy_static! { - /// Assigns each operator a sequential offset - pub static ref OP_OFFSETS: Mutex> = Mutex::new(HashMap::default()); -} - -#[derive(Debug)] -pub struct Counter { - /// Assigns each relative offset a global variable - pub counters: Arc>>, -} - -impl Counter { - pub fn new() -> Self { - let counters = Arc::new(Mutex::new(Vec::with_capacity(OperatorCode::OPERATOR_COUNT))); - Self { counters } - } - - pub fn global_name(index: usize) -> String { - format!("stylus_opcode{index}_count") - } -} - -impl Default for Counter { - fn default() -> Self { - Self::new() - } -} - -impl Middleware for Counter -where - M: ModuleMod, -{ - type FM<'a> = FuncCounter<'a>; - - fn update_module(&self, module: &mut M) -> Result<()> { - let mut counters = self.counters.lock(); - for index in 0..OperatorCode::OPERATOR_COUNT { - let zero_count = GlobalInit::I64Const(0); - let global = module.add_global(&Self::global_name(index), Type::I64, zero_count)?; - counters.push(global); - } - Ok(()) - } - - fn instrument<'a>(&self, _: LocalFunctionIndex) -> Result> { - Ok(FuncCounter::new(self.counters.clone())) - } - - fn name(&self) -> &'static str { - "operator counter" - } -} - -#[derive(Debug)] -pub struct FuncCounter<'a> { - /// Assigns each relative offset a global variable - counters: Arc>>, - /// Instructions of the current basic block - block: Vec>, -} - -impl FuncCounter<'_> { - fn new(counters: Arc>>) -> Self { - let block = vec![]; - Self { counters, block } - } -} - -impl<'a> FuncMiddleware<'a> for FuncCounter<'a> { - fn feed(&mut self, op: Operator<'a>, out: &mut O) -> Result<()> - where - O: Extend>, - { - use Operator::*; - - let end = op.ends_basic_block(); - self.block.push(op); - - if end { - let update = |global_index: u32, value: i64| { - [ - GlobalGet { global_index }, - I64Const { value }, - I64Add, - GlobalSet { global_index }, - ] - }; - - // there's always at least one op, so we chain the instrumentation - let mut increments = HashMap::default(); - for op in self.block.iter().chain(update(0, 0).iter()) { - let count = increments.entry(op.code()).or_default(); - *count += 1; - } - - // add the instrumentation's contribution to the overall counts - let kinds = increments.len() as i64; - for op in update(0, 0) { - let count = increments.get_mut(&op.code()).unwrap(); - *count += kinds - 1; // we included one in the last loop - } - - let counters = self.counters.lock(); - let mut operators = OP_OFFSETS.lock(); - for (op, count) in increments { - let opslen = operators.len(); - let offset = *operators.entry(op).or_insert(opslen); - let global = *counters.get(offset).ok_or_else(|| eyre!("no global"))?; - out.extend(update(global.as_u32(), count)); - } - - out.extend(self.block.drain(..)); - } - Ok(()) - } - - fn name(&self) -> &'static str { - "operator counter" - } -} - -pub trait CountingMachine { - fn operator_counts(&mut self) -> Result>; -} - -#[cfg(not(feature = "sp1"))] -impl CountingMachine for crate::Machine { - fn operator_counts(&mut self) -> Result> { - let mut counts = BTreeMap::new(); - - for (&op, &offset) in OP_OFFSETS.lock().iter() { - let count = self.get_global(&Counter::global_name(offset))?; - let count: u64 = count.try_into()?; - if count != 0 { - counts.insert(op, count); - } - } - Ok(counts) - } -} diff --git a/crates/prover/src/programs/counter.rs b/crates/prover/src/programs/counter.rs index 4c7aac2f4c9..86dfc70c35d 100644 --- a/crates/prover/src/programs/counter.rs +++ b/crates/prover/src/programs/counter.rs @@ -2,8 +2,12 @@ // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md use super::{FuncMiddleware, Middleware, ModuleMod}; +#[cfg(not(feature = "sp1"))] use crate::Machine; +#[cfg(feature = "sp1")] +use crate::operator::{OperatorCode, OperatorInfo}; +#[cfg(not(feature = "sp1"))] use arbutil::operator::{OperatorCode, OperatorInfo}; use eyre::{eyre, Result}; use fnv::FnvHashMap as HashMap; @@ -139,6 +143,7 @@ pub trait CountingMachine { fn operator_counts(&mut self) -> Result>; } +#[cfg(not(feature = "sp1"))] impl CountingMachine for Machine { fn operator_counts(&mut self) -> Result> { let mut counts = BTreeMap::new(); From 091a09cbad2ea0111bd5c6026a81bdd208090d11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 10 Mar 2026 17:12:16 +0100 Subject: [PATCH 089/189] Migrate depth.rs --- arbitrator/prover/src/programs/depth.rs | 545 ------------------------ crates/prover/src/programs/depth.rs | 10 +- 2 files changed, 9 insertions(+), 546 deletions(-) delete mode 100644 arbitrator/prover/src/programs/depth.rs diff --git a/arbitrator/prover/src/programs/depth.rs b/arbitrator/prover/src/programs/depth.rs deleted file mode 100644 index 6e9c557119e..00000000000 --- a/arbitrator/prover/src/programs/depth.rs +++ /dev/null @@ -1,545 +0,0 @@ -// Copyright 2022-2023, Offchain Labs, Inc. -// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md - -use super::{ - FuncMiddleware, Middleware, ModuleMod, - config::{CompileMemoryParams, SigMap}, -}; -use crate::value::{FunctionType, InternalFunc}; - -use arbutil::Color; -use eyre::{Result, bail}; -use fnv::FnvHashMap as HashMap; -use parking_lot::RwLock; -use std::sync::Arc; -use wasmer_types::{ - FunctionIndex, GlobalIndex, GlobalInit, LocalFunctionIndex, SignatureIndex, Type, -}; -use wasmparser::{BlockType, Operator, ValType}; - -pub const STYLUS_STACK_LEFT: &str = "stylus_stack_left"; - -/// This middleware ensures stack overflows are deterministic across different compilers and targets. -/// The internal notion of "stack space left" that makes this possible is strictly smaller than that of -/// the real stack space consumed on any target platform and is formed by inspecting the contents of each -/// function's frame. -/// Setting a limit smaller than that of any native platform's ensures stack overflows will have the same, -/// logical effect rather than actually exhausting the space provided by the OS. -#[derive(Debug)] -pub struct DepthChecker { - /// The amount of stack space left - global: RwLock>, - /// The maximum size of a stack frame, measured in words - frame_limit: u32, - /// The maximum number of overlapping value lifetimes in a frame - frame_contention: u16, - /// The function types of the module being instrumented - funcs: RwLock>>>, - /// The types of the module being instrumented - sigs: RwLock>>, -} - -impl DepthChecker { - pub fn new(params: CompileMemoryParams) -> Self { - Self { - global: RwLock::default(), - frame_limit: params.max_frame_size, - frame_contention: params.max_frame_contention, - funcs: RwLock::default(), - sigs: RwLock::default(), - } - } - - pub fn globals(&self) -> GlobalIndex { - self.global.read().unwrap() - } -} - -impl Middleware for DepthChecker { - type FM<'a> = FuncDepthChecker<'a>; - - fn update_module(&self, module: &mut M) -> Result<()> { - let limit = GlobalInit::I32Const(0); - let space = module.add_global(STYLUS_STACK_LEFT, Type::I32, limit)?; - *self.global.write() = Some(space); - *self.funcs.write() = Some(Arc::new(module.all_functions()?)); - *self.sigs.write() = Some(Arc::new(module.all_signatures()?)); - Ok(()) - } - - fn instrument<'a>(&self, func: LocalFunctionIndex) -> Result> { - Ok(FuncDepthChecker::new( - self.global.read().expect("no global"), - self.funcs.read().clone().expect("no funcs"), - self.sigs.read().clone().expect("no sigs"), - self.frame_limit, - self.frame_contention, - func, - )) - } - - fn name(&self) -> &'static str { - "depth checker" - } -} - -#[derive(Debug)] -pub struct FuncDepthChecker<'a> { - /// The amount of stack space left - global: GlobalIndex, - /// The function types in this function's module - funcs: Arc>, - /// All the types in this function's modules - sigs: Arc>, - /// The number of local variables this func has - locals: Option, - /// The function being instrumented - func: LocalFunctionIndex, - /// The maximum size of a stack frame, measured in words - frame_limit: u32, - /// The maximum number of overlapping value lifetimes in a frame - frame_contention: u16, - /// The number of open scopes - scopes: isize, - /// The entirety of the func's original instructions - code: Vec>, - /// True once it's statically known feed() won't be called again - done: bool, -} - -impl FuncDepthChecker<'_> { - fn new( - global: GlobalIndex, - funcs: Arc>, - sigs: Arc>, - frame_limit: u32, - frame_contention: u16, - func: LocalFunctionIndex, - ) -> Self { - Self { - global, - funcs, - sigs, - locals: None, - func, - frame_limit, - frame_contention, - scopes: 1, // a function starts with an open scope - code: vec![], - done: false, - } - } -} - -impl<'a> FuncMiddleware<'a> for FuncDepthChecker<'a> { - fn locals_info(&mut self, locals: &[ValType]) { - self.locals = Some(locals.len()); - } - - fn feed(&mut self, op: Operator<'a>, out: &mut O) -> Result<()> - where - O: Extend>, - { - use Operator::*; - - // Knowing when the feed ends requires detecting the final instruction, which is - // guaranteed to be an "End" opcode closing out function's initial opening scope. - if self.done { - bail!("finalized too soon"); - } - - let scopes = &mut self.scopes; - match op { - Block { .. } | Loop { .. } | If { .. } => *scopes += 1, - End => *scopes -= 1, - _ => {} - } - if *scopes < 0 { - bail!("malformed scoping detected"); - } - - let last = *scopes == 0 && matches!(op, End); // true when the feed ends - self.code.push(op); - if !last { - return Ok(()); - } - - // We've reached the final instruction and can instrument the function as follows: - // - When entering, check that the stack has sufficient space and deduct the amount used - // - When returning, credit back the amount used - - let size = self.worst_case_depth()?; - let global_index = self.global.as_u32(); - - if size > self.frame_limit { - let limit = self.frame_limit.red(); - bail!("frame too large: {} > {}-word limit", size.red(), limit); - } - - let blockty = BlockType::Empty; - out.extend([ - // if space <= size => panic with depth = 0 - GlobalGet { global_index }, - I32Const { value: size as i32 }, - I32LeU, - If { blockty }, - I32Const { value: 0 }, - GlobalSet { global_index }, - Unreachable, - End, - // space -= size - GlobalGet { global_index }, - I32Const { value: size as i32 }, - I32Sub, - GlobalSet { global_index }, - ]); - - let reclaim = |out: &mut O| { - out.extend([ - // space += size - GlobalGet { global_index }, - I32Const { value: size as i32 }, - I32Add, - GlobalSet { global_index }, - ]) - }; - - // add an extraneous return instruction to the end to match Arbitrator - let mut code = std::mem::take(&mut self.code); - let last = code.pop().unwrap(); - code.push(Return); - code.push(last); - - for op in code { - let exit = matches!(op, Return); - if exit { - reclaim(out); - } - out.extend([op]); - } - - self.done = true; - Ok(()) - } - - fn name(&self) -> &'static str { - "depth checker" - } -} - -impl FuncDepthChecker<'_> { - fn worst_case_depth(&self) -> Result { - use Operator::*; - - let mut worst: u32 = 0; - let mut stack: u32 = 0; - - macro_rules! push { - ($count:expr) => {{ - stack += $count; - worst = worst.max(stack); - }}; - () => { - push!(1) - }; - } - macro_rules! pop { - ($count:expr) => {{ - stack = stack.saturating_sub($count); - }}; - () => { - pop!(1) - }; - } - macro_rules! ins_and_outs { - ($ty:expr) => {{ - let ins = $ty.inputs.len() as u32; - let outs = $ty.outputs.len() as u32; - push!(outs); - pop!(ins); - }}; - } - macro_rules! op { - ($first:ident $(,$opcode:ident)* $(,)?) => { - $first $(| $opcode)* - }; - } - macro_rules! dot { - ($first:ident $(,$opcode:ident)* $(,)?) => { - $first { .. } $(| $opcode { .. })* - }; - } - #[rustfmt::skip] - macro_rules! block_type { - ($ty:expr) => {{ - match $ty { - BlockType::Empty => {} - BlockType::Type(_) => push!(1), - BlockType::FuncType(id) => { - let index = SignatureIndex::from_u32(*id); - let Some(ty) = self.sigs.get(&index) else { - bail!("missing type for func {}", id.red()) - }; - ins_and_outs!(ty); - } - } - }}; - } - - let mut scopes = vec![stack]; - - for op in &self.code { - #[rustfmt::skip] - match op { - Block { blockty } => { - block_type!(blockty); // we'll say any return slots have been pre-allocated - scopes.push(stack); - } - Loop { blockty } => { - block_type!(blockty); // return slots - scopes.push(stack); - } - If { blockty } => { - pop!(); // pop the conditional - block_type!(blockty); // return slots - scopes.push(stack); - } - Else => { - stack = match scopes.last() { - Some(scope) => *scope, - None => bail!("malformed if-else scope"), - }; - } - End => { - stack = match scopes.pop() { - Some(stack) => stack, - None => bail!("malformed scoping detected at end of block"), - }; - } - - Call { function_index } => { - let index = FunctionIndex::from_u32(*function_index); - let Some(ty) = self.funcs.get(&index) else { - bail!("missing type for func {}", function_index.red()) - }; - ins_and_outs!(ty) - } - CallIndirect { type_index, .. } => { - let index = SignatureIndex::from_u32(*type_index); - let Some(ty) = self.sigs.get(&index) else { - bail!("missing type for signature {}", type_index.red()) - }; - ins_and_outs!(ty); - pop!() // the table index - } - - MemoryFill { .. } => ins_and_outs!(InternalFunc::MemoryFill.ty()), - MemoryCopy { .. } => ins_and_outs!(InternalFunc::MemoryCopy.ty()), - - op!( - Nop, Unreachable, - I32Eqz, I64Eqz, I32Clz, I32Ctz, I32Popcnt, I64Clz, I64Ctz, I64Popcnt, - ) - | dot!( - Br, Return, - LocalTee, MemoryGrow, - I32Load, I64Load, F32Load, F64Load, - I32Load8S, I32Load8U, I32Load16S, I32Load16U, I64Load8S, I64Load8U, - I64Load16S, I64Load16U, I64Load32S, I64Load32U, - I32WrapI64, I64ExtendI32S, I64ExtendI32U, - I32Extend8S, I32Extend16S, I64Extend8S, I64Extend16S, I64Extend32S, - F32Abs, F32Neg, F32Ceil, F32Floor, F32Trunc, F32Nearest, F32Sqrt, - F64Abs, F64Neg, F64Ceil, F64Floor, F64Trunc, F64Nearest, F64Sqrt, - I32TruncF32S, I32TruncF32U, I32TruncF64S, I32TruncF64U, - I64TruncF32S, I64TruncF32U, I64TruncF64S, I64TruncF64U, - F32ConvertI32S, F32ConvertI32U, F32ConvertI64S, F32ConvertI64U, F32DemoteF64, - F64ConvertI32S, F64ConvertI32U, F64ConvertI64S, F64ConvertI64U, F64PromoteF32, - I32ReinterpretF32, I64ReinterpretF64, F32ReinterpretI32, F64ReinterpretI64, - I32TruncSatF32S, I32TruncSatF32U, I32TruncSatF64S, I32TruncSatF64U, - I64TruncSatF32S, I64TruncSatF32U, I64TruncSatF64S, I64TruncSatF64U, - ) => {} - - dot!( - LocalGet, GlobalGet, MemorySize, - I32Const, I64Const, F32Const, F64Const, - ) => push!(), - - op!( - Drop, - I32Eq, I32Ne, I32LtS, I32LtU, I32GtS, I32GtU, I32LeS, I32LeU, I32GeS, I32GeU, - I64Eq, I64Ne, I64LtS, I64LtU, I64GtS, I64GtU, I64LeS, I64LeU, I64GeS, I64GeU, - F32Eq, F32Ne, F32Lt, F32Gt, F32Le, F32Ge, - F64Eq, F64Ne, F64Lt, F64Gt, F64Le, F64Ge, - I32Add, I32Sub, I32Mul, I32DivS, I32DivU, I32RemS, I32RemU, - I64Add, I64Sub, I64Mul, I64DivS, I64DivU, I64RemS, I64RemU, - I32And, I32Or, I32Xor, I32Shl, I32ShrS, I32ShrU, I32Rotl, I32Rotr, - I64And, I64Or, I64Xor, I64Shl, I64ShrS, I64ShrU, I64Rotl, I64Rotr, - F32Add, F32Sub, F32Mul, F32Div, F32Min, F32Max, F32Copysign, - F64Add, F64Sub, F64Mul, F64Div, F64Min, F64Max, F64Copysign, - ) - | dot!(BrIf, BrTable, LocalSet, GlobalSet) => pop!(), - - dot!( - Select, - I32Store, I64Store, F32Store, F64Store, I32Store8, I32Store16, I64Store8, I64Store16, I64Store32, - ) => pop!(2), - - unsupported @ dot!(Try, Catch, Throw, Rethrow, ThrowRef, TryTable) => { - bail!("exception-handling extension not supported {unsupported:?}") - }, - - unsupported @ dot!(ReturnCall, ReturnCallIndirect) => { - bail!("tail-call extension not supported {unsupported:?}") - } - - unsupported @ dot!(CallRef, ReturnCallRef) => { - bail!("typed function references extension not supported {unsupported:?}") - } - - unsupported @ (dot!(Delegate) | op!(CatchAll)) => { - bail!("exception-handling extension not supported {unsupported:?}") - }, - - unsupported @ (op!(RefIsNull) | dot!(TypedSelect, RefNull, RefFunc, RefEq)) => { - bail!("reference-types extension not supported {unsupported:?}") - }, - - unsupported @ dot!(RefAsNonNull, BrOnNull, BrOnNonNull) => { - bail!("typed function references extension not supported {unsupported:?}") - }, - - unsupported @ ( - dot!( - MemoryInit, DataDrop, TableInit, ElemDrop, - TableCopy, TableFill, TableGet, TableSet, TableGrow, TableSize - ) - ) => bail!("bulk-memory-operations extension not fully supported {unsupported:?}"), - - unsupported @ dot!(MemoryDiscard) => { - bail!("typed function references extension not supported {unsupported:?}") - } - - unsupported @ ( - dot!( - StructNew, StructNewDefault, StructGet, StructGetS, StructGetU, StructSet, - ArrayNew, ArrayNewDefault, ArrayNewFixed, ArrayNewData, ArrayNewElem, - ArrayGet, ArrayGetS, ArrayGetU, ArraySet, ArrayLen, ArrayFill, ArrayCopy, - ArrayInitData, ArrayInitElem, - RefTestNonNull, RefTestNullable, RefCastNonNull, RefCastNullable, - BrOnCast, BrOnCastFail, AnyConvertExtern, ExternConvertAny, RefI31, I31GetS, I31GetU - ) - ) => bail!("garbage collection extension not supported {unsupported:?}"), - - unsupported @ ( - dot!( - MemoryAtomicNotify, MemoryAtomicWait32, MemoryAtomicWait64, AtomicFence, I32AtomicLoad, - I64AtomicLoad, I32AtomicLoad8U, I32AtomicLoad16U, I64AtomicLoad8U, I64AtomicLoad16U, - I64AtomicLoad32U, I32AtomicStore, I64AtomicStore, I32AtomicStore8, I32AtomicStore16, - I64AtomicStore8, I64AtomicStore16, I64AtomicStore32, I32AtomicRmwAdd, I64AtomicRmwAdd, - I32AtomicRmw8AddU, I32AtomicRmw16AddU, - I64AtomicRmw8AddU, I64AtomicRmw16AddU, I64AtomicRmw32AddU, - I32AtomicRmwSub, I64AtomicRmwSub, I32AtomicRmw8SubU, I32AtomicRmw16SubU, I64AtomicRmw8SubU, - I64AtomicRmw16SubU, I64AtomicRmw32SubU, I32AtomicRmwAnd, I64AtomicRmwAnd, I32AtomicRmw8AndU, - I32AtomicRmw16AndU, I64AtomicRmw8AndU, I64AtomicRmw16AndU, I64AtomicRmw32AndU, I32AtomicRmwOr, - I64AtomicRmwOr, I32AtomicRmw8OrU, I32AtomicRmw16OrU, I64AtomicRmw8OrU, I64AtomicRmw16OrU, - I64AtomicRmw32OrU, I32AtomicRmwXor, I64AtomicRmwXor, I32AtomicRmw8XorU, I32AtomicRmw16XorU, - I64AtomicRmw8XorU, I64AtomicRmw16XorU, I64AtomicRmw32XorU, I32AtomicRmwXchg, I64AtomicRmwXchg, - I32AtomicRmw8XchgU, I32AtomicRmw16XchgU, I64AtomicRmw8XchgU, I64AtomicRmw16XchgU, - I64AtomicRmw32XchgU, I32AtomicRmwCmpxchg, I64AtomicRmwCmpxchg, I32AtomicRmw8CmpxchgU, - I32AtomicRmw16CmpxchgU, I64AtomicRmw8CmpxchgU, I64AtomicRmw16CmpxchgU, I64AtomicRmw32CmpxchgU - ) - ) => bail!("threads extension not supported {unsupported:?}"), - - unsupported @ ( - dot!( - V128Load, V128Load8x8S, V128Load8x8U, V128Load16x4S, V128Load16x4U, V128Load32x2S, - V128Load8Splat, V128Load16Splat, V128Load32Splat, V128Load64Splat, V128Load32Zero, - V128Load64Zero, V128Load32x2U, - V128Store, V128Load8Lane, V128Load16Lane, V128Load32Lane, V128Load64Lane, V128Store8Lane, - V128Store16Lane, V128Store32Lane, V128Store64Lane, V128Const, - I8x16Shuffle, I8x16ExtractLaneS, I8x16ExtractLaneU, I8x16ReplaceLane, I16x8ExtractLaneS, - I16x8ExtractLaneU, I16x8ReplaceLane, I32x4ExtractLane, I32x4ReplaceLane, I64x2ExtractLane, - I64x2ReplaceLane, F32x4ExtractLane, F32x4ReplaceLane, F64x2ExtractLane, F64x2ReplaceLane, - I8x16Swizzle, I8x16Splat, I16x8Splat, I32x4Splat, I64x2Splat, F32x4Splat, F64x2Splat, I8x16Eq, - I8x16Ne, I8x16LtS, I8x16LtU, I8x16GtS, I8x16GtU, I8x16LeS, I8x16LeU, I8x16GeS, I8x16GeU, - I16x8Eq, I16x8Ne, I16x8LtS, I16x8LtU, I16x8GtS, I16x8GtU, I16x8LeS, I16x8LeU, I16x8GeS, - I16x8GeU, I32x4Eq, I32x4Ne, I32x4LtS, I32x4LtU, I32x4GtS, I32x4GtU, I32x4LeS, I32x4LeU, - I32x4GeS, I32x4GeU, I64x2Eq, I64x2Ne, I64x2LtS, I64x2GtS, I64x2LeS, I64x2GeS, - F32x4Eq, F32x4Ne, F32x4Lt, F32x4Gt, F32x4Le, F32x4Ge, - F64x2Eq, F64x2Ne, F64x2Lt, F64x2Gt, F64x2Le, F64x2Ge, - V128Not, V128And, V128AndNot, V128Or, V128Xor, V128Bitselect, V128AnyTrue, - I8x16Abs, I8x16Neg, I8x16Popcnt, I8x16AllTrue, I8x16Bitmask, - I8x16NarrowI16x8S, I8x16NarrowI16x8U, - I8x16Shl, I8x16ShrS, I8x16ShrU, I8x16Add, I8x16AddSatS, I8x16AddSatU, I8x16Sub, I8x16SubSatS, - I8x16SubSatU, I8x16MinS, I8x16MinU, I8x16MaxS, I8x16MaxU, I8x16AvgrU, - I16x8ExtAddPairwiseI8x16S, I16x8ExtAddPairwiseI8x16U, I16x8Abs, I16x8Neg, I16x8Q15MulrSatS, - I16x8AllTrue, I16x8Bitmask, I16x8NarrowI32x4S, I16x8NarrowI32x4U, I16x8ExtendLowI8x16S, - I16x8ExtendHighI8x16S, I16x8ExtendLowI8x16U, I16x8ExtendHighI8x16U, - I16x8Shl, I16x8ShrS, I16x8ShrU, I16x8Add, I16x8AddSatS, I16x8AddSatU, - I16x8Sub, I16x8SubSatS, I16x8SubSatU, I16x8Mul, I16x8MinS, I16x8MinU, - I16x8MaxS, I16x8MaxU, I16x8AvgrU, I16x8ExtMulLowI8x16S, - I16x8ExtMulHighI8x16S, I16x8ExtMulLowI8x16U, I16x8ExtMulHighI8x16U, - I32x4ExtAddPairwiseI16x8U, I32x4Abs, I32x4Neg, I32x4AllTrue, I32x4Bitmask, - I32x4ExtAddPairwiseI16x8S, I32x4ExtendLowI16x8S, I32x4ExtendHighI16x8S, I32x4ExtendLowI16x8U, - I32x4ExtendHighI16x8U, I32x4Shl, I32x4ShrS, I32x4ShrU, I32x4Add, I32x4Sub, I32x4Mul, - I32x4MinS, I32x4MinU, I32x4MaxS, I32x4MaxU, I32x4DotI16x8S, - I32x4ExtMulLowI16x8S, I32x4ExtMulHighI16x8S, I32x4ExtMulLowI16x8U, I32x4ExtMulHighI16x8U, - I64x2Abs, I64x2Neg, I64x2AllTrue, I64x2Bitmask, I64x2ExtendLowI32x4S, I64x2ExtendHighI32x4S, - I64x2ExtendLowI32x4U, I64x2ExtendHighI32x4U, I64x2Shl, I64x2ShrS, I64x2ShrU, I64x2Add, - I64x2ExtMulLowI32x4S, I64x2ExtMulHighI32x4S, I64x2Sub, I64x2Mul, - I64x2ExtMulLowI32x4U, I64x2ExtMulHighI32x4U, F32x4Ceil, F32x4Floor, F32x4Trunc, - F32x4Nearest, F32x4Abs, F32x4Neg, F32x4Sqrt, F32x4Add, F32x4Sub, F32x4Mul, F32x4Div, - F32x4Min, F32x4Max, F32x4PMin, F32x4PMax, F64x2Ceil, F64x2Floor, F64x2Trunc, - F64x2Nearest, F64x2Abs, F64x2Neg, F64x2Sqrt, F64x2Add, F64x2Sub, F64x2Mul, F64x2Div, F64x2Min, - F64x2Max, F64x2PMin, F64x2PMax, I32x4TruncSatF32x4S, I32x4TruncSatF32x4U, F32x4ConvertI32x4S, - F32x4ConvertI32x4U, I32x4TruncSatF64x2SZero, I32x4TruncSatF64x2UZero, F64x2ConvertLowI32x4S, - F64x2ConvertLowI32x4U, F32x4DemoteF64x2Zero, F64x2PromoteLowF32x4, I8x16RelaxedSwizzle, - I32x4RelaxedTruncF32x4S, I32x4RelaxedTruncF32x4U, I32x4RelaxedTruncF64x2SZero, - I32x4RelaxedTruncF64x2UZero, F32x4RelaxedMadd, F32x4RelaxedNmadd, F64x2RelaxedMadd, - F64x2RelaxedNmadd, I8x16RelaxedLaneselect, I16x8RelaxedLaneselect, I32x4RelaxedLaneselect, - I64x2RelaxedLaneselect, F32x4RelaxedMin, F32x4RelaxedMax, F64x2RelaxedMin, F64x2RelaxedMax, - I16x8RelaxedQ15mulrS, I16x8RelaxedDotI8x16I7x16S, I32x4RelaxedDotI8x16I7x16AddS - ) - ) => bail!("SIMD extension not supported {unsupported:?}"), - - #[cfg(feature = "sp1")] - _ => todo!("New operator not covered yet by nitro!") - }; - } - - if self.locals.is_none() { - bail!("missing locals info for func {}", self.func.as_u32().red()) - } - - let contention = worst; - if contention > self.frame_contention.into() { - bail!( - "too many values on the stack at once in func {}: {} > {}", - self.func.as_u32().red(), - contention.red(), - self.frame_contention.red() - ); - } - - let locals = self.locals.unwrap_or_default(); - Ok(worst + locals as u32 + 4) - } -} - -/// Note: implementers may panic if uninstrumented -pub trait DepthCheckedMachine { - fn stack_left(&mut self) -> u32; - fn set_stack(&mut self, size: u32); -} - -#[cfg(not(feature = "sp1"))] -impl DepthCheckedMachine for crate::Machine { - fn stack_left(&mut self) -> u32 { - let global = self.get_global(STYLUS_STACK_LEFT).unwrap(); - global.try_into().expect("instrumentation type mismatch") - } - - fn set_stack(&mut self, size: u32) { - self.set_global(STYLUS_STACK_LEFT, size.into()).unwrap(); - } -} diff --git a/crates/prover/src/programs/depth.rs b/crates/prover/src/programs/depth.rs index 1dcb77174b6..084eefde6da 100644 --- a/crates/prover/src/programs/depth.rs +++ b/crates/prover/src/programs/depth.rs @@ -5,7 +5,11 @@ use super::{ config::{CompileMemoryParams, SigMap}, FuncMiddleware, Middleware, ModuleMod, }; -use crate::{host::InternalFunc, value::FunctionType, Machine}; +#[cfg(not(feature = "sp1"))] +use crate::{host::InternalFunc, Machine}; +#[cfg(feature = "sp1")] +use crate::value::InternalFunc; +use crate::value::FunctionType; use arbutil::Color; use eyre::{bail, Result}; @@ -501,6 +505,9 @@ impl FuncDepthChecker<'_> { I16x8RelaxedQ15mulrS, I16x8RelaxedDotI8x16I7x16S, I32x4RelaxedDotI8x16I7x16AddS ) ) => bail!("SIMD extension not supported {unsupported:?}"), + + #[cfg(feature = "sp1")] + _ => todo!("New operator not covered yet by nitro!") }; } @@ -529,6 +536,7 @@ pub trait DepthCheckedMachine { fn set_stack(&mut self, size: u32); } +#[cfg(not(feature = "sp1"))] impl DepthCheckedMachine for Machine { fn stack_left(&mut self) -> u32 { let global = self.get_global(STYLUS_STACK_LEFT).unwrap(); From 9e3745b1a2123c45a7cf775cc62a44ec3058aa8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 10 Mar 2026 17:12:34 +0100 Subject: [PATCH 090/189] Remove some modules (unneeded) --- arbitrator/prover/src/programs/dynamic.rs | 154 ---------------------- arbitrator/prover/src/programs/heap.rs | 117 ---------------- arbitrator/prover/src/programs/memory.rs | 127 ------------------ 3 files changed, 398 deletions(-) delete mode 100644 arbitrator/prover/src/programs/dynamic.rs delete mode 100644 arbitrator/prover/src/programs/heap.rs delete mode 100644 arbitrator/prover/src/programs/memory.rs diff --git a/arbitrator/prover/src/programs/dynamic.rs b/arbitrator/prover/src/programs/dynamic.rs deleted file mode 100644 index 99c35361444..00000000000 --- a/arbitrator/prover/src/programs/dynamic.rs +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright 2023, Offchain Labs, Inc. -// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md - -use super::{ - FuncMiddleware, Middleware, ModuleMod, - config::CompilePricingParams, - meter::{STYLUS_INK_LEFT, STYLUS_INK_STATUS}, -}; -use eyre::{Result, bail}; -use parking_lot::RwLock; -use wasmer_types::{GlobalIndex, GlobalInit, LocalFunctionIndex, Type}; -use wasmparser::{BlockType, Operator}; - -pub const SCRATCH_GLOBAL: &str = "stylus_scratch_global"; - -#[derive(Debug)] -pub struct DynamicMeter { - memory_fill: u64, - memory_copy: u64, - globals: RwLock>, -} - -impl DynamicMeter { - pub fn new(pricing: &CompilePricingParams) -> Self { - Self { - memory_fill: pricing.memory_fill_ink, - memory_copy: pricing.memory_copy_ink, - globals: RwLock::default(), - } - } -} - -impl Middleware for DynamicMeter { - type FM<'a> = FuncDynamicMeter; - - fn update_module(&self, module: &mut M) -> Result<()> { - let ink = module.get_global(STYLUS_INK_LEFT)?; - let status = module.get_global(STYLUS_INK_STATUS)?; - let scratch = module.add_global(SCRATCH_GLOBAL, Type::I32, GlobalInit::I32Const(0))?; - *self.globals.write() = Some([ink, status, scratch]); - Ok(()) - } - - fn instrument<'a>(&self, _: LocalFunctionIndex) -> Result> { - let globals = self.globals.read().expect("no globals"); - Ok(FuncDynamicMeter::new( - self.memory_fill, - self.memory_copy, - globals, - )) - } - - fn name(&self) -> &'static str { - "dynamic ink meter" - } -} - -#[derive(Debug)] -pub struct FuncDynamicMeter { - memory_fill: u64, - memory_copy: u64, - globals: [GlobalIndex; 3], -} - -impl FuncDynamicMeter { - fn new(memory_fill: u64, memory_copy: u64, globals: [GlobalIndex; 3]) -> Self { - Self { - memory_fill, - memory_copy, - globals, - } - } -} - -impl<'a> FuncMiddleware<'a> for FuncDynamicMeter { - fn feed(&mut self, op: Operator<'a>, out: &mut O) -> Result<()> - where - O: Extend>, - { - use Operator::*; - macro_rules! dot { - ($first:ident $(,$opcode:ident)* $(,)?) => { - $first { .. } $(| $opcode { .. })* - }; - } - macro_rules! get { - ($global:expr) => { - GlobalGet { - global_index: $global, - } - }; - } - macro_rules! set { - ($global:expr) => { - GlobalSet { - global_index: $global, - } - }; - } - - let [ink, status, scratch] = self.globals.map(|x| x.as_u32()); - let blockty = BlockType::Empty; - - #[rustfmt::skip] - let linear = |coefficient| { - [ - // [user] → move user value to scratch - set!(scratch), - get!(ink), - get!(ink), - get!(scratch), - - // [ink ink size] → cost = size * coefficient (can't overflow) - I64ExtendI32U, - I64Const { value: coefficient }, - I64Mul, - - // [ink ink cost] → ink -= cost - I64Sub, - set!(ink), - get!(ink), - - // [old_ink, new_ink] → (old_ink < new_ink) (overflow detected) - I64LtU, - If { blockty }, - I32Const { value: 1 }, - set!(status), - Unreachable, - End, - - // [] → resume since user paid for ink - get!(scratch), - ] - }; - - match op { - dot!(MemoryFill) => out.extend(linear(self.memory_fill as i64)), - dot!(MemoryCopy) => out.extend(linear(self.memory_copy as i64)), - dot!( - MemoryInit, DataDrop, ElemDrop, TableInit, TableCopy, TableFill, TableGet, - TableSet, TableGrow, TableSize - ) => { - bail!("opcode not supported") - } - _ => {} - } - out.extend([op]); - Ok(()) - } - - fn name(&self) -> &'static str { - "dynamic ink meter" - } -} diff --git a/arbitrator/prover/src/programs/heap.rs b/arbitrator/prover/src/programs/heap.rs deleted file mode 100644 index f9eeb05396f..00000000000 --- a/arbitrator/prover/src/programs/heap.rs +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright 2022-2023, Offchain Labs, Inc. -// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md - -use crate::value::{ArbValueType, FunctionType}; - -use super::{ - FuncMiddleware, Middleware, ModuleMod, config::CompileMemoryParams, dynamic::SCRATCH_GLOBAL, -}; -use arbutil::Color; -use eyre::{Result, bail}; -use parking_lot::RwLock; -use wasmer_types::{FunctionIndex, GlobalIndex, ImportIndex, LocalFunctionIndex, Pages}; -use wasmparser::Operator; - -#[derive(Debug)] -pub struct HeapBound { - /// Upper bounds the amount of heap memory a module may use - limit: Pages, - /// Import called when allocating new pages - pay_func: RwLock>, - /// Scratch global shared among middlewares - scratch: RwLock>, -} - -impl HeapBound { - const PAY_FUNC: &'static str = "pay_for_memory_grow"; - - pub fn new(bounds: CompileMemoryParams) -> Self { - Self { - limit: bounds.heap_bound, - pay_func: RwLock::default(), - scratch: RwLock::default(), - } - } -} - -impl Middleware for HeapBound { - type FM<'a> = FuncHeapBound; - - fn update_module(&self, module: &mut M) -> Result<()> { - let scratch = module.get_global(SCRATCH_GLOBAL)?; - *self.scratch.write() = Some(scratch); - - let memory = module.memory_info()?; - let min = memory.min; - let max = memory.max; - let lim = self.limit; - - if min > lim { - bail!("memory size {} exceeds bound {}", min.0.red(), lim.0.red()); - } - if max == Some(min) { - return Ok(()); - } - - let ImportIndex::Function(import) = module.get_import("vm_hooks", Self::PAY_FUNC)? else { - bail!("wrong import kind for {}", Self::PAY_FUNC.red()); - }; - - let ty = module.get_function(import)?; - if ty != FunctionType::new(vec![ArbValueType::I32], vec![]) { - bail!("wrong type for {}: {}", Self::PAY_FUNC.red(), ty.red()); - } - - *self.pay_func.write() = Some(import); - Ok(()) - } - - fn instrument<'a>(&self, _: LocalFunctionIndex) -> Result> { - Ok(FuncHeapBound { - scratch: self.scratch.read().expect("no scratch global"), - pay_func: *self.pay_func.read(), - }) - } - - fn name(&self) -> &'static str { - "heap bound" - } -} - -#[derive(Debug)] -pub struct FuncHeapBound { - pay_func: Option, - scratch: GlobalIndex, -} - -impl<'a> FuncMiddleware<'a> for FuncHeapBound { - fn feed(&mut self, op: Operator<'a>, out: &mut O) -> Result<()> - where - O: Extend>, - { - use Operator::*; - - let Some(pay_func) = self.pay_func else { - out.extend([op]); - return Ok(()); - }; - - let global_index = self.scratch.as_u32(); - let function_index = pay_func.as_u32(); - - if let MemoryGrow { .. } = op { - out.extend([ - GlobalSet { global_index }, - GlobalGet { global_index }, - GlobalGet { global_index }, - Call { function_index }, - ]); - } - out.extend([op]); - Ok(()) - } - - fn name(&self) -> &'static str { - "heap bound" - } -} diff --git a/arbitrator/prover/src/programs/memory.rs b/arbitrator/prover/src/programs/memory.rs deleted file mode 100644 index 104c08381a8..00000000000 --- a/arbitrator/prover/src/programs/memory.rs +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright 2023, Offchain Labs, Inc. -// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md - -use arbutil::evm::api::Gas; - -#[derive(Clone, Copy, Debug)] -#[repr(C)] -pub struct MemoryModel { - /// Number of pages a tx gets for free - pub free_pages: u16, - /// Base cost of each additional wasm page - pub page_gas: u16, -} - -impl Default for MemoryModel { - fn default() -> Self { - Self { - free_pages: u16::MAX, - page_gas: 0, - } - } -} - -impl MemoryModel { - pub const fn new(free_pages: u16, page_gas: u16) -> Self { - Self { - free_pages, - page_gas, - } - } - - /// Determines the gas cost of allocating `new` pages given `open` are active and `ever` have ever been. - pub fn gas_cost(&self, new: u16, open: u16, ever: u16) -> Gas { - let new_open = open.saturating_add(new); - let new_ever = ever.max(new_open); - - // free until expansion beyond the first few - if new_ever <= self.free_pages { - return Gas(0); - } - - let credit = |pages: u16| pages.saturating_sub(self.free_pages); - let adding = credit(new_open).saturating_sub(credit(open)) as u64; - let linear = adding.saturating_mul(self.page_gas.into()); - let expand = Self::exp(new_ever) - Self::exp(ever); - Gas(linear.saturating_add(expand)) - } - - fn exp(pages: u16) -> u64 { - MEMORY_EXPONENTS - .get(pages as usize) - .map(|&x| x.into()) - .unwrap_or(u64::MAX) - } -} - -const MEMORY_EXPONENTS: [u32; 129] = [ - 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 14, 17, 19, 22, 25, 29, 33, 38, - 43, 50, 57, 65, 75, 85, 98, 112, 128, 147, 168, 193, 221, 253, 289, 331, 379, 434, 497, 569, - 651, 745, 853, 976, 1117, 1279, 1463, 1675, 1917, 2194, 2511, 2874, 3290, 3765, 4309, 4932, - 5645, 6461, 7395, 8464, 9687, 11087, 12689, 14523, 16621, 19024, 21773, 24919, 28521, 32642, - 37359, 42758, 48938, 56010, 64104, 73368, 83971, 96106, 109994, 125890, 144082, 164904, 188735, - 216010, 247226, 282953, 323844, 370643, 424206, 485509, 555672, 635973, 727880, 833067, 953456, - 1091243, 1248941, 1429429, 1636000, 1872423, 2143012, 2452704, 2807151, 3212820, 3677113, - 4208502, 4816684, 5512756, 6309419, 7221210, 8264766, 9459129, 10826093, 12390601, 14181199, - 16230562, 18576084, 21260563, 24332984, 27849408, 31873999, -]; - -#[test] -fn test_tables() { - let base = f64::exp(31_874_000_f64.ln() / 128.); - - for pages in 0..129 { - let value = base.powi(pages.into()) as u64; - assert_eq!(value, MemoryModel::exp(pages)); - } - assert_eq!(u64::MAX, MemoryModel::exp(129)); - assert_eq!(u64::MAX, MemoryModel::exp(u16::MAX)); -} - -#[test] -fn test_model() { - let model = MemoryModel::new(2, 1000); - - for jump in 1..=128 { - let mut total = Gas(0); - let mut pages = 0; - while pages < 128 { - let jump = jump.min(128 - pages); - total += model.gas_cost(jump, pages, pages); - pages += jump; - } - assert_eq!(total, Gas(31999998)); - } - - for jump in 1..=128 { - let mut total = 0; - let mut open = 0; - let mut ever = 0; - let mut adds = 0; - while ever < 128 { - let jump = jump.min(128 - open); - total += model.gas_cost(jump, open, ever).0; - open += jump; - ever = ever.max(open); - - if ever > model.free_pages { - adds += jump.min(ever - model.free_pages) as u64; - } - - // pretend we've deallocated some pages - open -= jump / 2; - } - let expected = 31873998 + adds * model.page_gas as u64; - assert_eq!(total, expected); - } - - // check saturation - assert_eq!(Gas(u64::MAX), model.gas_cost(129, 0, 0)); - assert_eq!(Gas(u64::MAX), model.gas_cost(u16::MAX, 0, 0)); - - // check free pages - let model = MemoryModel::new(128, 1000); - assert_eq!(Gas(0), model.gas_cost(128, 0, 0)); - assert_eq!(Gas(0), model.gas_cost(128, 0, 128)); - assert_eq!(Gas(u64::MAX), model.gas_cost(129, 0, 0)); -} From 03e9a013d52b58e7ba47402da97c1e55f14d83c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 10 Mar 2026 17:15:15 +0100 Subject: [PATCH 091/189] Migrate meter.rs --- arbitrator/prover/src/programs/meter.rs | 528 ------------------------ crates/prover/src/programs/meter.rs | 12 +- 2 files changed, 10 insertions(+), 530 deletions(-) delete mode 100644 arbitrator/prover/src/programs/meter.rs diff --git a/arbitrator/prover/src/programs/meter.rs b/arbitrator/prover/src/programs/meter.rs deleted file mode 100644 index e7d3729acf4..00000000000 --- a/arbitrator/prover/src/programs/meter.rs +++ /dev/null @@ -1,528 +0,0 @@ -// Copyright 2022-2023, Offchain Labs, Inc. -// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md -#![allow(clippy::needless_lifetimes)] - -#[cfg(feature = "sp1")] -use crate::operator::OperatorInfo; -use crate::{ - programs::{ - FuncMiddleware, Middleware, ModuleMod, - config::{CompilePricingParams, PricingParams, SigMap}, - }, - value::FunctionType, -}; -#[cfg(not(feature = "sp1"))] -use arbutil::operator::OperatorInfo; -use arbutil::{ - Bytes32, - evm::{ - self, - api::{Gas, Ink}, - }, - pricing, -}; -use derivative::Derivative; -use eyre::Result; -use fnv::FnvHashMap as HashMap; -use parking_lot::RwLock; -use std::{ - fmt::{Debug, Display}, - sync::Arc, -}; -use wasmer_types::{GlobalIndex, GlobalInit, LocalFunctionIndex, SignatureIndex, Type}; -use wasmparser::{BlockType, Operator}; - -use super::config::OpCosts; - -pub const STYLUS_INK_LEFT: &str = "stylus_ink_left"; -pub const STYLUS_INK_STATUS: &str = "stylus_ink_status"; - -pub trait OpcodePricer: Fn(&Operator, &SigMap) -> u64 + Send + Sync + Clone {} - -impl OpcodePricer for T where T: Fn(&Operator, &SigMap) -> u64 + Send + Sync + Clone {} - -#[derive(Derivative)] -#[derivative(Debug)] -pub struct Meter { - /// Associates opcodes to their ink costs. - #[derivative(Debug = "ignore")] - costs: F, - /// Cost of checking the amount of ink left. - header_cost: u64, - /// Ink and ink status globals. - globals: RwLock>, - /// The types of the module being instrumented - sigs: RwLock>>, -} - -impl Meter { - pub fn new(pricing: &CompilePricingParams) -> Meter { - Self { - costs: pricing.costs, - header_cost: pricing.ink_header_cost, - globals: RwLock::default(), - sigs: RwLock::default(), - } - } -} - -impl Meter { - pub fn globals(&self) -> [GlobalIndex; 2] { - self.globals.read().expect("missing globals") - } -} - -impl Middleware for Meter -where - M: ModuleMod, - F: OpcodePricer + 'static, -{ - type FM<'a> = FuncMeter<'a, F>; - - fn update_module(&self, module: &mut M) -> Result<()> { - let start_status = GlobalInit::I32Const(0); - let ink = module.add_global(STYLUS_INK_LEFT, Type::I64, GlobalInit::I64Const(0))?; - let status = module.add_global(STYLUS_INK_STATUS, Type::I32, start_status)?; - *self.globals.write() = Some([ink, status]); - *self.sigs.write() = Some(Arc::new(module.all_signatures()?)); - Ok(()) - } - - fn instrument<'a>(&self, _: LocalFunctionIndex) -> Result> { - let [ink, status] = self.globals(); - let sigs = self.sigs.read(); - let sigs = sigs.as_ref().expect("no types"); - Ok(FuncMeter::new( - ink, - status, - self.costs.clone(), - self.header_cost, - sigs.clone(), - )) - } - - fn name(&self) -> &'static str { - "ink meter" - } -} - -#[derive(Derivative)] -#[derivative(Debug)] -pub struct FuncMeter<'a, F: OpcodePricer> { - /// Represents the amount of ink left for consumption. - ink_global: GlobalIndex, - /// Represents whether the machine is out of ink. - status_global: GlobalIndex, - /// Instructions of the current basic block. - block: Vec>, - /// The accumulated cost of the current basic block. - block_cost: u64, - /// Cost of checking the amount of ink left. - header_cost: u64, - /// Associates opcodes to their ink costs. - #[derivative(Debug = "ignore")] - costs: F, - /// The types of the module being instrumented. - sigs: Arc, -} - -impl FuncMeter<'_, F> { - fn new( - ink_global: GlobalIndex, - status_global: GlobalIndex, - costs: F, - header_cost: u64, - sigs: Arc, - ) -> Self { - Self { - ink_global, - status_global, - block: vec![], - block_cost: 0, - header_cost, - costs, - sigs, - } - } -} - -impl<'a, F: OpcodePricer> FuncMiddleware<'a> for FuncMeter<'a, F> { - fn feed(&mut self, op: Operator<'a>, out: &mut O) -> Result<()> - where - O: Extend>, - { - use Operator::*; - - let end = op.ends_basic_block(); - - let op_cost = (self.costs)(&op, &self.sigs); - let mut cost = self.block_cost.saturating_add(op_cost); - self.block_cost = cost; - self.block.push(op); - - if end { - let ink = self.ink_global.as_u32(); - let status = self.status_global.as_u32(); - let blockty = BlockType::Empty; - - // include the cost of executing the header - cost = cost.saturating_add(self.header_cost); - - out.extend([ - // if ink < cost => panic with status = 1 - GlobalGet { global_index: ink }, - I64Const { value: cost as i64 }, - I64LtU, - If { blockty }, - I32Const { value: 1 }, - GlobalSet { - global_index: status, - }, - Unreachable, - End, - // ink -= cost - GlobalGet { global_index: ink }, - I64Const { value: cost as i64 }, - I64Sub, - GlobalSet { global_index: ink }, - ]); - out.extend(self.block.drain(..)); - self.block_cost = 0; - } - Ok(()) - } - - fn name(&self) -> &'static str { - "ink meter" - } -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum MachineMeter { - Ready(Ink), - Exhausted, -} - -impl MachineMeter { - pub fn ink(self) -> Ink { - match self { - Self::Ready(ink) => ink, - Self::Exhausted => Ink(0), - } - } - - pub fn status(self) -> u32 { - match self { - Self::Ready(_) => 0, - Self::Exhausted => 1, - } - } -} - -/// We don't implement `From` since it's unclear what 0 would map to -#[allow(clippy::from_over_into)] -impl Into for MachineMeter { - fn into(self) -> Ink { - self.ink() - } -} - -impl Display for MachineMeter { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Self::Ready(ink) => write!(f, "{} ink", ink.0), - Self::Exhausted => write!(f, "exhausted"), - } - } -} - -#[derive(Debug)] -pub struct OutOfInkError; - -impl std::error::Error for OutOfInkError {} - -impl Display for OutOfInkError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "out of ink") - } -} - -/// Note: implementers may panic if uninstrumented -pub trait MeteredMachine { - fn ink_left(&self) -> MachineMeter; - fn set_meter(&mut self, meter: MachineMeter); - - fn set_ink(&mut self, ink: Ink) { - self.set_meter(MachineMeter::Ready(ink)); - } - - fn out_of_ink(&mut self) -> Result { - self.set_meter(MachineMeter::Exhausted); - Err(OutOfInkError) - } - - fn ink_ready(&mut self) -> Result { - let MachineMeter::Ready(ink_left) = self.ink_left() else { - return self.out_of_ink(); - }; - Ok(ink_left) - } - - fn buy_ink(&mut self, ink: Ink) -> Result<(), OutOfInkError> { - let ink_left = self.ink_ready()?; - if ink_left < ink { - return self.out_of_ink(); - } - self.set_ink(ink_left - ink); - Ok(()) - } - - /// Checks if the user has enough ink, but doesn't burn any - fn require_ink(&mut self, ink: Ink) -> Result<(), OutOfInkError> { - let ink_left = self.ink_ready()?; - if ink_left < ink { - return self.out_of_ink(); - } - Ok(()) - } - - /// Pays for a write into the client. - fn pay_for_write(&mut self, bytes: u32) -> Result<(), OutOfInkError> { - self.buy_ink(pricing::write_price(bytes)) - } - - /// Pays for a read into the host. - fn pay_for_read(&mut self, bytes: u32) -> Result<(), OutOfInkError> { - self.buy_ink(pricing::read_price(bytes)) - } - - /// Pays for both I/O and keccak. - fn pay_for_keccak(&mut self, bytes: u32) -> Result<(), OutOfInkError> { - self.buy_ink(pricing::keccak_price(bytes)) - } - - /// Pays for the variable costs of exponentiation. - fn pay_for_pow(&mut self, exponent: &Bytes32) -> Result<(), OutOfInkError> { - self.buy_ink(pricing::pow_price(exponent)) - } -} - -pub trait GasMeteredMachine: MeteredMachine { - fn pricing(&self) -> PricingParams; - - fn gas_left(&self) -> Result { - let pricing = self.pricing(); - match self.ink_left() { - MachineMeter::Ready(ink) => Ok(pricing.ink_to_gas(ink)), - MachineMeter::Exhausted => Err(OutOfInkError), - } - } - - fn buy_gas(&mut self, gas: Gas) -> Result<(), OutOfInkError> { - let pricing = self.pricing(); - self.buy_ink(pricing.gas_to_ink(gas)) - } - - /// Checks if the user has enough gas, but doesn't burn any - fn require_gas(&mut self, gas: Gas) -> Result<(), OutOfInkError> { - let pricing = self.pricing(); - self.require_ink(pricing.gas_to_ink(gas)) - } - - fn pay_for_evm_log(&mut self, topics: u32, data_len: u32) -> Result<(), OutOfInkError> { - let cost = (1 + topics as u64) * evm::LOG_TOPIC_GAS; - let cost = cost.saturating_add(data_len as u64 * evm::LOG_DATA_GAS); - self.buy_gas(cost) - } -} - -#[cfg(not(feature = "sp1"))] -impl MeteredMachine for crate::Machine { - fn ink_left(&self) -> MachineMeter { - macro_rules! convert { - ($global:expr) => {{ $global.unwrap().try_into().expect("type mismatch") }}; - } - - let ink = || Ink(convert!(self.get_global(STYLUS_INK_LEFT))); - let status: u32 = convert!(self.get_global(STYLUS_INK_STATUS)); - - match status { - 0 => MachineMeter::Ready(ink()), - _ => MachineMeter::Exhausted, - } - } - - fn set_meter(&mut self, meter: MachineMeter) { - let ink = meter.ink(); - let status = meter.status(); - self.set_global(STYLUS_INK_LEFT, ink.0.into()).unwrap(); - self.set_global(STYLUS_INK_STATUS, status.into()).unwrap(); - } -} - -pub fn pricing_v1(op: &Operator, tys: &HashMap) -> u64 { - use Operator::*; - - macro_rules! op { - ($first:ident $(,$opcode:ident)*) => { - $first $(| $opcode)* - }; - } - macro_rules! dot { - ($first:ident $(,$opcode:ident)*) => { - $first { .. } $(| $opcode { .. })* - }; - } - - #[rustfmt::skip] - let ink = match op { - op!(Unreachable, Return) => 1, - op!(Nop) | dot!(I32Const, I64Const) => 1, - - op!(Drop) => 9, // could be 1, but using a higher number helps limit the number of ops in BOLD - - dot!(Block, Loop) | op!(Else, End) => 1, - dot!(Br, BrIf, If) => 765, - dot!(Select) => 1250, // TODO: improve wasmer codegen - dot!(Call) => 3800, - dot!(LocalGet, LocalTee) => 75, - dot!(LocalSet) => 210, - dot!(GlobalGet) => 225, - dot!(GlobalSet) => 575, - dot!(I32Load, I32Load8S, I32Load8U, I32Load16S, I32Load16U) => 670, - dot!(I64Load, I64Load8S, I64Load8U, I64Load16S, I64Load16U, I64Load32S, I64Load32U) => 680, - dot!(I32Store, I32Store8, I32Store16) => 825, - dot!(I64Store, I64Store8, I64Store16, I64Store32) => 950, - dot!(MemorySize) => 3000, - dot!(MemoryGrow) => 8050, // rest of cost handled by memory pricer - - op!(I32Eqz, I32Eq, I32Ne, I32LtS, I32LtU, I32GtS, I32GtU, I32LeS, I32LeU, I32GeS, I32GeU) => 170, - op!(I64Eqz, I64Eq, I64Ne, I64LtS, I64LtU, I64GtS, I64GtU, I64LeS, I64LeU, I64GeS, I64GeU) => 225, - - op!(I32Clz, I32Ctz) => 210, - op!(I32Add, I32Sub) => 70, - op!(I32Mul) => 160, - op!(I32DivS, I32DivU, I32RemS, I32RemU) => 1120, - op!(I32And, I32Or, I32Xor, I32Shl, I32ShrS, I32ShrU, I32Rotl, I32Rotr) => 70, - - op!(I64Clz, I64Ctz) => 210, - op!(I64Add, I64Sub) => 100, - op!(I64Mul) => 160, - op!(I64DivS, I64DivU, I64RemS, I64RemU) => 1270, - op!(I64And, I64Or, I64Xor, I64Shl, I64ShrS, I64ShrU, I64Rotl, I64Rotr) => 100, - - op!(I32Popcnt) => 2650, // slow on ARM, fast on x86 - op!(I64Popcnt) => 6000, // slow on ARM, fast on x86 - - op!(I32WrapI64, I64ExtendI32S, I64ExtendI32U) => 100, - op!(I32Extend8S, I32Extend16S, I64Extend8S, I64Extend16S, I64Extend32S) => 100, - dot!(MemoryCopy) => 950, - dot!(MemoryFill) => 950, - - BrTable { targets } => { - 2400 + 325 * targets.len() as u64 - }, - CallIndirect { type_index, .. } => { - let ty = tys.get(&SignatureIndex::from_u32(*type_index)).expect("no type"); - 13610 + 650 * ty.inputs.len() as u64 - }, - - // we don't support the following, so return u64::MAX - dot!( - Try, Catch, CatchAll, Delegate, Throw, Rethrow, ThrowRef, TryTable, - - RefNull, RefIsNull, RefFunc, RefEq, - - CallRef, ReturnCallRef, RefAsNonNull, BrOnNull, BrOnNonNull, - - TypedSelect, ReturnCall, ReturnCallIndirect, - - MemoryInit, DataDrop, TableInit, ElemDrop, - TableCopy, TableFill, TableGet, TableSet, TableGrow, TableSize, - - MemoryDiscard, - - StructNew, StructNewDefault, StructGet, StructGetS, StructGetU, StructSet, - ArrayNew, ArrayNewDefault, ArrayNewFixed, ArrayNewData, ArrayNewElem, - ArrayGet, ArrayGetS, ArrayGetU, ArraySet, ArrayLen, ArrayFill, ArrayCopy, - ArrayInitData, ArrayInitElem, RefTestNonNull, RefTestNullable, RefCastNonNull, RefCastNullable, - BrOnCast, BrOnCastFail, AnyConvertExtern, ExternConvertAny, RefI31, I31GetS, I31GetU, - - F32Load, F64Load, F32Store, F64Store, F32Const, F64Const, - F32Eq, F32Ne, F32Lt, F32Gt, F32Le, F32Ge, - F64Eq, F64Ne, F64Lt, F64Gt, F64Le, F64Ge, - F32Abs, F32Neg, F32Ceil, F32Floor, F32Trunc, F32Nearest, F32Sqrt, F32Add, F32Sub, F32Mul, - F32Div, F32Min, F32Max, F32Copysign, F64Abs, F64Neg, F64Ceil, F64Floor, F64Trunc, - F64Nearest, F64Sqrt, F64Add, F64Sub, F64Mul, F64Div, F64Min, F64Max, F64Copysign, - I32TruncF32S, I32TruncF32U, I32TruncF64S, I32TruncF64U, - I64TruncF32S, I64TruncF32U, I64TruncF64S, I64TruncF64U, - F32ConvertI32S, F32ConvertI32U, F32ConvertI64S, F32ConvertI64U, F32DemoteF64, - F64ConvertI32S, F64ConvertI32U, F64ConvertI64S, F64ConvertI64U, F64PromoteF32, - I32ReinterpretF32, I64ReinterpretF64, F32ReinterpretI32, F64ReinterpretI64, - I32TruncSatF32S, I32TruncSatF32U, I32TruncSatF64S, I32TruncSatF64U, - I64TruncSatF32S, I64TruncSatF32U, I64TruncSatF64S, I64TruncSatF64U, - - MemoryAtomicNotify, MemoryAtomicWait32, MemoryAtomicWait64, AtomicFence, I32AtomicLoad, - I64AtomicLoad, I32AtomicLoad8U, I32AtomicLoad16U, I64AtomicLoad8U, I64AtomicLoad16U, - I64AtomicLoad32U, I32AtomicStore, I64AtomicStore, I32AtomicStore8, I32AtomicStore16, - I64AtomicStore8, I64AtomicStore16, I64AtomicStore32, I32AtomicRmwAdd, I64AtomicRmwAdd, - I32AtomicRmw8AddU, I32AtomicRmw16AddU, I64AtomicRmw8AddU, I64AtomicRmw16AddU, I64AtomicRmw32AddU, - I32AtomicRmwSub, I64AtomicRmwSub, I32AtomicRmw8SubU, I32AtomicRmw16SubU, I64AtomicRmw8SubU, - I64AtomicRmw16SubU, I64AtomicRmw32SubU, I32AtomicRmwAnd, I64AtomicRmwAnd, I32AtomicRmw8AndU, - I32AtomicRmw16AndU, I64AtomicRmw8AndU, I64AtomicRmw16AndU, I64AtomicRmw32AndU, I32AtomicRmwOr, - I64AtomicRmwOr, I32AtomicRmw8OrU, I32AtomicRmw16OrU, I64AtomicRmw8OrU, I64AtomicRmw16OrU, - I64AtomicRmw32OrU, I32AtomicRmwXor, I64AtomicRmwXor, I32AtomicRmw8XorU, I32AtomicRmw16XorU, - I64AtomicRmw8XorU, I64AtomicRmw16XorU, I64AtomicRmw32XorU, I32AtomicRmwXchg, I64AtomicRmwXchg, - I32AtomicRmw8XchgU, I32AtomicRmw16XchgU, I64AtomicRmw8XchgU, I64AtomicRmw16XchgU, - I64AtomicRmw32XchgU, I32AtomicRmwCmpxchg, I64AtomicRmwCmpxchg, I32AtomicRmw8CmpxchgU, - I32AtomicRmw16CmpxchgU, I64AtomicRmw8CmpxchgU, I64AtomicRmw16CmpxchgU, I64AtomicRmw32CmpxchgU, - - V128Load, V128Load8x8S, V128Load8x8U, V128Load16x4S, V128Load16x4U, V128Load32x2S, V128Load32x2U, - V128Load8Splat, V128Load16Splat, V128Load32Splat, V128Load64Splat, V128Load32Zero, V128Load64Zero, - V128Store, V128Load8Lane, V128Load16Lane, V128Load32Lane, V128Load64Lane, V128Store8Lane, - V128Store16Lane, V128Store32Lane, V128Store64Lane, V128Const, - I8x16Shuffle, I8x16ExtractLaneS, I8x16ExtractLaneU, I8x16ReplaceLane, I16x8ExtractLaneS, - I16x8ExtractLaneU, I16x8ReplaceLane, I32x4ExtractLane, I32x4ReplaceLane, I64x2ExtractLane, - I64x2ReplaceLane, F32x4ExtractLane, F32x4ReplaceLane, F64x2ExtractLane, F64x2ReplaceLane, - I8x16Swizzle, I8x16Splat, I16x8Splat, I32x4Splat, I64x2Splat, F32x4Splat, F64x2Splat, I8x16Eq, - I8x16Ne, I8x16LtS, I8x16LtU, I8x16GtS, I8x16GtU, I8x16LeS, I8x16LeU, I8x16GeS, I8x16GeU, I16x8Eq, - I16x8Ne, I16x8LtS, I16x8LtU, I16x8GtS, I16x8GtU, I16x8LeS, I16x8LeU, I16x8GeS, I16x8GeU, I32x4Eq, - I32x4Ne, I32x4LtS, I32x4LtU, I32x4GtS, I32x4GtU, I32x4LeS, I32x4LeU, I32x4GeS, I32x4GeU, I64x2Eq, - I64x2Ne, I64x2LtS, I64x2GtS, I64x2LeS, I64x2GeS, - F32x4Eq, F32x4Ne, F32x4Lt, F32x4Gt, F32x4Le, F32x4Ge, - F64x2Eq, F64x2Ne, F64x2Lt, F64x2Gt, F64x2Le, F64x2Ge, - V128Not, V128And, V128AndNot, V128Or, V128Xor, V128Bitselect, V128AnyTrue, - I8x16Abs, I8x16Neg, I8x16Popcnt, I8x16AllTrue, I8x16Bitmask, I8x16NarrowI16x8S, I8x16NarrowI16x8U, - I8x16Shl, I8x16ShrS, I8x16ShrU, I8x16Add, I8x16AddSatS, I8x16AddSatU, I8x16Sub, I8x16SubSatS, - I8x16SubSatU, I8x16MinS, I8x16MinU, I8x16MaxS, I8x16MaxU, I8x16AvgrU, - I16x8ExtAddPairwiseI8x16S, I16x8ExtAddPairwiseI8x16U, I16x8Abs, I16x8Neg, I16x8Q15MulrSatS, - I16x8AllTrue, I16x8Bitmask, I16x8NarrowI32x4S, I16x8NarrowI32x4U, I16x8ExtendLowI8x16S, - I16x8ExtendHighI8x16S, I16x8ExtendLowI8x16U, I16x8ExtendHighI8x16U, I16x8Shl, I16x8ShrS, I16x8ShrU, - I16x8Add, I16x8AddSatS, I16x8AddSatU, I16x8Sub, I16x8SubSatS, I16x8SubSatU, I16x8Mul, I16x8MinS, - I16x8MinU, I16x8MaxS, I16x8MaxU, I16x8AvgrU, I16x8ExtMulLowI8x16S, - I16x8ExtMulHighI8x16S, I16x8ExtMulLowI8x16U, I16x8ExtMulHighI8x16U, I32x4ExtAddPairwiseI16x8S, - I32x4ExtAddPairwiseI16x8U, I32x4Abs, I32x4Neg, I32x4AllTrue, I32x4Bitmask, I32x4ExtendLowI16x8S, - I32x4ExtendHighI16x8S, I32x4ExtendLowI16x8U, I32x4ExtendHighI16x8U, I32x4Shl, I32x4ShrS, I32x4ShrU, - I32x4Add, I32x4Sub, I32x4Mul, I32x4MinS, I32x4MinU, I32x4MaxS, I32x4MaxU, I32x4DotI16x8S, - I32x4ExtMulLowI16x8S, I32x4ExtMulHighI16x8S, I32x4ExtMulLowI16x8U, I32x4ExtMulHighI16x8U, I64x2Abs, - I64x2Neg, I64x2AllTrue, I64x2Bitmask, I64x2ExtendLowI32x4S, I64x2ExtendHighI32x4S, - I64x2ExtendLowI32x4U, I64x2ExtendHighI32x4U, I64x2Shl, I64x2ShrS, I64x2ShrU, I64x2Add, I64x2Sub, - I64x2Mul, I64x2ExtMulLowI32x4S, I64x2ExtMulHighI32x4S, I64x2ExtMulLowI32x4U, I64x2ExtMulHighI32x4U, - F32x4Ceil, F32x4Floor, F32x4Trunc, F32x4Nearest, F32x4Abs, F32x4Neg, F32x4Sqrt, F32x4Add, F32x4Sub, - F32x4Mul, F32x4Div, F32x4Min, F32x4Max, F32x4PMin, F32x4PMax, F64x2Ceil, F64x2Floor, F64x2Trunc, - F64x2Nearest, F64x2Abs, F64x2Neg, F64x2Sqrt, F64x2Add, F64x2Sub, F64x2Mul, F64x2Div, F64x2Min, - F64x2Max, F64x2PMin, F64x2PMax, I32x4TruncSatF32x4S, I32x4TruncSatF32x4U, F32x4ConvertI32x4S, - F32x4ConvertI32x4U, I32x4TruncSatF64x2SZero, I32x4TruncSatF64x2UZero, F64x2ConvertLowI32x4S, - F64x2ConvertLowI32x4U, F32x4DemoteF64x2Zero, F64x2PromoteLowF32x4, I8x16RelaxedSwizzle, - I32x4RelaxedTruncF32x4S, I32x4RelaxedTruncF32x4U, I32x4RelaxedTruncF64x2SZero, - I32x4RelaxedTruncF64x2UZero, F32x4RelaxedMadd, F32x4RelaxedNmadd, F64x2RelaxedMadd, - F64x2RelaxedNmadd, I8x16RelaxedLaneselect, I16x8RelaxedLaneselect, I32x4RelaxedLaneselect, - I64x2RelaxedLaneselect, F32x4RelaxedMin, F32x4RelaxedMax, F64x2RelaxedMin, F64x2RelaxedMax, - I16x8RelaxedQ15mulrS, I16x8RelaxedDotI8x16I7x16S, I32x4RelaxedDotI8x16I7x16AddS - ) => u64::MAX, - - #[cfg(feature = "sp1")] - _ => todo!("New operator not covered yet by nitro!") - }; - ink -} diff --git a/crates/prover/src/programs/meter.rs b/crates/prover/src/programs/meter.rs index e18cfd03092..c9ae3f612f1 100644 --- a/crates/prover/src/programs/meter.rs +++ b/crates/prover/src/programs/meter.rs @@ -2,22 +2,26 @@ // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md #![allow(clippy::needless_lifetimes)] +#[cfg(feature = "sp1")] +use crate::operator::OperatorInfo; use crate::{ programs::{ config::{CompilePricingParams, PricingParams, SigMap}, FuncMiddleware, Middleware, ModuleMod, }, value::FunctionType, - Machine, }; +#[cfg(not(feature = "sp1"))] +use crate::Machine; use arbutil::{ evm::{ self, api::{Gas, Ink}, }, - operator::OperatorInfo, pricing, Bytes32, }; +#[cfg(not(feature = "sp1"))] +use arbutil::operator::OperatorInfo; use derivative::Derivative; use eyre::Result; use fnv::FnvHashMap as HashMap; @@ -333,6 +337,7 @@ pub trait GasMeteredMachine: MeteredMachine { } } +#[cfg(not(feature = "sp1"))] impl MeteredMachine for Machine { fn ink_left(&self) -> MachineMeter { macro_rules! convert { @@ -518,6 +523,9 @@ pub fn pricing_v1(op: &Operator, tys: &HashMap) -> I64x2RelaxedLaneselect, F32x4RelaxedMin, F32x4RelaxedMax, F64x2RelaxedMin, F64x2RelaxedMax, I16x8RelaxedQ15mulrS, I16x8RelaxedDotI8x16I7x16S, I32x4RelaxedDotI8x16I7x16AddS ) => u64::MAX, + + #[cfg(feature = "sp1")] + _ => todo!("New operator not covered yet by nitro!") }; ink } From 9c202fa031baec7510509022ed232b864a10579d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 10 Mar 2026 17:16:08 +0100 Subject: [PATCH 092/189] Migrate mod.rs --- arbitrator/prover/src/programs/mod.rs | 486 -------------------------- crates/prover/src/programs/mod.rs | 20 +- 2 files changed, 13 insertions(+), 493 deletions(-) delete mode 100644 arbitrator/prover/src/programs/mod.rs diff --git a/arbitrator/prover/src/programs/mod.rs b/arbitrator/prover/src/programs/mod.rs deleted file mode 100644 index c9fe8387825..00000000000 --- a/arbitrator/prover/src/programs/mod.rs +++ /dev/null @@ -1,486 +0,0 @@ -// Copyright 2022-2024, Offchain Labs, Inc. -// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md - -use crate::{ - binary::{ExportKind, WasmBinary}, - programs::config::CompileConfig, - value::{FunctionType as ArbFunctionType, MemoryType, Value}, -}; -use arbutil::{Bytes32, Color, evm::ARBOS_VERSION_STYLUS_CHARGING_FIXES, math::SaturatingSum}; -use eyre::{Report, Result, WrapErr, bail, eyre}; -use fnv::FnvHashMap as HashMap; -use std::fmt::Debug; -use wasmer_types::{ - FunctionIndex, GlobalIndex, GlobalInit, ImportIndex, LocalFunctionIndex, SignatureIndex, Type, - entity::EntityRef, -}; -use wasmparser::{Operator, ValType}; - -#[cfg(all(feature = "native", feature = "sp1"))] -use wasmer::sys::{FunctionMiddleware, MiddlewareError, MiddlewareReaderState, ModuleMiddleware}; -#[cfg(all(feature = "native", not(feature = "sp1")))] -use wasmer::{FunctionMiddleware, MiddlewareError, MiddlewareReaderState, ModuleMiddleware}; -#[cfg(feature = "native")] -use { - super::value, - std::marker::PhantomData, - wasmer::{ExportIndex, GlobalType, Mutability}, - wasmer_types::{MemoryIndex, ModuleInfo}, -}; - -pub mod config; -pub mod counter; -pub mod depth; -pub mod dynamic; -pub mod heap; -pub mod memory; -pub mod meter; -pub mod prelude; -pub mod start; - -pub const STYLUS_ENTRY_POINT: &str = "user_entrypoint"; - -pub trait ModuleMod { - fn add_global(&mut self, name: &str, ty: Type, init: GlobalInit) -> Result; - fn get_global(&mut self, name: &str) -> Result; - fn get_signature(&self, sig: SignatureIndex) -> Result; - fn get_function(&self, func: FunctionIndex) -> Result; - fn all_functions(&self) -> Result>; - fn all_signatures(&self) -> Result>; - fn get_import(&self, module: &str, name: &str) -> Result; - /// Moves the start function, returning true if present. - fn move_start_function(&mut self, name: &str) -> Result; - /// Drops debug-only info like export names. - fn drop_exports_and_names(&mut self, keep: &HashMap<&str, ExportKind>); - fn memory_info(&self) -> Result; -} - -pub trait Middleware { - type FM<'a>: FuncMiddleware<'a> + Debug; - - fn update_module(&self, module: &mut M) -> Result<()>; // not mutable due to wasmer - fn instrument<'a>(&self, func_index: LocalFunctionIndex) -> Result>; - fn name(&self) -> &'static str; -} - -pub trait FuncMiddleware<'a> { - /// Provide info on the function's locals. This is called before feed. - fn locals_info(&mut self, _locals: &[ValType]) {} - - /// Processes the given operator. - fn feed(&mut self, op: Operator<'a>, out: &mut O) -> Result<()> - where - O: Extend>; - - /// The name of the middleware - fn name(&self) -> &'static str; -} - -#[derive(Debug)] -pub struct DefaultFuncMiddleware; - -impl<'a> FuncMiddleware<'a> for DefaultFuncMiddleware { - fn feed(&mut self, op: Operator<'a>, out: &mut O) -> Result<()> - where - O: Extend>, - { - out.extend([op]); - Ok(()) - } - - fn name(&self) -> &'static str { - "default middleware" - } -} - -/// This wrapper exists to impl wasmer's `ModuleMiddleware` generically. -/// We can't use `T` directly since we don't define `ModuleMiddleware`, -/// and we need `M` to be part of the type. -#[cfg(feature = "native")] -#[derive(Debug)] -pub struct MiddlewareWrapper(pub T, PhantomData) -where - T: Middleware + Debug + Send + Sync, - M: ModuleMod; - -#[cfg(feature = "native")] -impl MiddlewareWrapper -where - T: Middleware + Debug + Send + Sync, - M: ModuleMod, -{ - pub fn new(middleware: T) -> Self { - Self(middleware, PhantomData) - } -} - -#[cfg(feature = "native")] -impl ModuleMiddleware for MiddlewareWrapper -where - T: Middleware + Debug + Send + Sync + 'static, -{ - fn transform_module_info(&self, module: &mut ModuleInfo) -> Result<(), MiddlewareError> { - let error = |err| MiddlewareError::new(self.0.name().red(), format!("{err:?}")); - self.0.update_module(module).map_err(error) - } - - fn generate_function_middleware<'a>( - &self, - local_function_index: LocalFunctionIndex, - ) -> Box + 'a> { - let worker = self.0.instrument(local_function_index).unwrap(); - Box::new(FuncMiddlewareWrapper(worker, PhantomData)) - } -} - -/// This wrapper exists to impl wasmer's `FunctionMiddleware` generically. -/// The logic is analogous to that of `ModuleMiddleware`, except this time -/// we need a phantom marker to parameterize by `T`'s reference's lifetime. -#[cfg(feature = "native")] -#[derive(Debug)] -pub struct FuncMiddlewareWrapper<'a, T: 'a>(T, PhantomData<&'a T>) -where - T: FuncMiddleware<'a> + Debug; - -#[cfg(feature = "native")] -impl<'a, T> FunctionMiddleware<'a> for FuncMiddlewareWrapper<'a, T> -where - T: FuncMiddleware<'a> + Debug, -{ - fn locals_info(&mut self, locals: &[ValType]) { - self.0.locals_info(locals); - } - - fn feed( - &mut self, - op: Operator<'a>, - out: &mut MiddlewareReaderState<'a>, - ) -> Result<(), MiddlewareError> { - let name = self.0.name().red(); - let error = |err| MiddlewareError::new(name, format!("{err:?}")); - self.0.feed(op, out).map_err(error) - } -} - -#[cfg(feature = "native")] -impl ModuleMod for ModuleInfo { - fn add_global(&mut self, name: &str, ty: Type, init: GlobalInit) -> Result { - let global_type = GlobalType::new(ty, Mutability::Var); - let name = name.to_owned(); - if self.exports.contains_key(&name) { - bail!("wasm already contains {}", name.red()) - } - let index = self.globals.push(global_type); - self.exports.insert(name, ExportIndex::Global(index)); - self.global_initializers.push(init); - Ok(index) - } - - fn get_global(&mut self, name: &str) -> Result { - let Some(ExportIndex::Global(global)) = self.exports.get(name) else { - bail!("missing global {}", name.red()) - }; - Ok(*global) - } - - fn get_signature(&self, sig: SignatureIndex) -> Result { - let error = Report::msg(format!("missing signature {}", sig.as_u32().red())); - let ty = self.signatures.get(sig).cloned().ok_or(error)?; - let ty = value::parser_func_type(ty); - ty.try_into() - } - - fn get_function(&self, func: FunctionIndex) -> Result { - let index = func.as_u32(); - match self.functions.get(func) { - Some(sig) => self.get_signature(*sig), - None => match self.function_names.get(&func) { - Some(name) => bail!("missing func {} @ index {}", name.red(), index.red()), - None => bail!("missing func @ index {}", index.red()), - }, - } - } - - fn all_functions(&self) -> Result> { - let mut funcs = HashMap::default(); - for (func, sig) in &self.functions { - let ty = self.get_signature(*sig)?; - funcs.insert(func, ty); - } - Ok(funcs) - } - - fn all_signatures(&self) -> Result> { - let mut signatures = HashMap::default(); - for (index, _) in &self.signatures { - let ty = self.get_signature(index)?; - signatures.insert(index, ty); - } - Ok(signatures) - } - - fn get_import(&self, module: &str, name: &str) -> Result { - self.imports - .iter() - .find(|(k, _)| k.module == module && k.field == name) - .map(|(_, v)| v.clone()) - .ok_or_else(|| eyre!("missing import {}", name.red())) - } - - fn move_start_function(&mut self, name: &str) -> Result { - if let Some(prior) = self.exports.get(name) { - bail!("function {} already exists @ index {:?}", name.red(), prior) - } - - let start = self.start_function.take(); - if let Some(start) = start { - let export = ExportIndex::Function(start); - self.exports.insert(name.to_owned(), export); - self.function_names.insert(start, name.to_owned()); - } - Ok(start.is_some()) - } - - fn drop_exports_and_names(&mut self, keep: &HashMap<&str, ExportKind>) { - self.exports.retain(|name, export| { - keep.get(name.as_str()) - .is_some_and(|x| *x == (*export).into()) - }); - self.function_names.clear(); - } - - fn memory_info(&self) -> Result { - if self.memories.is_empty() { - bail!("missing memory export with name {}", "memory".red()); - } - if self.memories.len() > 1 { - bail!("only one memory is allowed"); - } - if self.exports.get("memory") != Some(&ExportIndex::Memory(MemoryIndex::from_u32(0))) { - bail!("missing memory with export name {}", "memory".red()); - } - Ok(self.memories.last().unwrap().into()) - } -} - -impl ModuleMod for WasmBinary<'_> { - fn add_global(&mut self, name: &str, _ty: Type, init: GlobalInit) -> Result { - let global = match init { - GlobalInit::I32Const(x) => Value::I32(x as u32), - GlobalInit::I64Const(x) => Value::I64(x as u64), - GlobalInit::F32Const(x) => Value::F32(x), - GlobalInit::F64Const(x) => Value::F64(x), - ty => bail!("cannot add global of type {:?}", ty), - }; - if self.exports.contains_key(name) { - bail!("wasm already contains {}", name.red()) - } - let name = name.to_owned(); - let index = self.globals.len() as u32; - self.exports.insert(name, (index, ExportKind::Global)); - self.globals.push(global); - Ok(GlobalIndex::from_u32(index)) - } - - fn get_global(&mut self, name: &str) -> Result { - let Some((global, ExportKind::Global)) = self.exports.get(name) else { - bail!("missing global {}", name.red()) - }; - Ok(GlobalIndex::from_u32(*global)) - } - - fn get_signature(&self, sig: SignatureIndex) -> Result { - let index = sig.as_u32() as usize; - let error = Report::msg(format!("missing signature {}", index.red())); - self.types.get(index).cloned().ok_or(error) - } - - fn get_function(&self, func: FunctionIndex) -> Result { - let mut index = func.as_u32() as usize; - - let sig = if index < self.imports.len() { - self.imports.get(index).map(|x| &x.offset) - } else { - index -= self.imports.len(); - self.functions.get(index) - }; - - let func = func.as_u32(); - match sig { - Some(sig) => self.get_signature(SignatureIndex::from_u32(*sig)), - None => match self.names.functions.get(&func) { - Some(name) => bail!("missing func {} @ index {}", name.red(), func.red()), - None => bail!("missing func @ index {}", func.red()), - }, - } - } - - fn all_functions(&self) -> Result> { - let mut funcs = HashMap::default(); - let mut index = 0; - for import in &self.imports { - let ty = self.get_signature(SignatureIndex::from_u32(import.offset))?; - funcs.insert(FunctionIndex::new(index), ty); - index += 1; - } - for sig in &self.functions { - let ty = self.get_signature(SignatureIndex::from_u32(*sig))?; - funcs.insert(FunctionIndex::new(index), ty); - index += 1; - } - Ok(funcs) - } - - fn all_signatures(&self) -> Result> { - let mut signatures = HashMap::default(); - for (index, ty) in self.types.iter().enumerate() { - let sig = SignatureIndex::new(index); - signatures.insert(sig, ty.clone()); - } - Ok(signatures) - } - - fn get_import(&self, module: &str, name: &str) -> Result { - self.imports - .iter() - .position(|x| x.module == module && x.name == name) - .map(|x| ImportIndex::Function(FunctionIndex::from_u32(x as u32))) - .ok_or_else(|| eyre!("missing import {}", name.red())) - } - - fn move_start_function(&mut self, name: &str) -> Result { - if let Some(prior) = self.exports.get(name) { - bail!("function {} already exists @ index {:?}", name.red(), prior) - } - - let start = self.start.take(); - if let Some(start) = start { - let name = name.to_owned(); - self.exports.insert(name.clone(), (start, ExportKind::Func)); - self.names.functions.insert(start, name); - } - Ok(start.is_some()) - } - - fn drop_exports_and_names(&mut self, keep: &HashMap<&str, ExportKind>) { - self.exports - .retain(|name, ty| keep.get(name.as_str()).is_some_and(|x| *x == ty.1)); - self.names.functions.clear(); - } - - fn memory_info(&self) -> Result { - if self.memories.is_empty() { - bail!("missing memory export with name {}", "memory".red()); - } - if self.memories.len() > 1 { - bail!("only one memory is allowed"); - } - if self.exports.get("memory") != Some(&(0, ExportKind::Memory)) { - bail!("missing memory with export name {}", "memory".red()); - } - self.memories.last().unwrap().try_into() - } -} - -/// Information about an activated program. -#[derive(Clone, Copy, Debug)] -#[repr(C)] -pub struct StylusData { - /// Global index for the amount of ink left. - pub ink_left: u32, - /// Global index for whether the program is out of ink. - pub ink_status: u32, - /// Global index for the amount of stack space remaining. - pub depth_left: u32, - /// Cost paid to invoke the program. See `programs.go` for the translation to gas. - pub init_cost: u16, - /// Cost paid to invoke the program when stored in the init cache. - pub cached_init_cost: u16, - /// Canonical estimate of the asm length in bytes. - pub asm_estimate: u32, - /// Initial memory size in pages. - pub footprint: u16, - /// Entrypoint offset. - pub user_main: u32, -} - -impl StylusData { - pub fn global_offsets(&self) -> (u64, u64, u64) { - ( - self.ink_left as u64, - self.ink_status as u64, - self.depth_left as u64, - ) - } -} - -#[cfg(not(feature = "sp1"))] -impl crate::machine::Module { - pub fn activate( - wasm: &[u8], - codehash: &Bytes32, - stylus_version: u16, - arbos_version_for_gas: u64, // must only be used for activation gas - page_limit: u16, - debug: bool, - gas: &mut u64, - ) -> Result<(Self, StylusData)> { - let compile = CompileConfig::version(stylus_version, debug); - let (bin, stylus_data) = - WasmBinary::parse_user(wasm, arbos_version_for_gas, page_limit, &compile, codehash) - .wrap_err("failed to parse wasm")?; - - if arbos_version_for_gas > 0 { - // converts a number of microseconds to gas - // TODO: collapse to a single value after finalizing factors - let us_to_gas = |us: u64| { - let fudge = 2; - let sync_rate = 1_000_000 / 2; - let speed = 7_000_000; - us.saturating_mul(fudge * speed) / sync_rate - }; - - macro_rules! pay { - ($us:expr) => { - let amount = us_to_gas($us); - if *gas < amount { - *gas = 0; - bail!("out of gas"); - } - *gas -= amount; - }; - } - - // pay for wasm - if arbos_version_for_gas >= ARBOS_VERSION_STYLUS_CHARGING_FIXES { - let wasm_len = wasm.len() as u64; - pay!(wasm_len.saturating_mul(31_733) / 100_000); - } - - // pay for funcs - let funcs = bin.functions.len() as u64; - pay!(funcs.saturating_mul(17_263) / 100_000); - - // pay for data - let data = bin.datas.iter().map(|x| x.data.len()).saturating_sum() as u64; - pay!(data.saturating_mul(17_376) / 100_000); - - // pay for elements - let elems = bin.elements.iter().map(|x| x.range.len()).saturating_sum() as u64; - pay!(elems.saturating_mul(17_376) / 100_000); - - // pay for memory - let mem = bin.memories.first().map(|x| x.initial).unwrap_or_default(); - pay!(mem.saturating_mul(2217)); - - // pay for code - let code = bin.codes.iter().map(|x| x.expr.len()).saturating_sum() as u64; - pay!(code.saturating_mul(535) / 1_000); - } - - let module = Self::from_user_binary(&bin, compile.debug.debug_funcs, Some(stylus_data)) - .wrap_err("failed to build user module")?; - - Ok((module, stylus_data)) - } -} diff --git a/crates/prover/src/programs/mod.rs b/crates/prover/src/programs/mod.rs index 3c72fa99c70..3ca8fbf2b85 100644 --- a/crates/prover/src/programs/mod.rs +++ b/crates/prover/src/programs/mod.rs @@ -3,11 +3,13 @@ use crate::{ binary::{ExportKind, WasmBinary}, - machine::Module, - memory::MemoryType, programs::config::CompileConfig, value::{FunctionType as ArbFunctionType, Value}, }; +#[cfg(not(feature = "sp1"))] +use crate::{machine::Module, memory::MemoryType}; +#[cfg(feature = "sp1")] +use crate::value::MemoryType; use arbutil::{evm::ARBOS_VERSION_STYLUS_CHARGING_FIXES, math::SaturatingSum, Bytes32, Color}; use eyre::{bail, eyre, Report, Result, WrapErr}; use fnv::FnvHashMap as HashMap; @@ -18,13 +20,16 @@ use wasmer_types::{ }; use wasmparser::{Operator, ValType}; +#[cfg(all(feature = "native", feature = "sp1"))] +use wasmer::sys::{FunctionMiddleware, MiddlewareError, MiddlewareReaderState, ModuleMiddleware}; +#[cfg(all(feature = "native", not(feature = "sp1")))] +use wasmer::{FunctionMiddleware, MiddlewareError, MiddlewareReaderState, ModuleMiddleware}; + #[cfg(feature = "native")] use { super::value, std::marker::PhantomData, - wasmer::{ - ExportIndex, FunctionMiddleware, GlobalType, MiddlewareError, ModuleMiddleware, Mutability, - }, + wasmer::{ExportIndex, GlobalType, Mutability}, wasmer_types::{MemoryIndex, ModuleInfo}, }; @@ -127,7 +132,7 @@ where fn generate_function_middleware<'a>( &self, local_function_index: LocalFunctionIndex, - ) -> Box + 'a> { + ) -> Box + 'a> { let worker = self.0.instrument(local_function_index).unwrap(); Box::new(FuncMiddlewareWrapper(worker, PhantomData)) } @@ -154,7 +159,7 @@ where fn feed( &mut self, op: Operator<'a>, - out: &mut wasmer::MiddlewareReaderState<'a>, + out: &mut MiddlewareReaderState<'a>, ) -> Result<(), MiddlewareError> { let name = self.0.name().red(); let error = |err| MiddlewareError::new(name, format!("{err:?}")); @@ -414,6 +419,7 @@ impl StylusData { } } +#[cfg(not(feature = "sp1"))] impl Module { pub fn activate( wasm: &[u8], From 5fbfc9079631d03ac9923ffd3f80c84d7c4926cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 10 Mar 2026 17:16:21 +0100 Subject: [PATCH 093/189] Remove other modules --- arbitrator/prover/src/programs/prelude.rs | 12 ---- arbitrator/prover/src/programs/start.rs | 67 ----------------------- 2 files changed, 79 deletions(-) delete mode 100644 arbitrator/prover/src/programs/prelude.rs delete mode 100644 arbitrator/prover/src/programs/start.rs diff --git a/arbitrator/prover/src/programs/prelude.rs b/arbitrator/prover/src/programs/prelude.rs deleted file mode 100644 index 9fa531d5aaf..00000000000 --- a/arbitrator/prover/src/programs/prelude.rs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2022-2023, Offchain Labs, Inc. -// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md - -pub use super::{ - config::{CompileConfig, StylusConfig}, - counter::CountingMachine, - depth::DepthCheckedMachine, - meter::{GasMeteredMachine, MachineMeter, MeteredMachine}, -}; - -#[cfg(feature = "native")] -pub use super::start::StartlessMachine; diff --git a/arbitrator/prover/src/programs/start.rs b/arbitrator/prover/src/programs/start.rs deleted file mode 100644 index 0d9fa9e004f..00000000000 --- a/arbitrator/prover/src/programs/start.rs +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2022-2023, Offchain Labs, Inc. -// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md - -use crate::{ - binary::ExportKind, - programs::{DefaultFuncMiddleware, Middleware, ModuleMod, STYLUS_ENTRY_POINT}, -}; -use eyre::{Result, bail}; -use fnv::FnvHashMap as HashMap; -use lazy_static::lazy_static; -use wasmer_types::LocalFunctionIndex; - -#[cfg(feature = "native")] -use wasmer::TypedFunction; - -lazy_static! { - /// Lists the exports a user program map have - static ref EXPORT_WHITELIST: HashMap<&'static str, ExportKind> = { - let mut map = HashMap::default(); - map.insert(STYLUS_ENTRY_POINT, ExportKind::Func); - map.insert(StartMover::NAME, ExportKind::Func); - map.insert("memory", ExportKind::Memory); - map - }; -} - -#[derive(Debug)] -pub struct StartMover { - /// Whether to keep offchain information. - debug: bool, -} - -impl StartMover { - pub const NAME: &'static str = "stylus_start"; - - pub fn new(debug: bool) -> Self { - Self { debug } - } -} - -impl Middleware for StartMover { - type FM<'a> = DefaultFuncMiddleware; - - fn update_module(&self, module: &mut M) -> Result<()> { - let had_start = module.move_start_function(Self::NAME)?; - if had_start && !self.debug { - bail!("start functions not allowed"); - } - if !self.debug { - module.drop_exports_and_names(&EXPORT_WHITELIST); - } - Ok(()) - } - - fn instrument<'a>(&self, _: LocalFunctionIndex) -> Result> { - Ok(DefaultFuncMiddleware) - } - - fn name(&self) -> &'static str { - "start mover" - } -} - -#[cfg(feature = "native")] -pub trait StartlessMachine { - fn get_start(&self) -> Result>; -} From 4d572d5d15824571b65773de740e0bf6707b4491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 10 Mar 2026 17:17:51 +0100 Subject: [PATCH 094/189] Migrate operator.rs --- crates/arbutil/src/operator.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/arbutil/src/operator.rs b/crates/arbutil/src/operator.rs index 75880c73733..65da34b97ed 100644 --- a/crates/arbutil/src/operator.rs +++ b/crates/arbutil/src/operator.rs @@ -1178,6 +1178,8 @@ impl From<&Operator<'_>> for OperatorCode { O::I16x8RelaxedQ15mulrS { .. } => 0xfd111, O::I16x8RelaxedDotI8x16I7x16S { .. } => 0xfd112, O::I32x4RelaxedDotI8x16I7x16AddS { .. } => 0xfd113, + #[cfg(feature = "sp1")] + _ => todo!(), }) } } From 722cbca1b822f5aae7198249fad9993d66a0e42c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 10 Mar 2026 17:18:18 +0100 Subject: [PATCH 095/189] Migrate value.rs --- arbitrator/prover/src/value.rs | 572 --------------------------------- crates/prover/src/value.rs | 98 ++++++ 2 files changed, 98 insertions(+), 572 deletions(-) delete mode 100644 arbitrator/prover/src/value.rs diff --git a/arbitrator/prover/src/value.rs b/arbitrator/prover/src/value.rs deleted file mode 100644 index 6027826b9cc..00000000000 --- a/arbitrator/prover/src/value.rs +++ /dev/null @@ -1,572 +0,0 @@ -// Copyright 2021-2022, Offchain Labs, Inc. -// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md - -use crate::binary::FloatType; -use arbutil::{Bytes32, Color}; -use digest::Digest; -use eyre::{ErrReport, Result, bail}; -use num_derive::FromPrimitive; -use serde::{Deserialize, Serialize}; -use serde_with::{TryFromInto, serde_as}; -use sha3::Keccak256; -use std::{ - convert::{TryFrom, TryInto}, - fmt::Display, - ops::Add, -}; -use wasmer_types::Pages; -use wasmparser::{FuncType, RefType, ValType}; - -#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize, Deserialize)] -#[repr(u8)] -pub enum ArbValueType { - I32, - I64, - F32, - F64, - RefNull, - FuncRef, - InternalRef, -} - -impl ArbValueType { - pub fn serialize(self) -> u8 { - self as u8 - } -} - -impl TryFrom for ArbValueType { - type Error = eyre::Error; - - fn try_from(ty: ValType) -> Result { - use ValType as V; - Ok(match ty { - V::I32 => Self::I32, - V::I64 => Self::I64, - V::F32 => Self::F32, - V::F64 => Self::F64, - V::Ref(ty) => ty.try_into()?, - V::V128 => bail!("128-bit types are not supported"), - }) - } -} - -impl TryFrom for ArbValueType { - type Error = eyre::Error; - - fn try_from(value: RefType) -> Result { - Ok(match value { - RefType::FUNCREF => Self::FuncRef, - RefType::EXTERNREF => Self::FuncRef, - RefType::NULLREF => Self::RefNull, - _ => bail!("ref extensions not supported"), - }) - } -} - -impl From for ValType { - fn from(ty: ArbValueType) -> Self { - use ArbValueType as V; - match ty { - V::I32 => Self::I32, - V::I64 => Self::I64, - V::F32 => Self::F32, - V::F64 => Self::F64, - V::RefNull => Self::Ref(RefType::NULLREF), - V::FuncRef => Self::Ref(RefType::FUNCREF), - V::InternalRef => Self::Ref(RefType::FUNCREF), // not analogous, but essentially a func pointer - } - } -} - -#[cfg(feature = "native")] -pub fn parser_type(ty: &wasmer::Type) -> wasmer::wasmparser::ValType { - match ty { - wasmer::Type::I32 => wasmer::wasmparser::ValType::I32, - wasmer::Type::I64 => wasmer::wasmparser::ValType::I64, - wasmer::Type::F32 => wasmer::wasmparser::ValType::F32, - wasmer::Type::F64 => wasmer::wasmparser::ValType::F64, - wasmer::Type::V128 => wasmer::wasmparser::ValType::V128, - wasmer::Type::ExternRef => wasmer::wasmparser::ValType::Ref(RefType::EXTERNREF), - wasmer::Type::FuncRef => wasmer::wasmparser::ValType::Ref(RefType::FUNCREF), - #[cfg(feature = "sp1")] - _ => todo!(), - } -} - -#[cfg(feature = "native")] -pub fn parser_func_type(ty: wasmer::FunctionType) -> FuncType { - let convert = |t: &[wasmer::Type]| -> Vec { t.iter().map(parser_type).collect() }; - let params = convert(ty.params()); - let results = convert(ty.results()); - FuncType::new(params, results) -} - -impl From for ArbValueType { - fn from(ty: FloatType) -> ArbValueType { - match ty { - FloatType::F32 => ArbValueType::F32, - FloatType::F64 => ArbValueType::F64, - } - } -} - -#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize, Deserialize)] -pub enum IntegerValType { - I32, - I64, -} - -impl From for ArbValueType { - fn from(ty: IntegerValType) -> ArbValueType { - match ty { - IntegerValType::I32 => ArbValueType::I32, - IntegerValType::I64 => ArbValueType::I64, - } - } -} - -#[serde_as] -#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] -pub struct ProgramCounter { - #[serde_as(as = "TryFromInto")] - pub module: u32, - #[serde_as(as = "TryFromInto")] - pub func: u32, - #[serde_as(as = "TryFromInto")] - pub inst: u32, -} - -#[cfg(not(any(target_pointer_width = "32", target_pointer_width = "64",)))] -compile_error!("Architectures with less than a 32 bit pointer width are not supported"); - -impl ProgramCounter { - pub fn serialize(self) -> Bytes32 { - let mut b = [0u8; 32]; - b[28..].copy_from_slice(&self.inst.to_be_bytes()); - b[24..28].copy_from_slice(&self.func.to_be_bytes()); - b[20..24].copy_from_slice(&self.module.to_be_bytes()); - Bytes32(b) - } - - // These casts are safe because we checked above that a usize is at least as big as a u32 - - pub fn module(self) -> usize { - self.module as usize - } - - pub fn func(self) -> usize { - self.func as usize - } - - pub fn inst(self) -> usize { - self.inst as usize - } -} - -impl Add for ProgramCounter { - type Output = ProgramCounter; - - fn add(self, rhs: u32) -> Self::Output { - let mut counter = self; - counter.inst += rhs; - counter - } -} - -impl Display for ProgramCounter { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!( - f, - "{} {} {} {}{}{}", - "inst".grey(), - self.inst.pink(), - "in".grey(), - self.module.pink(), - ":".grey(), - self.func.pink() - ) - } -} - -#[derive(Clone, Copy, Debug, Serialize, Deserialize)] -pub enum Value { - I32(u32), - I64(u64), - F32(f32), - F64(f64), - RefNull, - FuncRef(u32), - InternalRef(ProgramCounter), -} - -impl Value { - pub fn ty(self) -> ArbValueType { - match self { - Value::I32(_) => ArbValueType::I32, - Value::I64(_) => ArbValueType::I64, - Value::F32(_) => ArbValueType::F32, - Value::F64(_) => ArbValueType::F64, - Value::RefNull => ArbValueType::RefNull, - Value::FuncRef(_) => ArbValueType::FuncRef, - Value::InternalRef(_) => ArbValueType::InternalRef, - } - } - - pub fn contents_for_proof(self) -> Bytes32 { - match self { - Value::I32(x) => x.into(), - Value::I64(x) => x.into(), - Value::F32(x) => x.to_bits().into(), - Value::F64(x) => x.to_bits().into(), - Value::RefNull => Bytes32::default(), - Value::FuncRef(x) => x.into(), - Value::InternalRef(pc) => pc.serialize(), - } - } - - pub fn serialize_for_proof(self) -> [u8; 33] { - let mut ret = [0u8; 33]; - ret[0] = self.ty().serialize(); - ret[1..].copy_from_slice(&*self.contents_for_proof()); - ret - } - - pub fn is_i32_zero(self) -> bool { - match self { - Value::I32(0) => true, - Value::I32(_) => false, - _ => panic!("WASM validation failed: i32.eqz equivalent called on {self:?}",), - } - } - - pub fn is_i64_zero(self) -> bool { - match self { - Value::I64(0) => true, - Value::I64(_) => false, - _ => panic!("WASM validation failed: i64.eqz equivalent called on {self:?}",), - } - } - - pub fn assume_u32(self) -> u32 { - match self { - Value::I32(x) => x, - _ => panic!("WASM validation failed: assume_u32 called on {self:?}"), - } - } - - pub fn assume_u64(self) -> u64 { - match self { - Value::I64(x) => x, - _ => panic!("WASM validation failed: assume_u64 called on {self:?}"), - } - } - - pub fn hash(self) -> Bytes32 { - let mut h = Keccak256::new(); - h.update(b"Value:"); - h.update([self.ty() as u8]); - h.update(self.contents_for_proof()); - h.finalize().into() - } - - pub fn default_of_type(ty: ArbValueType) -> Value { - match ty { - ArbValueType::I32 => Value::I32(0), - ArbValueType::I64 => Value::I64(0), - ArbValueType::F32 => Value::F32(0.), - ArbValueType::F64 => Value::F64(0.), - ArbValueType::RefNull | ArbValueType::FuncRef | ArbValueType::InternalRef => { - Value::RefNull - } - } - } -} - -impl Display for Value { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let lparem = "(".grey(); - let rparem = ")".grey(); - - macro_rules! single { - ($ty:expr, $value:expr) => {{ write!(f, "{}{}{}{}", $ty.grey(), lparem, $value, rparem) }}; - } - macro_rules! pair { - ($ty:expr, $left:expr, $right:expr) => {{ - let eq = "=".grey(); - write!( - f, - "{}{}{} {} {}{}", - $ty.grey(), - lparem, - $left, - eq, - $right, - rparem - ) - }}; - } - match self { - Value::I32(value) => { - if (*value as i32) < 0 { - pair!("i32", *value as i32, value) - } else { - single!("i32", *value) - } - } - Value::I64(value) => { - if (*value as i64) < 0 { - pair!("i64", *value as i64, value) - } else { - single!("i64", *value) - } - } - Value::F32(value) => single!("f32", *value), - Value::F64(value) => single!("f64", *value), - Value::RefNull => write!(f, "null"), - Value::FuncRef(func) => write!(f, "func {func}"), - Value::InternalRef(pc) => write!(f, "{pc}"), - } - } -} - -impl PartialEq for Value { - fn eq(&self, other: &Self) -> bool { - self.ty() == other.ty() && self.contents_for_proof() == other.contents_for_proof() - } -} - -impl From for Value { - fn from(value: u8) -> Self { - Value::I32(value.into()) - } -} - -impl From for Value { - fn from(value: u16) -> Self { - Value::I32(value.into()) - } -} - -impl From for Value { - fn from(value: u32) -> Self { - Value::I32(value) - } -} - -impl From for Value { - fn from(value: u64) -> Self { - Value::I64(value) - } -} - -impl From for Value { - fn from(value: f32) -> Self { - Value::F32(value) - } -} - -impl From for Value { - fn from(value: f64) -> Self { - Value::F64(value) - } -} - -impl From for Value { - fn from(value: ProgramCounter) -> Self { - Value::InternalRef(value) - } -} - -impl TryInto for Value { - type Error = ErrReport; - - fn try_into(self) -> Result { - match self { - Value::I32(value) => Ok(value), - _ => bail!("value not a u32"), - } - } -} - -impl TryInto for Value { - type Error = ErrReport; - - fn try_into(self) -> Result { - match self { - Value::I64(value) => Ok(value), - _ => bail!("value not a u64"), - } - } -} - -impl Eq for Value {} - -#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] -pub struct FunctionType { - pub inputs: Vec, - pub outputs: Vec, -} - -impl FunctionType { - pub fn new(inputs: T, outputs: U) -> FunctionType - where - T: Into>, - U: Into>, - { - FunctionType { - inputs: inputs.into(), - outputs: outputs.into(), - } - } - - pub fn hash(&self) -> Bytes32 { - let mut h = Keccak256::new(); - h.update(b"Function type:"); - h.update(Bytes32::from(self.inputs.len())); - for input in &self.inputs { - h.update([*input as u8]); - } - h.update(Bytes32::from(self.outputs.len())); - for output in &self.outputs { - h.update([*output as u8]); - } - h.finalize().into() - } -} - -impl TryFrom for FunctionType { - type Error = eyre::Error; - - fn try_from(func: FuncType) -> Result { - let mut inputs = vec![]; - let mut outputs = vec![]; - - for input in func.params() { - inputs.push(ArbValueType::try_from(*input)?) - } - for output in func.results() { - outputs.push(ArbValueType::try_from(*output)?) - } - Ok(Self { inputs, outputs }) - } -} - -impl Display for FunctionType { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let mut signature = "λ(".to_string(); - if !self.inputs.is_empty() { - for arg in &self.inputs { - signature += &format!("{arg}, "); - } - signature.pop(); - signature.pop(); - } - signature += ")"; - - let output_tuple = self.outputs.len() > 2; - if !self.outputs.is_empty() { - signature += " -> "; - if output_tuple { - signature += "("; - } - for out in &self.outputs { - signature += &format!("{out}, "); - } - signature.pop(); - signature.pop(); - if output_tuple { - signature += ")"; - } - } - write!(f, "{signature}") - } -} - -impl Display for ArbValueType { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - use ArbValueType::*; - match self { - I32 => write!(f, "i32"), - I64 => write!(f, "i64"), - F32 => write!(f, "f32"), - F64 => write!(f, "f64"), - RefNull => write!(f, "null"), - FuncRef => write!(f, "func"), - InternalRef => write!(f, "internal"), - } - } -} - -/// Represents the internal hostio functions a module may have. -#[derive(Clone, Copy, Debug, FromPrimitive)] -#[repr(u64)] -pub enum InternalFunc { - WavmCallerLoad8, - WavmCallerLoad32, - WavmCallerStore8, - WavmCallerStore32, - MemoryFill, - MemoryCopy, - UserInkLeft, - UserInkStatus, - UserSetInk, - UserStackLeft, - UserSetStack, - UserMemorySize, - CallMain, -} - -impl InternalFunc { - pub fn ty(&self) -> FunctionType { - use ArbValueType::*; - use InternalFunc::*; - macro_rules! func { - ([$($args:expr),*], [$($outs:expr),*]) => { - FunctionType::new(vec![$($args),*], vec![$($outs),*]) - }; - } - #[rustfmt::skip] - let ty = match self { - WavmCallerLoad8 | WavmCallerLoad32 => func!([I32], [I32]), - WavmCallerStore8 | WavmCallerStore32 => func!([I32, I32], []), - MemoryFill | MemoryCopy => func!([I32, I32, I32], []), - UserInkLeft => func!([], [I64]), // λ() → ink_left - UserInkStatus => func!([], [I32]), // λ() → ink_status - UserSetInk => func!([I64, I32], []), // λ(ink_left, ink_status) - UserStackLeft => func!([], [I32]), // λ() → stack_left - UserSetStack => func!([I32], []), // λ(stack_left) - UserMemorySize => func!([], [I32]), // λ() → memory_size - CallMain => func!([I32], [I32]), // λ(args_len) → status - }; - ty - } -} - -pub struct MemoryType { - pub min: Pages, - pub max: Option, -} - -impl MemoryType { - pub fn new(min: Pages, max: Option) -> Self { - Self { min, max } - } -} - -impl From<&wasmer_types::MemoryType> for MemoryType { - fn from(value: &wasmer_types::MemoryType) -> Self { - Self::new(value.minimum, value.maximum) - } -} - -impl TryFrom<&wasmparser::MemoryType> for MemoryType { - type Error = ErrReport; - - fn try_from(value: &wasmparser::MemoryType) -> std::result::Result { - Ok(Self { - min: Pages(value.initial.try_into()?), - max: value.maximum.map(|x| x.try_into()).transpose()?.map(Pages), - }) - } -} diff --git a/crates/prover/src/value.rs b/crates/prover/src/value.rs index d9b8445a60a..a8af7766bd8 100644 --- a/crates/prover/src/value.rs +++ b/crates/prover/src/value.rs @@ -87,6 +87,8 @@ pub fn parser_type(ty: &wasmer::Type) -> wasmer::wasmparser::ValType { wasmer::Type::V128 => wasmer::wasmparser::ValType::V128, wasmer::Type::ExternRef => wasmer::wasmparser::ValType::Ref(RefType::EXTERNREF), wasmer::Type::FuncRef => wasmer::wasmparser::ValType::Ref(RefType::FUNCREF), + #[cfg(feature = "sp1")] + _ => todo!(), } } @@ -495,3 +497,99 @@ impl Display for ArbValueType { } } } + +// When compiled via #[path] from sp1-crates, certain types that normally live in +// other crate modules (crate::memory, crate::host) must be available from crate::value, +// since sp1-crates/prover only exposes a subset of modules. + +// In the normal crates/prover context, InternalFunc lives in crate::host. +#[cfg(feature = "sp1")] +pub use self::sp1_internal_func::InternalFunc; + +#[cfg(feature = "sp1")] +mod sp1_internal_func { + use super::{ArbValueType, FunctionType}; + use num_derive::FromPrimitive; + + #[derive(Clone, Copy, Debug, FromPrimitive)] + #[repr(u64)] + pub enum InternalFunc { + WavmCallerLoad8, + WavmCallerLoad32, + WavmCallerStore8, + WavmCallerStore32, + MemoryFill, + MemoryCopy, + UserInkLeft, + UserInkStatus, + UserSetInk, + UserStackLeft, + UserSetStack, + UserMemorySize, + CallMain, + } + + impl InternalFunc { + pub fn ty(&self) -> FunctionType { + use ArbValueType::*; + use InternalFunc::*; + macro_rules! func { + ([$($args:expr),*], [$($outs:expr),*]) => { + FunctionType::new(vec![$($args),*], vec![$($outs),*]) + }; + } + #[rustfmt::skip] + let ty = match self { + WavmCallerLoad8 | WavmCallerLoad32 => func!([I32], [I32]), + WavmCallerStore8 | WavmCallerStore32 => func!([I32, I32], []), + MemoryFill | MemoryCopy => func!([I32, I32, I32], []), + UserInkLeft => func!([], [I64]), // λ() → ink_left + UserInkStatus => func!([], [I32]), // λ() → ink_status + UserSetInk => func!([I64, I32], []), // λ(ink_left, ink_status) + UserStackLeft => func!([], [I32]), // λ() → stack_left + UserSetStack => func!([I32], []), // λ(stack_left) + UserMemorySize => func!([], [I32]), // λ() → memory_size + CallMain => func!([I32], [I32]), // λ(args_len) → status + }; + ty + } + } +} + +// In the normal crates/prover context, MemoryType lives in crate::memory. +#[cfg(feature = "sp1")] +pub use self::sp1_memory_type::MemoryType; + +#[cfg(feature = "sp1")] +mod sp1_memory_type { + use eyre::ErrReport; + use wasmer_types::Pages; + + pub struct MemoryType { + pub min: Pages, + pub max: Option, + } + + impl MemoryType { + pub fn new(min: Pages, max: Option) -> Self { + Self { min, max } + } + } + + impl From<&wasmer_types::MemoryType> for MemoryType { + fn from(value: &wasmer_types::MemoryType) -> Self { + Self::new(value.minimum, value.maximum) + } + } + + impl TryFrom<&wasmparser::MemoryType> for MemoryType { + type Error = ErrReport; + + fn try_from(value: &wasmparser::MemoryType) -> std::result::Result { + Ok(Self { + min: Pages(value.initial.try_into()?), + max: value.maximum.map(|x| x.try_into()).transpose()?.map(Pages), + }) + } + } +} From 5a1a4633b500156f02d6ca1c6a4649dccc47bcf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 10 Mar 2026 17:18:58 +0100 Subject: [PATCH 096/189] Supress unexpected cfgs --- crates/arbutil/Cargo.toml | 4 ++++ crates/prover/Cargo.toml | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/crates/arbutil/Cargo.toml b/crates/arbutil/Cargo.toml index cece3b7fadd..24c2097baa9 100644 --- a/crates/arbutil/Cargo.toml +++ b/crates/arbutil/Cargo.toml @@ -21,3 +21,7 @@ serde = { workspace = true, features = ["derive", "rc"] } siphasher = { workspace = true } tiny-keccak = { workspace = true, features = ["keccak"] } wasmparser = { workspace = true } + +# See comment in crates/prover/Cargo.toml about the "sp1" cfg. +[lints.rust] +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(feature, values("sp1"))'] } diff --git a/crates/prover/Cargo.toml b/crates/prover/Cargo.toml index 5cac3fe29ac..14f630a2832 100644 --- a/crates/prover/Cargo.toml +++ b/crates/prover/Cargo.toml @@ -69,3 +69,10 @@ native = ["dep:wasmer", "dep:wasmer-compiler-singlepass", "brotli/wasmer_traits" singlepass_rayon = ["wasmer-compiler-singlepass?/rayon"] rayon = ["dep:rayon"] cc_brotli = ["brotli/cc_brotli"] + +# The "sp1" feature is never activated in this workspace. It exists only so that +# `#[cfg(feature = "sp1")]` gates don't produce warnings. These gates are used +# when sp1-crates/prover includes our source files via #[path] and compiles them +# with its own "sp1" feature enabled (under wasmer 6.x / wasmparser 0.224). +[lints.rust] +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(feature, values("sp1"))'] } From 509fcd18e39d7bed010942b1887cfdb845e83128 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 10 Mar 2026 17:28:57 +0100 Subject: [PATCH 097/189] Remove old operator file --- arbitrator/arbutil/src/operator.rs | 1211 ---------------------------- 1 file changed, 1211 deletions(-) delete mode 100644 arbitrator/arbutil/src/operator.rs diff --git a/arbitrator/arbutil/src/operator.rs b/arbitrator/arbutil/src/operator.rs deleted file mode 100644 index fad90d22703..00000000000 --- a/arbitrator/arbutil/src/operator.rs +++ /dev/null @@ -1,1211 +0,0 @@ -// Copyright 2021-2023, Offchain Labs, Inc. -// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md - -use std::fmt; -use std::fmt::{Debug, Display, Formatter}; -use std::hash::Hash; -use wasmparser::Operator; - -#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] -pub struct OperatorCode(usize); - -impl OperatorCode { - // TODO: use std::mem::variant_count when it's stabilized - pub const OPERATOR_COUNT: usize = 529; -} - -impl Display for OperatorCode { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - let name = match self.0 { - 0x00 => "Unreachable", - 0x01 => "Nop", - 0x02 => "Block", - 0x03 => "Loop", - 0x04 => "If", - 0x05 => "Else", - 0x06 => "Try", - 0x07 => "Catch", - 0x08 => "Throw", - 0x09 => "Rethrow", - 0x0a => "ThrowRef", - 0x0b => "End", - 0x0c => "Br", - 0x0d => "BrIf", - 0x0e => "BrTable", - 0x0f => "Return", - 0x10 => "Call", - 0x11 => "CallIndirect", - 0x12 => "ReturnCall", - 0x13 => "ReturnCallIndirect", - 0x14 => "CallRef", - 0x15 => "ReturnCallRef", - 0x18 => "Delegate", - 0x19 => "CatchAll", - 0x1a => "Drop", - 0x1b => "Select", - 0x1c => "TypedSelect", - 0x1f => "TryTable", - 0x20 => "LocalGet", - 0x21 => "LocalSet", - 0x22 => "LocalTee", - 0x23 => "GlobalGet", - 0x24 => "GlobalSet", - 0x25 => "TableGet", - 0x26 => "TableSet", - 0x28 => "I32Load", - 0x29 => "I64Load", - 0x2a => "F32Load", - 0x2b => "F64Load", - 0x2c => "I32Load8S", - 0x2d => "I32Load8U", - 0x2e => "I32Load16S", - 0x2f => "I32Load16U", - 0x30 => "I64Load8S", - 0x31 => "I64Load8U", - 0x32 => "I64Load16S", - 0x33 => "I64Load16U", - 0x34 => "I64Load32S", - 0x35 => "I64Load32U", - 0x36 => "I32Store", - 0x37 => "I64Store", - 0x38 => "F32Store", - 0x39 => "F64Store", - 0x3a => "I32Store8", - 0x3b => "I32Store16", - 0x3c => "I64Store8", - 0x3d => "I64Store16", - 0x3e => "I64Store32", - 0x3f => "MemorySize", - 0x40 => "MemoryGrow", - 0x41 => "I32Const", - 0x42 => "I64Const", - 0x43 => "F32Const", - 0x44 => "F64Const", - 0x45 => "I32Eqz", - 0x46 => "I32Eq", - 0x47 => "I32Ne", - 0x48 => "I32LtS", - 0x49 => "I32LtU", - 0x4a => "I32GtS", - 0x4b => "I32GtU", - 0x4c => "I32LeS", - 0x4d => "I32LeU", - 0x4e => "I32GeS", - 0x4f => "I32GeU", - 0x50 => "I64Eqz", - 0x51 => "I64Eq", - 0x52 => "I64Ne", - 0x53 => "I64LtS", - 0x54 => "I64LtU", - 0x55 => "I64GtS", - 0x56 => "I64GtU", - 0x57 => "I64LeS", - 0x58 => "I64LeU", - 0x59 => "I64GeS", - 0x5a => "I64GeU", - 0x5b => "F32Eq", - 0x5c => "F32Ne", - 0x5d => "F32Lt", - 0x5e => "F32Gt", - 0x5f => "F32Le", - 0x60 => "F32Ge", - 0x61 => "F64Eq", - 0x62 => "F64Ne", - 0x63 => "F64Lt", - 0x64 => "F64Gt", - 0x65 => "F64Le", - 0x66 => "F64Ge", - 0x67 => "I32Clz", - 0x68 => "I32Ctz", - 0x69 => "I32Popcnt", - 0x6a => "I32Add", - 0x6b => "I32Sub", - 0x6c => "I32Mul", - 0x6d => "I32DivS", - 0x6e => "I32DivU", - 0x6f => "I32RemS", - 0x70 => "I32RemU", - 0x71 => "I32And", - 0x72 => "I32Or", - 0x73 => "I32Xor", - 0x74 => "I32Shl", - 0x75 => "I32ShrS", - 0x76 => "I32ShrU", - 0x77 => "I32Rotl", - 0x78 => "I32Rotr", - 0x79 => "I64Clz", - 0x7a => "I64Ctz", - 0x7b => "I64Popcnt", - 0x7c => "I64Add", - 0x7d => "I64Sub", - 0x7e => "I64Mul", - 0x7f => "I64DivS", - 0x80 => "I64DivU", - 0x81 => "I64RemS", - 0x82 => "I64RemU", - 0x83 => "I64And", - 0x84 => "I64Or", - 0x85 => "I64Xor", - 0x86 => "I64Shl", - 0x87 => "I64ShrS", - 0x88 => "I64ShrU", - 0x89 => "I64Rotl", - 0x8a => "I64Rotr", - 0x8b => "F32Abs", - 0x8c => "F32Neg", - 0x8d => "F32Ceil", - 0x8e => "F32Floor", - 0x8f => "F32Trunc", - 0x90 => "F32Nearest", - 0x91 => "F32Sqrt", - 0x92 => "F32Add", - 0x93 => "F32Sub", - 0x94 => "F32Mul", - 0x95 => "F32Div", - 0x96 => "F32Min", - 0x97 => "F32Max", - 0x98 => "F32Copysign", - 0x99 => "F64Abs", - 0x9a => "F64Neg", - 0x9b => "F64Ceil", - 0x9c => "F64Floor", - 0x9d => "F64Trunc", - 0x9e => "F64Nearest", - 0x9f => "F64Sqrt", - 0xa0 => "F64Add", - 0xa1 => "F64Sub", - 0xa2 => "F64Mul", - 0xa3 => "F64Div", - 0xa4 => "F64Min", - 0xa5 => "F64Max", - 0xa6 => "F64Copysign", - 0xa7 => "I32WrapI64", - 0xa8 => "I32TruncF32S", - 0xa9 => "I32TruncF32U", - 0xaa => "I32TruncF64S", - 0xab => "I32TruncF64U", - 0xac => "I64ExtendI32S", - 0xad => "I64ExtendI32U", - 0xae => "I64TruncF32S", - 0xaf => "I64TruncF32U", - 0xb0 => "I64TruncF64S", - 0xb1 => "I64TruncF64U", - 0xb2 => "F32ConvertI32S", - 0xb3 => "F32ConvertI32U", - 0xb4 => "F32ConvertI64S", - 0xb5 => "F32ConvertI64U", - 0xb6 => "F32DemoteF64", - 0xb7 => "F64ConvertI32S", - 0xb8 => "F64ConvertI32U", - 0xb9 => "F64ConvertI64S", - 0xba => "F64ConvertI64U", - 0xbb => "F64PromoteF32", - 0xbc => "I32ReinterpretF32", - 0xbd => "I64ReinterpretF64", - 0xbe => "F32ReinterpretI32", - 0xbf => "F64ReinterpretI64", - 0xc0 => "I32Extend8S", - 0xc1 => "I32Extend16S", - 0xc2 => "I64Extend8S", - 0xc3 => "I64Extend16S", - 0xc4 => "I64Extend32S", - 0xd0 => "RefNull", - 0xd1 => "RefIsNull", - 0xd2 => "RefFunc", - 0xd3 => "RefAsNonNull", - 0xd4 => "BrOnNull", - 0xd5 => "RefEq", - 0xd6 => "BrOnNonNull", - 0xfb00 => "StructNew", - 0xfb01 => "StructNewDefault", - 0xfb02 => "StructGet", - 0xfb03 => "StructGetS", - 0xfb04 => "StructGetU", - 0xfb05 => "StructSet", - 0xfb06 => "ArrayNew", - 0xfb07 => "ArrayNewDefault", - 0xfb08 => "ArrayNewFixed", - 0xfb09 => "ArrayNewData", - 0xfb0a => "ArrayNewElem", - 0xfb0b => "ArrayGet", - 0xfb0c => "ArrayGetS", - 0xfb0d => "ArrayGetU", - 0xfb0e => "ArraySet", - 0xfb0f => "ArrayLen", - 0xfb10 => "ArrayFill", - 0xfb11 => "ArrayCopy", - 0xfb12 => "ArrayInitData", - 0xfb13 => "ArrayInitElem", - 0xfb14 => "RefTestNonNull", - 0xfb15 => "RefTestNullable", - 0xfb16 => "RefCastNonNull", - 0xfb17 => "RefCastNullable", - 0xfb18 => "BrOnCast", - 0xfb19 => "BrOnCastFail", - 0xfb1a => "AnyConvertExtern", - 0xfb1b => "ExternConvertAny", - 0xfb1c => "RefI31", - 0xfb1d => "I31GetS", - 0xfb1e => "I31GetU", - 0xfc00 => "I32TruncSatF32S", - 0xfc01 => "I32TruncSatF32U", - 0xfc02 => "I32TruncSatF64S", - 0xfc03 => "I32TruncSatF64U", - 0xfc04 => "I64TruncSatF32S", - 0xfc05 => "I64TruncSatF32U", - 0xfc06 => "I64TruncSatF64S", - 0xfc07 => "I64TruncSatF64U", - 0xfc08 => "MemoryInit", - 0xfc09 => "DataDrop", - 0xfc0a => "MemoryCopy", - 0xfc0b => "MemoryFill", - 0xfc0c => "TableInit", - 0xfc0d => "ElemDrop", - 0xfc0e => "TableCopy", - 0xfc0f => "TableGrow", - 0xfc10 => "TableSize", - 0xfc11 => "TableFill", - 0xfc12 => "MemoryDiscard", - 0xfd00 => "V128Load", - 0xfd01 => "V128Load8x8S", - 0xfd02 => "V128Load8x8U", - 0xfd03 => "V128Load16x4S", - 0xfd04 => "V128Load16x4U", - 0xfd05 => "V128Load32x2S", - 0xfd06 => "V128Load32x2U", - 0xfd07 => "V128Load8Splat", - 0xfd08 => "V128Load16Splat", - 0xfd09 => "V128Load32Splat", - 0xfd0a => "V128Load64Splat", - 0xfd0b => "V128Store", - 0xfd0c => "V128Const", - 0xfd0d => "I8x16Shuffle", - 0xfd0e => "I8x16Swizzle", - 0xfd0f => "I8x16Splat", - 0xfd10 => "I16x8Splat", - 0xfd11 => "I32x4Splat", - 0xfd12 => "I64x2Splat", - 0xfd13 => "F32x4Splat", - 0xfd14 => "F64x2Splat", - 0xfd15 => "I8x16ExtractLaneS", - 0xfd16 => "I8x16ExtractLaneU", - 0xfd17 => "I8x16ReplaceLane", - 0xfd18 => "I16x8ExtractLaneS", - 0xfd19 => "I16x8ExtractLaneU", - 0xfd1a => "I16x8ReplaceLane", - 0xfd1b => "I32x4ExtractLane", - 0xfd1c => "I32x4ReplaceLane", - 0xfd1d => "I64x2ExtractLane", - 0xfd1e => "I64x2ReplaceLane", - 0xfd1f => "F32x4ExtractLane", - 0xfd20 => "F32x4ReplaceLane", - 0xfd21 => "F64x2ExtractLane", - 0xfd22 => "F64x2ReplaceLane", - 0xfd23 => "I8x16Eq", - 0xfd24 => "I8x16Ne", - 0xfd25 => "I8x16LtS", - 0xfd26 => "I8x16LtU", - 0xfd27 => "I8x16GtS", - 0xfd28 => "I8x16GtU", - 0xfd29 => "I8x16LeS", - 0xfd2a => "I8x16LeU", - 0xfd2b => "I8x16GeS", - 0xfd2c => "I8x16GeU", - 0xfd2d => "I16x8Eq", - 0xfd2e => "I16x8Ne", - 0xfd2f => "I16x8LtS", - 0xfd30 => "I16x8LtU", - 0xfd31 => "I16x8GtS", - 0xfd32 => "I16x8GtU", - 0xfd33 => "I16x8LeS", - 0xfd34 => "I16x8LeU", - 0xfd35 => "I16x8GeS", - 0xfd36 => "I16x8GeU", - 0xfd37 => "I32x4Eq", - 0xfd38 => "I32x4Ne", - 0xfd39 => "I32x4LtS", - 0xfd3a => "I32x4LtU", - 0xfd3b => "I32x4GtS", - 0xfd3c => "I32x4GtU", - 0xfd3d => "I32x4LeS", - 0xfd3e => "I32x4LeU", - 0xfd3f => "I32x4GeS", - 0xfd40 => "I32x4GeU", - 0xfd41 => "F32x4Eq", - 0xfd42 => "F32x4Ne", - 0xfd43 => "F32x4Lt", - 0xfd44 => "F32x4Gt", - 0xfd45 => "F32x4Le", - 0xfd46 => "F32x4Ge", - 0xfd47 => "F64x2Eq", - 0xfd48 => "F64x2Ne", - 0xfd49 => "F64x2Lt", - 0xfd4a => "F64x2Gt", - 0xfd4b => "F64x2Le", - 0xfd4c => "F64x2Ge", - 0xfd4d => "V128Not", - 0xfd4e => "V128And", - 0xfd4f => "V128AndNot", - 0xfd50 => "V128Or", - 0xfd51 => "V128Xor", - 0xfd52 => "V128Bitselect", - 0xfd53 => "V128AnyTrue", - 0xfd54 => "V128Load8Lane", - 0xfd55 => "V128Load16Lane", - 0xfd56 => "V128Load32Lane", - 0xfd57 => "V128Load64Lane", - 0xfd58 => "V128Store8Lane", - 0xfd59 => "V128Store16Lane", - 0xfd5a => "V128Store32Lane", - 0xfd5b => "V128Store64Lane", - 0xfd5c => "V128Load32Zero", - 0xfd5d => "V128Load64Zero", - 0xfd5e => "F32x4DemoteF64x2Zero", - 0xfd5f => "F64x2PromoteLowF32x4", - 0xfd60 => "I8x16Abs", - 0xfd61 => "I8x16Neg", - 0xfd62 => "I8x16Popcnt", - 0xfd63 => "I8x16AllTrue", - 0xfd64 => "I8x16Bitmask", - 0xfd65 => "I8x16NarrowI16x8S", - 0xfd66 => "I8x16NarrowI16x8U", - 0xfd67 => "F32x4Ceil", - 0xfd68 => "F32x4Floor", - 0xfd69 => "F32x4Trunc", - 0xfd6a => "F32x4Nearest", - 0xfd6b => "I8x16Shl", - 0xfd6c => "I8x16ShrS", - 0xfd6d => "I8x16ShrU", - 0xfd6e => "I8x16Add", - 0xfd6f => "I8x16AddSatS", - 0xfd70 => "I8x16AddSatU", - 0xfd71 => "I8x16Sub", - 0xfd72 => "I8x16SubSatS", - 0xfd73 => "I8x16SubSatU", - 0xfd74 => "F64x2Ceil", - 0xfd75 => "F64x2Floor", - 0xfd76 => "I8x16MinS", - 0xfd77 => "I8x16MinU", - 0xfd78 => "I8x16MaxS", - 0xfd79 => "I8x16MaxU", - 0xfd7a => "F64x2Trunc", - 0xfd7b => "I8x16AvgrU", - 0xfd7c => "I16x8ExtAddPairwiseI8x16S", - 0xfd7d => "I16x8ExtAddPairwiseI8x16U", - 0xfd7e => "I32x4ExtAddPairwiseI16x8S", - 0xfd7f => "I32x4ExtAddPairwiseI16x8U", - 0xfd80 => "I16x8Abs", - 0xfd81 => "I16x8Neg", - 0xfd82 => "I16x8Q15MulrSatS", - 0xfd83 => "I16x8AllTrue", - 0xfd84 => "I16x8Bitmask", - 0xfd85 => "I16x8NarrowI32x4S", - 0xfd86 => "I16x8NarrowI32x4U", - 0xfd87 => "I16x8ExtendLowI8x16S", - 0xfd88 => "I16x8ExtendHighI8x16S", - 0xfd89 => "I16x8ExtendLowI8x16U", - 0xfd8a => "I16x8ExtendHighI8x16U", - 0xfd8b => "I16x8Shl", - 0xfd8c => "I16x8ShrS", - 0xfd8d => "I16x8ShrU", - 0xfd8e => "I16x8Add", - 0xfd8f => "I16x8AddSatS", - 0xfd90 => "I16x8AddSatU", - 0xfd91 => "I16x8Sub", - 0xfd92 => "I16x8SubSatS", - 0xfd93 => "I16x8SubSatU", - 0xfd94 => "F64x2Nearest", - 0xfd95 => "I16x8Mul", - 0xfd96 => "I16x8MinS", - 0xfd97 => "I16x8MinU", - 0xfd98 => "I16x8MaxS", - 0xfd99 => "I16x8MaxU", - 0xfd9b => "I16x8AvgrU", - 0xfd9c => "I16x8ExtMulLowI8x16S", - 0xfd9d => "I16x8ExtMulHighI8x16S", - 0xfd9e => "I16x8ExtMulLowI8x16U", - 0xfd9f => "I16x8ExtMulHighI8x16U", - 0xfda0 => "I32x4Abs", - 0xfda2 => "I8x16RelaxedSwizzle", - 0xfda1 => "I32x4Neg", - 0xfda3 => "I32x4AllTrue", - 0xfda4 => "I32x4Bitmask", - 0xfda5 => "I32x4RelaxedTruncF32x4S", - 0xfda6 => "I32x4RelaxedTruncF32x4U", - 0xfda7 => "I32x4ExtendLowI16x8S", - 0xfda8 => "I32x4ExtendHighI16x8S", - 0xfda9 => "I32x4ExtendLowI16x8U", - 0xfdaa => "I32x4ExtendHighI16x8U", - 0xfdab => "I32x4Shl", - 0xfdac => "I32x4ShrS", - 0xfdad => "I32x4ShrU", - 0xfdae => "I32x4Add", - 0xfdaf => "F32x4RelaxedMadd", - 0xfdb0 => "F32x4RelaxedNmadd", - 0xfdb1 => "I32x4Sub", - 0xfdb2 => "I8x16RelaxedLaneselect", - 0xfdb3 => "I16x8RelaxedLaneselect", - 0xfdb4 => "F32x4RelaxedMin", - 0xfdb5 => "I32x4Mul", - 0xfdb6 => "I32x4MinS", - 0xfdb7 => "I32x4MinU", - 0xfdb8 => "I32x4MaxS", - 0xfdb9 => "I32x4MaxU", - 0xfdba => "I32x4DotI16x8S", - 0xfdbc => "I32x4ExtMulLowI16x8S", - 0xfdbd => "I32x4ExtMulHighI16x8S", - 0xfdbe => "I32x4ExtMulLowI16x8U", - 0xfdbf => "I32x4ExtMulHighI16x8U", - 0xfdc0 => "I64x2Abs", - 0xfdc1 => "I64x2Neg", - 0xfdc3 => "I64x2AllTrue", - 0xfdc4 => "I64x2Bitmask", - 0xfdc5 => "I32x4RelaxedTruncF64x2SZero", - 0xfdc6 => "I32x4RelaxedTruncF64x2UZero", - 0xfdc7 => "I64x2ExtendLowI32x4S", - 0xfdc8 => "I64x2ExtendHighI32x4S", - 0xfdc9 => "I64x2ExtendLowI32x4U", - 0xfdca => "I64x2ExtendHighI32x4U", - 0xfdcb => "I64x2Shl", - 0xfdcc => "I64x2ShrS", - 0xfdcd => "I64x2ShrU", - 0xfdce => "I64x2Add", - 0xfdcf => "F64x2RelaxedMadd", - 0xfdd0 => "F64x2RelaxedNmadd", - 0xfdd1 => "I64x2Sub", - 0xfdd2 => "I32x4RelaxedLaneselect", - 0xfdd3 => "I64x2RelaxedLaneselect", - 0xfdd4 => "F64x2RelaxedMin", - 0xfdd5 => "I64x2Mul", - 0xfdd6 => "I64x2Eq", - 0xfdd7 => "I64x2Ne", - 0xfdd8 => "I64x2LtS", - 0xfdd9 => "I64x2GtS", - 0xfdda => "I64x2LeS", - 0xfddb => "I64x2GeS", - 0xfddc => "I64x2ExtMulLowI32x4S", - 0xfddd => "I64x2ExtMulHighI32x4S", - 0xfdde => "I64x2ExtMulLowI32x4U", - 0xfddf => "I64x2ExtMulHighI32x4U", - 0xfde0 => "F32x4Abs", - 0xfde1 => "F32x4Neg", - 0xfde2 => "F32x4RelaxedMax", - 0xfde3 => "F32x4Sqrt", - 0xfde4 => "F32x4Add", - 0xfde5 => "F32x4Sub", - 0xfde6 => "F32x4Mul", - 0xfde7 => "F32x4Div", - 0xfde8 => "F32x4Min", - 0xfde9 => "F32x4Max", - 0xfdea => "F32x4PMin", - 0xfdeb => "F32x4PMax", - 0xfdec => "F64x2Abs", - 0xfded => "F64x2Neg", - 0xfdee => "F64x2RelaxedMax", - 0xfdef => "F64x2Sqrt", - 0xfdf0 => "F64x2Add", - 0xfdf1 => "F64x2Sub", - 0xfdf2 => "F64x2Mul", - 0xfdf3 => "F64x2Div", - 0xfdf4 => "F64x2Min", - 0xfdf5 => "F64x2Max", - 0xfdf6 => "F64x2PMin", - 0xfdf7 => "F64x2PMax", - 0xfdf8 => "I32x4TruncSatF32x4S", - 0xfdf9 => "I32x4TruncSatF32x4U", - 0xfdfa => "F32x4ConvertI32x4S", - 0xfdfb => "F32x4ConvertI32x4U", - 0xfdfc => "I32x4TruncSatF64x2SZero", - 0xfdfd => "I32x4TruncSatF64x2UZero", - 0xfdfe => "F64x2ConvertLowI32x4S", - 0xfdff => "F64x2ConvertLowI32x4U", - 0xfe00 => "MemoryAtomicNotify", - 0xfe01 => "MemoryAtomicWait32", - 0xfe02 => "MemoryAtomicWait64", - 0xfe03 => "AtomicFence", - 0xfe10 => "I32AtomicLoad", - 0xfe11 => "I64AtomicLoad", - 0xfe12 => "I32AtomicLoad8U", - 0xfe13 => "I32AtomicLoad16U", - 0xfe14 => "I64AtomicLoad8U", - 0xfe15 => "I64AtomicLoad16U", - 0xfe16 => "I64AtomicLoad32U", - 0xfe17 => "I32AtomicStore", - 0xfe18 => "I64AtomicStore", - 0xfe19 => "I32AtomicStore8", - 0xfe1a => "I32AtomicStore16", - 0xfe1b => "I64AtomicStore8", - 0xfe1c => "I64AtomicStore16", - 0xfe1d => "I64AtomicStore32", - 0xfe1e => "I32AtomicRmwAdd", - 0xfe1f => "I64AtomicRmwAdd", - 0xfe20 => "I32AtomicRmw8AddU", - 0xfe21 => "I32AtomicRmw16AddU", - 0xfe22 => "I64AtomicRmw8AddU", - 0xfe23 => "I64AtomicRmw16AddU", - 0xfe24 => "I64AtomicRmw32AddU", - 0xfe25 => "I32AtomicRmwSub", - 0xfe26 => "I64AtomicRmwSub", - 0xfe27 => "I32AtomicRmw8SubU", - 0xfe28 => "I32AtomicRmw16SubU", - 0xfe29 => "I64AtomicRmw8SubU", - 0xfe2a => "I64AtomicRmw16SubU", - 0xfe2b => "I64AtomicRmw32SubU", - 0xfe2c => "I32AtomicRmwAnd", - 0xfe2d => "I64AtomicRmwAnd", - 0xfe2e => "I32AtomicRmw8AndU", - 0xfe2f => "I32AtomicRmw16AndU", - 0xfe30 => "I64AtomicRmw8AndU", - 0xfe31 => "I64AtomicRmw16AndU", - 0xfe32 => "I64AtomicRmw32AndU", - 0xfe33 => "I32AtomicRmwOr", - 0xfe34 => "I64AtomicRmwOr", - 0xfe35 => "I32AtomicRmw8OrU", - 0xfe36 => "I32AtomicRmw16OrU", - 0xfe37 => "I64AtomicRmw8OrU", - 0xfe38 => "I64AtomicRmw16OrU", - 0xfe39 => "I64AtomicRmw32OrU", - 0xfe3a => "I32AtomicRmwXor", - 0xfe3b => "I64AtomicRmwXor", - 0xfe3c => "I32AtomicRmw8XorU", - 0xfe3d => "I32AtomicRmw16XorU", - 0xfe3e => "I64AtomicRmw8XorU", - 0xfe3f => "I64AtomicRmw16XorU", - 0xfe40 => "I64AtomicRmw32XorU", - 0xfe41 => "I32AtomicRmwXchg", - 0xfe42 => "I64AtomicRmwXchg", - 0xfe43 => "I32AtomicRmw8XchgU", - 0xfe44 => "I32AtomicRmw16XchgU", - 0xfe45 => "I64AtomicRmw8XchgU", - 0xfe46 => "I64AtomicRmw16XchgU", - 0xfe47 => "I64AtomicRmw32XchgU", - 0xfe48 => "I32AtomicRmwCmpxchg", - 0xfe49 => "I64AtomicRmwCmpxchg", - 0xfe4a => "I32AtomicRmw8CmpxchgU", - 0xfe4b => "I32AtomicRmw16CmpxchgU", - 0xfe4c => "I64AtomicRmw8CmpxchgU", - 0xfe4d => "I64AtomicRmw16CmpxchgU", - 0xfe4e => "I64AtomicRmw32CmpxchgU", - 0xfd111 => "I16x8RelaxedQ15mulrS", - 0xfd112 => "I16x8RelaxedDotI8x16I7x16S", - 0xfd113 => "I32x4RelaxedDotI8x16I7x16AddS", - _ => "UNKNOWN", - }; - write!(f, "{name}") - } -} - -impl From> for OperatorCode { - fn from(op: Operator) -> Self { - OperatorCode::from(&op) - } -} - -impl From<&Operator<'_>> for OperatorCode { - fn from(op: &Operator) -> Self { - use Operator as O; - - OperatorCode(match op { - O::Unreachable => 0x00, - O::Nop => 0x01, - O::Block { .. } => 0x02, - O::Loop { .. } => 0x03, - O::If { .. } => 0x04, - O::Else => 0x05, - O::Try { .. } => 0x06, - O::Catch { .. } => 0x07, - O::Throw { .. } => 0x08, - O::Rethrow { .. } => 0x09, - O::ThrowRef { .. } => 0x0A, - O::End => 0x0b, - O::Br { .. } => 0x0c, - O::BrIf { .. } => 0x0d, - O::BrTable { .. } => 0x0e, - O::Return => 0x0f, - O::Call { .. } => 0x10, - O::CallIndirect { .. } => 0x11, - O::ReturnCall { .. } => 0x12, - O::ReturnCallIndirect { .. } => 0x13, - O::CallRef { .. } => 0x14, - O::ReturnCallRef { .. } => 0x15, - O::Delegate { .. } => 0x18, - O::CatchAll => 0x19, - O::Drop => 0x1a, - O::Select => 0x1b, - O::TypedSelect { .. } => 0x1c, - O::TryTable { .. } => 0x1f, - O::LocalGet { .. } => 0x20, - O::LocalSet { .. } => 0x21, - O::LocalTee { .. } => 0x22, - O::GlobalGet { .. } => 0x23, - O::GlobalSet { .. } => 0x24, - O::TableGet { .. } => 0x25, - O::TableSet { .. } => 0x26, - O::I32Load { .. } => 0x28, - O::I64Load { .. } => 0x29, - O::F32Load { .. } => 0x2a, - O::F64Load { .. } => 0x2b, - O::I32Load8S { .. } => 0x2c, - O::I32Load8U { .. } => 0x2d, - O::I32Load16S { .. } => 0x2e, - O::I32Load16U { .. } => 0x2f, - O::I64Load8S { .. } => 0x30, - O::I64Load8U { .. } => 0x31, - O::I64Load16S { .. } => 0x32, - O::I64Load16U { .. } => 0x33, - O::I64Load32S { .. } => 0x34, - O::I64Load32U { .. } => 0x35, - O::I32Store { .. } => 0x36, - O::I64Store { .. } => 0x37, - O::F32Store { .. } => 0x38, - O::F64Store { .. } => 0x39, - O::I32Store8 { .. } => 0x3a, - O::I32Store16 { .. } => 0x3b, - O::I64Store8 { .. } => 0x3c, - O::I64Store16 { .. } => 0x3d, - O::I64Store32 { .. } => 0x3e, - O::MemorySize { .. } => 0x3f, - O::MemoryGrow { .. } => 0x40, - O::I32Const { .. } => 0x41, - O::I64Const { .. } => 0x42, - O::F32Const { .. } => 0x43, - O::F64Const { .. } => 0x44, - O::I32Eqz => 0x45, - O::I32Eq => 0x46, - O::I32Ne => 0x47, - O::I32LtS => 0x48, - O::I32LtU => 0x49, - O::I32GtS => 0x4a, - O::I32GtU => 0x4b, - O::I32LeS => 0x4c, - O::I32LeU => 0x4d, - O::I32GeS => 0x4e, - O::I32GeU => 0x4f, - O::I64Eqz => 0x50, - O::I64Eq => 0x51, - O::I64Ne => 0x52, - O::I64LtS => 0x53, - O::I64LtU => 0x54, - O::I64GtS => 0x55, - O::I64GtU => 0x56, - O::I64LeS => 0x57, - O::I64LeU => 0x58, - O::I64GeS => 0x59, - O::I64GeU => 0x5a, - O::F32Eq => 0x5b, - O::F32Ne => 0x5c, - O::F32Lt => 0x5d, - O::F32Gt => 0x5e, - O::F32Le => 0x5f, - O::F32Ge => 0x60, - O::F64Eq => 0x61, - O::F64Ne => 0x62, - O::F64Lt => 0x63, - O::F64Gt => 0x64, - O::F64Le => 0x65, - O::F64Ge => 0x66, - O::I32Clz => 0x67, - O::I32Ctz => 0x68, - O::I32Popcnt => 0x69, - O::I32Add => 0x6a, - O::I32Sub => 0x6b, - O::I32Mul => 0x6c, - O::I32DivS => 0x6d, - O::I32DivU => 0x6e, - O::I32RemS => 0x6f, - O::I32RemU => 0x70, - O::I32And => 0x71, - O::I32Or => 0x72, - O::I32Xor => 0x73, - O::I32Shl => 0x74, - O::I32ShrS => 0x75, - O::I32ShrU => 0x76, - O::I32Rotl => 0x77, - O::I32Rotr => 0x78, - O::I64Clz => 0x79, - O::I64Ctz => 0x7a, - O::I64Popcnt => 0x7b, - O::I64Add => 0x7c, - O::I64Sub => 0x7d, - O::I64Mul => 0x7e, - O::I64DivS => 0x7f, - O::I64DivU => 0x80, - O::I64RemS => 0x81, - O::I64RemU => 0x82, - O::I64And => 0x83, - O::I64Or => 0x84, - O::I64Xor => 0x85, - O::I64Shl => 0x86, - O::I64ShrS => 0x87, - O::I64ShrU => 0x88, - O::I64Rotl => 0x89, - O::I64Rotr => 0x8a, - O::F32Abs => 0x8b, - O::F32Neg => 0x8c, - O::F32Ceil => 0x8d, - O::F32Floor => 0x8e, - O::F32Trunc => 0x8f, - O::F32Nearest => 0x90, - O::F32Sqrt => 0x91, - O::F32Add => 0x92, - O::F32Sub => 0x93, - O::F32Mul => 0x94, - O::F32Div => 0x95, - O::F32Min => 0x96, - O::F32Max => 0x97, - O::F32Copysign => 0x98, - O::F64Abs => 0x99, - O::F64Neg => 0x9a, - O::F64Ceil => 0x9b, - O::F64Floor => 0x9c, - O::F64Trunc => 0x9d, - O::F64Nearest => 0x9e, - O::F64Sqrt => 0x9f, - O::F64Add => 0xa0, - O::F64Sub => 0xa1, - O::F64Mul => 0xa2, - O::F64Div => 0xa3, - O::F64Min => 0xa4, - O::F64Max => 0xa5, - O::F64Copysign => 0xa6, - O::I32WrapI64 => 0xa7, - O::I32TruncF32S => 0xa8, - O::I32TruncF32U => 0xa9, - O::I32TruncF64S => 0xaa, - O::I32TruncF64U => 0xab, - O::I64ExtendI32S => 0xac, - O::I64ExtendI32U => 0xad, - O::I64TruncF32S => 0xae, - O::I64TruncF32U => 0xaf, - O::I64TruncF64S => 0xb0, - O::I64TruncF64U => 0xb1, - O::F32ConvertI32S => 0xb2, - O::F32ConvertI32U => 0xb3, - O::F32ConvertI64S => 0xb4, - O::F32ConvertI64U => 0xb5, - O::F32DemoteF64 => 0xb6, - O::F64ConvertI32S => 0xb7, - O::F64ConvertI32U => 0xb8, - O::F64ConvertI64S => 0xb9, - O::F64ConvertI64U => 0xba, - O::F64PromoteF32 => 0xbb, - O::I32ReinterpretF32 => 0xbc, - O::I64ReinterpretF64 => 0xbd, - O::F32ReinterpretI32 => 0xbe, - O::F64ReinterpretI64 => 0xbf, - O::I32Extend8S => 0xc0, - O::I32Extend16S => 0xc1, - O::I64Extend8S => 0xc2, - O::I64Extend16S => 0xc3, - O::I64Extend32S => 0xc4, - O::RefNull { .. } => 0xd0, - O::RefIsNull => 0xd1, - O::RefFunc { .. } => 0xd2, - O::RefAsNonNull => 0xd3, - O::BrOnNull { .. } => 0xd4, - O::RefEq { .. } => 0xd5, - O::BrOnNonNull { .. } => 0xd6, - O::StructNew { .. } => 0xfb00, - O::StructNewDefault { .. } => 0xfb01, - O::StructGet { .. } => 0xfb02, - O::StructGetS { .. } => 0xfb03, - O::StructGetU { .. } => 0xfb04, - O::StructSet { .. } => 0xfb05, - O::ArrayNew { .. } => 0xfb06, - O::ArrayNewDefault { .. } => 0xfb07, - O::ArrayNewFixed { .. } => 0xfb08, - O::ArrayNewData { .. } => 0xfb09, - O::ArrayNewElem { .. } => 0xfb0a, - O::ArrayGet { .. } => 0xfb0b, - O::ArrayGetS { .. } => 0xfb0c, - O::ArrayGetU { .. } => 0xfb0d, - O::ArraySet { .. } => 0xfb0e, - O::ArrayLen { .. } => 0xfb0f, - O::ArrayFill { .. } => 0xfb10, - O::ArrayCopy { .. } => 0xfb11, - O::ArrayInitData { .. } => 0xfb12, - O::ArrayInitElem { .. } => 0xfb13, - O::RefTestNonNull { .. } => 0xfb14, - O::RefTestNullable { .. } => 0xfb15, - O::RefCastNonNull { .. } => 0xfb16, - O::RefCastNullable { .. } => 0xfb17, - O::BrOnCast { .. } => 0xfb18, - O::BrOnCastFail { .. } => 0xfb19, - O::AnyConvertExtern => 0xfb1a, - O::ExternConvertAny => 0xfb1b, - O::RefI31 { .. } => 0xfb1c, - O::I31GetS => 0xfb1d, - O::I31GetU => 0xfb1e, - O::I32TruncSatF32S => 0xfc00, - O::I32TruncSatF32U => 0xfc01, - O::I32TruncSatF64S => 0xfc02, - O::I32TruncSatF64U => 0xfc03, - O::I64TruncSatF32S => 0xfc04, - O::I64TruncSatF32U => 0xfc05, - O::I64TruncSatF64S => 0xfc06, - O::I64TruncSatF64U => 0xfc07, - O::MemoryInit { .. } => 0xfc08, - O::DataDrop { .. } => 0xfc09, - O::MemoryCopy { .. } => 0xfc0a, - O::MemoryFill { .. } => 0xfc0b, - O::TableInit { .. } => 0xfc0c, - O::ElemDrop { .. } => 0xfc0d, - O::TableCopy { .. } => 0xfc0e, - O::TableGrow { .. } => 0xfc0f, - O::TableSize { .. } => 0xfc10, - O::TableFill { .. } => 0xfc11, - O::MemoryDiscard { .. } => 0xfc12, - O::V128Load { .. } => 0xfd00, - O::V128Load8x8S { .. } => 0xfd01, - O::V128Load8x8U { .. } => 0xfd02, - O::V128Load16x4S { .. } => 0xfd03, - O::V128Load16x4U { .. } => 0xfd04, - O::V128Load32x2S { .. } => 0xfd05, - O::V128Load32x2U { .. } => 0xfd06, - O::V128Load8Splat { .. } => 0xfd07, - O::V128Load16Splat { .. } => 0xfd08, - O::V128Load32Splat { .. } => 0xfd09, - O::V128Load64Splat { .. } => 0xfd0a, - O::V128Store { .. } => 0xfd0b, - O::V128Const { .. } => 0xfd0c, - O::I8x16Shuffle { .. } => 0xfd0d, - O::I8x16Swizzle => 0xfd0e, - O::I8x16Splat => 0xfd0f, - O::I16x8Splat => 0xfd10, - O::I32x4Splat => 0xfd11, - O::I64x2Splat => 0xfd12, - O::F32x4Splat => 0xfd13, - O::F64x2Splat => 0xfd14, - O::I8x16ExtractLaneS { .. } => 0xfd15, - O::I8x16ExtractLaneU { .. } => 0xfd16, - O::I8x16ReplaceLane { .. } => 0xfd17, - O::I16x8ExtractLaneS { .. } => 0xfd18, - O::I16x8ExtractLaneU { .. } => 0xfd19, - O::I16x8ReplaceLane { .. } => 0xfd1a, - O::I32x4ExtractLane { .. } => 0xfd1b, - O::I32x4ReplaceLane { .. } => 0xfd1c, - O::I64x2ExtractLane { .. } => 0xfd1d, - O::I64x2ReplaceLane { .. } => 0xfd1e, - O::F32x4ExtractLane { .. } => 0xfd1f, - O::F32x4ReplaceLane { .. } => 0xfd20, - O::F64x2ExtractLane { .. } => 0xfd21, - O::F64x2ReplaceLane { .. } => 0xfd22, - O::I8x16Eq => 0xfd23, - O::I8x16Ne => 0xfd24, - O::I8x16LtS => 0xfd25, - O::I8x16LtU => 0xfd26, - O::I8x16GtS => 0xfd27, - O::I8x16GtU => 0xfd28, - O::I8x16LeS => 0xfd29, - O::I8x16LeU => 0xfd2a, - O::I8x16GeS => 0xfd2b, - O::I8x16GeU => 0xfd2c, - O::I16x8Eq => 0xfd2d, - O::I16x8Ne => 0xfd2e, - O::I16x8LtS => 0xfd2f, - O::I16x8LtU => 0xfd30, - O::I16x8GtS => 0xfd31, - O::I16x8GtU => 0xfd32, - O::I16x8LeS => 0xfd33, - O::I16x8LeU => 0xfd34, - O::I16x8GeS => 0xfd35, - O::I16x8GeU => 0xfd36, - O::I32x4Eq => 0xfd37, - O::I32x4Ne => 0xfd38, - O::I32x4LtS => 0xfd39, - O::I32x4LtU => 0xfd3a, - O::I32x4GtS => 0xfd3b, - O::I32x4GtU => 0xfd3c, - O::I32x4LeS => 0xfd3d, - O::I32x4LeU => 0xfd3e, - O::I32x4GeS => 0xfd3f, - O::I32x4GeU => 0xfd40, - O::F32x4Eq => 0xfd41, - O::F32x4Ne => 0xfd42, - O::F32x4Lt => 0xfd43, - O::F32x4Gt => 0xfd44, - O::F32x4Le => 0xfd45, - O::F32x4Ge => 0xfd46, - O::F64x2Eq => 0xfd47, - O::F64x2Ne => 0xfd48, - O::F64x2Lt => 0xfd49, - O::F64x2Gt => 0xfd4a, - O::F64x2Le => 0xfd4b, - O::F64x2Ge => 0xfd4c, - O::V128Not => 0xfd4d, - O::V128And => 0xfd4e, - O::V128AndNot => 0xfd4f, - O::V128Or => 0xfd50, - O::V128Xor => 0xfd51, - O::V128Bitselect => 0xfd52, - O::V128AnyTrue => 0xfd53, - O::V128Load8Lane { .. } => 0xfd54, - O::V128Load16Lane { .. } => 0xfd55, - O::V128Load32Lane { .. } => 0xfd56, - O::V128Load64Lane { .. } => 0xfd57, - O::V128Store8Lane { .. } => 0xfd58, - O::V128Store16Lane { .. } => 0xfd59, - O::V128Store32Lane { .. } => 0xfd5a, - O::V128Store64Lane { .. } => 0xfd5b, - O::V128Load32Zero { .. } => 0xfd5c, - O::V128Load64Zero { .. } => 0xfd5d, - O::F32x4DemoteF64x2Zero => 0xfd5e, - O::F64x2PromoteLowF32x4 => 0xfd5f, - O::I8x16Abs => 0xfd60, - O::I8x16Neg => 0xfd61, - O::I8x16Popcnt => 0xfd62, - O::I8x16AllTrue => 0xfd63, - O::I8x16Bitmask => 0xfd64, - O::I8x16NarrowI16x8S => 0xfd65, - O::I8x16NarrowI16x8U => 0xfd66, - O::F32x4Ceil => 0xfd67, - O::F32x4Floor => 0xfd68, - O::F32x4Trunc => 0xfd69, - O::F32x4Nearest => 0xfd6a, - O::I8x16Shl => 0xfd6b, - O::I8x16ShrS => 0xfd6c, - O::I8x16ShrU => 0xfd6d, - O::I8x16Add => 0xfd6e, - O::I8x16AddSatS => 0xfd6f, - O::I8x16AddSatU => 0xfd70, - O::I8x16Sub => 0xfd71, - O::I8x16SubSatS => 0xfd72, - O::I8x16SubSatU => 0xfd73, - O::F64x2Ceil => 0xfd74, - O::F64x2Floor => 0xfd75, - O::I8x16MinS => 0xfd76, - O::I8x16MinU => 0xfd77, - O::I8x16MaxS => 0xfd78, - O::I8x16MaxU => 0xfd79, - O::F64x2Trunc => 0xfd7a, - O::I8x16AvgrU => 0xfd7b, - O::I16x8ExtAddPairwiseI8x16S => 0xfd7c, - O::I16x8ExtAddPairwiseI8x16U => 0xfd7d, - O::I32x4ExtAddPairwiseI16x8S => 0xfd7e, - O::I32x4ExtAddPairwiseI16x8U => 0xfd7f, - O::I16x8Abs => 0xfd80, - O::I16x8Neg => 0xfd81, - O::I16x8Q15MulrSatS => 0xfd82, - O::I16x8AllTrue => 0xfd83, - O::I16x8Bitmask => 0xfd84, - O::I16x8NarrowI32x4S => 0xfd85, - O::I16x8NarrowI32x4U => 0xfd86, - O::I16x8ExtendLowI8x16S => 0xfd87, - O::I16x8ExtendHighI8x16S => 0xfd88, - O::I16x8ExtendLowI8x16U => 0xfd89, - O::I16x8ExtendHighI8x16U => 0xfd8a, - O::I16x8Shl => 0xfd8b, - O::I16x8ShrS => 0xfd8c, - O::I16x8ShrU => 0xfd8d, - O::I16x8Add => 0xfd8e, - O::I16x8AddSatS => 0xfd8f, - O::I16x8AddSatU => 0xfd90, - O::I16x8Sub => 0xfd91, - O::I16x8SubSatS => 0xfd92, - O::I16x8SubSatU => 0xfd93, - O::F64x2Nearest => 0xfd94, - O::I16x8Mul => 0xfd95, - O::I16x8MinS => 0xfd96, - O::I16x8MinU => 0xfd97, - O::I16x8MaxS => 0xfd98, - O::I16x8MaxU => 0xfd99, - O::I16x8AvgrU => 0xfd9b, - O::I16x8ExtMulLowI8x16S => 0xfd9c, - O::I16x8ExtMulHighI8x16S => 0xfd9d, - O::I16x8ExtMulLowI8x16U => 0xfd9e, - O::I16x8ExtMulHighI8x16U => 0xfd9f, - O::I32x4Abs => 0xfda0, - O::I8x16RelaxedSwizzle => 0xfda2, - O::I32x4Neg => 0xfda1, - O::I32x4AllTrue => 0xfda3, - O::I32x4Bitmask => 0xfda4, - O::I32x4RelaxedTruncF32x4S => 0xfda5, - O::I32x4RelaxedTruncF32x4U => 0xfda6, - O::I32x4ExtendLowI16x8S => 0xfda7, - O::I32x4ExtendHighI16x8S => 0xfda8, - O::I32x4ExtendLowI16x8U => 0xfda9, - O::I32x4ExtendHighI16x8U => 0xfdaa, - O::I32x4Shl => 0xfdab, - O::I32x4ShrS => 0xfdac, - O::I32x4ShrU => 0xfdad, - O::I32x4Add => 0xfdae, - O::F32x4RelaxedMadd => 0xfdaf, - O::F32x4RelaxedNmadd => 0xfdb0, - O::I32x4Sub => 0xfdb1, - O::I8x16RelaxedLaneselect => 0xfdb2, - O::I16x8RelaxedLaneselect => 0xfdb3, - O::F32x4RelaxedMin => 0xfdb4, - O::I32x4Mul => 0xfdb5, - O::I32x4MinS => 0xfdb6, - O::I32x4MinU => 0xfdb7, - O::I32x4MaxS => 0xfdb8, - O::I32x4MaxU => 0xfdb9, - O::I32x4DotI16x8S => 0xfdba, - O::I32x4ExtMulLowI16x8S => 0xfdbc, - O::I32x4ExtMulHighI16x8S => 0xfdbd, - O::I32x4ExtMulLowI16x8U => 0xfdbe, - O::I32x4ExtMulHighI16x8U => 0xfdbf, - O::I64x2Abs => 0xfdc0, - O::I64x2Neg => 0xfdc1, - O::I64x2AllTrue => 0xfdc3, - O::I64x2Bitmask => 0xfdc4, - O::I32x4RelaxedTruncF64x2SZero => 0xfdc5, - O::I32x4RelaxedTruncF64x2UZero => 0xfdc6, - O::I64x2ExtendLowI32x4S => 0xfdc7, - O::I64x2ExtendHighI32x4S => 0xfdc8, - O::I64x2ExtendLowI32x4U => 0xfdc9, - O::I64x2ExtendHighI32x4U => 0xfdca, - O::I64x2Shl => 0xfdcb, - O::I64x2ShrS => 0xfdcc, - O::I64x2ShrU => 0xfdcd, - O::I64x2Add => 0xfdce, - O::F64x2RelaxedMadd => 0xfdcf, - O::F64x2RelaxedNmadd => 0xfdd0, - O::I64x2Sub => 0xfdd1, - O::I32x4RelaxedLaneselect => 0xfdd2, - O::I64x2RelaxedLaneselect => 0xfdd3, - O::F64x2RelaxedMin => 0xfdd4, - O::I64x2Mul => 0xfdd5, - O::I64x2Eq => 0xfdd6, - O::I64x2Ne => 0xfdd7, - O::I64x2LtS => 0xfdd8, - O::I64x2GtS => 0xfdd9, - O::I64x2LeS => 0xfdda, - O::I64x2GeS => 0xfddb, - O::I64x2ExtMulLowI32x4S => 0xfddc, - O::I64x2ExtMulHighI32x4S => 0xfddd, - O::I64x2ExtMulLowI32x4U => 0xfdde, - O::I64x2ExtMulHighI32x4U => 0xfddf, - O::F32x4Abs => 0xfde0, - O::F32x4Neg => 0xfde1, - O::F32x4RelaxedMax => 0xfde2, - O::F32x4Sqrt => 0xfde3, - O::F32x4Add => 0xfde4, - O::F32x4Sub => 0xfde5, - O::F32x4Mul => 0xfde6, - O::F32x4Div => 0xfde7, - O::F32x4Min => 0xfde8, - O::F32x4Max => 0xfde9, - O::F32x4PMin => 0xfdea, - O::F32x4PMax => 0xfdeb, - O::F64x2Abs => 0xfdec, - O::F64x2Neg => 0xfded, - O::F64x2RelaxedMax => 0xfdee, - O::F64x2Sqrt => 0xfdef, - O::F64x2Add => 0xfdf0, - O::F64x2Sub => 0xfdf1, - O::F64x2Mul => 0xfdf2, - O::F64x2Div => 0xfdf3, - O::F64x2Min => 0xfdf4, - O::F64x2Max => 0xfdf5, - O::F64x2PMin => 0xfdf6, - O::F64x2PMax => 0xfdf7, - O::I32x4TruncSatF32x4S => 0xfdf8, - O::I32x4TruncSatF32x4U => 0xfdf9, - O::F32x4ConvertI32x4S => 0xfdfa, - O::F32x4ConvertI32x4U => 0xfdfb, - O::I32x4TruncSatF64x2SZero => 0xfdfc, - O::I32x4TruncSatF64x2UZero => 0xfdfd, - O::F64x2ConvertLowI32x4S => 0xfdfe, - O::F64x2ConvertLowI32x4U => 0xfdff, - O::MemoryAtomicNotify { .. } => 0xfe00, - O::MemoryAtomicWait32 { .. } => 0xfe01, - O::MemoryAtomicWait64 { .. } => 0xfe02, - O::AtomicFence { .. } => 0xfe03, - O::I32AtomicLoad { .. } => 0xfe10, - O::I64AtomicLoad { .. } => 0xfe11, - O::I32AtomicLoad8U { .. } => 0xfe12, - O::I32AtomicLoad16U { .. } => 0xfe13, - O::I64AtomicLoad8U { .. } => 0xfe14, - O::I64AtomicLoad16U { .. } => 0xfe15, - O::I64AtomicLoad32U { .. } => 0xfe16, - O::I32AtomicStore { .. } => 0xfe17, - O::I64AtomicStore { .. } => 0xfe18, - O::I32AtomicStore8 { .. } => 0xfe19, - O::I32AtomicStore16 { .. } => 0xfe1a, - O::I64AtomicStore8 { .. } => 0xfe1b, - O::I64AtomicStore16 { .. } => 0xfe1c, - O::I64AtomicStore32 { .. } => 0xfe1d, - O::I32AtomicRmwAdd { .. } => 0xfe1e, - O::I64AtomicRmwAdd { .. } => 0xfe1f, - O::I32AtomicRmw8AddU { .. } => 0xfe20, - O::I32AtomicRmw16AddU { .. } => 0xfe21, - O::I64AtomicRmw8AddU { .. } => 0xfe22, - O::I64AtomicRmw16AddU { .. } => 0xfe23, - O::I64AtomicRmw32AddU { .. } => 0xfe24, - O::I32AtomicRmwSub { .. } => 0xfe25, - O::I64AtomicRmwSub { .. } => 0xfe26, - O::I32AtomicRmw8SubU { .. } => 0xfe27, - O::I32AtomicRmw16SubU { .. } => 0xfe28, - O::I64AtomicRmw8SubU { .. } => 0xfe29, - O::I64AtomicRmw16SubU { .. } => 0xfe2a, - O::I64AtomicRmw32SubU { .. } => 0xfe2b, - O::I32AtomicRmwAnd { .. } => 0xfe2c, - O::I64AtomicRmwAnd { .. } => 0xfe2d, - O::I32AtomicRmw8AndU { .. } => 0xfe2e, - O::I32AtomicRmw16AndU { .. } => 0xfe2f, - O::I64AtomicRmw8AndU { .. } => 0xfe30, - O::I64AtomicRmw16AndU { .. } => 0xfe31, - O::I64AtomicRmw32AndU { .. } => 0xfe32, - O::I32AtomicRmwOr { .. } => 0xfe33, - O::I64AtomicRmwOr { .. } => 0xfe34, - O::I32AtomicRmw8OrU { .. } => 0xfe35, - O::I32AtomicRmw16OrU { .. } => 0xfe36, - O::I64AtomicRmw8OrU { .. } => 0xfe37, - O::I64AtomicRmw16OrU { .. } => 0xfe38, - O::I64AtomicRmw32OrU { .. } => 0xfe39, - O::I32AtomicRmwXor { .. } => 0xfe3a, - O::I64AtomicRmwXor { .. } => 0xfe3b, - O::I32AtomicRmw8XorU { .. } => 0xfe3c, - O::I32AtomicRmw16XorU { .. } => 0xfe3d, - O::I64AtomicRmw8XorU { .. } => 0xfe3e, - O::I64AtomicRmw16XorU { .. } => 0xfe3f, - O::I64AtomicRmw32XorU { .. } => 0xfe40, - O::I32AtomicRmwXchg { .. } => 0xfe41, - O::I64AtomicRmwXchg { .. } => 0xfe42, - O::I32AtomicRmw8XchgU { .. } => 0xfe43, - O::I32AtomicRmw16XchgU { .. } => 0xfe44, - O::I64AtomicRmw8XchgU { .. } => 0xfe45, - O::I64AtomicRmw16XchgU { .. } => 0xfe46, - O::I64AtomicRmw32XchgU { .. } => 0xfe47, - O::I32AtomicRmwCmpxchg { .. } => 0xfe48, - O::I64AtomicRmwCmpxchg { .. } => 0xfe49, - O::I32AtomicRmw8CmpxchgU { .. } => 0xfe4a, - O::I32AtomicRmw16CmpxchgU { .. } => 0xfe4b, - O::I64AtomicRmw8CmpxchgU { .. } => 0xfe4c, - O::I64AtomicRmw16CmpxchgU { .. } => 0xfe4d, - O::I64AtomicRmw32CmpxchgU { .. } => 0xfe4e, - O::I16x8RelaxedQ15mulrS { .. } => 0xfd111, - O::I16x8RelaxedDotI8x16I7x16S { .. } => 0xfd112, - O::I32x4RelaxedDotI8x16I7x16AddS { .. } => 0xfd113, - #[cfg(feature = "sp1")] - _ => todo!(), - }) - } -} - -pub trait OperatorInfo { - fn ends_basic_block(&self) -> bool; - fn code(&self) -> OperatorCode; -} - -impl OperatorInfo for Operator<'_> { - fn ends_basic_block(&self) -> bool { - use Operator::*; - - macro_rules! dot { - ($first:ident $(,$opcode:ident)*) => { - $first { .. } $(| $opcode { .. })* - }; - } - - matches!( - self, - End | Else | Return | dot!(Loop, Br, BrTable, BrIf, If, Call, CallIndirect) - ) - } - - fn code(&self) -> OperatorCode { - self.into() - } -} From 7029e319a1636d6c5e7929d9dc28db4647c31156 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 10 Mar 2026 18:11:47 +0100 Subject: [PATCH 098/189] Deduplicate --- crates/prover/src/host.rs | 46 +-------- crates/prover/src/memory.rs | 34 +------ crates/prover/src/programs/depth.rs | 3 +- crates/prover/src/programs/mod.rs | 3 +- crates/prover/src/value.rs | 142 ++++++++++++---------------- 5 files changed, 67 insertions(+), 161 deletions(-) diff --git a/crates/prover/src/host.rs b/crates/prover/src/host.rs index a515f41984d..632062577df 100644 --- a/crates/prover/src/host.rs +++ b/crates/prover/src/host.rs @@ -14,53 +14,9 @@ use crate::{ use arbutil::{evm::user::UserOutcomeKind, Color, PreimageType}; use eyre::{bail, ErrReport, Result}; use lazy_static::lazy_static; -use num_derive::FromPrimitive; use std::{collections::HashMap, path::Path, str::FromStr}; -/// Represents the internal hostio functions a module may have. -#[derive(Clone, Copy, Debug, FromPrimitive)] -#[repr(u64)] -pub enum InternalFunc { - WavmCallerLoad8, - WavmCallerLoad32, - WavmCallerStore8, - WavmCallerStore32, - MemoryFill, - MemoryCopy, - UserInkLeft, - UserInkStatus, - UserSetInk, - UserStackLeft, - UserSetStack, - UserMemorySize, - CallMain, -} - -impl InternalFunc { - pub fn ty(&self) -> FunctionType { - use ArbValueType::*; - use InternalFunc::*; - macro_rules! func { - ([$($args:expr),*], [$($outs:expr),*]) => { - FunctionType::new(vec![$($args),*], vec![$($outs),*]) - }; - } - #[rustfmt::skip] - let ty = match self { - WavmCallerLoad8 | WavmCallerLoad32 => func!([I32], [I32]), - WavmCallerStore8 | WavmCallerStore32 => func!([I32, I32], []), - MemoryFill | MemoryCopy => func!([I32, I32, I32], []), - UserInkLeft => func!([], [I64]), // λ() → ink_left - UserInkStatus => func!([], [I32]), // λ() → ink_status - UserSetInk => func!([I64, I32], []), // λ(ink_left, ink_status) - UserStackLeft => func!([], [I32]), // λ() → stack_left - UserSetStack => func!([I32], []), // λ(stack_left) - UserMemorySize => func!([], [I32]), // λ() → memory_size - CallMain => func!([I32], [I32]), // λ(args_len) → status - }; - ty - } -} +pub use crate::value::InternalFunc; /// Represents the internal hostio functions a module may have. pub enum Hostio { diff --git a/crates/prover/src/memory.rs b/crates/prover/src/memory.rs index f1851d8bcff..75f5425cef7 100644 --- a/crates/prover/src/memory.rs +++ b/crates/prover/src/memory.rs @@ -7,17 +7,15 @@ use crate::{ }; use arbutil::Bytes32; use digest::Digest; -use eyre::{bail, ErrReport, Result}; +use eyre::{bail, Result}; use parking_lot::Mutex; use serde::{Deserialize, Serialize}; use sha3::Keccak256; -use std::{borrow::Cow, collections::HashSet, convert::TryFrom}; +use std::{borrow::Cow, collections::HashSet}; #[cfg(feature = "counters")] use std::sync::atomic::{AtomicUsize, Ordering}; -use wasmer_types::Pages; - #[cfg(feature = "rayon")] use rayon::prelude::*; @@ -37,33 +35,7 @@ pub fn print_counters() { ); } -pub struct MemoryType { - pub min: Pages, - pub max: Option, -} - -impl MemoryType { - pub fn new(min: Pages, max: Option) -> Self { - Self { min, max } - } -} - -impl From<&wasmer_types::MemoryType> for MemoryType { - fn from(value: &wasmer_types::MemoryType) -> Self { - Self::new(value.minimum, value.maximum) - } -} - -impl TryFrom<&wasmparser::MemoryType> for MemoryType { - type Error = ErrReport; - - fn try_from(value: &wasmparser::MemoryType) -> std::result::Result { - Ok(Self { - min: Pages(value.initial.try_into()?), - max: value.maximum.map(|x| x.try_into()).transpose()?.map(Pages), - }) - } -} +pub use crate::value::MemoryType; #[derive(Debug, Default, Serialize, Deserialize)] pub struct Memory { diff --git a/crates/prover/src/programs/depth.rs b/crates/prover/src/programs/depth.rs index 084eefde6da..ef6e2581276 100644 --- a/crates/prover/src/programs/depth.rs +++ b/crates/prover/src/programs/depth.rs @@ -6,8 +6,7 @@ use super::{ FuncMiddleware, Middleware, ModuleMod, }; #[cfg(not(feature = "sp1"))] -use crate::{host::InternalFunc, Machine}; -#[cfg(feature = "sp1")] +use crate::Machine; use crate::value::InternalFunc; use crate::value::FunctionType; diff --git a/crates/prover/src/programs/mod.rs b/crates/prover/src/programs/mod.rs index 3ca8fbf2b85..3261e833625 100644 --- a/crates/prover/src/programs/mod.rs +++ b/crates/prover/src/programs/mod.rs @@ -7,8 +7,7 @@ use crate::{ value::{FunctionType as ArbFunctionType, Value}, }; #[cfg(not(feature = "sp1"))] -use crate::{machine::Module, memory::MemoryType}; -#[cfg(feature = "sp1")] +use crate::machine::Module; use crate::value::MemoryType; use arbutil::{evm::ARBOS_VERSION_STYLUS_CHARGING_FIXES, math::SaturatingSum, Bytes32, Color}; use eyre::{bail, eyre, Report, Result, WrapErr}; diff --git a/crates/prover/src/value.rs b/crates/prover/src/value.rs index a8af7766bd8..ce8780ddd2e 100644 --- a/crates/prover/src/value.rs +++ b/crates/prover/src/value.rs @@ -5,6 +5,7 @@ use crate::binary::FloatType; use arbutil::{Bytes32, Color}; use digest::Digest; use eyre::{bail, ErrReport, Result}; +use num_derive::FromPrimitive; use serde::{Deserialize, Serialize}; use serde_with::{serde_as, TryFromInto}; use sha3::Keccak256; @@ -498,98 +499,77 @@ impl Display for ArbValueType { } } -// When compiled via #[path] from sp1-crates, certain types that normally live in -// other crate modules (crate::memory, crate::host) must be available from crate::value, -// since sp1-crates/prover only exposes a subset of modules. - -// In the normal crates/prover context, InternalFunc lives in crate::host. -#[cfg(feature = "sp1")] -pub use self::sp1_internal_func::InternalFunc; - -#[cfg(feature = "sp1")] -mod sp1_internal_func { - use super::{ArbValueType, FunctionType}; - use num_derive::FromPrimitive; - - #[derive(Clone, Copy, Debug, FromPrimitive)] - #[repr(u64)] - pub enum InternalFunc { - WavmCallerLoad8, - WavmCallerLoad32, - WavmCallerStore8, - WavmCallerStore32, - MemoryFill, - MemoryCopy, - UserInkLeft, - UserInkStatus, - UserSetInk, - UserStackLeft, - UserSetStack, - UserMemorySize, - CallMain, - } - - impl InternalFunc { - pub fn ty(&self) -> FunctionType { - use ArbValueType::*; - use InternalFunc::*; - macro_rules! func { - ([$($args:expr),*], [$($outs:expr),*]) => { - FunctionType::new(vec![$($args),*], vec![$($outs),*]) - }; - } - #[rustfmt::skip] - let ty = match self { - WavmCallerLoad8 | WavmCallerLoad32 => func!([I32], [I32]), - WavmCallerStore8 | WavmCallerStore32 => func!([I32, I32], []), - MemoryFill | MemoryCopy => func!([I32, I32, I32], []), - UserInkLeft => func!([], [I64]), // λ() → ink_left - UserInkStatus => func!([], [I32]), // λ() → ink_status - UserSetInk => func!([I64, I32], []), // λ(ink_left, ink_status) - UserStackLeft => func!([], [I32]), // λ() → stack_left - UserSetStack => func!([I32], []), // λ(stack_left) - UserMemorySize => func!([], [I32]), // λ() → memory_size - CallMain => func!([I32], [I32]), // λ(args_len) → status +/// Represents the internal hostio functions a module may have. +#[derive(Clone, Copy, Debug, FromPrimitive)] +#[repr(u64)] +pub enum InternalFunc { + WavmCallerLoad8, + WavmCallerLoad32, + WavmCallerStore8, + WavmCallerStore32, + MemoryFill, + MemoryCopy, + UserInkLeft, + UserInkStatus, + UserSetInk, + UserStackLeft, + UserSetStack, + UserMemorySize, + CallMain, +} + +impl InternalFunc { + pub fn ty(&self) -> FunctionType { + use ArbValueType::*; + use InternalFunc::*; + macro_rules! func { + ([$($args:expr),*], [$($outs:expr),*]) => { + FunctionType::new(vec![$($args),*], vec![$($outs),*]) }; - ty } + #[rustfmt::skip] + let ty = match self { + WavmCallerLoad8 | WavmCallerLoad32 => func!([I32], [I32]), + WavmCallerStore8 | WavmCallerStore32 => func!([I32, I32], []), + MemoryFill | MemoryCopy => func!([I32, I32, I32], []), + UserInkLeft => func!([], [I64]), // λ() → ink_left + UserInkStatus => func!([], [I32]), // λ() → ink_status + UserSetInk => func!([I64, I32], []), // λ(ink_left, ink_status) + UserStackLeft => func!([], [I32]), // λ() → stack_left + UserSetStack => func!([I32], []), // λ(stack_left) + UserMemorySize => func!([], [I32]), // λ() → memory_size + CallMain => func!([I32], [I32]), // λ(args_len) → status + }; + ty } } -// In the normal crates/prover context, MemoryType lives in crate::memory. -#[cfg(feature = "sp1")] -pub use self::sp1_memory_type::MemoryType; - -#[cfg(feature = "sp1")] -mod sp1_memory_type { - use eyre::ErrReport; - use wasmer_types::Pages; +use wasmer_types::Pages; - pub struct MemoryType { - pub min: Pages, - pub max: Option, - } +pub struct MemoryType { + pub min: Pages, + pub max: Option, +} - impl MemoryType { - pub fn new(min: Pages, max: Option) -> Self { - Self { min, max } - } +impl MemoryType { + pub fn new(min: Pages, max: Option) -> Self { + Self { min, max } } +} - impl From<&wasmer_types::MemoryType> for MemoryType { - fn from(value: &wasmer_types::MemoryType) -> Self { - Self::new(value.minimum, value.maximum) - } +impl From<&wasmer_types::MemoryType> for MemoryType { + fn from(value: &wasmer_types::MemoryType) -> Self { + Self::new(value.minimum, value.maximum) } +} - impl TryFrom<&wasmparser::MemoryType> for MemoryType { - type Error = ErrReport; +impl TryFrom<&wasmparser::MemoryType> for MemoryType { + type Error = ErrReport; - fn try_from(value: &wasmparser::MemoryType) -> std::result::Result { - Ok(Self { - min: Pages(value.initial.try_into()?), - max: value.maximum.map(|x| x.try_into()).transpose()?.map(Pages), - }) - } + fn try_from(value: &wasmparser::MemoryType) -> std::result::Result { + Ok(Self { + min: Pages(value.initial.try_into()?), + max: value.maximum.map(|x| x.try_into()).transpose()?.map(Pages), + }) } } From ab66c375017eef73463328c0934919467e983d23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 10 Mar 2026 18:22:00 +0100 Subject: [PATCH 099/189] Dedicated modules --- crates/prover/src/internal_func.rs | 50 +++++++++++++++++++ crates/prover/src/memory_type.rs | 33 ++++++++++++ crates/prover/src/value.rs | 80 +++--------------------------- 3 files changed, 89 insertions(+), 74 deletions(-) create mode 100644 crates/prover/src/internal_func.rs create mode 100644 crates/prover/src/memory_type.rs diff --git a/crates/prover/src/internal_func.rs b/crates/prover/src/internal_func.rs new file mode 100644 index 00000000000..aad19076508 --- /dev/null +++ b/crates/prover/src/internal_func.rs @@ -0,0 +1,50 @@ +// Copyright 2021-2026, Offchain Labs, Inc. +// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md + +use super::{ArbValueType, FunctionType}; +use num_derive::FromPrimitive; + +/// Represents the internal hostio functions a module may have. +#[derive(Clone, Copy, Debug, FromPrimitive)] +#[repr(u64)] +pub enum InternalFunc { + WavmCallerLoad8, + WavmCallerLoad32, + WavmCallerStore8, + WavmCallerStore32, + MemoryFill, + MemoryCopy, + UserInkLeft, + UserInkStatus, + UserSetInk, + UserStackLeft, + UserSetStack, + UserMemorySize, + CallMain, +} + +impl InternalFunc { + pub fn ty(&self) -> FunctionType { + use ArbValueType::*; + use InternalFunc::*; + macro_rules! func { + ([$($args:expr),*], [$($outs:expr),*]) => { + FunctionType::new(vec![$($args),*], vec![$($outs),*]) + }; + } + #[rustfmt::skip] + let ty = match self { + WavmCallerLoad8 | WavmCallerLoad32 => func!([I32], [I32]), + WavmCallerStore8 | WavmCallerStore32 => func!([I32, I32], []), + MemoryFill | MemoryCopy => func!([I32, I32, I32], []), + UserInkLeft => func!([], [I64]), // λ() → ink_left + UserInkStatus => func!([], [I32]), // λ() → ink_status + UserSetInk => func!([I64, I32], []), // λ(ink_left, ink_status) + UserStackLeft => func!([], [I32]), // λ() → stack_left + UserSetStack => func!([I32], []), // λ(stack_left) + UserMemorySize => func!([], [I32]), // λ() → memory_size + CallMain => func!([I32], [I32]), // λ(args_len) → status + }; + ty + } +} diff --git a/crates/prover/src/memory_type.rs b/crates/prover/src/memory_type.rs new file mode 100644 index 00000000000..be33d155832 --- /dev/null +++ b/crates/prover/src/memory_type.rs @@ -0,0 +1,33 @@ +// Copyright 2021-2026, Offchain Labs, Inc. +// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md + +use eyre::ErrReport; +use wasmer_types::Pages; + +pub struct MemoryType { + pub min: Pages, + pub max: Option, +} + +impl MemoryType { + pub fn new(min: Pages, max: Option) -> Self { + Self { min, max } + } +} + +impl From<&wasmer_types::MemoryType> for MemoryType { + fn from(value: &wasmer_types::MemoryType) -> Self { + Self::new(value.minimum, value.maximum) + } +} + +impl TryFrom<&wasmparser::MemoryType> for MemoryType { + type Error = ErrReport; + + fn try_from(value: &wasmparser::MemoryType) -> std::result::Result { + Ok(Self { + min: Pages(value.initial.try_into()?), + max: value.maximum.map(|x| x.try_into()).transpose()?.map(Pages), + }) + } +} diff --git a/crates/prover/src/value.rs b/crates/prover/src/value.rs index ce8780ddd2e..b7a7f1ca859 100644 --- a/crates/prover/src/value.rs +++ b/crates/prover/src/value.rs @@ -5,7 +5,6 @@ use crate::binary::FloatType; use arbutil::{Bytes32, Color}; use digest::Digest; use eyre::{bail, ErrReport, Result}; -use num_derive::FromPrimitive; use serde::{Deserialize, Serialize}; use serde_with::{serde_as, TryFromInto}; use sha3::Keccak256; @@ -499,77 +498,10 @@ impl Display for ArbValueType { } } -/// Represents the internal hostio functions a module may have. -#[derive(Clone, Copy, Debug, FromPrimitive)] -#[repr(u64)] -pub enum InternalFunc { - WavmCallerLoad8, - WavmCallerLoad32, - WavmCallerStore8, - WavmCallerStore32, - MemoryFill, - MemoryCopy, - UserInkLeft, - UserInkStatus, - UserSetInk, - UserStackLeft, - UserSetStack, - UserMemorySize, - CallMain, -} - -impl InternalFunc { - pub fn ty(&self) -> FunctionType { - use ArbValueType::*; - use InternalFunc::*; - macro_rules! func { - ([$($args:expr),*], [$($outs:expr),*]) => { - FunctionType::new(vec![$($args),*], vec![$($outs),*]) - }; - } - #[rustfmt::skip] - let ty = match self { - WavmCallerLoad8 | WavmCallerLoad32 => func!([I32], [I32]), - WavmCallerStore8 | WavmCallerStore32 => func!([I32, I32], []), - MemoryFill | MemoryCopy => func!([I32, I32, I32], []), - UserInkLeft => func!([], [I64]), // λ() → ink_left - UserInkStatus => func!([], [I32]), // λ() → ink_status - UserSetInk => func!([I64, I32], []), // λ(ink_left, ink_status) - UserStackLeft => func!([], [I32]), // λ() → stack_left - UserSetStack => func!([I32], []), // λ(stack_left) - UserMemorySize => func!([], [I32]), // λ() → memory_size - CallMain => func!([I32], [I32]), // λ(args_len) → status - }; - ty - } -} - -use wasmer_types::Pages; - -pub struct MemoryType { - pub min: Pages, - pub max: Option, -} - -impl MemoryType { - pub fn new(min: Pages, max: Option) -> Self { - Self { min, max } - } -} +#[path = "internal_func.rs"] +mod internal_func; +pub use internal_func::InternalFunc; -impl From<&wasmer_types::MemoryType> for MemoryType { - fn from(value: &wasmer_types::MemoryType) -> Self { - Self::new(value.minimum, value.maximum) - } -} - -impl TryFrom<&wasmparser::MemoryType> for MemoryType { - type Error = ErrReport; - - fn try_from(value: &wasmparser::MemoryType) -> std::result::Result { - Ok(Self { - min: Pages(value.initial.try_into()?), - max: value.maximum.map(|x| x.try_into()).transpose()?.map(Pages), - }) - } -} +#[path = "memory_type.rs"] +mod memory_type; +pub use memory_type::MemoryType; From ab43307d50f77d5c04baa6a005df2e622fe08eb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 10 Mar 2026 18:22:11 +0100 Subject: [PATCH 100/189] fmt --- crates/prover/src/programs/depth.rs | 4 ++-- crates/prover/src/programs/meter.rs | 6 +++--- crates/prover/src/programs/mod.rs | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/crates/prover/src/programs/depth.rs b/crates/prover/src/programs/depth.rs index ef6e2581276..8e929a9b719 100644 --- a/crates/prover/src/programs/depth.rs +++ b/crates/prover/src/programs/depth.rs @@ -5,10 +5,10 @@ use super::{ config::{CompileMemoryParams, SigMap}, FuncMiddleware, Middleware, ModuleMod, }; +use crate::value::FunctionType; +use crate::value::InternalFunc; #[cfg(not(feature = "sp1"))] use crate::Machine; -use crate::value::InternalFunc; -use crate::value::FunctionType; use arbutil::Color; use eyre::{bail, Result}; diff --git a/crates/prover/src/programs/meter.rs b/crates/prover/src/programs/meter.rs index c9ae3f612f1..526bf56113e 100644 --- a/crates/prover/src/programs/meter.rs +++ b/crates/prover/src/programs/meter.rs @@ -4,6 +4,8 @@ #[cfg(feature = "sp1")] use crate::operator::OperatorInfo; +#[cfg(not(feature = "sp1"))] +use crate::Machine; use crate::{ programs::{ config::{CompilePricingParams, PricingParams, SigMap}, @@ -12,7 +14,7 @@ use crate::{ value::FunctionType, }; #[cfg(not(feature = "sp1"))] -use crate::Machine; +use arbutil::operator::OperatorInfo; use arbutil::{ evm::{ self, @@ -20,8 +22,6 @@ use arbutil::{ }, pricing, Bytes32, }; -#[cfg(not(feature = "sp1"))] -use arbutil::operator::OperatorInfo; use derivative::Derivative; use eyre::Result; use fnv::FnvHashMap as HashMap; diff --git a/crates/prover/src/programs/mod.rs b/crates/prover/src/programs/mod.rs index 3261e833625..38ab0abcf78 100644 --- a/crates/prover/src/programs/mod.rs +++ b/crates/prover/src/programs/mod.rs @@ -1,14 +1,14 @@ // Copyright 2022-2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md +#[cfg(not(feature = "sp1"))] +use crate::machine::Module; +use crate::value::MemoryType; use crate::{ binary::{ExportKind, WasmBinary}, programs::config::CompileConfig, value::{FunctionType as ArbFunctionType, Value}, }; -#[cfg(not(feature = "sp1"))] -use crate::machine::Module; -use crate::value::MemoryType; use arbutil::{evm::ARBOS_VERSION_STYLUS_CHARGING_FIXES, math::SaturatingSum, Bytes32, Color}; use eyre::{bail, eyre, Report, Result, WrapErr}; use fnv::FnvHashMap as HashMap; From 945b757d7c7d7fb5ad6ecac7b83310fa7de14540 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 13 Mar 2026 15:01:02 +0100 Subject: [PATCH 101/189] Rename ValidationRequest to ValidationTask (to free the name) --- crates/validator/src/engine/execution.rs | 28 +++++++++++------------ crates/validator/src/engine/machine.rs | 2 +- crates/validator/src/spawner_endpoints.rs | 6 ++--- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/crates/validator/src/engine/execution.rs b/crates/validator/src/engine/execution.rs index 1d33e82cc3e..c68d902eb04 100644 --- a/crates/validator/src/engine/execution.rs +++ b/crates/validator/src/engine/execution.rs @@ -4,7 +4,7 @@ //! Validation Execution Logic and Request Models. //! //! This module serves as the central entry point for running validation tasks. -//! It defines the standard `ValidationRequest` structure used by the API and +//! It defines the standard `ValidationTask` structure used by the API and //! implements the two primary validation strategies: //! //! 1. **Native Mode (`validate_native`):** Runs validation in-process using the @@ -28,23 +28,23 @@ use crate::{ machine::JitProcessManager, machine_locator::MachineLocator, replay_binary, ModuleRoot, DEFAULT_JIT_CRANELIFT, }, - spawner_endpoints::ValidationRequest, + spawner_endpoints::ValidationTask, }; pub async fn validate_native( locator: &MachineLocator, module_cache: &HashMap, - request: ValidationRequest, + task: ValidationTask, ) -> Result, String> { - let delayed_inbox = match request.validation_input.has_delayed_msg { + let delayed_inbox = match task.validation_input.has_delayed_msg { true => vec![BatchInfo { - number: request.validation_input.delayed_msg_nr, - data: request.validation_input.delayed_msg, + number: task.validation_input.delayed_msg_nr, + data: task.validation_input.delayed_msg, }], false => vec![], }; - let module_root = request + let module_root = task .module_root .unwrap_or(locator.latest_wasm_module_root().module_root); @@ -60,11 +60,11 @@ pub async fn validate_native( require_success: false, // Relevant for JIT binary only. }, input_mode: jit::InputMode::Native(jit::NativeInput { - old_state: request.validation_input.start_state.into(), - inbox: request.validation_input.batch_info, + old_state: task.validation_input.start_state.into(), + inbox: task.validation_input.batch_info, delayed_inbox, - preimages: request.validation_input.preimages, - programs: request.validation_input.user_wasms[local_target()].clone(), + preimages: task.validation_input.preimages, + programs: task.validation_input.user_wasms[local_target()].clone(), }), }; @@ -85,16 +85,16 @@ pub async fn validate_native( pub async fn validate_continuous( locator: &MachineLocator, jit_manager: &JitProcessManager, - request: ValidationRequest, + task: ValidationTask, ) -> Result, String> { - let module_root = request + let module_root = task .module_root .unwrap_or_else(|| locator.latest_wasm_module_root().module_root); info!("validate continuous serving request with module_root {module_root}"); let new_state = jit_manager - .feed_machine_with_root(&request.validation_input, module_root) + .feed_machine_with_root(&task.validation_input, module_root) .await .map_err(|error| format!("{error:?}"))?; diff --git a/crates/validator/src/engine/machine.rs b/crates/validator/src/engine/machine.rs index 82e374d9dae..c119d1a42da 100644 --- a/crates/validator/src/engine/machine.rs +++ b/crates/validator/src/engine/machine.rs @@ -16,7 +16,7 @@ //! 1. **Handshake (Stdin):** The server opens an ephemeral TCP listener and writes its //! address to the subprocess's Standard Input. //! 2. **Data Transport (TCP):** The subprocess connects back to the provided address. -//! This TCP stream is then used for data transfer of the `ValidationRequest` and +//! This TCP stream is then used for data transfer of the `ValidationTask` and //! the resulting `GlobalState`. use crate::config::get_jit_path; diff --git a/crates/validator/src/spawner_endpoints.rs b/crates/validator/src/spawner_endpoints.rs index 0e7f0f7c88b..cd13a938fe7 100644 --- a/crates/validator/src/spawner_endpoints.rs +++ b/crates/validator/src/spawner_endpoints.rs @@ -58,8 +58,8 @@ impl JsonRpcResponse { } } -/// Validation request that includes both ValidationInput and module_root. -pub struct ValidationRequest { +/// A single validation task: the input data paired with an optional module root. +pub struct ValidationTask { pub validation_input: ValidationInput, pub module_root: Option, } @@ -122,7 +122,7 @@ async fn validate(state: &Arc, params: &[Value]) -> Result Date: Fri, 13 Mar 2026 15:01:52 +0100 Subject: [PATCH 102/189] Move the definition to a more proper place --- crates/validator/src/engine/execution.rs | 9 +++++++-- crates/validator/src/spawner_endpoints.rs | 8 +------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/crates/validator/src/engine/execution.rs b/crates/validator/src/engine/execution.rs index c68d902eb04..5537b874f40 100644 --- a/crates/validator/src/engine/execution.rs +++ b/crates/validator/src/engine/execution.rs @@ -21,16 +21,21 @@ use std::collections::HashMap; use axum::Json; use jit::CompiledModule; use tracing::info; -use validation::{local_target, BatchInfo, GoGlobalState}; +use validation::{local_target, BatchInfo, GoGlobalState, ValidationInput}; use crate::{ engine::{ machine::JitProcessManager, machine_locator::MachineLocator, replay_binary, ModuleRoot, DEFAULT_JIT_CRANELIFT, }, - spawner_endpoints::ValidationTask, }; +/// A single validation task: the input data paired with an optional module root. +pub struct ValidationTask { + pub validation_input: ValidationInput, + pub module_root: Option, +} + pub async fn validate_native( locator: &MachineLocator, module_cache: &HashMap, diff --git a/crates/validator/src/spawner_endpoints.rs b/crates/validator/src/spawner_endpoints.rs index cd13a938fe7..afc8291f7b2 100644 --- a/crates/validator/src/spawner_endpoints.rs +++ b/crates/validator/src/spawner_endpoints.rs @@ -8,7 +8,7 @@ //! field names). use crate::config::ExecutionMode; -use crate::engine::execution::{validate_continuous, validate_native}; +use crate::engine::execution::{validate_continuous, validate_native, ValidationTask}; use crate::engine::ModuleRoot; use crate::ServerState; use axum::extract::State; @@ -58,12 +58,6 @@ impl JsonRpcResponse { } } -/// A single validation task: the input data paired with an optional module root. -pub struct ValidationTask { - pub validation_input: ValidationInput, - pub module_root: Option, -} - /// JSON-RPC 2.0 dispatch request with `method` field. #[derive(Deserialize)] pub struct JsonRpcRequest { From fdad0169af01579e09063a7136bec21814de9928 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 13 Mar 2026 15:04:37 +0100 Subject: [PATCH 103/189] Actually... it is not needed - remove the wrapper and just pass the two args separately --- crates/validator/src/engine/execution.rs | 43 +++++++++-------------- crates/validator/src/engine/machine.rs | 2 +- crates/validator/src/spawner_endpoints.rs | 11 ++---- 3 files changed, 21 insertions(+), 35 deletions(-) diff --git a/crates/validator/src/engine/execution.rs b/crates/validator/src/engine/execution.rs index 5537b874f40..f56df8d390d 100644 --- a/crates/validator/src/engine/execution.rs +++ b/crates/validator/src/engine/execution.rs @@ -1,11 +1,9 @@ // Copyright 2025-2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md -//! Validation Execution Logic and Request Models. +//! Validation Execution Logic. //! -//! This module serves as the central entry point for running validation tasks. -//! It defines the standard `ValidationTask` structure used by the API and -//! implements the two primary validation strategies: +//! This module implements the two primary validation strategies: //! //! 1. **Native Mode (`validate_native`):** Runs validation in-process using the //! embedded `jit` crate. This utilizes the `jit::InputMode::Native` configuration @@ -30,28 +28,21 @@ use crate::{ }, }; -/// A single validation task: the input data paired with an optional module root. -pub struct ValidationTask { - pub validation_input: ValidationInput, - pub module_root: Option, -} - pub async fn validate_native( locator: &MachineLocator, module_cache: &HashMap, - task: ValidationTask, + input: ValidationInput, + module_root: Option, ) -> Result, String> { - let delayed_inbox = match task.validation_input.has_delayed_msg { + let delayed_inbox = match input.has_delayed_msg { true => vec![BatchInfo { - number: task.validation_input.delayed_msg_nr, - data: task.validation_input.delayed_msg, + number: input.delayed_msg_nr, + data: input.delayed_msg, }], false => vec![], }; - let module_root = task - .module_root - .unwrap_or(locator.latest_wasm_module_root().module_root); + let module_root = module_root.unwrap_or(locator.latest_wasm_module_root().module_root); let binary_path = locator.get_machine_path(module_root)?; let binary = replay_binary(&binary_path); @@ -65,11 +56,11 @@ pub async fn validate_native( require_success: false, // Relevant for JIT binary only. }, input_mode: jit::InputMode::Native(jit::NativeInput { - old_state: task.validation_input.start_state.into(), - inbox: task.validation_input.batch_info, + old_state: input.start_state.into(), + inbox: input.batch_info, delayed_inbox, - preimages: task.validation_input.preimages, - programs: task.validation_input.user_wasms[local_target()].clone(), + preimages: input.preimages, + programs: input.user_wasms[local_target()].clone(), }), }; @@ -90,16 +81,16 @@ pub async fn validate_native( pub async fn validate_continuous( locator: &MachineLocator, jit_manager: &JitProcessManager, - task: ValidationTask, + input: ValidationInput, + module_root: Option, ) -> Result, String> { - let module_root = task - .module_root - .unwrap_or_else(|| locator.latest_wasm_module_root().module_root); + let module_root = + module_root.unwrap_or_else(|| locator.latest_wasm_module_root().module_root); info!("validate continuous serving request with module_root {module_root}"); let new_state = jit_manager - .feed_machine_with_root(&task.validation_input, module_root) + .feed_machine_with_root(&input, module_root) .await .map_err(|error| format!("{error:?}"))?; diff --git a/crates/validator/src/engine/machine.rs b/crates/validator/src/engine/machine.rs index c119d1a42da..70da1c730f1 100644 --- a/crates/validator/src/engine/machine.rs +++ b/crates/validator/src/engine/machine.rs @@ -16,7 +16,7 @@ //! 1. **Handshake (Stdin):** The server opens an ephemeral TCP listener and writes its //! address to the subprocess's Standard Input. //! 2. **Data Transport (TCP):** The subprocess connects back to the provided address. -//! This TCP stream is then used for data transfer of the `ValidationTask` and +//! This TCP stream is then used for data transfer of the `ValidationInput` and //! the resulting `GlobalState`. use crate::config::get_jit_path; diff --git a/crates/validator/src/spawner_endpoints.rs b/crates/validator/src/spawner_endpoints.rs index afc8291f7b2..f705ce6b8ed 100644 --- a/crates/validator/src/spawner_endpoints.rs +++ b/crates/validator/src/spawner_endpoints.rs @@ -8,7 +8,7 @@ //! field names). use crate::config::ExecutionMode; -use crate::engine::execution::{validate_continuous, validate_native, ValidationTask}; +use crate::engine::execution::{validate_continuous, validate_native}; use crate::engine::ModuleRoot; use crate::ServerState; use axum::extract::State; @@ -116,17 +116,12 @@ async fn validate(state: &Arc, params: &[Value]) -> Result { - validate_native(&state.locator, module_cache, request).await + validate_native(&state.locator, module_cache, validation_input, module_root).await } ExecutionMode::Continuous { jit_manager } => { - validate_continuous(&state.locator, jit_manager, request).await + validate_continuous(&state.locator, jit_manager, validation_input, module_root).await } }?; From cdccc29db42be2bae6353e17d70e4147a1229842 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 13 Mar 2026 15:09:15 +0100 Subject: [PATCH 104/189] Rename ValidationInput to ValidationRequest --- crates/jit/src/prepare.rs | 4 ++-- crates/jit/src/wavmio.rs | 4 ++-- crates/prover/src/prepare.rs | 4 ++-- crates/validation/src/lib.rs | 4 ++-- crates/validation/src/transfer/receiver.rs | 6 +++--- crates/validation/src/transfer/sender.rs | 4 ++-- crates/validation/src/transfer/tests.rs | 16 ++++++++-------- crates/validator/README.md | 4 ++-- crates/validator/src/engine/execution.rs | 6 +++--- crates/validator/src/engine/machine.rs | 12 ++++++------ crates/validator/src/spawner_endpoints.rs | 4 ++-- sp1-crates/prover/src/binary_input.rs | 4 ++-- sp1-crates/runner/src/main.rs | 4 ++-- 13 files changed, 38 insertions(+), 38 deletions(-) diff --git a/crates/jit/src/prepare.rs b/crates/jit/src/prepare.rs index e116c4c484c..8f72d0e6e61 100644 --- a/crates/jit/src/prepare.rs +++ b/crates/jit/src/prepare.rs @@ -6,13 +6,13 @@ use eyre::Ok; use std::fs::File; use std::io::BufReader; use std::path::Path; -use validation::{local_target, ValidationInput}; +use validation::{local_target, ValidationRequest}; pub fn prepare_env_from_json(json_inputs: &Path, debug: bool) -> eyre::Result { let file = File::open(json_inputs)?; let reader = BufReader::new(file); - let data = ValidationInput::from_reader(reader)?; + let data = ValidationRequest::from_reader(reader)?; let mut env = WasmEnv::default(); env.process.already_has_input = true; diff --git a/crates/jit/src/wavmio.rs b/crates/jit/src/wavmio.rs index f8c9b76326a..c5caeef8d17 100644 --- a/crates/jit/src/wavmio.rs +++ b/crates/jit/src/wavmio.rs @@ -14,7 +14,7 @@ use std::{ time::Instant, }; use validation::local_target; -use validation::transfer::receive_validation_input; +use validation::transfer::receive_validation_request; /// Reads 32-bytes of global state. pub fn get_global_state_bytes32(mut env: WasmEnvMut, idx: u32, out_ptr: GuestPtr) -> MaybeEscape { @@ -228,7 +228,7 @@ fn ready_hostio(env: &mut WasmEnv) -> MaybeEscape { socket.set_nodelay(true)?; let mut reader = BufReader::new(socket.try_clone()?); - let input = receive_validation_input(&mut reader)?; + let input = receive_validation_request(&mut reader)?; env.small_globals = [input.start_state.batch, input.start_state.pos_in_batch]; env.large_globals = [input.start_state.block_hash, input.start_state.send_root]; diff --git a/crates/prover/src/prepare.rs b/crates/prover/src/prepare.rs index 4da21db513b..11f042ea178 100644 --- a/crates/prover/src/prepare.rs +++ b/crates/prover/src/prepare.rs @@ -8,13 +8,13 @@ use std::fs::File; use std::io::BufReader; use std::path::{Path, PathBuf}; use std::sync::Arc; -use validation::ValidationInput; +use validation::ValidationRequest; pub fn prepare_machine(preimages: PathBuf, machines: PathBuf) -> eyre::Result { let file = File::open(preimages)?; let reader = BufReader::new(file); - let data = ValidationInput::from_reader(reader)?; + let data = ValidationRequest::from_reader(reader)?; let preimages = data .preimages .into_iter() diff --git a/crates/validation/src/lib.rs b/crates/validation/src/lib.rs index fe0b312f219..029539ca5a1 100644 --- a/crates/validation/src/lib.rs +++ b/crates/validation/src/lib.rs @@ -78,7 +78,7 @@ impl TryFrom> for UserWasm { /// Counterpart to Go `validator.server_api.InputJSON`. #[derive(Clone, Debug, Default, PartialEq, Eq, Deserialize)] #[serde(rename_all = "PascalCase")] -pub struct ValidationInput { +pub struct ValidationRequest { pub id: u64, pub has_delayed_msg: bool, pub delayed_msg_nr: u64, @@ -98,7 +98,7 @@ pub struct ValidationInput { pub max_user_wasm_size: u64, } -impl ValidationInput { +impl ValidationRequest { pub fn from_reader(mut reader: R) -> io::Result { Ok(serde_json::from_reader(&mut reader)?) } diff --git a/crates/validation/src/transfer/receiver.rs b/crates/validation/src/transfer/receiver.rs index d11ffb51946..a797f3fc55d 100644 --- a/crates/validation/src/transfer/receiver.rs +++ b/crates/validation/src/transfer/receiver.rs @@ -2,7 +2,7 @@ // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md use crate::transfer::primitives::{read_bytes, read_bytes32, read_u32, read_u64, read_u8}; use crate::transfer::{markers, IOResult}; -use crate::{local_target, BatchInfo, GoGlobalState, PreimageMap, UserWasm, ValidationInput}; +use crate::{local_target, BatchInfo, GoGlobalState, PreimageMap, UserWasm, ValidationRequest}; use arbutil::{Bytes32, PreimageType}; use io::Error; use std::collections::HashMap; @@ -10,7 +10,7 @@ use std::io; use std::io::ErrorKind::InvalidData; use std::io::Read; -pub fn receive_validation_input(reader: &mut impl Read) -> IOResult { +pub fn receive_validation_request(reader: &mut impl Read) -> IOResult { let start_state = receive_global_state(reader)?; let inbox = receive_batches(reader)?; let delayed_message = receive_delayed_message(reader)?.unwrap_or_default(); @@ -18,7 +18,7 @@ pub fn receive_validation_input(reader: &mut impl Read) -> IOResult IOResult<()> { +pub fn send_validation_request(writer: &mut impl Write, input: &ValidationRequest) -> IOResult<()> { send_global_state(writer, &input.start_state)?; send_batches(writer, &input.batch_info)?; let batch = input.delayed_msg().map(|b| [b]).unwrap_or_default(); diff --git a/crates/validation/src/transfer/tests.rs b/crates/validation/src/transfer/tests.rs index 5390d6ee3ee..b72f1aa6089 100644 --- a/crates/validation/src/transfer/tests.rs +++ b/crates/validation/src/transfer/tests.rs @@ -1,10 +1,10 @@ // Copyright 2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md use crate::transfer::{ - receive_response, receive_validation_input, send_failure_response, send_successful_response, - send_validation_input, + receive_response, receive_validation_request, send_failure_response, send_successful_response, + send_validation_request, }; -use crate::{local_target, BatchInfo, GoGlobalState, UserWasm, ValidationInput}; +use crate::{local_target, BatchInfo, GoGlobalState, UserWasm, ValidationRequest}; use arbutil::{Bytes32, PreimageType}; use std::collections::HashMap; use std::io::pipe; @@ -47,7 +47,7 @@ fn transfer_failure_response() -> Result<(), Box> { #[test] fn transfer_input() -> Result<(), Box> { - let input = ValidationInput { + let input = ValidationRequest { start_state: Default::default(), batch_info: vec![ @@ -95,8 +95,8 @@ fn transfer_input() -> Result<(), Box> { let (mut reader, mut writer) = pipe()?; - send_validation_input(&mut writer, &input)?; - let received_input = receive_validation_input(&mut reader)?; + send_validation_request(&mut writer, &input)?; + let received_input = receive_validation_request(&mut reader)?; assert_eq!(received_input, input); @@ -105,7 +105,7 @@ fn transfer_input() -> Result<(), Box> { #[test] fn local_stylus_target_must_be_present_if_some_target_is_present() { - let input = ValidationInput { + let input = ValidationRequest { user_wasms: HashMap::from([( "some-other-target".to_string(), HashMap::from([(Bytes32::from([0u8; 32]), UserWasm(vec![1, 2, 3]))]), @@ -115,7 +115,7 @@ fn local_stylus_target_must_be_present_if_some_target_is_present() { let (_, mut writer) = pipe().unwrap(); - let result = send_validation_input(&mut writer, &input); + let result = send_validation_request(&mut writer, &input); assert!(result.is_err()); assert!(result.unwrap_err().to_string().contains("bad stylus arch")); } diff --git a/crates/validator/README.md b/crates/validator/README.md index 3c71fc36c92..8c7ff30b17a 100644 --- a/crates/validator/README.md +++ b/crates/validator/README.md @@ -14,7 +14,7 @@ go test -v -run "TestProgramStorage$" ./system_tests/... -count 1 -- \ --recordBlockInputs.WithBlockIdInFileNameEnabled=false ``` -This produces JSON files (e.g. `system_tests/target/TestProgramStorage/block_inputs.json`) containing `ValidationInput` data. +This produces JSON files (e.g. `system_tests/target/TestProgramStorage/block_inputs.json`) containing `ValidationRequest` data. ## Validation modes @@ -122,7 +122,7 @@ curl http://localhost:4141/validation_stylusArchs Performs block validation. Accepts a JSON-RPC 2.0 request where `params` is an array containing: -1. A `ValidationInput` object (required) +1. A `ValidationRequest` object (required) 2. A module root hex string (optional) Without module root (uses `latest`) diff --git a/crates/validator/src/engine/execution.rs b/crates/validator/src/engine/execution.rs index f56df8d390d..d1b67214511 100644 --- a/crates/validator/src/engine/execution.rs +++ b/crates/validator/src/engine/execution.rs @@ -19,7 +19,7 @@ use std::collections::HashMap; use axum::Json; use jit::CompiledModule; use tracing::info; -use validation::{local_target, BatchInfo, GoGlobalState, ValidationInput}; +use validation::{local_target, BatchInfo, GoGlobalState, ValidationRequest}; use crate::{ engine::{ @@ -31,7 +31,7 @@ use crate::{ pub async fn validate_native( locator: &MachineLocator, module_cache: &HashMap, - input: ValidationInput, + input: ValidationRequest, module_root: Option, ) -> Result, String> { let delayed_inbox = match input.has_delayed_msg { @@ -81,7 +81,7 @@ pub async fn validate_native( pub async fn validate_continuous( locator: &MachineLocator, jit_manager: &JitProcessManager, - input: ValidationInput, + input: ValidationRequest, module_root: Option, ) -> Result, String> { let module_root = diff --git a/crates/validator/src/engine/machine.rs b/crates/validator/src/engine/machine.rs index 70da1c730f1..dc53cf0da89 100644 --- a/crates/validator/src/engine/machine.rs +++ b/crates/validator/src/engine/machine.rs @@ -16,7 +16,7 @@ //! 1. **Handshake (Stdin):** The server opens an ephemeral TCP listener and writes its //! address to the subprocess's Standard Input. //! 2. **Data Transport (TCP):** The subprocess connects back to the provided address. -//! This TCP stream is then used for data transfer of the `ValidationInput` and +//! This TCP stream is then used for data transfer of the `ValidationRequest` and //! the resulting `GlobalState`. use crate::config::get_jit_path; @@ -44,8 +44,8 @@ use tokio::{ sync::Mutex, }; use tracing::{debug, error, info, warn}; -use validation::transfer::{receive_response, send_validation_input}; -use validation::{GoGlobalState, ValidationInput}; +use validation::transfer::{receive_response, send_validation_request}; +use validation::{GoGlobalState, ValidationRequest}; #[derive(Debug)] pub struct JitMachine { @@ -65,7 +65,7 @@ impl JitMachine { pub async fn feed_machine( &self, wasm_memory_usage_limit: u64, - request: &ValidationInput, + request: &ValidationRequest, ) -> Result { // 0. Ensure process is alive self.ensure_alive().await?; @@ -93,7 +93,7 @@ impl JitMachine { .context("failed to open listener connection")?; // 5. Send data - send_validation_input(&mut conn, request)?; + send_validation_request(&mut conn, request)?; // 6. Read Response and return new state match receive_response(&mut conn)? { @@ -159,7 +159,7 @@ impl JitProcessManager { pub async fn feed_machine_with_root( &self, - request: &ValidationInput, + request: &ValidationRequest, module_root: ModuleRoot, ) -> Result { // Reject new operations if we're shutting down diff --git a/crates/validator/src/spawner_endpoints.rs b/crates/validator/src/spawner_endpoints.rs index f705ce6b8ed..fa02a9bceb5 100644 --- a/crates/validator/src/spawner_endpoints.rs +++ b/crates/validator/src/spawner_endpoints.rs @@ -16,7 +16,7 @@ use axum::Json; use serde::{Deserialize, Serialize}; use serde_json::{json, Value}; use std::sync::Arc; -use validation::ValidationInput; +use validation::ValidationRequest; /// JSON-RPC 2.0 response envelope. #[derive(Serialize)] @@ -103,7 +103,7 @@ fn module_roots(state: Arc) -> Vec { } async fn validate(state: &Arc, params: &[Value]) -> Result { - let validation_input: ValidationInput = params + let validation_input: ValidationRequest = params .first() .ok_or_else(|| "Missing params".to_string()) .and_then(|v| { diff --git a/sp1-crates/prover/src/binary_input.rs b/sp1-crates/prover/src/binary_input.rs index c5b6d3d1e67..fa64f51071a 100644 --- a/sp1-crates/prover/src/binary_input.rs +++ b/sp1-crates/prover/src/binary_input.rs @@ -3,7 +3,7 @@ use std::{ collections::{BTreeMap, HashMap}, io::Read, }; -use validation::{UserWasm, ValidationInput}; +use validation::{UserWasm, ValidationRequest}; /// This groups components in Arbitrum's WasmEnv that come from FileData. /// It helps us maintain a clear separation between Arbitrum inputs, and other @@ -40,7 +40,7 @@ pub fn decompress_aligned(user_wasm: &UserWasm) -> ModuleAsm { impl Input { /// This takes hint from `arbitrator/jit/src/prepare.rs` - pub fn from_file_data(data: ValidationInput) -> eyre::Result { + pub fn from_file_data(data: ValidationRequest) -> eyre::Result { let large_globals = [data.start_state.block_hash.0, data.start_state.send_root.0]; let small_globals = [data.start_state.batch, data.start_state.pos_in_batch]; diff --git a/sp1-crates/runner/src/main.rs b/sp1-crates/runner/src/main.rs index c86804ff27e..104246c2bba 100644 --- a/sp1-crates/runner/src/main.rs +++ b/sp1-crates/runner/src/main.rs @@ -8,7 +8,7 @@ use std::collections::HashMap; use std::ops::Deref; use std::sync::Arc; use std::time::SystemTime; -use validation::ValidationInput; +use validation::ValidationRequest; #[derive(Debug, Parser)] #[command(version, about, long_about = None)] @@ -118,7 +118,7 @@ async fn main() { // we can easily inject debugging code to dump stdin when needed. fn build_input(cli: &Cli) -> Vec { let file_data = - serde_json::from_slice::(&std::fs::read(&cli.block_file).expect("read input block")) + serde_json::from_slice::(&std::fs::read(&cli.block_file).expect("read input block")) .expect("parse input block"); let mut module_asms = HashMap::default(); From 31af49d2d068b796110138f8a94d1d6952947353 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 13 Mar 2026 15:19:48 +0100 Subject: [PATCH 105/189] Introduce new ValidationInput type --- crates/jit/src/prepare.rs | 34 +++++------ crates/validation/src/lib.rs | 56 +++++++++++++++++- sp1-crates/prover/src/binary_input.rs | 85 +++++++++------------------ sp1-crates/runner/src/main.rs | 23 +++----- 4 files changed, 108 insertions(+), 90 deletions(-) diff --git a/crates/jit/src/prepare.rs b/crates/jit/src/prepare.rs index 8f72d0e6e61..8bedea5beb7 100644 --- a/crates/jit/src/prepare.rs +++ b/crates/jit/src/prepare.rs @@ -2,47 +2,45 @@ // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md use crate::machine::WasmEnv; +use arbutil::{Bytes32, PreimageType}; use eyre::Ok; use std::fs::File; use std::io::BufReader; use std::path::Path; -use validation::{local_target, ValidationRequest}; +use validation::{local_target, ValidationInput, ValidationRequest}; pub fn prepare_env_from_json(json_inputs: &Path, debug: bool) -> eyre::Result { let file = File::open(json_inputs)?; let reader = BufReader::new(file); - let data = ValidationRequest::from_reader(reader)?; + let req = ValidationRequest::from_reader(reader)?; + let input = ValidationInput::from_request(&req, local_target()); let mut env = WasmEnv::default(); env.process.already_has_input = true; env.process.debug = debug; - env.small_globals = [data.start_state.batch, data.start_state.pos_in_batch]; - env.large_globals = [data.start_state.block_hash, data.start_state.send_root]; + env.small_globals = input.small_globals; + env.large_globals = input.large_globals.map(Bytes32); - for batch_info in data.batch_info.iter() { - env.sequencer_messages - .insert(batch_info.number, batch_info.data.clone()); + for (num, data) in input.sequencer_messages { + env.sequencer_messages.insert(num, data); } - - if data.delayed_msg_nr != 0 && !data.delayed_msg.is_empty() { - env.delayed_messages - .insert(data.delayed_msg_nr, data.delayed_msg.clone()); + for (num, data) in input.delayed_messages { + env.delayed_messages.insert(num, data); } - for (preimage_ty, inner_map) in data.preimages { + for (preimage_ty, inner_map) in input.preimages { + let preimage_ty = PreimageType::try_from(preimage_ty) + .unwrap_or_else(|_| panic!("unknown preimage type: {preimage_ty}")); let map = env.preimages.entry(preimage_ty).or_default(); for (hash, preimage) in inner_map { - map.insert(hash, preimage); + map.insert(Bytes32(hash), preimage); } } - if let Some(user_wasms) = data.user_wasms.get(local_target()) { - for (module_hash, module_asm) in user_wasms.iter() { - env.module_asms - .insert(*module_hash, module_asm.as_vec().into()); - } + for (module_hash, asm) in input.module_asms { + env.module_asms.insert(Bytes32(module_hash), asm.into()); } Ok(env) diff --git a/crates/validation/src/lib.rs b/crates/validation/src/lib.rs index 029539ca5a1..6820a86704f 100644 --- a/crates/validation/src/lib.rs +++ b/crates/validation/src/lib.rs @@ -4,7 +4,7 @@ use arbutil::{Bytes32, PreimageType}; use serde::{Deserialize, Serialize}; use serde_with::{base64::Base64, As, DisplayFromStr}; use std::{ - collections::HashMap, + collections::{BTreeMap, HashMap}, io::{self, BufRead}, }; @@ -12,6 +12,60 @@ pub mod transfer; pub type PreimageMap = HashMap>>; +pub type Inbox = BTreeMap>; +pub type Preimages = BTreeMap>>; + +/// The runtime data needed by any machine (JIT, SP1, Prover) to execute +/// a single block validation. Extracted from a `ValidationRequest` by +/// selecting a target architecture and stripping request metadata. +pub struct ValidationInput { + pub small_globals: [u64; 2], + pub large_globals: [[u8; 32]; 2], + pub preimages: Preimages, + pub sequencer_messages: Inbox, + pub delayed_messages: Inbox, + pub module_asms: HashMap<[u8; 32], Vec>, +} + +impl ValidationInput { + /// Extract runtime data from a request for the given target architecture. + pub fn from_request(req: &ValidationRequest, target: &str) -> Self { + let mut sequencer_messages = Inbox::new(); + for batch in &req.batch_info { + sequencer_messages.insert(batch.number, batch.data.clone()); + } + + let mut delayed_messages = Inbox::new(); + if req.delayed_msg_nr != 0 && !req.delayed_msg.is_empty() { + delayed_messages.insert(req.delayed_msg_nr, req.delayed_msg.clone()); + } + + let mut preimages = Preimages::new(); + for (preimage_ty, inner_map) in &req.preimages { + let map = preimages.entry(*preimage_ty as u8).or_default(); + for (hash, preimage) in inner_map { + map.insert(**hash, preimage.clone()); + } + } + + let mut module_asms = HashMap::new(); + if let Some(user_wasms) = req.user_wasms.get(target) { + for (module_hash, wasm) in user_wasms { + module_asms.insert(**module_hash, wasm.as_vec()); + } + } + + Self { + small_globals: [req.start_state.batch, req.start_state.pos_in_batch], + large_globals: [req.start_state.block_hash.0, req.start_state.send_root.0], + preimages, + sequencer_messages, + delayed_messages, + module_asms, + } + } +} + pub const TARGET_ARM_64: &str = "arm64"; pub const TARGET_AMD_64: &str = "amd64"; pub const TARGET_HOST: &str = "host"; diff --git a/sp1-crates/prover/src/binary_input.rs b/sp1-crates/prover/src/binary_input.rs index fa64f51071a..64502f55400 100644 --- a/sp1-crates/prover/src/binary_input.rs +++ b/sp1-crates/prover/src/binary_input.rs @@ -1,23 +1,15 @@ use bytes::{Bytes, BytesMut}; -use std::{ - collections::{BTreeMap, HashMap}, - io::Read, -}; -use validation::{UserWasm, ValidationRequest}; +use std::{collections::HashMap, io::Read}; +use validation::{UserWasm, ValidationInput, ValidationRequest}; -/// This groups components in Arbitrum's WasmEnv that come from FileData. -/// It helps us maintain a clear separation between Arbitrum inputs, and other -/// WASM required data. -/// For details of each field other than FileData, please refer to: -/// https://github.com/OffchainLabs/nitro/blob/11255c6177d50c1ebc43dbcd4bb5f6e9fae5383a/arbitrator/jit/src/machine.rs#L193-L214 #[derive(rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)] pub struct Input { pub small_globals: [u64; 2], pub large_globals: [[u8; 32]; 2], - pub preimages: Preimages, + pub preimages: validation::Preimages, pub module_asms: HashMap<[u8; 32], ModuleAsm>, - pub sequencer_messages: Inbox, - pub delayed_messages: Inbox, + pub sequencer_messages: validation::Inbox, + pub delayed_messages: validation::Inbox, } // SP1 has additional alignment requirements, we have to decompress the data @@ -38,45 +30,32 @@ pub fn decompress_aligned(user_wasm: &UserWasm) -> ModuleAsm { bytes.slice(offset..offset + data.len()) } -impl Input { - /// This takes hint from `arbitrator/jit/src/prepare.rs` - pub fn from_file_data(data: ValidationRequest) -> eyre::Result { - let large_globals = [data.start_state.block_hash.0, data.start_state.send_root.0]; - let small_globals = [data.start_state.batch, data.start_state.pos_in_batch]; - - let mut sequencer_messages = Inbox::default(); - for batch_info in data.batch_info.iter() { - sequencer_messages.insert(batch_info.number, batch_info.data.clone()); - } - - let mut delayed_messages = Inbox::default(); - if data.delayed_msg_nr != 0 && !data.delayed_msg.is_empty() { - delayed_messages.insert(data.delayed_msg_nr, data.delayed_msg.clone()); - } - - let mut preimages = Preimages::default(); - for (preimage_ty, inner_map) in data.preimages { - let map = preimages.entry(preimage_ty as u8).or_default(); - for (hash, preimage) in inner_map { - map.insert(*hash, preimage); - } - } - - let mut module_asms = HashMap::default(); - if let Some(user_wasms) = data.user_wasms.get(&local_target()) { - for (module_hash, module_asm) in user_wasms.iter() { - module_asms.insert(**module_hash, decompress_aligned(&module_asm)); - } - } +pub fn decompress_aligned_from_vec(data: Vec) -> ModuleAsm { + let mut buffer = BytesMut::zeroed(data.len() + 7); + let p = buffer.as_ptr() as usize; + let aligned_p = (p + 7) / 8 * 8; + let offset = aligned_p - p; + buffer[offset..offset + data.len()].copy_from_slice(&data); + let bytes = buffer.freeze(); + bytes.slice(offset..offset + data.len()) +} - Ok(Self { - small_globals, - large_globals, - preimages, +impl Input { + pub fn from_request(req: &ValidationRequest) -> Self { + let base = ValidationInput::from_request(req, "rv64"); + let module_asms = base + .module_asms + .into_iter() + .map(|(hash, data)| (hash, decompress_aligned_from_vec(data))) + .collect(); + Self { + small_globals: base.small_globals, + large_globals: base.large_globals, + preimages: base.preimages, + sequencer_messages: base.sequencer_messages, + delayed_messages: base.delayed_messages, module_asms, - sequencer_messages, - delayed_messages, - }) + } } // This utilizes binary format from rykv @@ -92,10 +71,4 @@ impl Input { } } -fn local_target() -> String { - "rv64".to_string() -} - -pub type Inbox = BTreeMap>; -pub type Preimages = BTreeMap>>; pub type ModuleAsm = Bytes; diff --git a/sp1-crates/runner/src/main.rs b/sp1-crates/runner/src/main.rs index 104246c2bba..4c3032bb8db 100644 --- a/sp1-crates/runner/src/main.rs +++ b/sp1-crates/runner/src/main.rs @@ -4,7 +4,6 @@ use prover::{ }; use sp1_core_executor::{MinimalExecutor, Program}; use sp1_sdk::{Elf, Prover, ProverClient, SP1Stdin}; -use std::collections::HashMap; use std::ops::Deref; use std::sync::Arc; use std::time::SystemTime; @@ -117,32 +116,26 @@ async fn main() { // Build SP1 input from Arbitrum block. It is serialized to Vec, so // we can easily inject debugging code to dump stdin when needed. fn build_input(cli: &Cli) -> Vec { - let file_data = + let req = serde_json::from_slice::(&std::fs::read(&cli.block_file).expect("read input block")) .expect("parse input block"); - let mut module_asms = HashMap::default(); - if let Some(binaries) = file_data.user_wasms.get("rv64") { - for (module_hash, binary) in binaries.iter() { - module_asms.insert(**module_hash, decompress_aligned(binary)); - } - } - if let Some(wasms) = file_data.user_wasms.get("wasm") { + let mut input = Input::from_request(&req); + + // Compile wasm modules that don't have rv64 binaries via the SP1 stylus compiler. + if let Some(wasms) = req.user_wasms.get("wasm") { for (module_hash, wasm) in wasms.iter() { // rv64 binaries take precedence. This way when nitro introduces // caching for rv64 binaries, no changes will be needed for runner. - if module_asms.contains_key(module_hash.deref()) { + if input.module_asms.contains_key(module_hash.deref()) { continue; } let decompressed = decompress_aligned(wasm); - let binary = run_in_sp1(&cli, &decompressed); - module_asms.insert(**module_hash, binary.into()); + let binary = run_in_sp1(cli, &decompressed); + input.module_asms.insert(**module_hash, binary.into()); } } - let mut input = Input::from_file_data(file_data).expect("create input"); - input.module_asms = module_asms; - let binary_input = rkyv::to_bytes::(&input) .expect("to bytes") .to_vec(); From 81736799677d14c286da33800a499914101bd614 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 13 Mar 2026 16:38:55 +0100 Subject: [PATCH 106/189] Add rkyv feature to validation --- Cargo.lock | 134 +++++++++++++++++++++++++++++++--- Cargo.toml | 1 + crates/validation/Cargo.toml | 5 ++ crates/validation/src/lib.rs | 4 + sp1-crates/Cargo.lock | 2 + sp1-crates/program/Cargo.toml | 5 +- 6 files changed, 138 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 16e2aa2c74e..30d921fb91f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -378,8 +378,20 @@ version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" dependencies = [ - "bytecheck_derive", - "ptr_meta", + "bytecheck_derive 0.6.12", + "ptr_meta 0.1.4", + "simdutf8", +] + +[[package]] +name = "bytecheck" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0caa33a2c0edca0419d15ac723dff03f1956f7978329b1e3b5fdaaaed9d3ca8b" +dependencies = [ + "bytecheck_derive 0.8.2", + "ptr_meta 0.3.1", + "rancor", "simdutf8", ] @@ -394,6 +406,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "bytecheck_derive" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89385e82b5d1821d2219e0b095efa2cc1f246cbf99080f3be46a1a85c0d392d9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "byteorder" version = "1.5.0" @@ -2056,6 +2079,26 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" +[[package]] +name = "munge" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e17401f259eba956ca16491461b6e8f72913a0a114e39736ce404410f915a0c" +dependencies = [ + "munge_macro", +] + +[[package]] +name = "munge_macro" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4568f25ccbd45ab5d5603dc34318c1ec56b117531781260002151b8530a9f931" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "nom" version = "7.1.3" @@ -2434,7 +2477,16 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" dependencies = [ - "ptr_meta_derive", + "ptr_meta_derive 0.1.4", +] + +[[package]] +name = "ptr_meta" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9a0cf95a1196af61d4f1cbdab967179516d9a4a4312af1f31948f8f6224a79" +dependencies = [ + "ptr_meta_derive 0.3.1", ] [[package]] @@ -2448,6 +2500,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "ptr_meta_derive" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7347867d0a7e1208d93b46767be83e2b8f978c3dad35f775ac8d8847551d6fe1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "quinn" version = "0.11.9" @@ -2525,6 +2588,15 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" +[[package]] +name = "rancor" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a063ea72381527c2a0561da9c80000ef822bdd7c3241b1cc1b12100e3df081ee" +dependencies = [ + "ptr_meta 0.3.1", +] + [[package]] name = "rand" version = "0.4.6" @@ -2727,7 +2799,16 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" dependencies = [ - "bytecheck", + "bytecheck 0.6.12", +] + +[[package]] +name = "rend" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cadadef317c2f20755a64d7fdc48f9e7178ee6b0e1f7fce33fa60f1d68a276e6" +dependencies = [ + "bytecheck 0.8.2", ] [[package]] @@ -2799,18 +2880,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5cba464629b3394fc4dbc6f940ff8f5b4ff5c7aef40f29166fd4ad12acbc99c0" dependencies = [ "bitvec", - "bytecheck", + "bytecheck 0.6.12", "bytes", "hashbrown 0.12.3", "indexmap 1.9.3", - "ptr_meta", - "rend", - "rkyv_derive", + "ptr_meta 0.1.4", + "rend 0.4.2", + "rkyv_derive 0.7.44", "seahash", "tinyvec", "uuid", ] +[[package]] +name = "rkyv" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a30e631b7f4a03dee9056b8ef6982e8ba371dd5bedb74d3ec86df4499132c70" +dependencies = [ + "bytecheck 0.8.2", + "bytes", + "hashbrown 0.16.1", + "indexmap 2.13.0", + "munge", + "ptr_meta 0.3.1", + "rancor", + "rend 0.5.3", + "rkyv_derive 0.8.15", + "tinyvec", + "uuid", +] + [[package]] name = "rkyv_derive" version = "0.7.44" @@ -2822,6 +2922,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "rkyv_derive" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8100bb34c0a1d0f907143db3149e6b4eea3c33b9ee8b189720168e818303986f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "ruint2" version = "1.9.0" @@ -3858,6 +3969,7 @@ version = "0.1.0" dependencies = [ "arbutil", "brotli", + "rkyv 0.8.15", "serde", "serde_json", "serde_with", @@ -4053,7 +4165,7 @@ dependencies = [ "memmap2 0.5.10", "more-asserts", "region", - "rkyv", + "rkyv 0.7.44", "self_cell", "shared-buffer", "smallvec", @@ -4134,12 +4246,12 @@ dependencies = [ name = "wasmer-types" version = "4.2.8" dependencies = [ - "bytecheck", + "bytecheck 0.6.12", "enum-iterator 0.7.0", "enumset", "indexmap 1.9.3", "more-asserts", - "rkyv", + "rkyv 0.7.44", "target-lexicon", "thiserror 1.0.63", ] diff --git a/Cargo.toml b/Cargo.toml index f76e977105a..7c19be30dd6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -72,6 +72,7 @@ paste = { version = "1.0.15" } rand = { version = "0.8.4", default-features = false } rand_pcg = { version = "0.3.1", default-features = false } rayon = { version = "1.5.1" } +rkyv = { version = "0.8.8" } reqwest = { version = "0.13.1" } ruint2 = { version = "1.9.0" } rustc-demangle = { version = "0.1.21" } diff --git a/crates/validation/Cargo.toml b/crates/validation/Cargo.toml index 01890c463b1..0ca87eac163 100644 --- a/crates/validation/Cargo.toml +++ b/crates/validation/Cargo.toml @@ -12,6 +12,11 @@ rust-version.workspace = true [dependencies] arbutil = { workspace = true } brotli = { workspace = true } +rkyv = { workspace = true, optional = true } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } serde_with = { workspace = true, features = ["base64"] } + +[features] +default = [] +rkyv = ["dep:rkyv"] diff --git a/crates/validation/src/lib.rs b/crates/validation/src/lib.rs index 6820a86704f..5e26dca30df 100644 --- a/crates/validation/src/lib.rs +++ b/crates/validation/src/lib.rs @@ -18,6 +18,10 @@ pub type Preimages = BTreeMap>>; /// The runtime data needed by any machine (JIT, SP1, Prover) to execute /// a single block validation. Extracted from a `ValidationRequest` by /// selecting a target architecture and stripping request metadata. +#[cfg_attr( + feature = "rkyv", + derive(rkyv::Archive, rkyv::Deserialize, rkyv::Serialize) +)] pub struct ValidationInput { pub small_globals: [u64; 2], pub large_globals: [[u8; 32]; 2], diff --git a/sp1-crates/Cargo.lock b/sp1-crates/Cargo.lock index 1af7e5364f7..c81656256eb 100644 --- a/sp1-crates/Cargo.lock +++ b/sp1-crates/Cargo.lock @@ -3770,6 +3770,7 @@ dependencies = [ "sp1-zkvm", "thiserror 1.0.69", "tiny-keccak 2.0.2 (git+https://github.com/sp1-patches/tiny-keccak?tag=patch-2.0.2-sp1-6.0.0)", + "validation", "wasmer", "wasmer-types", "wasmer-vm", @@ -6736,6 +6737,7 @@ version = "0.1.0" dependencies = [ "arbutil", "brotli", + "rkyv", "serde", "serde_json", "serde_with", diff --git a/sp1-crates/program/Cargo.toml b/sp1-crates/program/Cargo.toml index 67986bba44a..e9b7b9a467f 100644 --- a/sp1-crates/program/Cargo.toml +++ b/sp1-crates/program/Cargo.toml @@ -5,13 +5,14 @@ version = "0.1.0" edition = "2024" [dependencies] +arbutil = { workspace = true } caller-env = { workspace = true, features = ["brotli"] } +prover = { workspace = true, features = ["native"] } sp1-zkvm = { workspace = true } +validation = { workspace = true, features = ["rkyv"] } wasmer = { workspace = true } wasmer-types = { workspace = true } wasmer-vm = { workspace = true } -prover = { workspace = true, features = ["native"] } -arbutil = { workspace = true } bytes = { workspace = true } corosensei = { workspace = true } From 65433dca3898aeae7e49f30686da7886a65dcbeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 13 Mar 2026 16:42:15 +0100 Subject: [PATCH 107/189] Use ValidationInput in sp1 world. Remove Input --- sp1-crates/program/src/platform.rs | 7 +-- sp1-crates/program/src/replay.rs | 12 +++-- sp1-crates/prover/src/binary_input.rs | 68 ++++++--------------------- sp1-crates/runner/src/main.rs | 10 ++-- 4 files changed, 30 insertions(+), 67 deletions(-) diff --git a/sp1-crates/program/src/platform.rs b/sp1-crates/program/src/platform.rs index 98e5aa7117f..e3b770cf855 100644 --- a/sp1-crates/program/src/platform.rs +++ b/sp1-crates/program/src/platform.rs @@ -1,13 +1,14 @@ -use prover::binary_input::Input; +use prover::binary_input::read_validation_input; use sp1_zkvm::{io, syscalls}; +use validation::ValidationInput; pub fn print_string(fd: u32, bytes: &[u8]) { syscalls::syscall_write(fd, bytes.as_ptr(), bytes.len()); } -pub fn read_input() -> Input { +pub fn read_input() -> ValidationInput { let s = io::read::>(); - Input::from_reader(std::io::Cursor::new(s)).expect("parse input file") + read_validation_input(std::io::Cursor::new(s)).expect("parse input file") } pub fn exit(code: u32) -> ! { diff --git a/sp1-crates/program/src/replay.rs b/sp1-crates/program/src/replay.rs index 55aa3ccfe42..76daa60bf6a 100644 --- a/sp1-crates/program/src/replay.rs +++ b/sp1-crates/program/src/replay.rs @@ -10,7 +10,8 @@ use arbutil::{Bytes32, evm::EvmData}; use bytes::Bytes; use corosensei::{Coroutine, CoroutineResult, Yielder, stack::DefaultStack}; use once_cell::unsync::Lazy; -use prover::{binary_input::Input, programs::meter::MeteredMachine}; +use prover::{binary_input, programs::meter::MeteredMachine}; +use validation::ValidationInput; use rand_pcg::Pcg32; use std::marker::PhantomData; use std::ops::{Deref, DerefMut}; @@ -89,7 +90,7 @@ pub struct CustomEnvData { pub time: u64, pub pcg: Pcg32, - input: Lazy, + input: Lazy, yielder: SendYielder<(), MainYieldMessage>, } @@ -109,11 +110,11 @@ impl CustomEnvData { } } - pub fn input(&self) -> &Input { + pub fn input(&self) -> &ValidationInput { self.input.deref() } - pub fn input_mut(&mut self) -> &mut Input { + pub fn input_mut(&mut self) -> &mut ValidationInput { self.input.deref_mut() } @@ -132,7 +133,8 @@ impl CustomEnvData { let Some(module) = self.input.module_asms.get(module_hash.deref()) else { return Escape::logical(format!("Unable to locate module: {module_hash}")); }; - let cothread = Cothread::new(module.clone(), calldata, config, evm_data, gas); + let aligned = binary_input::align_bytes(module); + let cothread = Cothread::new(aligned, calldata, config, evm_data, gas); cothreads_mut().push(cothread); Ok(cothreads().len().try_into().unwrap()) diff --git a/sp1-crates/prover/src/binary_input.rs b/sp1-crates/prover/src/binary_input.rs index 64502f55400..69689207f66 100644 --- a/sp1-crates/prover/src/binary_input.rs +++ b/sp1-crates/prover/src/binary_input.rs @@ -1,74 +1,36 @@ use bytes::{Bytes, BytesMut}; -use std::{collections::HashMap, io::Read}; -use validation::{UserWasm, ValidationInput, ValidationRequest}; - -#[derive(rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)] -pub struct Input { - pub small_globals: [u64; 2], - pub large_globals: [[u8; 32]; 2], - pub preimages: validation::Preimages, - pub module_asms: HashMap<[u8; 32], ModuleAsm>, - pub sequencer_messages: validation::Inbox, - pub delayed_messages: validation::Inbox, -} +use std::io::Read; +use validation::{UserWasm, ValidationInput}; // SP1 has additional alignment requirements, we have to decompress the data // into aligned bytes -pub fn decompress_aligned(user_wasm: &UserWasm) -> ModuleAsm { +pub fn decompress_aligned(user_wasm: &UserWasm) -> Bytes { // This is less ideal but until one of the following happens, we // will have to stick with it: // * Allocator allocates aligned memory // * Bytes add alignment options // * Wasmer's Module does not simply accept `IntoBytes` trait. - let data = user_wasm.as_vec(); - let mut buffer = BytesMut::zeroed(data.len() + 7); - let p = buffer.as_ptr() as usize; - let aligned_p = (p + 7) / 8 * 8; - let offset = aligned_p - p; - buffer[offset..offset + data.len()].copy_from_slice(&data); - let bytes = buffer.freeze(); - bytes.slice(offset..offset + data.len()) + align_bytes(&user_wasm.as_vec()) } -pub fn decompress_aligned_from_vec(data: Vec) -> ModuleAsm { +pub fn align_bytes(data: &[u8]) -> Bytes { let mut buffer = BytesMut::zeroed(data.len() + 7); let p = buffer.as_ptr() as usize; let aligned_p = (p + 7) / 8 * 8; let offset = aligned_p - p; - buffer[offset..offset + data.len()].copy_from_slice(&data); + buffer[offset..offset + data.len()].copy_from_slice(data); let bytes = buffer.freeze(); bytes.slice(offset..offset + data.len()) } -impl Input { - pub fn from_request(req: &ValidationRequest) -> Self { - let base = ValidationInput::from_request(req, "rv64"); - let module_asms = base - .module_asms - .into_iter() - .map(|(hash, data)| (hash, decompress_aligned_from_vec(data))) - .collect(); - Self { - small_globals: base.small_globals, - large_globals: base.large_globals, - preimages: base.preimages, - sequencer_messages: base.sequencer_messages, - delayed_messages: base.delayed_messages, - module_asms, - } - } - - // This utilizes binary format from rykv - pub fn from_reader(mut reader: R) -> Result { - let mut s = Vec::new(); - reader - .read_to_end(&mut s) - .map_err(|e| format!("IO Error: {e:?}"))?; - let archived = rkyv::access::(&s[..]) +pub fn read_validation_input(mut reader: R) -> Result { + let mut s = Vec::new(); + reader + .read_to_end(&mut s) + .map_err(|e| format!("IO Error: {e:?}"))?; + let archived = + rkyv::access::(&s[..]) .map_err(|e| format!("rkyv access error: {e:?}"))?; - rkyv::deserialize::(archived) - .map_err(|e| format!("rkyv deserialize error: {e:?}")) - } + rkyv::deserialize::(archived) + .map_err(|e| format!("rkyv deserialize error: {e:?}")) } - -pub type ModuleAsm = Bytes; diff --git a/sp1-crates/runner/src/main.rs b/sp1-crates/runner/src/main.rs index 4c3032bb8db..c5fa69e11bb 100644 --- a/sp1-crates/runner/src/main.rs +++ b/sp1-crates/runner/src/main.rs @@ -1,13 +1,11 @@ use clap::{ArgAction, Parser, ValueEnum}; -use prover::{ - binary_input::{Input, decompress_aligned}, -}; +use prover::binary_input::decompress_aligned; use sp1_core_executor::{MinimalExecutor, Program}; use sp1_sdk::{Elf, Prover, ProverClient, SP1Stdin}; use std::ops::Deref; use std::sync::Arc; use std::time::SystemTime; -use validation::ValidationRequest; +use validation::{ValidationInput, ValidationRequest}; #[derive(Debug, Parser)] #[command(version, about, long_about = None)] @@ -120,7 +118,7 @@ fn build_input(cli: &Cli) -> Vec { serde_json::from_slice::(&std::fs::read(&cli.block_file).expect("read input block")) .expect("parse input block"); - let mut input = Input::from_request(&req); + let mut input = ValidationInput::from_request(&req, "rv64"); // Compile wasm modules that don't have rv64 binaries via the SP1 stylus compiler. if let Some(wasms) = req.user_wasms.get("wasm") { @@ -132,7 +130,7 @@ fn build_input(cli: &Cli) -> Vec { } let decompressed = decompress_aligned(wasm); let binary = run_in_sp1(cli, &decompressed); - input.module_asms.insert(**module_hash, binary.into()); + input.module_asms.insert(**module_hash, binary); } } From bb79382b799938ffaadf569d346f790065003026 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 13 Mar 2026 16:48:40 +0100 Subject: [PATCH 108/189] Simplify alignment --- sp1-crates/Cargo.lock | 1 - sp1-crates/prover/src/binary_input.rs | 15 +++------------ sp1-crates/runner/Cargo.toml | 3 +-- sp1-crates/runner/src/main.rs | 4 +--- 4 files changed, 5 insertions(+), 18 deletions(-) diff --git a/sp1-crates/Cargo.lock b/sp1-crates/Cargo.lock index c81656256eb..43e32a49051 100644 --- a/sp1-crates/Cargo.lock +++ b/sp1-crates/Cargo.lock @@ -5869,7 +5869,6 @@ version = "0.1.0" dependencies = [ "bincode", "clap", - "prover", "rkyv", "serde_json", "sp1-core-executor", diff --git a/sp1-crates/prover/src/binary_input.rs b/sp1-crates/prover/src/binary_input.rs index 69689207f66..17b5cfed42f 100644 --- a/sp1-crates/prover/src/binary_input.rs +++ b/sp1-crates/prover/src/binary_input.rs @@ -1,18 +1,9 @@ use bytes::{Bytes, BytesMut}; use std::io::Read; -use validation::{UserWasm, ValidationInput}; - -// SP1 has additional alignment requirements, we have to decompress the data -// into aligned bytes -pub fn decompress_aligned(user_wasm: &UserWasm) -> Bytes { - // This is less ideal but until one of the following happens, we - // will have to stick with it: - // * Allocator allocates aligned memory - // * Bytes add alignment options - // * Wasmer's Module does not simply accept `IntoBytes` trait. - align_bytes(&user_wasm.as_vec()) -} +use validation::ValidationInput; +/// Copies `data` into 8-byte-aligned memory and returns it as `Bytes`. +/// SP1's wasmer fork requires aligned memory for `Module::deserialize`. pub fn align_bytes(data: &[u8]) -> Bytes { let mut buffer = BytesMut::zeroed(data.len() + 7); let p = buffer.as_ptr() as usize; diff --git a/sp1-crates/runner/Cargo.toml b/sp1-crates/runner/Cargo.toml index cea8bfb0bcd..32878d0700b 100644 --- a/sp1-crates/runner/Cargo.toml +++ b/sp1-crates/runner/Cargo.toml @@ -7,8 +7,7 @@ edition = "2024" [dependencies] sp1-core-executor = { workspace = true } sp1-sdk = { workspace = true } -prover = { workspace = true } -validation = { workspace = true } +validation = { workspace = true, features = ["rkyv"] } bincode = { workspace = true } clap = { workspace = true } diff --git a/sp1-crates/runner/src/main.rs b/sp1-crates/runner/src/main.rs index c5fa69e11bb..fde0dcbee82 100644 --- a/sp1-crates/runner/src/main.rs +++ b/sp1-crates/runner/src/main.rs @@ -1,5 +1,4 @@ use clap::{ArgAction, Parser, ValueEnum}; -use prover::binary_input::decompress_aligned; use sp1_core_executor::{MinimalExecutor, Program}; use sp1_sdk::{Elf, Prover, ProverClient, SP1Stdin}; use std::ops::Deref; @@ -128,8 +127,7 @@ fn build_input(cli: &Cli) -> Vec { if input.module_asms.contains_key(module_hash.deref()) { continue; } - let decompressed = decompress_aligned(wasm); - let binary = run_in_sp1(cli, &decompressed); + let binary = run_in_sp1(cli, wasm.as_ref()); input.module_asms.insert(**module_hash, binary); } } From c732e06b2dc3b258ebe9931683260eb9d4e35251 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 13 Mar 2026 16:53:03 +0100 Subject: [PATCH 109/189] Move reading to validation --- crates/validation/src/lib.rs | 12 ++++++++++++ sp1-crates/Cargo.lock | 2 -- sp1-crates/program/src/platform.rs | 3 +-- sp1-crates/prover/Cargo.toml | 2 -- sp1-crates/prover/src/binary_input.rs | 14 -------------- 5 files changed, 13 insertions(+), 20 deletions(-) diff --git a/crates/validation/src/lib.rs b/crates/validation/src/lib.rs index 5e26dca30df..697dfd4bf6f 100644 --- a/crates/validation/src/lib.rs +++ b/crates/validation/src/lib.rs @@ -68,6 +68,18 @@ impl ValidationInput { module_asms, } } + + #[cfg(feature = "rkyv")] + pub fn from_reader(mut reader: R) -> Result { + let mut s = Vec::new(); + reader + .read_to_end(&mut s) + .map_err(|e| format!("IO Error: {e:?}"))?; + let archived = rkyv::access::(&s[..]) + .map_err(|e| format!("rkyv access error: {e:?}"))?; + rkyv::deserialize::(archived) + .map_err(|e| format!("rkyv deserialize error: {e:?}")) + } } pub const TARGET_ARM_64: &str = "arm64"; diff --git a/sp1-crates/Cargo.lock b/sp1-crates/Cargo.lock index 43e32a49051..7c4745811fe 100644 --- a/sp1-crates/Cargo.lock +++ b/sp1-crates/Cargo.lock @@ -3844,11 +3844,9 @@ dependencies = [ "num-derive", "num-traits", "parking_lot", - "rkyv", "serde", "serde_with", "sha3", - "validation", "wasmer", "wasmer-types", "wasmparser 0.224.1", diff --git a/sp1-crates/program/src/platform.rs b/sp1-crates/program/src/platform.rs index e3b770cf855..5d787307f01 100644 --- a/sp1-crates/program/src/platform.rs +++ b/sp1-crates/program/src/platform.rs @@ -1,4 +1,3 @@ -use prover::binary_input::read_validation_input; use sp1_zkvm::{io, syscalls}; use validation::ValidationInput; @@ -8,7 +7,7 @@ pub fn print_string(fd: u32, bytes: &[u8]) { pub fn read_input() -> ValidationInput { let s = io::read::>(); - read_validation_input(std::io::Cursor::new(s)).expect("parse input file") + ValidationInput::from_reader(std::io::Cursor::new(s)).expect("parse input file") } pub fn exit(code: u32) -> ! { diff --git a/sp1-crates/prover/Cargo.toml b/sp1-crates/prover/Cargo.toml index a6059457ba5..3718b6a14d8 100644 --- a/sp1-crates/prover/Cargo.toml +++ b/sp1-crates/prover/Cargo.toml @@ -19,8 +19,6 @@ parking_lot = { workspace = true } serde = { workspace = true, features = ["derive", "rc"] } serde_with = { workspace = true, features = ["base64"] } sha3 = { workspace = true } -rkyv = { workspace = true } -validation = { workspace = true } wasmer = { workspace = true, optional = true } wasmer-types = { workspace = true, optional = true } wasmparser = { workspace = true, optional = true } diff --git a/sp1-crates/prover/src/binary_input.rs b/sp1-crates/prover/src/binary_input.rs index 17b5cfed42f..e861e21844b 100644 --- a/sp1-crates/prover/src/binary_input.rs +++ b/sp1-crates/prover/src/binary_input.rs @@ -1,6 +1,4 @@ use bytes::{Bytes, BytesMut}; -use std::io::Read; -use validation::ValidationInput; /// Copies `data` into 8-byte-aligned memory and returns it as `Bytes`. /// SP1's wasmer fork requires aligned memory for `Module::deserialize`. @@ -13,15 +11,3 @@ pub fn align_bytes(data: &[u8]) -> Bytes { let bytes = buffer.freeze(); bytes.slice(offset..offset + data.len()) } - -pub fn read_validation_input(mut reader: R) -> Result { - let mut s = Vec::new(); - reader - .read_to_end(&mut s) - .map_err(|e| format!("IO Error: {e:?}"))?; - let archived = - rkyv::access::(&s[..]) - .map_err(|e| format!("rkyv access error: {e:?}"))?; - rkyv::deserialize::(archived) - .map_err(|e| format!("rkyv deserialize error: {e:?}")) -} From 5c2e64a0f39d01b904bd0fcd3f28ffba293d0bc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 13 Mar 2026 16:55:21 +0100 Subject: [PATCH 110/189] Move alignment utility --- sp1-crates/Cargo.lock | 1 - sp1-crates/program/src/replay.rs | 17 +++++++++++++++-- sp1-crates/prover/Cargo.toml | 1 - sp1-crates/prover/src/binary_input.rs | 13 ------------- sp1-crates/prover/src/lib.rs | 1 - 5 files changed, 15 insertions(+), 18 deletions(-) delete mode 100644 sp1-crates/prover/src/binary_input.rs diff --git a/sp1-crates/Cargo.lock b/sp1-crates/Cargo.lock index 7c4745811fe..259b91b65af 100644 --- a/sp1-crates/Cargo.lock +++ b/sp1-crates/Cargo.lock @@ -3834,7 +3834,6 @@ version = "0.1.0" dependencies = [ "arbutil", "brotli", - "bytes", "derivative", "digest", "eyre", diff --git a/sp1-crates/program/src/replay.rs b/sp1-crates/program/src/replay.rs index 76daa60bf6a..1d352dd8af5 100644 --- a/sp1-crates/program/src/replay.rs +++ b/sp1-crates/program/src/replay.rs @@ -10,7 +10,7 @@ use arbutil::{Bytes32, evm::EvmData}; use bytes::Bytes; use corosensei::{Coroutine, CoroutineResult, Yielder, stack::DefaultStack}; use once_cell::unsync::Lazy; -use prover::{binary_input, programs::meter::MeteredMachine}; +use prover::programs::meter::MeteredMachine; use validation::ValidationInput; use rand_pcg::Pcg32; use std::marker::PhantomData; @@ -133,7 +133,7 @@ impl CustomEnvData { let Some(module) = self.input.module_asms.get(module_hash.deref()) else { return Escape::logical(format!("Unable to locate module: {module_hash}")); }; - let aligned = binary_input::align_bytes(module); + let aligned = align_bytes(module); let cothread = Cothread::new(aligned, calldata, config, evm_data, gas); cothreads_mut().push(cothread); @@ -396,6 +396,19 @@ fn build_imports( ) } +/// Copies `data` into 8-byte-aligned memory and returns it as `Bytes`. +/// SP1's wasmer fork requires aligned memory for `Module::deserialize`. +fn align_bytes(data: &[u8]) -> Bytes { + use bytes::BytesMut; + let mut buffer = BytesMut::zeroed(data.len() + 7); + let p = buffer.as_ptr() as usize; + let aligned_p = (p + 7) / 8 * 8; + let offset = aligned_p - p; + buffer[offset..offset + data.len()].copy_from_slice(data); + let bytes = buffer.freeze(); + bytes.slice(offset..offset + data.len()) +} + pub(crate) fn handle_result(result: Result, RuntimeError>) -> ! { let message = match result { Ok(value) => format!("Machine exited prematurely with: {:?}", value), diff --git a/sp1-crates/prover/Cargo.toml b/sp1-crates/prover/Cargo.toml index 3718b6a14d8..fbf7f7066f9 100644 --- a/sp1-crates/prover/Cargo.toml +++ b/sp1-crates/prover/Cargo.toml @@ -6,7 +6,6 @@ edition = "2024" [dependencies] arbutil = { workspace = true } brotli = { workspace = true } -bytes = { workspace = true } derivative = { workspace = true } digest = { workspace = true } eyre = { workspace = true } diff --git a/sp1-crates/prover/src/binary_input.rs b/sp1-crates/prover/src/binary_input.rs deleted file mode 100644 index e861e21844b..00000000000 --- a/sp1-crates/prover/src/binary_input.rs +++ /dev/null @@ -1,13 +0,0 @@ -use bytes::{Bytes, BytesMut}; - -/// Copies `data` into 8-byte-aligned memory and returns it as `Bytes`. -/// SP1's wasmer fork requires aligned memory for `Module::deserialize`. -pub fn align_bytes(data: &[u8]) -> Bytes { - let mut buffer = BytesMut::zeroed(data.len() + 7); - let p = buffer.as_ptr() as usize; - let aligned_p = (p + 7) / 8 * 8; - let offset = aligned_p - p; - buffer[offset..offset + data.len()].copy_from_slice(data); - let bytes = buffer.freeze(); - bytes.slice(offset..offset + data.len()) -} diff --git a/sp1-crates/prover/src/lib.rs b/sp1-crates/prover/src/lib.rs index 4c01f2e4b06..ec6cc33fef6 100644 --- a/sp1-crates/prover/src/lib.rs +++ b/sp1-crates/prover/src/lib.rs @@ -20,4 +20,3 @@ pub mod value; #[path = "../../../crates/arbutil/src/operator.rs"] pub mod operator; -pub mod binary_input; From e4cbc315d5840887a304ef5a1542bcbe817d4e75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 13 Mar 2026 17:29:43 +0100 Subject: [PATCH 111/189] Protocol is for sending input, not full request --- crates/jit/src/wavmio.rs | 32 +++---- crates/validation/src/transfer/receiver.rs | 97 +++++++++----------- crates/validation/src/transfer/sender.rs | 79 +++++++--------- crates/validation/src/transfer/tests.rs | 102 ++++++++------------- crates/validator/src/engine/execution.rs | 11 +-- crates/validator/src/engine/machine.rs | 15 ++- 6 files changed, 145 insertions(+), 191 deletions(-) diff --git a/crates/jit/src/wavmio.rs b/crates/jit/src/wavmio.rs index c5caeef8d17..5661708c45e 100644 --- a/crates/jit/src/wavmio.rs +++ b/crates/jit/src/wavmio.rs @@ -13,8 +13,7 @@ use std::{ net::TcpStream, time::Instant, }; -use validation::local_target; -use validation::transfer::receive_validation_request; +use validation::transfer::receive_validation_input; /// Reads 32-bytes of global state. pub fn get_global_state_bytes32(mut env: WasmEnvMut, idx: u32, out_ptr: GuestPtr) -> MaybeEscape { @@ -228,27 +227,28 @@ fn ready_hostio(env: &mut WasmEnv) -> MaybeEscape { socket.set_nodelay(true)?; let mut reader = BufReader::new(socket.try_clone()?); - let input = receive_validation_request(&mut reader)?; + let input = receive_validation_input(&mut reader)?; - env.small_globals = [input.start_state.batch, input.start_state.pos_in_batch]; - env.large_globals = [input.start_state.block_hash, input.start_state.send_root]; + env.small_globals = input.small_globals; + env.large_globals = input.large_globals.map(arbutil::Bytes32); - for batch in input.batch_info { - env.sequencer_messages.insert(batch.number, batch.data); + for (num, data) in input.sequencer_messages { + env.sequencer_messages.insert(num, data); } - if input.has_delayed_msg { - env.delayed_messages - .insert(input.delayed_msg_nr, input.delayed_msg); + for (num, data) in input.delayed_messages { + env.delayed_messages.insert(num, data); } - for (preimage_type, preimages) in input.preimages { - let preimage_map = env.preimages.entry(preimage_type).or_default(); - for (hash, preimage) in preimages { - preimage_map.insert(hash, preimage); + for (preimage_ty, inner_map) in input.preimages { + let preimage_ty = arbutil::PreimageType::try_from(preimage_ty) + .unwrap_or_else(|_| panic!("unknown preimage type: {preimage_ty}")); + let map = env.preimages.entry(preimage_ty).or_default(); + for (hash, preimage) in inner_map { + map.insert(arbutil::Bytes32(hash), preimage); } } - for (module_hash, module_asm) in &input.user_wasms[local_target()] { + for (module_hash, module_asm) in input.module_asms { env.module_asms - .insert(*module_hash, module_asm.as_vec().into()); + .insert(arbutil::Bytes32(module_hash), module_asm.into()); } let writer = BufWriter::new(socket); diff --git a/crates/validation/src/transfer/receiver.rs b/crates/validation/src/transfer/receiver.rs index a797f3fc55d..b28809e4766 100644 --- a/crates/validation/src/transfer/receiver.rs +++ b/crates/validation/src/transfer/receiver.rs @@ -1,39 +1,42 @@ // Copyright 2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md -use crate::transfer::primitives::{read_bytes, read_bytes32, read_u32, read_u64, read_u8}; +use crate::transfer::primitives::{read_bytes, read_u32, read_u64, read_u8}; use crate::transfer::{markers, IOResult}; -use crate::{local_target, BatchInfo, GoGlobalState, PreimageMap, UserWasm, ValidationRequest}; -use arbutil::{Bytes32, PreimageType}; +use crate::{GoGlobalState, Inbox, Preimages, ValidationInput}; use io::Error; use std::collections::HashMap; use std::io; use std::io::ErrorKind::InvalidData; use std::io::Read; -pub fn receive_validation_request(reader: &mut impl Read) -> IOResult { - let start_state = receive_global_state(reader)?; - let inbox = receive_batches(reader)?; - let delayed_message = receive_delayed_message(reader)?.unwrap_or_default(); +pub fn receive_validation_input(reader: &mut impl Read) -> IOResult { + let (small_globals, large_globals) = receive_globals(reader)?; + let sequencer_messages = receive_inbox(reader)?; + let delayed_messages = receive_inbox(reader)?; let preimages = receive_preimages(reader)?; - let user_wasms = receive_user_wasms(reader)?; + let module_asms = receive_module_asms(reader)?; ensure_readiness(reader)?; - Ok(ValidationRequest { - has_delayed_msg: !delayed_message.data.is_empty(), - delayed_msg_nr: delayed_message.number, + Ok(ValidationInput { + small_globals, + large_globals, preimages, - batch_info: inbox, - delayed_msg: delayed_message.data, - start_state, - user_wasms: HashMap::from([(local_target().to_string(), user_wasms)]), - ..Default::default() + sequencer_messages, + delayed_messages, + module_asms, }) } pub fn receive_response(reader: &mut impl Read) -> IOResult> { match read_u8(reader)? { markers::SUCCESS => { - let new_state = receive_global_state(reader)?; + let (small, large) = receive_globals(reader)?; + let new_state = GoGlobalState { + batch: small[0], + pos_in_batch: small[1], + block_hash: arbutil::Bytes32(large[0]), + send_root: arbutil::Bytes32(large[1]), + }; let memory_used = read_u64(reader)?; Ok(Ok((new_state, memory_used))) } @@ -46,47 +49,34 @@ pub fn receive_response(reader: &mut impl Read) -> IOResult IOResult { - let inbox_position = read_u64(reader)?; - let position_within_message = read_u64(reader)?; - let last_block_hash = read_bytes32(reader)?; - let last_send_root = read_bytes32(reader)?; - Ok(GoGlobalState { - block_hash: last_block_hash, - send_root: last_send_root, - batch: inbox_position, - pos_in_batch: position_within_message, - }) +fn receive_globals(reader: &mut impl Read) -> IOResult<([u64; 2], [[u8; 32]; 2])> { + let small_globals = [read_u64(reader)?, read_u64(reader)?]; + let mut large_globals = [[0u8; 32]; 2]; + reader.read_exact(&mut large_globals[0])?; + reader.read_exact(&mut large_globals[1])?; + Ok((small_globals, large_globals)) } -fn receive_batches(reader: &mut impl Read) -> IOResult> { - let mut batches = vec![]; +fn receive_inbox(reader: &mut impl Read) -> IOResult { + let mut inbox = Inbox::new(); while read_u8(reader)? == markers::ANOTHER { let number = read_u64(reader)?; let data = read_bytes(reader)?; - batches.push(BatchInfo { number, data }); - } - Ok(batches) -} - -fn receive_delayed_message(reader: &mut impl Read) -> IOResult> { - match &receive_batches(reader)?[..] { - [] => Ok(None), - [batch_info] => Ok(Some(batch_info.clone())), - _ => Err(Error::new(InvalidData, "multiple delayed batches")), + inbox.insert(number, data); } + Ok(inbox) } -fn receive_preimages(reader: &mut impl Read) -> IOResult { +fn receive_preimages(reader: &mut impl Read) -> IOResult { let preimage_types = read_u32(reader)?; - let mut preimages = PreimageMap::with_capacity(preimage_types as usize); + let mut preimages = Preimages::new(); for _ in 0..preimage_types { - let preimage_ty = PreimageType::try_from(read_u8(reader)?) - .map_err(|e| Error::new(InvalidData, e.to_string()))?; + let preimage_ty = read_u8(reader)?; let map = preimages.entry(preimage_ty).or_default(); let preimage_count = read_u32(reader)?; for _ in 0..preimage_count { - let hash = read_bytes32(reader)?; + let mut hash = [0u8; 32]; + reader.read_exact(&mut hash)?; let preimage = read_bytes(reader)?; map.insert(hash, preimage); } @@ -94,15 +84,16 @@ fn receive_preimages(reader: &mut impl Read) -> IOResult { Ok(preimages) } -fn receive_user_wasms(reader: &mut impl Read) -> IOResult> { - let programs_count = read_u32(reader)?; - let mut user_wasms = HashMap::with_capacity(programs_count as usize); - for _ in 0..programs_count { - let module_hash = read_bytes32(reader)?; - let module_asm = read_bytes(reader)?; - user_wasms.insert(module_hash, UserWasm(module_asm)); +fn receive_module_asms(reader: &mut impl Read) -> IOResult>> { + let count = read_u32(reader)?; + let mut module_asms = HashMap::with_capacity(count as usize); + for _ in 0..count { + let mut hash = [0u8; 32]; + reader.read_exact(&mut hash)?; + let asm = read_bytes(reader)?; + module_asms.insert(hash, asm); } - Ok(user_wasms) + Ok(module_asms) } fn ensure_readiness(reader: &mut impl Read) -> IOResult<()> { diff --git a/crates/validation/src/transfer/sender.rs b/crates/validation/src/transfer/sender.rs index cf6f96e1f9b..448da7393ab 100644 --- a/crates/validation/src/transfer/sender.rs +++ b/crates/validation/src/transfer/sender.rs @@ -1,20 +1,17 @@ // Copyright 2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md -use crate::transfer::primitives::{write_bytes, write_bytes32, write_u32, write_u64, write_u8}; +use crate::transfer::primitives::{write_bytes, write_u32, write_u64, write_u8}; use crate::transfer::{markers, IOResult}; -use crate::{local_target, BatchInfo, GoGlobalState, PreimageMap, UserWasm, ValidationRequest}; -use arbutil::Bytes32; +use crate::{GoGlobalState, Inbox, Preimages, ValidationInput}; use std::collections::HashMap; -use std::io::ErrorKind::InvalidData; -use std::io::{Error, Write}; +use std::io::Write; -pub fn send_validation_request(writer: &mut impl Write, input: &ValidationRequest) -> IOResult<()> { - send_global_state(writer, &input.start_state)?; - send_batches(writer, &input.batch_info)?; - let batch = input.delayed_msg().map(|b| [b]).unwrap_or_default(); - send_batches(writer, &batch)?; +pub fn send_validation_input(writer: &mut impl Write, input: &ValidationInput) -> IOResult<()> { + send_globals(writer, &input.small_globals, &input.large_globals)?; + send_inbox(writer, &input.sequencer_messages)?; + send_inbox(writer, &input.delayed_messages)?; send_preimages(writer, &input.preimages)?; - send_user_wasms(writer, &input.user_wasms)?; + send_module_asms(writer, &input.module_asms)?; finish_sending(writer) } @@ -24,7 +21,7 @@ pub fn send_successful_response( memory_used: u64, ) -> IOResult<()> { write_u8(writer, markers::SUCCESS)?; - send_global_state(writer, new_state)?; + send_globals(writer, &[new_state.batch, new_state.pos_in_batch], &[new_state.block_hash.0, new_state.send_root.0])?; write_u64(writer, memory_used) } @@ -33,61 +30,47 @@ pub fn send_failure_response(writer: &mut impl Write, error_message: &str) -> IO write_bytes(writer, error_message.as_bytes()) } -fn send_global_state(writer: &mut impl Write, start_state: &GoGlobalState) -> IOResult<()> { - write_u64(writer, start_state.batch)?; - write_u64(writer, start_state.pos_in_batch)?; - write_bytes32(writer, &start_state.block_hash)?; - write_bytes32(writer, &start_state.send_root) +fn send_globals( + writer: &mut impl Write, + small_globals: &[u64; 2], + large_globals: &[[u8; 32]; 2], +) -> IOResult<()> { + write_u64(writer, small_globals[0])?; + write_u64(writer, small_globals[1])?; + writer.write_all(&large_globals[0])?; + writer.write_all(&large_globals[1]) } -fn send_batches(writer: &mut impl Write, batch_info: &[BatchInfo]) -> IOResult<()> { - for batch in batch_info { +fn send_inbox(writer: &mut impl Write, inbox: &Inbox) -> IOResult<()> { + for (number, data) in inbox { write_u8(writer, markers::ANOTHER)?; - write_u64(writer, batch.number)?; - write_bytes(writer, &batch.data)?; + write_u64(writer, *number)?; + write_bytes(writer, data)?; } write_u8(writer, markers::SUCCESS) } -fn send_preimages(writer: &mut impl Write, preimages: &PreimageMap) -> IOResult<()> { +fn send_preimages(writer: &mut impl Write, preimages: &Preimages) -> IOResult<()> { write_u32(writer, preimages.len() as u32)?; for (preimage_type, preimage_map) in preimages { - write_u8(writer, *preimage_type as u8)?; + write_u8(writer, *preimage_type)?; write_u32(writer, preimage_map.len() as u32)?; for (hash, preimage) in preimage_map { - write_bytes32(writer, hash)?; + writer.write_all(hash)?; write_bytes(writer, preimage)?; } } Ok(()) } -fn send_user_wasms( +fn send_module_asms( writer: &mut impl Write, - user_wasms: &HashMap>, + module_asms: &HashMap<[u8; 32], Vec>, ) -> IOResult<()> { - let local_target = local_target(); - let local_target_user_wasms = user_wasms.get(local_target); - - if local_target_user_wasms.is_none_or(|m| m.is_empty()) { - for (arch, wasms) in user_wasms { - if !wasms.is_empty() { - return Err(Error::new( - InvalidData, - format!("bad stylus arch. got {arch}, expected {local_target}"), - )); - } - } - } - - let Some(local_target_user_wasms) = local_target_user_wasms else { - return Ok(()); - }; - - write_u32(writer, local_target_user_wasms.len() as u32)?; - for (hash, wasm) in local_target_user_wasms { - write_bytes32(writer, hash)?; - write_bytes(writer, wasm.as_ref())?; + write_u32(writer, module_asms.len() as u32)?; + for (hash, asm) in module_asms { + writer.write_all(hash)?; + write_bytes(writer, asm)?; } Ok(()) } diff --git a/crates/validation/src/transfer/tests.rs b/crates/validation/src/transfer/tests.rs index b72f1aa6089..0131c896f5d 100644 --- a/crates/validation/src/transfer/tests.rs +++ b/crates/validation/src/transfer/tests.rs @@ -1,13 +1,13 @@ // Copyright 2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md use crate::transfer::{ - receive_response, receive_validation_request, send_failure_response, send_successful_response, - send_validation_request, + receive_response, receive_validation_input, send_failure_response, send_successful_response, + send_validation_input, }; -use crate::{local_target, BatchInfo, GoGlobalState, UserWasm, ValidationRequest}; -use arbutil::{Bytes32, PreimageType}; -use std::collections::HashMap; +use crate::{GoGlobalState, ValidationInput}; +use std::collections::{BTreeMap, HashMap}; use std::io::pipe; +use arbutil::Bytes32; #[test] fn transfer_successful_response() -> Result<(), Box> { @@ -46,76 +46,50 @@ fn transfer_failure_response() -> Result<(), Box> { } #[test] -fn transfer_input() -> Result<(), Box> { - let input = ValidationRequest { - start_state: Default::default(), - - batch_info: vec![ - BatchInfo { - number: 10, - data: vec![1, 2, 3], - }, - BatchInfo { - number: 11, - data: vec![4, 5, 6], - }, - BatchInfo { - number: 12, - data: vec![7, 8], - }, - ], - - has_delayed_msg: true, - delayed_msg_nr: 1, - delayed_msg: vec![0xAA, 0xBB, 0xCC], - - preimages: HashMap::from([ +fn transfer_validation_input() -> Result<(), Box> { + let input = ValidationInput { + small_globals: [42, 7], + large_globals: [[1u8; 32], [2u8; 32]], + + sequencer_messages: BTreeMap::from([ + (10, vec![1, 2, 3]), + (11, vec![4, 5, 6]), + (12, vec![7, 8]), + ]), + + delayed_messages: BTreeMap::from([(1, vec![0xAA, 0xBB, 0xCC])]), + + preimages: BTreeMap::from([ ( - PreimageType::Keccak256, - HashMap::from([ - (Bytes32::from([0u8; 32]), vec![0xDE, 0xAD, 0xBE, 0xEF]), - (Bytes32::from([1u8; 32]), vec![0xBA, 0xAD, 0xF0, 0x0D]), + 0, // Keccak256 + BTreeMap::from([ + ([0u8; 32], vec![0xDE, 0xAD, 0xBE, 0xEF]), + ([1u8; 32], vec![0xBA, 0xAD, 0xF0, 0x0D]), ]), ), ( - PreimageType::DACertificate, - HashMap::from([(Bytes32::from([2u8; 32]), vec![0xFE, 0xED, 0xFA, 0xCE])]), + 3, // DACertificate + BTreeMap::from([([2u8; 32], vec![0xFE, 0xED, 0xFA, 0xCE])]), ), ]), - user_wasms: HashMap::from([( - local_target().to_string(), - HashMap::from([ - (Bytes32::from([3u8; 32]), UserWasm(vec![20, 21, 22])), - (Bytes32::from([4u8; 32]), UserWasm(vec![30, 31, 32])), - ]), - )]), - - ..Default::default() + + module_asms: HashMap::from([ + ([3u8; 32], vec![20, 21, 22]), + ([4u8; 32], vec![30, 31, 32]), + ]), }; let (mut reader, mut writer) = pipe()?; - send_validation_request(&mut writer, &input)?; - let received_input = receive_validation_request(&mut reader)?; + send_validation_input(&mut writer, &input)?; + let received = receive_validation_input(&mut reader)?; - assert_eq!(received_input, input); + assert_eq!(received.small_globals, input.small_globals); + assert_eq!(received.large_globals, input.large_globals); + assert_eq!(received.sequencer_messages, input.sequencer_messages); + assert_eq!(received.delayed_messages, input.delayed_messages); + assert_eq!(received.preimages, input.preimages); + assert_eq!(received.module_asms, input.module_asms); Ok(()) } - -#[test] -fn local_stylus_target_must_be_present_if_some_target_is_present() { - let input = ValidationRequest { - user_wasms: HashMap::from([( - "some-other-target".to_string(), - HashMap::from([(Bytes32::from([0u8; 32]), UserWasm(vec![1, 2, 3]))]), - )]), - ..Default::default() - }; - - let (_, mut writer) = pipe().unwrap(); - - let result = send_validation_request(&mut writer, &input); - assert!(result.is_err()); - assert!(result.unwrap_err().to_string().contains("bad stylus arch")); -} diff --git a/crates/validator/src/engine/execution.rs b/crates/validator/src/engine/execution.rs index d1b67214511..5054dc96daa 100644 --- a/crates/validator/src/engine/execution.rs +++ b/crates/validator/src/engine/execution.rs @@ -21,11 +21,9 @@ use jit::CompiledModule; use tracing::info; use validation::{local_target, BatchInfo, GoGlobalState, ValidationRequest}; -use crate::{ - engine::{ - machine::JitProcessManager, machine_locator::MachineLocator, replay_binary, ModuleRoot, - DEFAULT_JIT_CRANELIFT, - }, +use crate::engine::{ + machine::JitProcessManager, machine_locator::MachineLocator, replay_binary, ModuleRoot, + DEFAULT_JIT_CRANELIFT, }; pub async fn validate_native( @@ -84,8 +82,7 @@ pub async fn validate_continuous( input: ValidationRequest, module_root: Option, ) -> Result, String> { - let module_root = - module_root.unwrap_or_else(|| locator.latest_wasm_module_root().module_root); + let module_root = module_root.unwrap_or_else(|| locator.latest_wasm_module_root().module_root); info!("validate continuous serving request with module_root {module_root}"); diff --git a/crates/validator/src/engine/machine.rs b/crates/validator/src/engine/machine.rs index dc53cf0da89..b09af6287ea 100644 --- a/crates/validator/src/engine/machine.rs +++ b/crates/validator/src/engine/machine.rs @@ -44,8 +44,8 @@ use tokio::{ sync::Mutex, }; use tracing::{debug, error, info, warn}; -use validation::transfer::{receive_response, send_validation_request}; -use validation::{GoGlobalState, ValidationRequest}; +use validation::transfer::{receive_response, send_validation_input}; +use validation::{local_target, GoGlobalState, ValidationInput, ValidationRequest}; #[derive(Debug)] pub struct JitMachine { @@ -93,7 +93,16 @@ impl JitMachine { .context("failed to open listener connection")?; // 5. Send data - send_validation_request(&mut conn, request)?; + let target = local_target(); + if request.user_wasms.get(target).is_none_or(|m| m.is_empty()) { + for (arch, wasms) in &request.user_wasms { + if !wasms.is_empty() { + return Err(anyhow!("bad stylus arch: got {arch}, expected {target}")); + } + } + } + let input = ValidationInput::from_request(request, target); + send_validation_input(&mut conn, &input)?; // 6. Read Response and return new state match receive_response(&mut conn)? { From d3b22fb43c47e6b5dfa7c6d8584f6ab6ebbb028d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Mon, 16 Mar 2026 10:36:55 +0100 Subject: [PATCH 112/189] Reuse ValidationInput instead of fields in JIT --- crates/jit/src/caller_env.rs | 25 +++++++--------- crates/jit/src/lib.rs | 8 ++--- crates/jit/src/machine.rs | 31 +++++++------------- crates/jit/src/prepare.rs | 27 ++++------------- crates/jit/src/wavmio.rs | 30 +++++-------------- crates/validation/src/lib.rs | 1 + crates/validation/src/transfer/primitives.rs | 10 ------- 7 files changed, 39 insertions(+), 93 deletions(-) diff --git a/crates/jit/src/caller_env.rs b/crates/jit/src/caller_env.rs index d8639fd1cf9..ab71846b2d1 100644 --- a/crates/jit/src/caller_env.rs +++ b/crates/jit/src/caller_env.rs @@ -135,11 +135,11 @@ impl ExecEnv for JitExecEnv<'_> { impl WavmIo for WasmEnv { fn get_u64_global(&self, idx: usize) -> Option { - self.small_globals.get(idx).copied() + self.input.small_globals.get(idx).copied() } fn set_u64_global(&mut self, idx: usize, val: u64) -> bool { - let Some(g) = self.small_globals.get_mut(idx) else { + let Some(g) = self.input.small_globals.get_mut(idx) else { return false; }; *g = val; @@ -147,33 +147,30 @@ impl WavmIo for WasmEnv { } fn get_bytes32_global(&self, idx: usize) -> Option<&[u8; 32]> { - self.large_globals.get(idx).map(|b| &b.0) + self.input.large_globals.get(idx) } fn set_bytes32_global(&mut self, idx: usize, val: [u8; 32]) -> bool { - let Some(g) = self.large_globals.get_mut(idx) else { + let Some(g) = self.input.large_globals.get_mut(idx) else { return false; }; - *g = val.into(); + *g = val; true } fn get_sequencer_message(&self, num: u64) -> Option<&[u8]> { - self.sequencer_messages.get(&num).map(|v| v.as_slice()) + self.input.sequencer_messages.get(&num).map(|v| v.as_slice()) } fn get_delayed_message(&self, num: u64) -> Option<&[u8]> { - self.delayed_messages.get(&num).map(|v| v.as_slice()) + self.input.delayed_messages.get(&num).map(|v| v.as_slice()) } fn get_preimage(&self, preimage_type: u8, hash: &[u8; 32]) -> Option<&[u8]> { - let Ok(pt) = preimage_type.try_into() else { - eprintln!("Go trying to get a preimage with unknown type {preimage_type}"); - return None; - }; - self.preimages - .get(&pt) - .and_then(|m| m.get(&Bytes32(*hash))) + self.input + .preimages + .get(&preimage_type) + .and_then(|m| m.get(hash)) .map(|v| v.as_slice()) } } diff --git a/crates/jit/src/lib.rs b/crates/jit/src/lib.rs index 8a60dcae697..118353b179f 100644 --- a/crates/jit/src/lib.rs +++ b/crates/jit/src/lib.rs @@ -176,10 +176,10 @@ fn run_instance( memory_used, runtime: env.process.timestamp.elapsed(), new_state: GlobalState { - last_block_hash: env.large_globals[0], - last_send_root: env.large_globals[1], - inbox_position: env.small_globals[0], - position_within_message: env.small_globals[1], + last_block_hash: Bytes32(env.input.large_globals[0]), + last_send_root: Bytes32(env.input.large_globals[1]), + inbox_position: env.input.small_globals[0], + position_within_message: env.input.small_globals[1], }, error: None, trace: vec![], diff --git a/crates/jit/src/machine.rs b/crates/jit/src/machine.rs index 5d156c2212c..659ada88663 100644 --- a/crates/jit/src/machine.rs +++ b/crates/jit/src/machine.rs @@ -11,7 +11,6 @@ use caller_env::GoRuntimeState; use eyre::{bail, ErrReport, Report, Result}; use sha3::{Digest, Keccak256}; use std::{ - collections::BTreeMap, collections::HashMap, fs::File, io::{self, BufReader, BufWriter, ErrorKind, Read}, @@ -236,8 +235,6 @@ impl From for Escape { } pub type WasmEnvMut<'a> = FunctionEnvMut<'a, WasmEnv>; -pub type Inbox = BTreeMap>; -pub type Preimages = BTreeMap>>; pub type ModuleAsm = Arc<[u8]>; #[derive(Default)] @@ -246,18 +243,10 @@ pub struct WasmEnv { pub memory: Option, /// Go's general runtime state pub go_state: GoRuntimeState, - /// An ordered list of the 8-byte globals - pub small_globals: [u64; 2], - /// An ordered list of the 32-byte globals - pub large_globals: [Bytes32; 2], - /// An oracle allowing the prover to reverse keccak256 - pub preimages: Preimages, + /// Validation input (globals, inbox, preimages) + pub input: validation::ValidationInput, /// A collection of programs called during the course of execution pub module_asms: HashMap, - /// The sequencer inbox's messages - pub sequencer_messages: Inbox, - /// The delayed inbox's messages - pub delayed_messages: Inbox, /// The purpose and connections of this process pub process: ProcessEnv, // threads @@ -343,16 +332,16 @@ fn prepare_env_from_native(mut env: WasmEnv, input: &NativeInput) -> Result Result eyre::Result Keccak256::digest(preimage).into(), PreimageType::Sha2_256 => Sha256::digest(preimage).into(), PreimageType::EthVersionedHash => hash, @@ -227,30 +228,15 @@ fn ready_hostio(env: &mut WasmEnv) -> MaybeEscape { socket.set_nodelay(true)?; let mut reader = BufReader::new(socket.try_clone()?); - let input = receive_validation_input(&mut reader)?; + let mut input = receive_validation_input(&mut reader)?; - env.small_globals = input.small_globals; - env.large_globals = input.large_globals.map(arbutil::Bytes32); - - for (num, data) in input.sequencer_messages { - env.sequencer_messages.insert(num, data); - } - for (num, data) in input.delayed_messages { - env.delayed_messages.insert(num, data); - } - for (preimage_ty, inner_map) in input.preimages { - let preimage_ty = arbutil::PreimageType::try_from(preimage_ty) - .unwrap_or_else(|_| panic!("unknown preimage type: {preimage_ty}")); - let map = env.preimages.entry(preimage_ty).or_default(); - for (hash, preimage) in inner_map { - map.insert(arbutil::Bytes32(hash), preimage); - } - } - for (module_hash, module_asm) in input.module_asms { + for (module_hash, module_asm) in input.module_asms.drain() { env.module_asms .insert(arbutil::Bytes32(module_hash), module_asm.into()); } + env.input = input; + let writer = BufWriter::new(socket); env.process.socket = Some((writer, reader)); env.process.already_has_input = true; diff --git a/crates/validation/src/lib.rs b/crates/validation/src/lib.rs index 697dfd4bf6f..e7c3bf6582d 100644 --- a/crates/validation/src/lib.rs +++ b/crates/validation/src/lib.rs @@ -18,6 +18,7 @@ pub type Preimages = BTreeMap>>; /// The runtime data needed by any machine (JIT, SP1, Prover) to execute /// a single block validation. Extracted from a `ValidationRequest` by /// selecting a target architecture and stripping request metadata. +#[derive(Default)] #[cfg_attr( feature = "rkyv", derive(rkyv::Archive, rkyv::Deserialize, rkyv::Serialize) diff --git a/crates/validation/src/transfer/primitives.rs b/crates/validation/src/transfer/primitives.rs index 3bb0dbbeb46..93b2a0f4948 100644 --- a/crates/validation/src/transfer/primitives.rs +++ b/crates/validation/src/transfer/primitives.rs @@ -1,7 +1,6 @@ // Copyright 2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md use crate::transfer::IOResult; -use arbutil::Bytes32; use std::io::{Read, Write}; pub fn read_u8(reader: &mut impl Read) -> IOResult { @@ -34,15 +33,6 @@ pub fn write_u64(writer: &mut impl Write, data: u64) -> IOResult<()> { writer.write_all(&buf) } -pub fn read_bytes32(reader: &mut impl Read) -> IOResult { - let mut buf = [0u8; 32]; - reader.read_exact(&mut buf).map(|_| buf.into()) -} - -pub fn write_bytes32(writer: &mut impl Write, data: &Bytes32) -> IOResult<()> { - writer.write_all(data.as_slice()) -} - pub fn read_bytes(reader: &mut impl Read) -> IOResult> { let size = read_u64(reader)?; let mut buf = vec![0; size as usize]; From a976178bbbab600110778b909427edd6dbd2489b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Mon, 16 Mar 2026 11:00:36 +0100 Subject: [PATCH 113/189] Add conversion from NativeInput --- crates/jit/src/lib.rs | 36 ++++++++++++++++++++++++++++++++++++ crates/jit/src/machine.rs | 30 +++++------------------------- 2 files changed, 41 insertions(+), 25 deletions(-) diff --git a/crates/jit/src/lib.rs b/crates/jit/src/lib.rs index 118353b179f..2c76794843d 100644 --- a/crates/jit/src/lib.rs +++ b/crates/jit/src/lib.rs @@ -125,6 +125,42 @@ pub struct NativeInput { pub programs: HashMap, } +impl From<&NativeInput> for validation::ValidationInput { + fn from(input: &NativeInput) -> Self { + let sequencer_messages = input.inbox.iter().map(|m| (m.number, m.data.clone())).collect(); + let delayed_messages = input.delayed_inbox.iter().map(|m| (m.number, m.data.clone())).collect(); + + let mut preimages = validation::Preimages::new(); + for (preimage_type, preimages_map) in &input.preimages { + let type_map = preimages.entry(*preimage_type as u8).or_default(); + for (hash, preimage) in preimages_map { + type_map.insert(hash.0, preimage.clone()); + } + } + + let module_asms = input + .programs + .iter() + .map(|(hash, wasm)| (hash.0, wasm.as_vec())) + .collect(); + + Self { + small_globals: [ + input.old_state.inbox_position, + input.old_state.position_within_message, + ], + large_globals: [ + input.old_state.last_block_hash.0, + input.old_state.last_send_root.0, + ], + preimages, + sequencer_messages, + delayed_messages, + module_asms, + } + } +} + /// Result of running the JIT validation. pub struct RunResult { /// Amount of memory used by the Wasm instance. diff --git a/crates/jit/src/machine.rs b/crates/jit/src/machine.rs index 659ada88663..ac9839f57a9 100644 --- a/crates/jit/src/machine.rs +++ b/crates/jit/src/machine.rs @@ -331,32 +331,12 @@ fn prepare_env_from_files(env: WasmEnv, input: &LocalInput) -> Result { fn prepare_env_from_native(mut env: WasmEnv, input: &NativeInput) -> Result { env.process.already_has_input = true; - for msg in &input.inbox { - env.input.sequencer_messages.insert(msg.number, msg.data.clone()); + let mut vi = validation::ValidationInput::from(input); + for (module_hash, module_asm) in vi.module_asms.drain() { + env.module_asms + .insert(Bytes32(module_hash), module_asm.into()); } - for msg in &input.delayed_inbox { - env.input.delayed_messages.insert(msg.number, msg.data.clone()); - } - - for (preimage_type, preimages_map) in &input.preimages { - let type_map = env.input.preimages.entry(*preimage_type as u8).or_default(); - for (hash, preimage) in preimages_map { - type_map.insert(hash.0, preimage.clone()); - } - } - - for (hash, program) in &input.programs { - env.module_asms.insert(*hash, program.as_ref().into()); - } - - env.input.small_globals = [ - input.old_state.inbox_position, - input.old_state.position_within_message, - ]; - env.input.large_globals = [ - input.old_state.last_block_hash.0, - input.old_state.last_send_root.0, - ]; + env.input = vi; Ok(env) } From f1cb45e1ead929f7887044dd082cb4a2108ceef4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Mon, 16 Mar 2026 11:09:53 +0100 Subject: [PATCH 114/189] fmt --- crates/jit/src/caller_env.rs | 5 ++++- crates/jit/src/lib.rs | 12 ++++++++++-- crates/validation/src/transfer/sender.rs | 6 +++++- crates/validation/src/transfer/tests.rs | 7 ++----- 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/crates/jit/src/caller_env.rs b/crates/jit/src/caller_env.rs index ab71846b2d1..26610e591ae 100644 --- a/crates/jit/src/caller_env.rs +++ b/crates/jit/src/caller_env.rs @@ -159,7 +159,10 @@ impl WavmIo for WasmEnv { } fn get_sequencer_message(&self, num: u64) -> Option<&[u8]> { - self.input.sequencer_messages.get(&num).map(|v| v.as_slice()) + self.input + .sequencer_messages + .get(&num) + .map(|v| v.as_slice()) } fn get_delayed_message(&self, num: u64) -> Option<&[u8]> { diff --git a/crates/jit/src/lib.rs b/crates/jit/src/lib.rs index 2c76794843d..66aa4bad3ac 100644 --- a/crates/jit/src/lib.rs +++ b/crates/jit/src/lib.rs @@ -127,8 +127,16 @@ pub struct NativeInput { impl From<&NativeInput> for validation::ValidationInput { fn from(input: &NativeInput) -> Self { - let sequencer_messages = input.inbox.iter().map(|m| (m.number, m.data.clone())).collect(); - let delayed_messages = input.delayed_inbox.iter().map(|m| (m.number, m.data.clone())).collect(); + let sequencer_messages = input + .inbox + .iter() + .map(|m| (m.number, m.data.clone())) + .collect(); + let delayed_messages = input + .delayed_inbox + .iter() + .map(|m| (m.number, m.data.clone())) + .collect(); let mut preimages = validation::Preimages::new(); for (preimage_type, preimages_map) in &input.preimages { diff --git a/crates/validation/src/transfer/sender.rs b/crates/validation/src/transfer/sender.rs index 448da7393ab..7eaa52637f8 100644 --- a/crates/validation/src/transfer/sender.rs +++ b/crates/validation/src/transfer/sender.rs @@ -21,7 +21,11 @@ pub fn send_successful_response( memory_used: u64, ) -> IOResult<()> { write_u8(writer, markers::SUCCESS)?; - send_globals(writer, &[new_state.batch, new_state.pos_in_batch], &[new_state.block_hash.0, new_state.send_root.0])?; + send_globals( + writer, + &[new_state.batch, new_state.pos_in_batch], + &[new_state.block_hash.0, new_state.send_root.0], + )?; write_u64(writer, memory_used) } diff --git a/crates/validation/src/transfer/tests.rs b/crates/validation/src/transfer/tests.rs index 0131c896f5d..10e9923669d 100644 --- a/crates/validation/src/transfer/tests.rs +++ b/crates/validation/src/transfer/tests.rs @@ -5,9 +5,9 @@ use crate::transfer::{ send_validation_input, }; use crate::{GoGlobalState, ValidationInput}; +use arbutil::Bytes32; use std::collections::{BTreeMap, HashMap}; use std::io::pipe; -use arbutil::Bytes32; #[test] fn transfer_successful_response() -> Result<(), Box> { @@ -73,10 +73,7 @@ fn transfer_validation_input() -> Result<(), Box> { ), ]), - module_asms: HashMap::from([ - ([3u8; 32], vec![20, 21, 22]), - ([4u8; 32], vec![30, 31, 32]), - ]), + module_asms: HashMap::from([([3u8; 32], vec![20, 21, 22]), ([4u8; 32], vec![30, 31, 32])]), }; let (mut reader, mut writer) = pipe()?; From 30b88e8654d57edae2db404c9879311cadff1243 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Mon, 16 Mar 2026 11:49:46 +0100 Subject: [PATCH 115/189] Remove alias --- crates/validation/src/lib.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/crates/validation/src/lib.rs b/crates/validation/src/lib.rs index e7c3bf6582d..48aa830dc7f 100644 --- a/crates/validation/src/lib.rs +++ b/crates/validation/src/lib.rs @@ -10,8 +10,6 @@ use std::{ pub mod transfer; -pub type PreimageMap = HashMap>>; - pub type Inbox = BTreeMap>; pub type Preimages = BTreeMap>>; @@ -157,7 +155,7 @@ pub struct ValidationRequest { rename = "PreimagesB64", with = "As::>>" )] - pub preimages: PreimageMap, + pub preimages: HashMap>>, pub batch_info: Vec, #[serde(rename = "DelayedMsgB64", with = "As::")] pub delayed_msg: Vec, From be2b18aa8bdb88af8a59c705340fbaf1a24cc18b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Mon, 16 Mar 2026 12:04:00 +0100 Subject: [PATCH 116/189] Remove NativeInput --- crates/jit/src/lib.rs | 58 +----------------------- crates/jit/src/machine.rs | 43 +++++++++--------- crates/validation/src/lib.rs | 2 +- crates/validator/src/engine/execution.rs | 20 ++------ 4 files changed, 28 insertions(+), 95 deletions(-) diff --git a/crates/jit/src/lib.rs b/crates/jit/src/lib.rs index 66aa4bad3ac..61033c9a625 100644 --- a/crates/jit/src/lib.rs +++ b/crates/jit/src/lib.rs @@ -2,14 +2,12 @@ // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md use crate::machine::Escape; -use arbutil::{Bytes32, PreimageType}; +use arbutil::Bytes32; use clap::{Args, Parser, Subcommand}; -use std::collections::HashMap; use std::io::BufWriter; use std::net::TcpStream; use std::path::PathBuf; use std::time::Duration; -use validation::{BatchInfo, UserWasm}; use wasmer::{FrameInfo, FunctionEnv, Instance, Pages, Store}; mod arbcompress; @@ -63,7 +61,7 @@ pub enum InputMode { Local(LocalInput), /// Use direct Rust objects #[command(skip)] - Native(NativeInput), + Native(validation::ValidationInput), /// Continuously read new inputs from TCP connections Continuous, } @@ -116,58 +114,6 @@ impl From for validation::GoGlobalState { } } -#[derive(Clone, Debug)] -pub struct NativeInput { - pub old_state: GlobalState, - pub inbox: Vec, - pub delayed_inbox: Vec, - pub preimages: HashMap>>, - pub programs: HashMap, -} - -impl From<&NativeInput> for validation::ValidationInput { - fn from(input: &NativeInput) -> Self { - let sequencer_messages = input - .inbox - .iter() - .map(|m| (m.number, m.data.clone())) - .collect(); - let delayed_messages = input - .delayed_inbox - .iter() - .map(|m| (m.number, m.data.clone())) - .collect(); - - let mut preimages = validation::Preimages::new(); - for (preimage_type, preimages_map) in &input.preimages { - let type_map = preimages.entry(*preimage_type as u8).or_default(); - for (hash, preimage) in preimages_map { - type_map.insert(hash.0, preimage.clone()); - } - } - - let module_asms = input - .programs - .iter() - .map(|(hash, wasm)| (hash.0, wasm.as_vec())) - .collect(); - - Self { - small_globals: [ - input.old_state.inbox_position, - input.old_state.position_within_message, - ], - large_globals: [ - input.old_state.last_block_hash.0, - input.old_state.last_send_root.0, - ], - preimages, - sequencer_messages, - delayed_messages, - module_asms, - } - } -} /// Result of running the JIT validation. pub struct RunResult { diff --git a/crates/jit/src/machine.rs b/crates/jit/src/machine.rs index ac9839f57a9..27e968e990b 100644 --- a/crates/jit/src/machine.rs +++ b/crates/jit/src/machine.rs @@ -3,7 +3,7 @@ use crate::{ arbcompress, arbcrypto, prepare::prepare_env_from_json, program, - stylus_backend::CothreadHandler, wasip1_stub, wavmio, InputMode, LocalInput, NativeInput, Opts, + stylus_backend::CothreadHandler, wasip1_stub, wavmio, InputMode, LocalInput, Opts, ValidatorOpts, }; use arbutil::{Bytes32, PreimageType}; @@ -19,7 +19,6 @@ use std::{ time::Instant, }; use thiserror::Error; -use validation::BatchInfo; use wasmer::{ imports, CompilerConfig, Engine, Function, FunctionEnv, FunctionEnvMut, Instance, Memory, Module, RuntimeError, Store, @@ -263,19 +262,20 @@ impl TryFrom<&Opts> for WasmEnv { match &opts.input_mode { InputMode::Json { inputs } => prepare_env_from_json(inputs, opts.validator.debug), InputMode::Local(local) => prepare_env_from_files(env, local), - InputMode::Native(native) => prepare_env_from_native(env, native), + InputMode::Native(vi) => prepare_env_from_validation_input(env, vi), InputMode::Continuous => Ok(env), } } } fn prepare_env_from_files(env: WasmEnv, input: &LocalInput) -> Result { - let mut native = NativeInput { - old_state: input.old_state.clone(), - inbox: vec![], - delayed_inbox: vec![], - preimages: HashMap::new(), - programs: HashMap::new(), + let mut vi = validation::ValidationInput { + small_globals: [ + input.old_state.inbox_position, + input.old_state.position_within_message, + ], + large_globals: [input.old_state.last_block_hash.0, input.old_state.last_send_root.0], + ..Default::default() }; let mut inbox_position = input.old_state.inbox_position; @@ -284,19 +284,13 @@ fn prepare_env_from_files(env: WasmEnv, input: &LocalInput) -> Result { for path in &input.inbox { let mut msg = vec![]; File::open(path)?.read_to_end(&mut msg)?; - native.inbox.push(BatchInfo { - number: inbox_position, - data: msg, - }); + vi.sequencer_messages.insert(inbox_position, msg); inbox_position += 1; } for path in &input.delayed_inbox { let mut msg = vec![]; File::open(path)?.read_to_end(&mut msg)?; - native.delayed_inbox.push(BatchInfo { - number: delayed_position, - data: msg, - }); + vi.delayed_messages.insert(delayed_position, msg); delayed_position += 1; } @@ -316,7 +310,10 @@ fn prepare_env_from_files(env: WasmEnv, input: &LocalInput) -> Result { file.read_exact(&mut buf)?; preimages.push(buf); } - let keccak_preimages = native.preimages.entry(PreimageType::Keccak256).or_default(); + let keccak_preimages = vi + .preimages + .entry(PreimageType::Keccak256 as u8) + .or_default(); for preimage in preimages { let mut hasher = Keccak256::new(); hasher.update(&preimage); @@ -325,13 +322,15 @@ fn prepare_env_from_files(env: WasmEnv, input: &LocalInput) -> Result { } } - prepare_env_from_native(env, &native) + prepare_env_from_validation_input(env, &vi) } -fn prepare_env_from_native(mut env: WasmEnv, input: &NativeInput) -> Result { +fn prepare_env_from_validation_input( + mut env: WasmEnv, + input: &validation::ValidationInput, +) -> Result { env.process.already_has_input = true; - - let mut vi = validation::ValidationInput::from(input); + let mut vi = input.clone(); for (module_hash, module_asm) in vi.module_asms.drain() { env.module_asms .insert(Bytes32(module_hash), module_asm.into()); diff --git a/crates/validation/src/lib.rs b/crates/validation/src/lib.rs index 48aa830dc7f..62e4581dacf 100644 --- a/crates/validation/src/lib.rs +++ b/crates/validation/src/lib.rs @@ -16,7 +16,7 @@ pub type Preimages = BTreeMap>>; /// The runtime data needed by any machine (JIT, SP1, Prover) to execute /// a single block validation. Extracted from a `ValidationRequest` by /// selecting a target architecture and stripping request metadata. -#[derive(Default)] +#[derive(Clone, Debug, Default)] #[cfg_attr( feature = "rkyv", derive(rkyv::Archive, rkyv::Deserialize, rkyv::Serialize) diff --git a/crates/validator/src/engine/execution.rs b/crates/validator/src/engine/execution.rs index 5054dc96daa..b75a1aeb234 100644 --- a/crates/validator/src/engine/execution.rs +++ b/crates/validator/src/engine/execution.rs @@ -19,7 +19,7 @@ use std::collections::HashMap; use axum::Json; use jit::CompiledModule; use tracing::info; -use validation::{local_target, BatchInfo, GoGlobalState, ValidationRequest}; +use validation::{local_target, GoGlobalState, ValidationInput, ValidationRequest}; use crate::engine::{ machine::JitProcessManager, machine_locator::MachineLocator, replay_binary, ModuleRoot, @@ -32,14 +32,6 @@ pub async fn validate_native( input: ValidationRequest, module_root: Option, ) -> Result, String> { - let delayed_inbox = match input.has_delayed_msg { - true => vec![BatchInfo { - number: input.delayed_msg_nr, - data: input.delayed_msg, - }], - false => vec![], - }; - let module_root = module_root.unwrap_or(locator.latest_wasm_module_root().module_root); let binary_path = locator.get_machine_path(module_root)?; @@ -53,13 +45,9 @@ pub async fn validate_native( debug: false, // JIT's debug messages are using printlns, which would clutter the server logs require_success: false, // Relevant for JIT binary only. }, - input_mode: jit::InputMode::Native(jit::NativeInput { - old_state: input.start_state.into(), - inbox: input.batch_info, - delayed_inbox, - preimages: input.preimages, - programs: input.user_wasms[local_target()].clone(), - }), + input_mode: jit::InputMode::Native( + ValidationInput::from_request(&input, local_target()), + ), }; let result = match module_cache.get(&module_root) { From a02631279eacb1252796cfa365b116000b25afbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Mon, 16 Mar 2026 12:05:19 +0100 Subject: [PATCH 117/189] fmt --- crates/jit/src/lib.rs | 1 - crates/jit/src/machine.rs | 5 ++++- crates/validator/src/engine/execution.rs | 4 +--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/jit/src/lib.rs b/crates/jit/src/lib.rs index 61033c9a625..412a2d32827 100644 --- a/crates/jit/src/lib.rs +++ b/crates/jit/src/lib.rs @@ -114,7 +114,6 @@ impl From for validation::GoGlobalState { } } - /// Result of running the JIT validation. pub struct RunResult { /// Amount of memory used by the Wasm instance. diff --git a/crates/jit/src/machine.rs b/crates/jit/src/machine.rs index 27e968e990b..c10fa443e02 100644 --- a/crates/jit/src/machine.rs +++ b/crates/jit/src/machine.rs @@ -274,7 +274,10 @@ fn prepare_env_from_files(env: WasmEnv, input: &LocalInput) -> Result { input.old_state.inbox_position, input.old_state.position_within_message, ], - large_globals: [input.old_state.last_block_hash.0, input.old_state.last_send_root.0], + large_globals: [ + input.old_state.last_block_hash.0, + input.old_state.last_send_root.0, + ], ..Default::default() }; diff --git a/crates/validator/src/engine/execution.rs b/crates/validator/src/engine/execution.rs index b75a1aeb234..eba106ddde1 100644 --- a/crates/validator/src/engine/execution.rs +++ b/crates/validator/src/engine/execution.rs @@ -45,9 +45,7 @@ pub async fn validate_native( debug: false, // JIT's debug messages are using printlns, which would clutter the server logs require_success: false, // Relevant for JIT binary only. }, - input_mode: jit::InputMode::Native( - ValidationInput::from_request(&input, local_target()), - ), + input_mode: jit::InputMode::Native(ValidationInput::from_request(&input, local_target())), }; let result = match module_cache.get(&module_root) { From 889a3a76881101527fa67b076452534043782c05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Mon, 16 Mar 2026 12:13:48 +0100 Subject: [PATCH 118/189] inline json preparing --- crates/jit/src/lib.rs | 1 - crates/jit/src/machine.rs | 15 ++++++++++----- crates/jit/src/prepare.rs | 30 ------------------------------ 3 files changed, 10 insertions(+), 36 deletions(-) delete mode 100644 crates/jit/src/prepare.rs diff --git a/crates/jit/src/lib.rs b/crates/jit/src/lib.rs index 412a2d32827..f98fc6ec412 100644 --- a/crates/jit/src/lib.rs +++ b/crates/jit/src/lib.rs @@ -14,7 +14,6 @@ mod arbcompress; mod arbcrypto; mod caller_env; pub mod machine; -mod prepare; pub mod program; pub mod stylus_backend; mod test; diff --git a/crates/jit/src/machine.rs b/crates/jit/src/machine.rs index c10fa443e02..d8bdab7b5c6 100644 --- a/crates/jit/src/machine.rs +++ b/crates/jit/src/machine.rs @@ -2,10 +2,10 @@ // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md use crate::{ - arbcompress, arbcrypto, prepare::prepare_env_from_json, program, - stylus_backend::CothreadHandler, wasip1_stub, wavmio, InputMode, LocalInput, Opts, - ValidatorOpts, + arbcompress, arbcrypto, program, stylus_backend::CothreadHandler, wasip1_stub, wavmio, + InputMode, LocalInput, Opts, ValidatorOpts, }; +use validation::local_target; use arbutil::{Bytes32, PreimageType}; use caller_env::GoRuntimeState; use eyre::{bail, ErrReport, Report, Result}; @@ -260,7 +260,12 @@ impl TryFrom<&Opts> for WasmEnv { env.process.debug = opts.validator.debug; match &opts.input_mode { - InputMode::Json { inputs } => prepare_env_from_json(inputs, opts.validator.debug), + InputMode::Json { inputs } => { + let file = File::open(inputs)?; + let req = validation::ValidationRequest::from_reader(BufReader::new(file))?; + let input = validation::ValidationInput::from_request(&req, local_target()); + prepare_env_from_validation_input(env, &input) + } InputMode::Local(local) => prepare_env_from_files(env, local), InputMode::Native(vi) => prepare_env_from_validation_input(env, vi), InputMode::Continuous => Ok(env), @@ -328,7 +333,7 @@ fn prepare_env_from_files(env: WasmEnv, input: &LocalInput) -> Result { prepare_env_from_validation_input(env, &vi) } -fn prepare_env_from_validation_input( +pub(crate) fn prepare_env_from_validation_input( mut env: WasmEnv, input: &validation::ValidationInput, ) -> Result { diff --git a/crates/jit/src/prepare.rs b/crates/jit/src/prepare.rs deleted file mode 100644 index 26ec1e2a5c6..00000000000 --- a/crates/jit/src/prepare.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2022-2026, Offchain Labs, Inc. -// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md - -use crate::machine::WasmEnv; -use arbutil::Bytes32; -use eyre::Ok; -use std::fs::File; -use std::io::BufReader; -use std::path::Path; -use validation::{local_target, ValidationInput, ValidationRequest}; - -pub fn prepare_env_from_json(json_inputs: &Path, debug: bool) -> eyre::Result { - let file = File::open(json_inputs)?; - let reader = BufReader::new(file); - - let req = ValidationRequest::from_reader(reader)?; - let mut input = ValidationInput::from_request(&req, local_target()); - - let mut env = WasmEnv::default(); - env.process.already_has_input = true; - env.process.debug = debug; - - for (module_hash, asm) in input.module_asms.drain() { - env.module_asms.insert(Bytes32(module_hash), asm.into()); - } - - env.input = input; - - Ok(env) -} From 815dd24ea7c876c956529a722d5da8349e461553 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Mon, 16 Mar 2026 12:14:01 +0100 Subject: [PATCH 119/189] fmt --- crates/jit/src/machine.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/jit/src/machine.rs b/crates/jit/src/machine.rs index d8bdab7b5c6..b008d0760cf 100644 --- a/crates/jit/src/machine.rs +++ b/crates/jit/src/machine.rs @@ -5,7 +5,6 @@ use crate::{ arbcompress, arbcrypto, program, stylus_backend::CothreadHandler, wasip1_stub, wavmio, InputMode, LocalInput, Opts, ValidatorOpts, }; -use validation::local_target; use arbutil::{Bytes32, PreimageType}; use caller_env::GoRuntimeState; use eyre::{bail, ErrReport, Report, Result}; @@ -19,6 +18,7 @@ use std::{ time::Instant, }; use thiserror::Error; +use validation::local_target; use wasmer::{ imports, CompilerConfig, Engine, Function, FunctionEnv, FunctionEnvMut, Instance, Memory, Module, RuntimeError, Store, From 919229dcd0a80e2b27eec1ab23d34db3745e512b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Mon, 16 Mar 2026 12:16:04 +0100 Subject: [PATCH 120/189] no pub(crate) --- crates/jit/src/machine.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/jit/src/machine.rs b/crates/jit/src/machine.rs index b008d0760cf..8af02863d41 100644 --- a/crates/jit/src/machine.rs +++ b/crates/jit/src/machine.rs @@ -333,7 +333,7 @@ fn prepare_env_from_files(env: WasmEnv, input: &LocalInput) -> Result { prepare_env_from_validation_input(env, &vi) } -pub(crate) fn prepare_env_from_validation_input( +fn prepare_env_from_validation_input( mut env: WasmEnv, input: &validation::ValidationInput, ) -> Result { From 56c7b89738aa405cf600c196517ea012093628d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Mon, 16 Mar 2026 12:20:22 +0100 Subject: [PATCH 121/189] load also in wavmio --- crates/jit/src/machine.rs | 20 +++++++++----------- crates/jit/src/wavmio.rs | 10 ++-------- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/crates/jit/src/machine.rs b/crates/jit/src/machine.rs index 8af02863d41..c8a4af0a556 100644 --- a/crates/jit/src/machine.rs +++ b/crates/jit/src/machine.rs @@ -264,16 +264,17 @@ impl TryFrom<&Opts> for WasmEnv { let file = File::open(inputs)?; let req = validation::ValidationRequest::from_reader(BufReader::new(file))?; let input = validation::ValidationInput::from_request(&req, local_target()); - prepare_env_from_validation_input(env, &input) + load_validation_input(&mut env, &input); } - InputMode::Local(local) => prepare_env_from_files(env, local), - InputMode::Native(vi) => prepare_env_from_validation_input(env, vi), - InputMode::Continuous => Ok(env), + InputMode::Local(local) => prepare_env_from_files(&mut env, local)?, + InputMode::Native(vi) => load_validation_input(&mut env, vi), + InputMode::Continuous => {} } + Ok(env) } } -fn prepare_env_from_files(env: WasmEnv, input: &LocalInput) -> Result { +fn prepare_env_from_files(env: &mut WasmEnv, input: &LocalInput) -> Result<()> { let mut vi = validation::ValidationInput { small_globals: [ input.old_state.inbox_position, @@ -330,13 +331,11 @@ fn prepare_env_from_files(env: WasmEnv, input: &LocalInput) -> Result { } } - prepare_env_from_validation_input(env, &vi) + load_validation_input(env, &vi); + Ok(()) } -fn prepare_env_from_validation_input( - mut env: WasmEnv, - input: &validation::ValidationInput, -) -> Result { +pub(crate) fn load_validation_input(env: &mut WasmEnv, input: &validation::ValidationInput) { env.process.already_has_input = true; let mut vi = input.clone(); for (module_hash, module_asm) in vi.module_asms.drain() { @@ -344,7 +343,6 @@ fn prepare_env_from_validation_input( .insert(Bytes32(module_hash), module_asm.into()); } env.input = vi; - Ok(env) } pub struct ProcessEnv { diff --git a/crates/jit/src/wavmio.rs b/crates/jit/src/wavmio.rs index 7cb607b00d7..fc6cfc32aa6 100644 --- a/crates/jit/src/wavmio.rs +++ b/crates/jit/src/wavmio.rs @@ -228,14 +228,8 @@ fn ready_hostio(env: &mut WasmEnv) -> MaybeEscape { socket.set_nodelay(true)?; let mut reader = BufReader::new(socket.try_clone()?); - let mut input = receive_validation_input(&mut reader)?; - - for (module_hash, module_asm) in input.module_asms.drain() { - env.module_asms - .insert(arbutil::Bytes32(module_hash), module_asm.into()); - } - - env.input = input; + let input = receive_validation_input(&mut reader)?; + crate::machine::load_validation_input(env, &input); let writer = BufWriter::new(socket); env.process.socket = Some((writer, reader)); From 2b0066fafcfa25a32486db0f16d208c06fe565e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 17 Mar 2026 09:33:22 +0100 Subject: [PATCH 122/189] Comment draining --- crates/jit/src/machine.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/crates/jit/src/machine.rs b/crates/jit/src/machine.rs index c8a4af0a556..4115e8e1194 100644 --- a/crates/jit/src/machine.rs +++ b/crates/jit/src/machine.rs @@ -242,9 +242,11 @@ pub struct WasmEnv { pub memory: Option, /// Go's general runtime state pub go_state: GoRuntimeState, - /// Validation input (globals, inbox, preimages) + /// Validation input (globals, inbox, preimages). Note: module_asms is drained + /// into the `module_asms` field below during loading, so it will be empty at runtime. pub input: validation::ValidationInput, - /// A collection of programs called during the course of execution + /// Arc-wrapped module assemblies, drained from `input.module_asms` to allow + /// cheap cloning when passing modules to stylus program threads. pub module_asms: HashMap, /// The purpose and connections of this process pub process: ProcessEnv, @@ -338,6 +340,9 @@ fn prepare_env_from_files(env: &mut WasmEnv, input: &LocalInput) -> Result<()> { pub(crate) fn load_validation_input(env: &mut WasmEnv, input: &validation::ValidationInput) { env.process.already_has_input = true; let mut vi = input.clone(); + // Drain module_asms into a separate Arc-based cache to avoid copying + // the full wasm binary on each lookup. vi.module_asms will be empty after this, + // but that's fine — module lookups go through env.module_asms instead. for (module_hash, module_asm) in vi.module_asms.drain() { env.module_asms .insert(Bytes32(module_hash), module_asm.into()); From 74e12dbfc32da6adfd542b129e13bd7c614b7fa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 17 Mar 2026 09:39:24 +0100 Subject: [PATCH 123/189] Derive Eq --- Cargo.toml | 2 +- crates/validation/src/lib.rs | 2 +- crates/validation/src/transfer/tests.rs | 9 +-------- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7c19be30dd6..1649e681edc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -55,7 +55,7 @@ enum-iterator = { version = "2.0.1" } eyre = { version = "0.6.5" } fnv = { version = "1.0.7" } gperftools = { version = "0.2.0" } -hex = { version = "0.4.3", default-features = false } +hex = { version = "0.4.3", default-features = false, features = ["alloc"] } k256 = { version = "0.13.4", default-features = false} lazy_static = { version = "1.4.0" } libc = { version = "0.2.132" } diff --git a/crates/validation/src/lib.rs b/crates/validation/src/lib.rs index 62e4581dacf..674e875cc22 100644 --- a/crates/validation/src/lib.rs +++ b/crates/validation/src/lib.rs @@ -16,7 +16,7 @@ pub type Preimages = BTreeMap>>; /// The runtime data needed by any machine (JIT, SP1, Prover) to execute /// a single block validation. Extracted from a `ValidationRequest` by /// selecting a target architecture and stripping request metadata. -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug, Default, PartialEq, Eq)] #[cfg_attr( feature = "rkyv", derive(rkyv::Archive, rkyv::Deserialize, rkyv::Serialize) diff --git a/crates/validation/src/transfer/tests.rs b/crates/validation/src/transfer/tests.rs index 10e9923669d..1eba67b98f0 100644 --- a/crates/validation/src/transfer/tests.rs +++ b/crates/validation/src/transfer/tests.rs @@ -80,13 +80,6 @@ fn transfer_validation_input() -> Result<(), Box> { send_validation_input(&mut writer, &input)?; let received = receive_validation_input(&mut reader)?; - - assert_eq!(received.small_globals, input.small_globals); - assert_eq!(received.large_globals, input.large_globals); - assert_eq!(received.sequencer_messages, input.sequencer_messages); - assert_eq!(received.delayed_messages, input.delayed_messages); - assert_eq!(received.preimages, input.preimages); - assert_eq!(received.module_asms, input.module_asms); - + assert_eq!(received, input); Ok(()) } From 72c575ae655152b1cc20fea80adc0f62e1d4fe1a Mon Sep 17 00:00:00 2001 From: Igor Braga <5835477+bragaigor@users.noreply.github.com> Date: Thu, 19 Mar 2026 08:15:29 -0400 Subject: [PATCH 124/189] formatting and update sp1-crates deps Signed-off-by: Igor Braga <5835477+bragaigor@users.noreply.github.com> --- .gitmodules | 1 + crates/prover/src/programs/counter.rs | 2 +- crates/tools/wasmer | 2 +- sp1-crates/Cargo.lock | 541 ++++++++++++++++++-------- sp1-crates/Cargo.toml | 12 +- sp1-crates/rust-toolchain.toml | 2 +- 6 files changed, 391 insertions(+), 169 deletions(-) diff --git a/.gitmodules b/.gitmodules index 6ae8a9cccd4..974b4573347 100644 --- a/.gitmodules +++ b/.gitmodules @@ -17,6 +17,7 @@ [submodule "crates/tools/wasmer"] path = crates/tools/wasmer url = https://github.com/OffchainLabs/wasmer.git + branch = zk-prove-any/sp1-runner [submodule "nitro-testnode"] path = nitro-testnode url = https://github.com/OffchainLabs/nitro-testnode.git diff --git a/crates/prover/src/programs/counter.rs b/crates/prover/src/programs/counter.rs index 8b367bc609e..35ce9ccbad0 100644 --- a/crates/prover/src/programs/counter.rs +++ b/crates/prover/src/programs/counter.rs @@ -9,10 +9,10 @@ use eyre::{eyre, Result}; use fnv::FnvHashMap as HashMap; use lazy_static::lazy_static; use parking_lot::Mutex; -use wasmparser::Operator; use std::collections::BTreeMap; use std::{clone::Clone, fmt::Debug, sync::Arc}; use wasmer_types::{GlobalIndex, GlobalInit, LocalFunctionIndex, Type}; +use wasmparser::Operator; lazy_static! { /// Assigns each operator a sequential offset diff --git a/crates/tools/wasmer b/crates/tools/wasmer index c230375e42a..329ea40cc56 160000 --- a/crates/tools/wasmer +++ b/crates/tools/wasmer @@ -1 +1 @@ -Subproject commit c230375e42a9e6b5545220c417b974d0729e5c47 +Subproject commit 329ea40cc563b1c09716f8bd89b181b6dffbc596 diff --git a/sp1-crates/Cargo.lock b/sp1-crates/Cargo.lock index 259b91b65af..1d28d12b148 100644 --- a/sp1-crates/Cargo.lock +++ b/sp1-crates/Cargo.lock @@ -19,7 +19,7 @@ version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" dependencies = [ - "gimli", + "gimli 0.32.3", ] [[package]] @@ -133,7 +133,7 @@ checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" name = "arbutil" version = "0.1.0" dependencies = [ - "digest", + "digest 0.10.7", "eyre", "fnv", "hex", @@ -143,7 +143,7 @@ dependencies = [ "serde", "siphasher 0.3.11", "tiny-keccak 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmparser 0.121.2", + "wasmparser 0.245.1", ] [[package]] @@ -157,7 +157,7 @@ dependencies = [ "ark-serialize", "ark-std", "derivative", - "digest", + "digest 0.10.7", "itertools 0.10.5", "num-bigint 0.4.6", "num-traits", @@ -196,7 +196,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" dependencies = [ "ark-std", - "digest", + "digest 0.10.7", "num-bigint 0.4.6", ] @@ -252,7 +252,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -263,7 +263,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -400,7 +400,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -420,7 +420,7 @@ dependencies = [ "regex", "rustc-hash 2.1.1", "shlex", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -453,7 +453,7 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" dependencies = [ - "digest", + "digest 0.10.7", ] [[package]] @@ -489,6 +489,15 @@ dependencies = [ "generic-array 0.14.7", ] +[[package]] +name = "block-buffer" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be" +dependencies = [ + "hybrid-array", +] + [[package]] name = "bls12_381" version = "0.7.1" @@ -542,7 +551,7 @@ checksum = "89385e82b5d1821d2219e0b095efa2cc1f246cbf99080f3be46a1a85c0d392d9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -562,7 +571,7 @@ checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -573,9 +582,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.11.0" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" + +[[package]] +name = "bytesize" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" +checksum = "6bd91ee7b2422bcb158d90ef4d14f75ef67f340943fc4149891dcce8f8b972a3" [[package]] name = "caller-env" @@ -707,7 +722,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -756,6 +771,12 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +[[package]] +name = "const-oid" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" + [[package]] name = "const_format" version = "0.2.35" @@ -925,6 +946,15 @@ dependencies = [ "typenum", ] +[[package]] +name = "crypto-common" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710" +dependencies = [ + "hybrid-array", +] + [[package]] name = "darling" version = "0.21.3" @@ -946,7 +976,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -957,7 +987,7 @@ checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ "darling_core", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -1079,7 +1109,7 @@ checksum = "e0f8817865cacf3b93b943ca06b0fc5fd8e99eabfdb7ea5d296efcbc4afc4f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -1088,7 +1118,7 @@ version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" dependencies = [ - "const-oid", + "const-oid 0.9.6", "pem-rfc7468", "zeroize", ] @@ -1122,7 +1152,7 @@ checksum = "ef941ded77d15ca19b40374869ac6000af1c9f2a4c0f3d4c70926287e6364a8f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -1135,7 +1165,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -1164,7 +1194,7 @@ checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -1177,7 +1207,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.111", + "syn 2.0.114", "unicode-xid", ] @@ -1187,12 +1217,23 @@ version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer", - "const-oid", - "crypto-common", + "block-buffer 0.10.4", + "const-oid 0.9.6", + "crypto-common 0.1.7", "subtle", ] +[[package]] +name = "digest" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4850db49bf08e663084f7fb5c87d202ef91a3907271aff24a94eb97ff039153c" +dependencies = [ + "block-buffer 0.12.0", + "const-oid 0.10.2", + "crypto-common 0.2.1", +] + [[package]] name = "dirs" version = "5.0.1" @@ -1222,7 +1263,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -1237,7 +1278,7 @@ version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ac1e888d6830712d565b2f3a974be3200be9296bc1b03db8251a4cbf18a4a34" dependencies = [ - "digest", + "digest 0.10.7", "futures", "rand 0.8.5", "reqwest", @@ -1263,14 +1304,14 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] name = "dynasm" -version = "4.0.2" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d36219658beb39702975c707dee7895943ca281ca46eebbc5ea395171b9c182b" +checksum = "df4bf11ba8aecc00489b7ec4e8963cd3860651c3ea2a114394f8ba7e92a0e94a" dependencies = [ "bitflags 2.10.0", "byteorder", @@ -1278,7 +1319,7 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -1295,12 +1336,12 @@ dependencies = [ [[package]] name = "dynasmrt" -version = "4.0.2" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bc32ed2a02b82bc43a7631dd624e8c5731a8377e40a468da28e62fc2e028952" +checksum = "b38e5331d851567729d892ed28d898d22f49a96940b29e23b5c3e681bd30ffb3" dependencies = [ "byteorder", - "dynasm 4.0.2", + "dynasm 5.0.0", "fnv", "memmap2 0.9.9", ] @@ -1312,7 +1353,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ "der", - "digest", + "digest 0.10.7", "elliptic-curve", "rfc6979 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "serdect", @@ -1326,7 +1367,7 @@ version = "0.16.9" source = "git+https://github.com/sp1-patches/signatures?tag=sp1-skip-verify-on-recovery#1880299a48fe7ef249edaa616fd411239fb5daf1" dependencies = [ "der", - "digest", + "digest 0.10.7", "elliptic-curve", "rfc6979 0.4.0 (git+https://github.com/sp1-patches/signatures?tag=sp1-skip-verify-on-recovery)", "signature", @@ -1356,7 +1397,7 @@ checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ "base16ct", "crypto-bigint", - "digest", + "digest 0.10.7", "ff 0.13.1", "generic-array 0.14.7", "group 0.13.0", @@ -1405,7 +1446,7 @@ checksum = "685adfa4d6f3d765a26bc5dbc936577de9abf756c1feeb3089b01dd395034842" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -1426,7 +1467,7 @@ checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -1447,7 +1488,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -1493,12 +1534,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "fallible-iterator" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" - [[package]] name = "fastrand" version = "2.3.0" @@ -1667,7 +1702,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -1766,8 +1801,23 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "r-efi", + "r-efi 5.3.0", + "wasip2", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "r-efi 6.0.0", "wasip2", + "wasip3", "wasm-bindgen", ] @@ -1776,8 +1826,15 @@ name = "gimli" version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" + +[[package]] +name = "gimli" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf7f043f89559805f8c7cacc432749b2fa0d0a0a9ee46ce47164ed5ba7f126c" dependencies = [ - "fallible-iterator", + "fnv", + "hashbrown 0.16.1", "indexmap 2.13.0", "stable_deref_trait", ] @@ -1879,7 +1936,6 @@ dependencies = [ "allocator-api2", "equivalent", "foldhash 0.1.5", - "serde", ] [[package]] @@ -1889,6 +1945,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" dependencies = [ "foldhash 0.2.0", + "serde", + "serde_core", ] [[package]] @@ -1924,7 +1982,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest", + "digest 0.10.7", ] [[package]] @@ -1972,6 +2030,15 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "hybrid-array" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8655f91cd07f2b9d0c24137bd650fe69617773435ee5ec83022377777ce65ef1" +dependencies = [ + "typenum", +] + [[package]] name = "hyper" version = "1.8.1" @@ -2154,6 +2221,12 @@ dependencies = [ "zerovec", ] +[[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + [[package]] name = "ident_case" version = "1.0.1" @@ -2189,7 +2262,7 @@ checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -2236,8 +2309,9 @@ dependencies = [ [[package]] name = "inkwell" -version = "0.7.1" -source = "git+https://github.com/TheDan64/inkwell.git?rev=b9c53276e30935ccec841d12c9687a17e9199958#b9c53276e30935ccec841d12c9687a17e9199958" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1def4112dfb2ce2993db7027f7acdb43c1f4ee1c70a082a2eef306ed5d0df365" dependencies = [ "inkwell_internals", "libc", @@ -2248,12 +2322,13 @@ dependencies = [ [[package]] name = "inkwell_internals" -version = "0.12.0" -source = "git+https://github.com/TheDan64/inkwell.git?rev=b9c53276e30935ccec841d12c9687a17e9199958#b9c53276e30935ccec841d12c9687a17e9199958" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63736175c9a30ea123f7018de9f26163e0b39cd6978990ae486b510c4f3bad69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -2355,7 +2430,7 @@ dependencies = [ "elliptic-curve", "once_cell", "serdect", - "sha2", + "sha2 0.10.9", "signature", ] @@ -2369,7 +2444,7 @@ dependencies = [ "elliptic-curve", "hex", "once_cell", - "sha2", + "sha2 0.10.9", "signature", "sp1-lib 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2398,6 +2473,12 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + [[package]] name = "libc" version = "0.2.178" @@ -2416,9 +2497,9 @@ dependencies = [ [[package]] name = "libm" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libredox" @@ -2547,7 +2628,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" dependencies = [ "cfg-if", - "digest", + "digest 0.10.7", ] [[package]] @@ -2670,7 +2751,7 @@ checksum = "4568f25ccbd45ab5d5603dc34318c1ec56b117531781260002151b8530a9f931" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -2759,7 +2840,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -2867,7 +2948,7 @@ dependencies = [ "proc-macro-crate 3.4.0", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -2892,9 +2973,9 @@ dependencies = [ [[package]] name = "object" -version = "0.38.0" +version = "0.38.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8b28f24bd43920cd8e0bc4f9c6553e8b93221c512cb9a1014987fc89d36f830" +checksum = "271638cd5fa9cca89c4c304675ca658efc4e64a66c716b7cfe1afb4b9611dbbc" dependencies = [ "crc32fast", "flate2", @@ -2945,7 +3026,7 @@ dependencies = [ "ecdsa 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", "elliptic-curve", "primeorder", - "sha2", + "sha2 0.10.9", ] [[package]] @@ -3478,7 +3559,7 @@ dependencies = [ "proc-macro-crate 3.4.0", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -3596,7 +3677,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -3625,7 +3706,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -3687,7 +3768,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -3737,14 +3818,14 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] name = "proc-macro2" -version = "1.0.103" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" dependencies = [ "unicode-ident", ] @@ -3802,7 +3883,7 @@ dependencies = [ "prost", "prost-types", "regex", - "syn 2.0.111", + "syn 2.0.114", "tempfile", ] @@ -3816,7 +3897,7 @@ dependencies = [ "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -3835,7 +3916,7 @@ dependencies = [ "arbutil", "brotli", "derivative", - "digest", + "digest 0.10.7", "eyre", "fnv", "lazy_static", @@ -3848,7 +3929,7 @@ dependencies = [ "sha3", "wasmer", "wasmer-types", - "wasmparser 0.224.1", + "wasmparser 0.245.1", ] [[package]] @@ -3868,7 +3949,7 @@ checksum = "7347867d0a7e1208d93b46767be83e2b8f978c3dad35f775ac8d8847551d6fe1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -3928,9 +4009,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.42" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" +checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" dependencies = [ "proc-macro2", ] @@ -3941,6 +4022,12 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + [[package]] name = "radium" version = "0.7.0" @@ -4036,6 +4123,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "rangemap" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "973443cf09a9c8656b574a866ab68dfa19f0867d0340648c7d2f6a71b8a8ea68" + [[package]] name = "rayon" version = "1.11.0" @@ -4111,7 +4204,7 @@ checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -4247,13 +4340,13 @@ dependencies = [ [[package]] name = "rkyv" -version = "0.8.12" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35a640b26f007713818e9a9b65d34da1cf58538207b052916a83d80e43f3ffa4" +checksum = "1a30e631b7f4a03dee9056b8ef6982e8ba371dd5bedb74d3ec86df4499132c70" dependencies = [ "bytecheck", "bytes", - "hashbrown 0.15.5", + "hashbrown 0.16.1", "indexmap 2.13.0", "munge", "ptr_meta", @@ -4266,13 +4359,13 @@ dependencies = [ [[package]] name = "rkyv_derive" -version = "0.8.12" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd83f5f173ff41e00337d97f6572e416d022ef8a19f371817259ae960324c482" +checksum = "8100bb34c0a1d0f907143db3149e6b4eea3c33b9ee8b189720168e818303986f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -4448,7 +4541,7 @@ dependencies = [ "proc-macro-crate 3.4.0", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -4592,7 +4685,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -4648,7 +4741,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -4683,7 +4776,7 @@ checksum = "5d69265a08751de7844521fd15003ae0a888e035773ba05695c5c759a6f89eef" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -4700,7 +4793,18 @@ checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", "cpufeatures", - "digest", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.11.0-rc.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c5f3b1e2dc8aad28310d8410bd4d7e180eca65fca176c52ab00d364475d0024" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.11.2", ] [[package]] @@ -4709,7 +4813,7 @@ version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ - "digest", + "digest 0.10.7", "keccak", ] @@ -4753,7 +4857,7 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ - "digest", + "digest 0.10.7", "rand_core 0.6.4", ] @@ -5345,7 +5449,7 @@ dependencies = [ "sp1-core-executor", "sp1-sdk", "wasmer", - "wasmparser 0.224.1", + "wasmparser 0.245.1", ] [[package]] @@ -5600,7 +5704,7 @@ dependencies = [ "p3-poseidon2 0.2.3-succinct", "p3-symmetric 0.2.3-succinct", "serde", - "sha2", + "sha2 0.10.9", ] [[package]] @@ -5617,7 +5721,7 @@ dependencies = [ "lazy_static", "num-bigint 0.4.6", "serde", - "sha2", + "sha2 0.10.9", "slop-algebra 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "slop-bn254 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "slop-challenger 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5640,7 +5744,7 @@ dependencies = [ "lazy_static", "num-bigint 0.4.6", "serde", - "sha2", + "sha2 0.10.9", "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-bn254 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", @@ -5678,7 +5782,7 @@ dependencies = [ "serde", "serde_json", "serial_test", - "sha2", + "sha2 0.10.9", "slop-air", "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-basefold", @@ -5827,7 +5931,7 @@ dependencies = [ "num-bigint 0.4.6", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "sp1-hypercube", @@ -5924,7 +6028,7 @@ dependencies = [ "hex", "lazy_static", "serde", - "sha2", + "sha2 0.10.9", "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", @@ -5950,7 +6054,7 @@ dependencies = [ "lazy_static", "libm", "rand 0.8.5", - "sha2", + "sha2 0.10.9", "sp1-lib 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", ] @@ -6022,7 +6126,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -6043,7 +6147,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -6095,9 +6199,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.111" +version = "2.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" +checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" dependencies = [ "proc-macro2", "quote", @@ -6121,7 +6225,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -6200,7 +6304,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -6211,7 +6315,7 @@ checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -6328,7 +6432,7 @@ checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -6455,7 +6559,7 @@ dependencies = [ "prost-build", "prost-types", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -6555,7 +6659,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -6781,7 +6885,16 @@ version = "1.0.1+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" dependencies = [ - "wit-bindgen", + "wit-bindgen 0.46.0", +] + +[[package]] +name = "wasip3" +version = "0.4.0+wasi-0.3.0-rc-2026-01-06" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +dependencies = [ + "wit-bindgen 0.51.0", ] [[package]] @@ -6829,7 +6942,7 @@ dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", "wasm-bindgen-shared", ] @@ -6842,6 +6955,28 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "wasm-encoder" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +dependencies = [ + "leb128fmt", + "wasmparser 0.244.0", +] + +[[package]] +name = "wasm-metadata" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +dependencies = [ + "anyhow", + "indexmap 2.13.0", + "wasm-encoder", + "wasmparser 0.244.0", +] + [[package]] name = "wasm-streams" version = "0.4.2" @@ -6857,8 +6992,7 @@ dependencies = [ [[package]] name = "wasmer" -version = "6.1.0" -source = "git+https://github.com/wakabat/official-wasmer?rev=e065880#e065880e79728b4d15ffc9d4eccd5153d249de2c" +version = "7.1.0-rc.2" dependencies = [ "bindgen 0.72.1", "bytes", @@ -6884,18 +7018,18 @@ dependencies = [ "wasmer-derive", "wasmer-types", "wasmer-vm", - "wasmparser 0.224.1", + "wasmparser 0.245.1", "windows-sys 0.61.2", ] [[package]] name = "wasmer-compiler" -version = "6.1.0" -source = "git+https://github.com/wakabat/official-wasmer?rev=e065880#e065880e79728b4d15ffc9d4eccd5153d249de2c" +version = "7.1.0-rc.2" dependencies = [ "backtrace", "bytes", "cfg-if", + "crossbeam-channel", "enum-iterator", "enumset", "itertools 0.14.0", @@ -6904,7 +7038,9 @@ dependencies = [ "macho-unwind-info", "memmap2 0.9.9", "more-asserts", - "object 0.38.0", + "object 0.38.1", + "rangemap", + "rayon", "region", "rkyv", "self_cell", @@ -6915,23 +7051,23 @@ dependencies = [ "thiserror 2.0.17", "wasmer-types", "wasmer-vm", - "wasmparser 0.224.1", + "wasmparser 0.245.1", "which", "windows-sys 0.61.2", - "xxhash-rust", ] [[package]] name = "wasmer-compiler-llvm" -version = "6.1.0" -source = "git+https://github.com/wakabat/official-wasmer?rev=e065880#e065880e79728b4d15ffc9d4eccd5153d249de2c" +version = "7.1.0-rc.2" dependencies = [ "byteorder", "cc", + "crossbeam-channel", + "enumset", "inkwell", "itertools 0.14.0", "libc", - "object 0.38.0", + "object 0.38.1", "phf", "rayon", "regex", @@ -6947,14 +7083,13 @@ dependencies = [ [[package]] name = "wasmer-compiler-singlepass" -version = "6.1.0" -source = "git+https://github.com/wakabat/official-wasmer?rev=e065880#e065880e79728b4d15ffc9d4eccd5153d249de2c" +version = "7.1.0-rc.2" dependencies = [ "byteorder", - "dynasm 4.0.2", - "dynasmrt 4.0.2", + "dynasm 5.0.0", + "dynasmrt 5.0.0", "enumset", - "gimli", + "gimli 0.33.0", "itertools 0.14.0", "more-asserts", "rayon", @@ -6967,40 +7102,37 @@ dependencies = [ [[package]] name = "wasmer-derive" -version = "6.1.0" -source = "git+https://github.com/wakabat/official-wasmer?rev=e065880#e065880e79728b4d15ffc9d4eccd5153d249de2c" +version = "7.1.0-rc.2" dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] name = "wasmer-types" -version = "6.1.0" -source = "git+https://github.com/wakabat/official-wasmer?rev=e065880#e065880e79728b4d15ffc9d4eccd5153d249de2c" +version = "7.1.0-rc.2" dependencies = [ "bytecheck", "enum-iterator", "enumset", - "getrandom 0.2.16", + "getrandom 0.4.2", "hex", "indexmap 2.13.0", "more-asserts", "rkyv", - "sha2", + "sha2 0.11.0-rc.5", "target-lexicon", "thiserror 2.0.17", - "xxhash-rust", ] [[package]] name = "wasmer-vm" -version = "6.1.0" -source = "git+https://github.com/wakabat/official-wasmer?rev=e065880#e065880e79728b4d15ffc9d4eccd5153d249de2c" +version = "7.1.0-rc.2" dependencies = [ "backtrace", + "bytesize", "cc", "cfg-if", "corosensei", @@ -7008,7 +7140,9 @@ dependencies = [ "dashmap", "enum-iterator", "fnv", + "gimli 0.33.0", "indexmap 2.13.0", + "itertools 0.14.0", "libc", "libunwind", "mach2 0.6.0", @@ -7025,23 +7159,24 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.121.2" +version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dbe55c8f9d0dbd25d9447a5a889ff90c0cc3feaa7395310d3d826b2c703eaab" +checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ "bitflags 2.10.0", + "hashbrown 0.15.5", "indexmap 2.13.0", "semver", ] [[package]] name = "wasmparser" -version = "0.224.1" +version = "0.245.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04f17a5917c2ddd3819e84c661fae0d6ba29d7b9c1f0e96c708c65a9c4188e11" +checksum = "4f08c9adee0428b7bddf3890fc27e015ac4b761cc608c822667102b8bfd6995e" dependencies = [ "bitflags 2.10.0", - "hashbrown 0.15.5", + "hashbrown 0.16.1", "indexmap 2.13.0", "semver", "serde", @@ -7148,7 +7283,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -7159,7 +7294,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -7447,6 +7582,94 @@ version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" +[[package]] +name = "wit-bindgen" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +dependencies = [ + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen-core" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +dependencies = [ + "anyhow", + "heck", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +dependencies = [ + "anyhow", + "heck", + "indexmap 2.13.0", + "prettyplease", + "syn 2.0.114", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn 2.0.114", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +dependencies = [ + "anyhow", + "bitflags 2.10.0", + "indexmap 2.13.0", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser 0.244.0", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +dependencies = [ + "anyhow", + "id-arena", + "indexmap 2.13.0", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser 0.244.0", +] + [[package]] name = "writeable" version = "0.6.2" @@ -7472,12 +7695,6 @@ dependencies = [ "rustix", ] -[[package]] -name = "xxhash-rust" -version = "0.8.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdd20c5420375476fbd4394763288da7eb0cc0b8c11deed431a91562af7335d3" - [[package]] name = "yoke" version = "0.8.1" @@ -7497,7 +7714,7 @@ checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", "synstructure", ] @@ -7518,7 +7735,7 @@ checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -7538,7 +7755,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", "synstructure", ] @@ -7559,7 +7776,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -7592,7 +7809,7 @@ checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -7617,7 +7834,7 @@ dependencies = [ "pasta_curves 0.5.1", "rand 0.8.5", "serde", - "sha2", + "sha2 0.10.9", "sha3", "subtle", ] diff --git a/sp1-crates/Cargo.toml b/sp1-crates/Cargo.toml index 48c85c7d6e3..0981c76988a 100644 --- a/sp1-crates/Cargo.toml +++ b/sp1-crates/Cargo.toml @@ -40,13 +40,17 @@ sp1-zkvm = { version = "6.0.0", features = ["untrusted_programs", "may_dump_elf" thiserror = { version = "1.0.33" } tokio = { version = "1.42.0" } tracing = { version = "0.1.40" } -wasmparser = { version = "0.224.0" } +wasmparser = { version = "0.245.0" } secp256k1 = { git = "https://github.com/sp1-patches/rust-secp256k1", tag = "patch-0.29.1-sp1-6.0.0", features = ["recovery", "global-context"] } tiny-keccak = { git = "https://github.com/sp1-patches/tiny-keccak", tag = "patch-2.0.2-sp1-6.0.0", features = ["keccak"] } -wasmer = { git = "https://github.com/wakabat/official-wasmer", rev = "e065880", default-features = false, features = ["sys", "compiler", "singlepass", "wasmparser"] } -wasmer-types = { git = "https://github.com/wakabat/official-wasmer", rev = "e065880" } -wasmer-vm = { git = "https://github.com/wakabat/official-wasmer", rev = "e065880", features = ["force-baremetal"] } +# wasmer = { git = "https://github.com/wakabat/official-wasmer", rev = "e065880", default-features = false, features = ["sys", "compiler", "singlepass", "wasmparser"] } +# wasmer-types = { git = "https://github.com/wakabat/official-wasmer", rev = "e065880" } +# wasmer-vm = { git = "https://github.com/wakabat/official-wasmer", rev = "e065880", features = ["force-baremetal"] } + +wasmer = { path = "../crates/tools/wasmer/lib/api", default-features = false, features = ["sys", "compiler", "singlepass", "wasmparser"] } +wasmer-types = { path = "../crates/tools/wasmer/lib/types" } +wasmer-vm = { path = "../crates/tools/wasmer/lib/vm" } [patch.crates-io] target-lexicon = { git = "https://github.com/OffchainLabs/target-lexicon", tag = "v0.13.5-sp1" } diff --git a/sp1-crates/rust-toolchain.toml b/sp1-crates/rust-toolchain.toml index 73328e053b3..075062e5e6b 100644 --- a/sp1-crates/rust-toolchain.toml +++ b/sp1-crates/rust-toolchain.toml @@ -1,2 +1,2 @@ [toolchain] -channel = "1.90" +channel = "1.93.0" From 2068b02e1792ec791f1de2b9632f7c653ac91db1 Mon Sep 17 00:00:00 2001 From: Igor Braga <5835477+bragaigor@users.noreply.github.com> Date: Thu, 19 Mar 2026 10:16:20 -0400 Subject: [PATCH 125/189] update wasmer and fix sp1 compilation Signed-off-by: Igor Braga <5835477+bragaigor@users.noreply.github.com> --- crates/prover/src/programs/config.rs | 8 ++++---- crates/prover/src/programs/counter.rs | 1 + crates/tools/wasmer | 2 +- sp1-crates/Cargo.toml | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/crates/prover/src/programs/config.rs b/crates/prover/src/programs/config.rs index eb62e0631a7..394dc9f03e4 100644 --- a/crates/prover/src/programs/config.rs +++ b/crates/prover/src/programs/config.rs @@ -11,7 +11,7 @@ use std::fmt::Debug; use wasmer_types::{Pages, SignatureIndex, WASM_PAGE_SIZE}; use wasmparser::Operator; -#[cfg(feature = "native")] +#[cfg(all(feature = "native", not(feature = "sp1")))] use { super::{ counter::Counter, depth::DepthChecker, dynamic::DynamicMeter, heap::HeapBound, @@ -181,7 +181,7 @@ impl CompileConfig { config } - #[cfg(feature = "native")] + #[cfg(all(feature = "native", not(feature = "sp1")))] fn engine_type(&self, target: Target, cranelift: bool) -> Engine { use wasmer::sys::EngineBuilder; @@ -220,13 +220,13 @@ impl CompileConfig { .into() } - #[cfg(feature = "native")] + #[cfg(all(feature = "native", not(feature = "sp1")))] // cranelift only matters for compilation and not usually needed pub fn engine(&self, target: Target) -> Engine { self.engine_type(target, true) } - #[cfg(feature = "native")] + #[cfg(all(feature = "native", not(feature = "sp1")))] pub fn store(&self, target: Target, cranelift: bool) -> Store { Store::new(self.engine_type(target, cranelift)) } diff --git a/crates/prover/src/programs/counter.rs b/crates/prover/src/programs/counter.rs index 35ce9ccbad0..7acda29e88f 100644 --- a/crates/prover/src/programs/counter.rs +++ b/crates/prover/src/programs/counter.rs @@ -2,6 +2,7 @@ // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md use super::{FuncMiddleware, Middleware, ModuleMod}; +#[cfg(not(feature = "sp1"))] use crate::Machine; use arbutil::operator::{OperatorCode, OperatorInfo}; diff --git a/crates/tools/wasmer b/crates/tools/wasmer index 329ea40cc56..1b32d836047 160000 --- a/crates/tools/wasmer +++ b/crates/tools/wasmer @@ -1 +1 @@ -Subproject commit 329ea40cc563b1c09716f8bd89b181b6dffbc596 +Subproject commit 1b32d8360472ca8957f0cb1424316996a81b57c3 diff --git a/sp1-crates/Cargo.toml b/sp1-crates/Cargo.toml index 0981c76988a..e6dda3152f6 100644 --- a/sp1-crates/Cargo.toml +++ b/sp1-crates/Cargo.toml @@ -50,7 +50,7 @@ tiny-keccak = { git = "https://github.com/sp1-patches/tiny-keccak", tag = "patch wasmer = { path = "../crates/tools/wasmer/lib/api", default-features = false, features = ["sys", "compiler", "singlepass", "wasmparser"] } wasmer-types = { path = "../crates/tools/wasmer/lib/types" } -wasmer-vm = { path = "../crates/tools/wasmer/lib/vm" } +wasmer-vm = { path = "../crates/tools/wasmer/lib/vm", features = ["force-baremetal"] } [patch.crates-io] target-lexicon = { git = "https://github.com/OffchainLabs/target-lexicon", tag = "v0.13.5-sp1" } From 9a233543f490c24caa03551af8982cc0dcc8586b Mon Sep 17 00:00:00 2001 From: Igor Braga <5835477+bragaigor@users.noreply.github.com> Date: Thu, 19 Mar 2026 10:25:34 -0400 Subject: [PATCH 126/189] update wasmer for missing publish_eh_frame on x86 Signed-off-by: Igor Braga <5835477+bragaigor@users.noreply.github.com> --- crates/tools/wasmer | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/tools/wasmer b/crates/tools/wasmer index 1b32d836047..4eda3bcbf09 160000 --- a/crates/tools/wasmer +++ b/crates/tools/wasmer @@ -1 +1 @@ -Subproject commit 1b32d8360472ca8957f0cb1424316996a81b57c3 +Subproject commit 4eda3bcbf09bc3b7bb24b153649814ba234b2637 From 6857904e98090b4e5e0e7beefae5622cf0f6b698 Mon Sep 17 00:00:00 2001 From: Igor Braga <5835477+bragaigor@users.noreply.github.com> Date: Thu, 19 Mar 2026 12:46:36 -0400 Subject: [PATCH 127/189] attempt to fix Sp1 validation Signed-off-by: Igor Braga <5835477+bragaigor@users.noreply.github.com> --- crates/tools/wasmer | 2 +- sp1-crates/Cargo.lock | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/tools/wasmer b/crates/tools/wasmer index 4eda3bcbf09..319e3a341e6 160000 --- a/crates/tools/wasmer +++ b/crates/tools/wasmer @@ -1 +1 @@ -Subproject commit 4eda3bcbf09bc3b7bb24b153649814ba234b2637 +Subproject commit 319e3a341e691943e4189aa5db8290b7ea464723 diff --git a/sp1-crates/Cargo.lock b/sp1-crates/Cargo.lock index 1d28d12b148..2c038fb4860 100644 --- a/sp1-crates/Cargo.lock +++ b/sp1-crates/Cargo.lock @@ -7092,7 +7092,6 @@ dependencies = [ "gimli 0.33.0", "itertools 0.14.0", "more-asserts", - "rayon", "smallvec", "target-lexicon", "tempfile", From 8c4b7466e24c9e76623864c1aa2ec06f4f28b98d Mon Sep 17 00:00:00 2001 From: Igor Braga <5835477+bragaigor@users.noreply.github.com> Date: Thu, 19 Mar 2026 14:03:36 -0400 Subject: [PATCH 128/189] test without custom brotli Signed-off-by: Igor Braga <5835477+bragaigor@users.noreply.github.com> --- crates/tools/wasmer | 2 +- sp1-crates/build.sh | 36 ++++++++++++++++++------------------ 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/crates/tools/wasmer b/crates/tools/wasmer index 319e3a341e6..fb73482ca03 160000 --- a/crates/tools/wasmer +++ b/crates/tools/wasmer @@ -1 +1 @@ -Subproject commit 319e3a341e691943e4189aa5db8290b7ea464723 +Subproject commit fb73482ca0395a998ca468373a914ace13f23c7d diff --git a/sp1-crates/build.sh b/sp1-crates/build.sh index c61b47a1245..e09efbd3d94 100755 --- a/sp1-crates/build.sh +++ b/sp1-crates/build.sh @@ -18,24 +18,24 @@ if [ ! -d "$HOME/.sp1/riscv" ]; then fi # Build brotli for SP1 -cp sp1-crates/brotli_cmake_patch.txt brotli/CMakeLists.txt -rm -rf target/build-sp1/brotli target/lib-sp1 -mkdir -p target/build-sp1/brotli -cd target/build-sp1/brotli -cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \ - -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY \ - -DCMAKE_SYSTEM_NAME=Generic \ - -DCMAKE_C_COMPILER="$HOME"/.sp1/riscv/bin/riscv64-unknown-elf-gcc \ - -DCMAKE_C_FLAGS="-march=rv64im -mabi=lp64 -DBROTLI_BUILD_PORTABLE -mcmodel=medany -ffunction-sections -fdata-sections -fPIC" \ - -DCMAKE_AR="$HOME"/.sp1/riscv/bin/riscv64-unknown-elf-ar \ - -DCMAKE_RANLIB="$HOME"/.sp1/riscv/bin/riscv64-unknown-elf-ranlib \ - -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_INSTALL_PREFIX="$TOP"/target/lib-sp1 \ - -DBROTLI_DISABLE_TESTS=ON \ - "$TOP"/brotli -make -make install -cd "$TOP" +# cp sp1-crates/brotli_cmake_patch.txt brotli/CMakeLists.txt +# rm -rf target/build-sp1/brotli target/lib-sp1 +# mkdir -p target/build-sp1/brotli +# cd target/build-sp1/brotli +# cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \ +# -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY \ +# -DCMAKE_SYSTEM_NAME=Generic \ +# -DCMAKE_C_COMPILER="$HOME"/.sp1/riscv/bin/riscv64-unknown-elf-gcc \ +# -DCMAKE_C_FLAGS="-march=rv64im -mabi=lp64 -DBROTLI_BUILD_PORTABLE -mcmodel=medany -ffunction-sections -fdata-sections -fPIC" \ +# -DCMAKE_AR="$HOME"/.sp1/riscv/bin/riscv64-unknown-elf-ar \ +# -DCMAKE_RANLIB="$HOME"/.sp1/riscv/bin/riscv64-unknown-elf-ranlib \ +# -DCMAKE_BUILD_TYPE=Release \ +# -DCMAKE_INSTALL_PREFIX="$TOP"/target/lib-sp1 \ +# -DBROTLI_DISABLE_TESTS=ON \ +# "$TOP"/brotli +# make +# make install +# cd "$TOP" # Build nitro dependencies make build-replay-env test-go-deps From c93242d141217c7815c203da660448b05438ae0e Mon Sep 17 00:00:00 2001 From: Igor Braga <5835477+bragaigor@users.noreply.github.com> Date: Thu, 19 Mar 2026 14:34:49 -0400 Subject: [PATCH 129/189] readd brotli and update upstream wasmer Signed-off-by: Igor Braga <5835477+bragaigor@users.noreply.github.com> --- crates/tools/wasmer | 2 +- sp1-crates/build.sh | 36 ++++++++++++++++++------------------ 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/crates/tools/wasmer b/crates/tools/wasmer index fb73482ca03..82ffc70a5e6 160000 --- a/crates/tools/wasmer +++ b/crates/tools/wasmer @@ -1 +1 @@ -Subproject commit fb73482ca0395a998ca468373a914ace13f23c7d +Subproject commit 82ffc70a5e653b93462172aacf15dc280e0a3348 diff --git a/sp1-crates/build.sh b/sp1-crates/build.sh index e09efbd3d94..c61b47a1245 100755 --- a/sp1-crates/build.sh +++ b/sp1-crates/build.sh @@ -18,24 +18,24 @@ if [ ! -d "$HOME/.sp1/riscv" ]; then fi # Build brotli for SP1 -# cp sp1-crates/brotli_cmake_patch.txt brotli/CMakeLists.txt -# rm -rf target/build-sp1/brotli target/lib-sp1 -# mkdir -p target/build-sp1/brotli -# cd target/build-sp1/brotli -# cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \ -# -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY \ -# -DCMAKE_SYSTEM_NAME=Generic \ -# -DCMAKE_C_COMPILER="$HOME"/.sp1/riscv/bin/riscv64-unknown-elf-gcc \ -# -DCMAKE_C_FLAGS="-march=rv64im -mabi=lp64 -DBROTLI_BUILD_PORTABLE -mcmodel=medany -ffunction-sections -fdata-sections -fPIC" \ -# -DCMAKE_AR="$HOME"/.sp1/riscv/bin/riscv64-unknown-elf-ar \ -# -DCMAKE_RANLIB="$HOME"/.sp1/riscv/bin/riscv64-unknown-elf-ranlib \ -# -DCMAKE_BUILD_TYPE=Release \ -# -DCMAKE_INSTALL_PREFIX="$TOP"/target/lib-sp1 \ -# -DBROTLI_DISABLE_TESTS=ON \ -# "$TOP"/brotli -# make -# make install -# cd "$TOP" +cp sp1-crates/brotli_cmake_patch.txt brotli/CMakeLists.txt +rm -rf target/build-sp1/brotli target/lib-sp1 +mkdir -p target/build-sp1/brotli +cd target/build-sp1/brotli +cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \ + -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY \ + -DCMAKE_SYSTEM_NAME=Generic \ + -DCMAKE_C_COMPILER="$HOME"/.sp1/riscv/bin/riscv64-unknown-elf-gcc \ + -DCMAKE_C_FLAGS="-march=rv64im -mabi=lp64 -DBROTLI_BUILD_PORTABLE -mcmodel=medany -ffunction-sections -fdata-sections -fPIC" \ + -DCMAKE_AR="$HOME"/.sp1/riscv/bin/riscv64-unknown-elf-ar \ + -DCMAKE_RANLIB="$HOME"/.sp1/riscv/bin/riscv64-unknown-elf-ranlib \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX="$TOP"/target/lib-sp1 \ + -DBROTLI_DISABLE_TESTS=ON \ + "$TOP"/brotli +make +make install +cd "$TOP" # Build nitro dependencies make build-replay-env test-go-deps From 20ffc8a7bcc8af368e08dc7f685e58e060b175dc Mon Sep 17 00:00:00 2001 From: Igor Braga <5835477+bragaigor@users.noreply.github.com> Date: Fri, 20 Mar 2026 08:32:21 -0400 Subject: [PATCH 130/189] guard with sp1 Signed-off-by: Igor Braga <5835477+bragaigor@users.noreply.github.com> --- crates/prover/src/programs/depth.rs | 9 ++++++++- crates/prover/src/programs/mod.rs | 7 +++++-- crates/prover/src/value.rs | 12 ++++++++++++ sp1-crates/runner/src/main.rs | 2 +- 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/crates/prover/src/programs/depth.rs b/crates/prover/src/programs/depth.rs index 29ee8941fbc..7d9f4cee13f 100644 --- a/crates/prover/src/programs/depth.rs +++ b/crates/prover/src/programs/depth.rs @@ -5,9 +5,16 @@ use super::{ config::{CompileMemoryParams, SigMap}, FuncMiddleware, Middleware, ModuleMod, }; -use crate::{value::FunctionType, Machine}; +#[cfg(not(feature = "sp1"))] +use crate::Machine; + +use crate::value::FunctionType; +#[cfg(feature = "sp1")] +use crate::value::InternalFunc; +#[cfg(not(feature = "sp1"))] use crate::internal_func::InternalFunc; + use arbutil::Color; use eyre::{bail, Result}; use fnv::FnvHashMap as HashMap; diff --git a/crates/prover/src/programs/mod.rs b/crates/prover/src/programs/mod.rs index 4e3c67385da..2bc67074722 100644 --- a/crates/prover/src/programs/mod.rs +++ b/crates/prover/src/programs/mod.rs @@ -1,9 +1,13 @@ // Copyright 2022-2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md +#[cfg(feature = "sp1")] +use crate::value::MemoryType; +#[cfg(not(feature = "sp1"))] +use crate::{machine::Module, memory_type::MemoryType}; + use crate::{ binary::{ExportKind, WasmBinary}, - machine::Module, programs::config::CompileConfig, value::{FunctionType as ArbFunctionType, Value}, }; @@ -17,7 +21,6 @@ use wasmer_types::{ }; use wasmparser::{Operator, ValType}; -use crate::memory_type::MemoryType; #[cfg(feature = "native")] use { super::value, diff --git a/crates/prover/src/value.rs b/crates/prover/src/value.rs index 61bee87f670..f1d9a953434 100644 --- a/crates/prover/src/value.rs +++ b/crates/prover/src/value.rs @@ -496,3 +496,15 @@ impl Display for ArbValueType { } } } + +#[cfg(feature = "sp1")] +#[path = "internal_func.rs"] +mod internal_func; +#[cfg(feature = "sp1")] +pub use internal_func::InternalFunc; + +#[cfg(feature = "sp1")] +#[path = "memory_type.rs"] +mod memory_type; +#[cfg(feature = "sp1")] +pub use memory_type::MemoryType; diff --git a/sp1-crates/runner/src/main.rs b/sp1-crates/runner/src/main.rs index fde0dcbee82..385a825f639 100644 --- a/sp1-crates/runner/src/main.rs +++ b/sp1-crates/runner/src/main.rs @@ -117,7 +117,7 @@ fn build_input(cli: &Cli) -> Vec { serde_json::from_slice::(&std::fs::read(&cli.block_file).expect("read input block")) .expect("parse input block"); - let mut input = ValidationInput::from_request(&req, "rv64"); + let mut input = ValidationInput::from_request(&req, "rv64").expect("request validation input"); // Compile wasm modules that don't have rv64 binaries via the SP1 stylus compiler. if let Some(wasms) = req.user_wasms.get("wasm") { From a2641fb332eb24e5ec6360ee795c46233252582d Mon Sep 17 00:00:00 2001 From: Igor Braga <5835477+bragaigor@users.noreply.github.com> Date: Fri, 20 Mar 2026 09:02:29 -0400 Subject: [PATCH 131/189] guard bad stylus arch check against sp1 builds Signed-off-by: Igor Braga <5835477+bragaigor@users.noreply.github.com> --- crates/validation/Cargo.toml | 1 + crates/validation/src/lib.rs | 2 +- sp1-crates/runner/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/validation/Cargo.toml b/crates/validation/Cargo.toml index 0ca87eac163..af5a568dd7e 100644 --- a/crates/validation/Cargo.toml +++ b/crates/validation/Cargo.toml @@ -20,3 +20,4 @@ serde_with = { workspace = true, features = ["base64"] } [features] default = [] rkyv = ["dep:rkyv"] +sp1 = [] diff --git a/crates/validation/src/lib.rs b/crates/validation/src/lib.rs index c632ce5fd41..e57d4b8a86e 100644 --- a/crates/validation/src/lib.rs +++ b/crates/validation/src/lib.rs @@ -59,7 +59,7 @@ impl ValidationInput { for (module_hash, wasm) in user_wasms { module_asms.insert(**module_hash, wasm.as_vec()); } - } else { + } else if !cfg!(feature = "sp1") { for (arch, wasms) in &req.user_wasms { if !wasms.is_empty() { return Err(format!("bad stylus arch: got {arch}, expected {target}")); diff --git a/sp1-crates/runner/Cargo.toml b/sp1-crates/runner/Cargo.toml index 32878d0700b..3240115c1d8 100644 --- a/sp1-crates/runner/Cargo.toml +++ b/sp1-crates/runner/Cargo.toml @@ -7,7 +7,7 @@ edition = "2024" [dependencies] sp1-core-executor = { workspace = true } sp1-sdk = { workspace = true } -validation = { workspace = true, features = ["rkyv"] } +validation = { workspace = true, features = ["rkyv", "sp1"] } bincode = { workspace = true } clap = { workspace = true } From 9e3f5ddc1ca5706a93d140b4f8e3e2dc1588b0df Mon Sep 17 00:00:00 2001 From: Igor Braga <5835477+bragaigor@users.noreply.github.com> Date: Mon, 23 Mar 2026 09:21:02 -0400 Subject: [PATCH 132/189] remove redundant code Signed-off-by: Igor Braga <5835477+bragaigor@users.noreply.github.com> --- crates/prover/src/binary.rs | 3 --- sp1-crates/Cargo.toml | 3 --- 2 files changed, 6 deletions(-) diff --git a/crates/prover/src/binary.rs b/crates/prover/src/binary.rs index 8ab3cf33dac..54fc1e2dc04 100644 --- a/crates/prover/src/binary.rs +++ b/crates/prover/src/binary.rs @@ -327,9 +327,6 @@ pub fn parse<'a>(input: &'a [u8], path: &'_ Path) -> Result> { features.set(WasmFeatures::CM_NESTED_NAMES, false); features.set(WasmFeatures::GC_TYPES, true); - #[cfg(feature = "sp1")] - features.set(WasmFeatures::FLOATS, true); - Validator::new_with_features(features) .validate_all(input) .wrap_err_with(|| eyre!("failed to validate {}", path.to_string_lossy().red()))?; diff --git a/sp1-crates/Cargo.toml b/sp1-crates/Cargo.toml index e6dda3152f6..8bb2978922b 100644 --- a/sp1-crates/Cargo.toml +++ b/sp1-crates/Cargo.toml @@ -44,9 +44,6 @@ wasmparser = { version = "0.245.0" } secp256k1 = { git = "https://github.com/sp1-patches/rust-secp256k1", tag = "patch-0.29.1-sp1-6.0.0", features = ["recovery", "global-context"] } tiny-keccak = { git = "https://github.com/sp1-patches/tiny-keccak", tag = "patch-2.0.2-sp1-6.0.0", features = ["keccak"] } -# wasmer = { git = "https://github.com/wakabat/official-wasmer", rev = "e065880", default-features = false, features = ["sys", "compiler", "singlepass", "wasmparser"] } -# wasmer-types = { git = "https://github.com/wakabat/official-wasmer", rev = "e065880" } -# wasmer-vm = { git = "https://github.com/wakabat/official-wasmer", rev = "e065880", features = ["force-baremetal"] } wasmer = { path = "../crates/tools/wasmer/lib/api", default-features = false, features = ["sys", "compiler", "singlepass", "wasmparser"] } wasmer-types = { path = "../crates/tools/wasmer/lib/types" } From 37b2642d3022b4bcb56f3994b6ce4afbab1b0529 Mon Sep 17 00:00:00 2001 From: Igor Braga <5835477+bragaigor@users.noreply.github.com> Date: Tue, 24 Mar 2026 08:49:58 -0400 Subject: [PATCH 133/189] Consolidate sp1-crates into crates Step1: Move sp1-crates into crates Step2: TODO: consolidate sp1 crate into workspace of crates Signed-off-by: Igor Braga <5835477+bragaigor@users.noreply.github.com> --- .github/workflows/zk-proving.yml | 2 +- Cargo.toml | 1 + crates/prover/Cargo.toml | 2 +- {sp1-crates => crates/sp1}/.cargo/config.toml | 0 {sp1-crates => crates/sp1}/.gitignore | 0 {sp1-crates => crates/sp1}/Cargo.lock | 0 {sp1-crates => crates/sp1}/Cargo.toml | 14 +++++++------- {sp1-crates => crates/sp1}/README.md | 2 +- {sp1-crates => crates/sp1}/brotli_cmake_patch.txt | 0 {sp1-crates => crates/sp1}/build.sh | 4 ++-- {sp1-crates => crates/sp1}/builder/Cargo.toml | 0 {sp1-crates => crates/sp1}/builder/build.rs | 0 {sp1-crates => crates/sp1}/builder/src/main.rs | 0 {sp1-crates => crates/sp1}/program/Cargo.toml | 0 .../sp1}/program/src/imports/arbcompress.rs | 0 .../sp1}/program/src/imports/debug.rs | 0 .../sp1}/program/src/imports/mod.rs | 0 .../sp1}/program/src/imports/precompiles.rs | 0 .../sp1}/program/src/imports/programs.rs | 0 .../sp1}/program/src/imports/vm_hooks.rs | 0 .../sp1}/program/src/imports/wasi_stub.rs | 0 .../sp1}/program/src/imports/wavmio.rs | 0 {sp1-crates => crates/sp1}/program/src/lib.rs | 0 {sp1-crates => crates/sp1}/program/src/main.rs | 0 {sp1-crates => crates/sp1}/program/src/memory.rs | 0 {sp1-crates => crates/sp1}/program/src/platform.rs | 0 {sp1-crates => crates/sp1}/program/src/replay.rs | 0 {sp1-crates => crates/sp1}/program/src/state.rs | 0 {sp1-crates => crates/sp1}/program/src/stylus.rs | 0 {sp1-crates => crates/sp1}/prover/Cargo.toml | 0 {sp1-crates => crates/sp1}/prover/src/lib.rs | 8 ++++---- {sp1-crates => crates/sp1}/runner/Cargo.toml | 0 {sp1-crates => crates/sp1}/runner/src/main.rs | 0 {sp1-crates => crates/sp1}/rust-toolchain.toml | 0 .../sp1}/stylus-compiler-program/Cargo.toml | 0 .../sp1}/stylus-compiler-program/src/main.rs | 0 36 files changed, 17 insertions(+), 16 deletions(-) rename {sp1-crates => crates/sp1}/.cargo/config.toml (100%) rename {sp1-crates => crates/sp1}/.gitignore (100%) rename {sp1-crates => crates/sp1}/Cargo.lock (100%) rename {sp1-crates => crates/sp1}/Cargo.toml (82%) rename {sp1-crates => crates/sp1}/README.md (99%) rename {sp1-crates => crates/sp1}/brotli_cmake_patch.txt (100%) rename {sp1-crates => crates/sp1}/build.sh (96%) rename {sp1-crates => crates/sp1}/builder/Cargo.toml (100%) rename {sp1-crates => crates/sp1}/builder/build.rs (100%) rename {sp1-crates => crates/sp1}/builder/src/main.rs (100%) rename {sp1-crates => crates/sp1}/program/Cargo.toml (100%) rename {sp1-crates => crates/sp1}/program/src/imports/arbcompress.rs (100%) rename {sp1-crates => crates/sp1}/program/src/imports/debug.rs (100%) rename {sp1-crates => crates/sp1}/program/src/imports/mod.rs (100%) rename {sp1-crates => crates/sp1}/program/src/imports/precompiles.rs (100%) rename {sp1-crates => crates/sp1}/program/src/imports/programs.rs (100%) rename {sp1-crates => crates/sp1}/program/src/imports/vm_hooks.rs (100%) rename {sp1-crates => crates/sp1}/program/src/imports/wasi_stub.rs (100%) rename {sp1-crates => crates/sp1}/program/src/imports/wavmio.rs (100%) rename {sp1-crates => crates/sp1}/program/src/lib.rs (100%) rename {sp1-crates => crates/sp1}/program/src/main.rs (100%) rename {sp1-crates => crates/sp1}/program/src/memory.rs (100%) rename {sp1-crates => crates/sp1}/program/src/platform.rs (100%) rename {sp1-crates => crates/sp1}/program/src/replay.rs (100%) rename {sp1-crates => crates/sp1}/program/src/state.rs (100%) rename {sp1-crates => crates/sp1}/program/src/stylus.rs (100%) rename {sp1-crates => crates/sp1}/prover/Cargo.toml (100%) rename {sp1-crates => crates/sp1}/prover/src/lib.rs (75%) rename {sp1-crates => crates/sp1}/runner/Cargo.toml (100%) rename {sp1-crates => crates/sp1}/runner/src/main.rs (100%) rename {sp1-crates => crates/sp1}/rust-toolchain.toml (100%) rename {sp1-crates => crates/sp1}/stylus-compiler-program/Cargo.toml (100%) rename {sp1-crates => crates/sp1}/stylus-compiler-program/src/main.rs (100%) diff --git a/.github/workflows/zk-proving.yml b/.github/workflows/zk-proving.yml index 71920f9b16f..1fda6fd7ff7 100644 --- a/.github/workflows/zk-proving.yml +++ b/.github/workflows/zk-proving.yml @@ -45,7 +45,7 @@ jobs: rustc +succinct --print target-list | grep succinct - name: Build binaries and record block - run: ./sp1-crates/build.sh + run: ./crates/sp1/build.sh - name: Run validation run: | diff --git a/Cargo.toml b/Cargo.toml index a6ea7b29fc7..aa8e28d0ea6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,6 +25,7 @@ default-members = [ ] exclude = [ "crates/langs", + "crates/sp1", "crates/stylus/tests", "crates/tools", "crates/wasm-testsuite", diff --git a/crates/prover/Cargo.toml b/crates/prover/Cargo.toml index 14f630a2832..6b0e2a0d6af 100644 --- a/crates/prover/Cargo.toml +++ b/crates/prover/Cargo.toml @@ -72,7 +72,7 @@ cc_brotli = ["brotli/cc_brotli"] # The "sp1" feature is never activated in this workspace. It exists only so that # `#[cfg(feature = "sp1")]` gates don't produce warnings. These gates are used -# when sp1-crates/prover includes our source files via #[path] and compiles them +# when crates/sp1/prover includes our source files via #[path] and compiles them # with its own "sp1" feature enabled (under wasmer 6.x / wasmparser 0.224). [lints.rust] unexpected_cfgs = { level = "warn", check-cfg = ['cfg(feature, values("sp1"))'] } diff --git a/sp1-crates/.cargo/config.toml b/crates/sp1/.cargo/config.toml similarity index 100% rename from sp1-crates/.cargo/config.toml rename to crates/sp1/.cargo/config.toml diff --git a/sp1-crates/.gitignore b/crates/sp1/.gitignore similarity index 100% rename from sp1-crates/.gitignore rename to crates/sp1/.gitignore diff --git a/sp1-crates/Cargo.lock b/crates/sp1/Cargo.lock similarity index 100% rename from sp1-crates/Cargo.lock rename to crates/sp1/Cargo.lock diff --git a/sp1-crates/Cargo.toml b/crates/sp1/Cargo.toml similarity index 82% rename from sp1-crates/Cargo.toml rename to crates/sp1/Cargo.toml index 8bb2978922b..6077208295c 100644 --- a/sp1-crates/Cargo.toml +++ b/crates/sp1/Cargo.toml @@ -4,11 +4,11 @@ resolver = "3" members = ["program", "builder", "stylus-compiler-program", "prover", "runner"] [workspace.dependencies] -arbutil = { path = "../crates/arbutil" } -brotli = { path = "../crates/brotli" } -caller-env = { path = "../crates/caller-env", default-features = false } +arbutil = { path = "../arbutil" } +brotli = { path = "../brotli" } +caller-env = { path = "../caller-env", default-features = false } prover = { path = "prover", default-features = false, features = ["sp1"] } -validation = { path = "../crates/validation", default-features = false } +validation = { path = "../validation", default-features = false } bincode = { version = "1.3.3" } bytes = { version = "1" } @@ -45,9 +45,9 @@ wasmparser = { version = "0.245.0" } secp256k1 = { git = "https://github.com/sp1-patches/rust-secp256k1", tag = "patch-0.29.1-sp1-6.0.0", features = ["recovery", "global-context"] } tiny-keccak = { git = "https://github.com/sp1-patches/tiny-keccak", tag = "patch-2.0.2-sp1-6.0.0", features = ["keccak"] } -wasmer = { path = "../crates/tools/wasmer/lib/api", default-features = false, features = ["sys", "compiler", "singlepass", "wasmparser"] } -wasmer-types = { path = "../crates/tools/wasmer/lib/types" } -wasmer-vm = { path = "../crates/tools/wasmer/lib/vm", features = ["force-baremetal"] } +wasmer = { path = "../tools/wasmer/lib/api", default-features = false, features = ["sys", "compiler", "singlepass", "wasmparser"] } +wasmer-types = { path = "../tools/wasmer/lib/types" } +wasmer-vm = { path = "../tools/wasmer/lib/vm", features = ["force-baremetal"] } [patch.crates-io] target-lexicon = { git = "https://github.com/OffchainLabs/target-lexicon", tag = "v0.13.5-sp1" } diff --git a/sp1-crates/README.md b/crates/sp1/README.md similarity index 99% rename from sp1-crates/README.md rename to crates/sp1/README.md index 472a5e3f5c4..b577417b6a0 100644 --- a/sp1-crates/README.md +++ b/crates/sp1/README.md @@ -30,7 +30,7 @@ Now you can start the build process: ```bash $ git clone https://github.com/OffchainLabs/nitro $ # Checkout current PR -$ ./sp1-crates/build.sh +$ ./crates/sp1/build.sh ``` To make things easier to understand, for now we are using a simple bash script. As the code grow more mature, we would merge the bash script into the top-level makefile. diff --git a/sp1-crates/brotli_cmake_patch.txt b/crates/sp1/brotli_cmake_patch.txt similarity index 100% rename from sp1-crates/brotli_cmake_patch.txt rename to crates/sp1/brotli_cmake_patch.txt diff --git a/sp1-crates/build.sh b/crates/sp1/build.sh similarity index 96% rename from sp1-crates/build.sh rename to crates/sp1/build.sh index c61b47a1245..3a08746b6d8 100755 --- a/sp1-crates/build.sh +++ b/crates/sp1/build.sh @@ -3,7 +3,7 @@ set -ex SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" -export TOP=$SCRIPT_DIR/.. +export TOP=$SCRIPT_DIR/../.. cd "$TOP" @@ -18,7 +18,7 @@ if [ ! -d "$HOME/.sp1/riscv" ]; then fi # Build brotli for SP1 -cp sp1-crates/brotli_cmake_patch.txt brotli/CMakeLists.txt +cp crates/sp1/brotli_cmake_patch.txt brotli/CMakeLists.txt rm -rf target/build-sp1/brotli target/lib-sp1 mkdir -p target/build-sp1/brotli cd target/build-sp1/brotli diff --git a/sp1-crates/builder/Cargo.toml b/crates/sp1/builder/Cargo.toml similarity index 100% rename from sp1-crates/builder/Cargo.toml rename to crates/sp1/builder/Cargo.toml diff --git a/sp1-crates/builder/build.rs b/crates/sp1/builder/build.rs similarity index 100% rename from sp1-crates/builder/build.rs rename to crates/sp1/builder/build.rs diff --git a/sp1-crates/builder/src/main.rs b/crates/sp1/builder/src/main.rs similarity index 100% rename from sp1-crates/builder/src/main.rs rename to crates/sp1/builder/src/main.rs diff --git a/sp1-crates/program/Cargo.toml b/crates/sp1/program/Cargo.toml similarity index 100% rename from sp1-crates/program/Cargo.toml rename to crates/sp1/program/Cargo.toml diff --git a/sp1-crates/program/src/imports/arbcompress.rs b/crates/sp1/program/src/imports/arbcompress.rs similarity index 100% rename from sp1-crates/program/src/imports/arbcompress.rs rename to crates/sp1/program/src/imports/arbcompress.rs diff --git a/sp1-crates/program/src/imports/debug.rs b/crates/sp1/program/src/imports/debug.rs similarity index 100% rename from sp1-crates/program/src/imports/debug.rs rename to crates/sp1/program/src/imports/debug.rs diff --git a/sp1-crates/program/src/imports/mod.rs b/crates/sp1/program/src/imports/mod.rs similarity index 100% rename from sp1-crates/program/src/imports/mod.rs rename to crates/sp1/program/src/imports/mod.rs diff --git a/sp1-crates/program/src/imports/precompiles.rs b/crates/sp1/program/src/imports/precompiles.rs similarity index 100% rename from sp1-crates/program/src/imports/precompiles.rs rename to crates/sp1/program/src/imports/precompiles.rs diff --git a/sp1-crates/program/src/imports/programs.rs b/crates/sp1/program/src/imports/programs.rs similarity index 100% rename from sp1-crates/program/src/imports/programs.rs rename to crates/sp1/program/src/imports/programs.rs diff --git a/sp1-crates/program/src/imports/vm_hooks.rs b/crates/sp1/program/src/imports/vm_hooks.rs similarity index 100% rename from sp1-crates/program/src/imports/vm_hooks.rs rename to crates/sp1/program/src/imports/vm_hooks.rs diff --git a/sp1-crates/program/src/imports/wasi_stub.rs b/crates/sp1/program/src/imports/wasi_stub.rs similarity index 100% rename from sp1-crates/program/src/imports/wasi_stub.rs rename to crates/sp1/program/src/imports/wasi_stub.rs diff --git a/sp1-crates/program/src/imports/wavmio.rs b/crates/sp1/program/src/imports/wavmio.rs similarity index 100% rename from sp1-crates/program/src/imports/wavmio.rs rename to crates/sp1/program/src/imports/wavmio.rs diff --git a/sp1-crates/program/src/lib.rs b/crates/sp1/program/src/lib.rs similarity index 100% rename from sp1-crates/program/src/lib.rs rename to crates/sp1/program/src/lib.rs diff --git a/sp1-crates/program/src/main.rs b/crates/sp1/program/src/main.rs similarity index 100% rename from sp1-crates/program/src/main.rs rename to crates/sp1/program/src/main.rs diff --git a/sp1-crates/program/src/memory.rs b/crates/sp1/program/src/memory.rs similarity index 100% rename from sp1-crates/program/src/memory.rs rename to crates/sp1/program/src/memory.rs diff --git a/sp1-crates/program/src/platform.rs b/crates/sp1/program/src/platform.rs similarity index 100% rename from sp1-crates/program/src/platform.rs rename to crates/sp1/program/src/platform.rs diff --git a/sp1-crates/program/src/replay.rs b/crates/sp1/program/src/replay.rs similarity index 100% rename from sp1-crates/program/src/replay.rs rename to crates/sp1/program/src/replay.rs diff --git a/sp1-crates/program/src/state.rs b/crates/sp1/program/src/state.rs similarity index 100% rename from sp1-crates/program/src/state.rs rename to crates/sp1/program/src/state.rs diff --git a/sp1-crates/program/src/stylus.rs b/crates/sp1/program/src/stylus.rs similarity index 100% rename from sp1-crates/program/src/stylus.rs rename to crates/sp1/program/src/stylus.rs diff --git a/sp1-crates/prover/Cargo.toml b/crates/sp1/prover/Cargo.toml similarity index 100% rename from sp1-crates/prover/Cargo.toml rename to crates/sp1/prover/Cargo.toml diff --git a/sp1-crates/prover/src/lib.rs b/crates/sp1/prover/src/lib.rs similarity index 75% rename from sp1-crates/prover/src/lib.rs rename to crates/sp1/prover/src/lib.rs index ec6cc33fef6..6a3b2cd0cd5 100644 --- a/sp1-crates/prover/src/lib.rs +++ b/crates/sp1/prover/src/lib.rs @@ -7,16 +7,16 @@ #![allow(unexpected_cfgs)] #[cfg(feature = "native")] -#[path = "../../../crates/prover/src/binary.rs"] +#[path = "../../../prover/src/binary.rs"] pub mod binary; #[cfg(feature = "native")] -#[path = "../../../crates/prover/src/programs/mod.rs"] +#[path = "../../../prover/src/programs/mod.rs"] pub mod programs; #[cfg(feature = "native")] -#[path = "../../../crates/prover/src/value.rs"] +#[path = "../../../prover/src/value.rs"] pub mod value; #[cfg(feature = "native")] -#[path = "../../../crates/arbutil/src/operator.rs"] +#[path = "../../../arbutil/src/operator.rs"] pub mod operator; diff --git a/sp1-crates/runner/Cargo.toml b/crates/sp1/runner/Cargo.toml similarity index 100% rename from sp1-crates/runner/Cargo.toml rename to crates/sp1/runner/Cargo.toml diff --git a/sp1-crates/runner/src/main.rs b/crates/sp1/runner/src/main.rs similarity index 100% rename from sp1-crates/runner/src/main.rs rename to crates/sp1/runner/src/main.rs diff --git a/sp1-crates/rust-toolchain.toml b/crates/sp1/rust-toolchain.toml similarity index 100% rename from sp1-crates/rust-toolchain.toml rename to crates/sp1/rust-toolchain.toml diff --git a/sp1-crates/stylus-compiler-program/Cargo.toml b/crates/sp1/stylus-compiler-program/Cargo.toml similarity index 100% rename from sp1-crates/stylus-compiler-program/Cargo.toml rename to crates/sp1/stylus-compiler-program/Cargo.toml diff --git a/sp1-crates/stylus-compiler-program/src/main.rs b/crates/sp1/stylus-compiler-program/src/main.rs similarity index 100% rename from sp1-crates/stylus-compiler-program/src/main.rs rename to crates/sp1/stylus-compiler-program/src/main.rs From c3b769ef94030334bf8ecc571370bf8ce372e5e3 Mon Sep 17 00:00:00 2001 From: Igor Braga <5835477+bragaigor@users.noreply.github.com> Date: Tue, 24 Mar 2026 14:21:06 -0400 Subject: [PATCH 134/189] start incorporating sp1-crates into crates Signed-off-by: Igor Braga <5835477+bragaigor@users.noreply.github.com> --- Cargo.lock | 5358 ++++++++--- Cargo.toml | 17 +- crates/brotli/build.rs | 8 +- crates/prover/Cargo.toml | 17 +- crates/prover/src/lib.rs | 48 +- crates/prover/src/machine.rs | 16 +- crates/prover/src/programs/meter.rs | 3 - crates/prover/src/programs/mod.rs | 11 +- crates/prover/src/utils.rs | 19 +- crates/sp1/.cargo/config.toml | 2 - crates/sp1/Cargo.lock | 7839 ----------------- crates/sp1/Cargo.toml | 61 - crates/sp1/README.md | 4 +- crates/sp1/builder/Cargo.toml | 8 +- crates/sp1/program/Cargo.toml | 12 +- crates/sp1/program/src/imports/precompiles.rs | 7 +- crates/sp1/program/src/imports/wasi_stub.rs | 6 +- crates/sp1/program/src/imports/wavmio.rs | 96 +- crates/sp1/program/src/lib.rs | 4 +- crates/sp1/program/src/main.rs | 2 +- crates/sp1/program/src/replay.rs | 2 +- crates/sp1/program/src/state.rs | 18 +- crates/sp1/prover/Cargo.toml | 28 - crates/sp1/prover/src/lib.rs | 22 - crates/sp1/runner/Cargo.toml | 8 +- crates/sp1/runner/src/main.rs | 7 +- crates/sp1/rust-toolchain.toml | 2 - crates/sp1/stylus-compiler-program/Cargo.toml | 6 +- 28 files changed, 4600 insertions(+), 9031 deletions(-) delete mode 100644 crates/sp1/.cargo/config.toml delete mode 100644 crates/sp1/Cargo.lock delete mode 100644 crates/sp1/Cargo.toml delete mode 100644 crates/sp1/prover/Cargo.toml delete mode 100644 crates/sp1/prover/src/lib.rs delete mode 100644 crates/sp1/rust-toolchain.toml diff --git a/Cargo.lock b/Cargo.lock index 90dd9b3c857..fea925ece32 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,17 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "addchain" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e33f6a175ec6a9e0aca777567f9ff7c3deefc255660df887e7fa3585e9801d8" +dependencies = [ + "num-bigint 0.3.3", + "num-integer", + "num-traits", +] + [[package]] name = "addr2line" version = "0.22.0" @@ -23,6 +34,18 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if 1.0.4", + "once_cell", + "version_check", + "zerocopy", +] + [[package]] name = "aho-corasick" version = "1.1.3" @@ -55,7 +78,7 @@ dependencies = [ "c-kzg", "derive_more 2.1.1", "either", - "k256", + "k256 0.13.4 (registry+https://github.com/rust-lang/crates.io-index)", "once_cell", "rand 0.8.5", "secp256k1", @@ -147,21 +170,21 @@ checksum = "de3b431b4e72cd8bd0ec7a50b4be18e73dab74de0dba180eef171055e5d5926e" dependencies = [ "alloy-rlp", "bytes", - "cfg-if 1.0.0", + "cfg-if 1.0.4", "const-hex", "derive_more 2.1.1", "foldhash 0.2.0", "hashbrown 0.16.1", "indexmap 2.13.0", "itoa", - "k256", + "k256 0.13.4 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-asm", "paste", "proptest", "rand 0.9.2", "rapidhash", "ruint", - "rustc-hash", + "rustc-hash 2.1.1", "serde", "sha3", ] @@ -361,7 +384,7 @@ dependencies = [ "fnv", "hex", "num-traits", - "num_enum", + "num_enum 0.7.3", "ruint2", "serde", "siphasher 0.3.11", @@ -380,7 +403,7 @@ dependencies = [ "ark-serialize 0.3.0", "ark-std 0.3.0", "derivative", - "num-bigint", + "num-bigint 0.4.6", "num-traits", "paste", "rustc_version 0.3.3", @@ -400,7 +423,7 @@ dependencies = [ "derivative", "digest 0.10.7", "itertools 0.10.5", - "num-bigint", + "num-bigint 0.4.6", "num-traits", "paste", "rustc_version 0.4.0", @@ -421,7 +444,7 @@ dependencies = [ "digest 0.10.7", "educe", "itertools 0.13.0", - "num-bigint", + "num-bigint 0.4.6", "num-traits", "paste", "zeroize", @@ -463,7 +486,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db2fd794a08ccb318058009eefdf15bcaaaaf6f8161eb3345f907222bac38b20" dependencies = [ - "num-bigint", + "num-bigint 0.4.6", "num-traits", "quote", "syn 1.0.109", @@ -475,7 +498,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" dependencies = [ - "num-bigint", + "num-bigint 0.4.6", "num-traits", "proc-macro2", "quote", @@ -488,7 +511,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09be120733ee33f7693ceaa202ca41accd5653b779563608f1234f78ae07c4b3" dependencies = [ - "num-bigint", + "num-bigint 0.4.6", "num-traits", "proc-macro2", "quote", @@ -513,7 +536,7 @@ checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" dependencies = [ "ark-std 0.4.0", "digest 0.10.7", - "num-bigint", + "num-bigint 0.4.6", ] [[package]] @@ -525,7 +548,7 @@ dependencies = [ "ark-std 0.5.0", "arrayvec", "digest 0.10.7", - "num-bigint", + "num-bigint 0.4.6", ] [[package]] @@ -558,11 +581,70 @@ dependencies = [ "rand 0.8.5", ] +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "async-scoped" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4042078ea593edffc452eef14e99fdb2b120caa4ad9618bcdeabc4a023b98740" +dependencies = [ + "futures", + "pin-project", + "tokio", +] + +[[package]] +name = "async-stream" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "async-trait" +version = "0.1.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "atomic" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "a89cbf775b137e9b968e67227ef7f775587cde3fd31b0d8599dbd0f598a48340" +dependencies = [ + "bytemuck", +] [[package]] name = "atomic-waker" @@ -620,13 +702,40 @@ dependencies = [ "fs_extra", ] +[[package]] +name = "axum" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" +dependencies = [ + "async-trait", + "axum-core 0.4.5", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "itoa", + "matchit 0.7.3", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper", + "tower 0.5.2", + "tower-layer", + "tower-service", +] + [[package]] name = "axum" version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8" dependencies = [ - "axum-core", + "axum-core 0.5.5", "bytes", "form_urlencoded", "futures-util", @@ -636,7 +745,7 @@ dependencies = [ "hyper", "hyper-util", "itoa", - "matchit", + "matchit 0.8.4", "memchr", "mime", "percent-encoding", @@ -647,12 +756,32 @@ dependencies = [ "serde_urlencoded", "sync_wrapper", "tokio", - "tower", + "tower 0.5.2", "tower-layer", "tower-service", "tracing", ] +[[package]] +name = "axum-core" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "rustversion", + "sync_wrapper", + "tower-layer", + "tower-service", +] + [[package]] name = "axum-core" version = "0.5.5" @@ -678,8 +807,8 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9963ff19f40c6102c76756ef0a46004c0d58957d87259fc9208ff8441c12ab96" dependencies = [ - "axum", - "axum-core", + "axum 0.8.8", + "axum-core 0.5.5", "bytes", "futures-util", "headers", @@ -703,11 +832,12 @@ checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" dependencies = [ "addr2line", "cc", - "cfg-if 1.0.0", + "cfg-if 1.0.4", "libc", "miniz_oxide 0.7.4", "object 0.36.2", "rustc-demangle", + "serde", ] [[package]] @@ -716,6 +846,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + [[package]] name = "base64" version = "0.22.1" @@ -747,6 +883,26 @@ dependencies = [ "serde", ] +[[package]] +name = "bindgen" +version = "0.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" +dependencies = [ + "bitflags 2.11.0", + "cexpr", + "clang-sys", + "itertools 0.13.0", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash 1.1.0", + "shlex", + "syn 2.0.117", +] + [[package]] name = "bindgen" version = "0.72.1" @@ -762,7 +918,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "rustc-hash", + "rustc-hash 2.1.1", "shlex", "syn 2.0.117", ] @@ -823,13 +979,47 @@ dependencies = [ "wyz", ] +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "blake2b_simd" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b79834656f71332577234b50bfc009996f7449e0c056884e6a02492ded0ca2f3" +dependencies = [ + "arrayref", + "arrayvec", + "constant_time_eq", +] + +[[package]] +name = "blake3" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2468ef7d57b3fb7e16b576e8377cdbde2320c60e1491e961d11da40fc4f02a2d" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if 1.0.4", + "constant_time_eq", + "cpufeatures", +] + [[package]] name = "block-buffer" version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "generic-array", + "generic-array 0.14.7", ] [[package]] @@ -841,6 +1031,19 @@ dependencies = [ "hybrid-array", ] +[[package]] +name = "bls12_381" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3c196a77437e7cc2fb515ce413a6401291578b5afc8ecb29a3c7ab957f05941" +dependencies = [ + "ff 0.12.1", + "group 0.12.1", + "pairing", + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "blst" version = "0.3.14" @@ -870,7 +1073,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0686c856aa6aac0c4498f936d7d6a02df690f614c03e4d906d1018062b5c5e2c" dependencies = [ "once_cell", - "proc-macro-crate", + "proc-macro-crate 3.3.0", "proc-macro2", "quote", "syn 2.0.117", @@ -882,7 +1085,7 @@ version = "0.1.0" dependencies = [ "cc", "lazy_static", - "num_enum", + "num_enum 0.7.3", "wasmer", ] @@ -924,6 +1127,26 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "bytemuck" +version = "1.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "byteorder" version = "1.5.0" @@ -966,14 +1189,46 @@ version = "0.1.0" dependencies = [ "brotli", "hex", - "k256", + "k256 0.13.4 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.8.5", "rand_pcg", - "spin", + "spin 0.10.0", "tiny-keccak", "wasmer", ] +[[package]] +name = "camino" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e629a66d692cb9ff1a1c664e41771b3dcaf961985a9774c0eb0bd1b51cf60a48" +dependencies = [ + "serde_core", +] + +[[package]] +name = "cargo-platform" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" +dependencies = [ + "camino", + "cargo-platform", + "semver 1.0.27", + "serde", + "serde_json", + "thiserror 1.0.63", +] + [[package]] name = "cast" version = "0.3.0" @@ -1015,9 +1270,9 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cfg_aliases" @@ -1162,13 +1417,32 @@ dependencies = [ "memchr", ] +[[package]] +name = "console" +version = "0.15.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" +dependencies = [ + "encode_unicode", + "libc", + "once_cell", + "unicode-width 0.2.2", + "windows-sys 0.59.0", +] + +[[package]] +name = "const-default" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b396d1f76d455557e1218ec8066ae14bba60b4b36ecd55577ba979f5db7ecaa" + [[package]] name = "const-hex" version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "531185e432bb31db1ecda541e9e7ab21468d4d844ad7505e0546a49b4945d49b" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 1.0.4", "cpufeatures", "proptest", "serde_core", @@ -1186,6 +1460,12 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" +[[package]] +name = "constant_time_eq" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" + [[package]] name = "convert_case" version = "0.4.0" @@ -1230,21 +1510,22 @@ checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "corosensei" version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c54787b605c7df106ceccf798df23da4f2e09918defad66705d1cedf3bb914f" +source = "git+https://github.com/OffchainLabs/corosensei?rev=6681138454747733c6adad5037024400f0c9d4e3#6681138454747733c6adad5037024400f0c9d4e3" dependencies = [ "autocfg", - "cfg-if 1.0.0", + "cfg-if 1.0.4", "libc", "scopeguard", + "sp1-primitives 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sp1-zkvm", "windows-sys 0.59.0", ] [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" dependencies = [ "libc", ] @@ -1305,7 +1586,7 @@ dependencies = [ "libm", "log", "regalloc2", - "rustc-hash", + "rustc-hash 2.1.1", "serde", "smallvec", "target-lexicon", @@ -1394,7 +1675,7 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 1.0.4", ] [[package]] @@ -1433,6 +1714,25 @@ dependencies = [ "itertools 0.10.5", ] +[[package]] +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" + +[[package]] +name = "crossbeam" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-epoch", + "crossbeam-queue", + "crossbeam-utils", +] + [[package]] name = "crossbeam-channel" version = "0.5.15" @@ -1488,7 +1788,7 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ - "generic-array", + "generic-array 0.14.7", "rand_core 0.6.4", "subtle", "zeroize", @@ -1500,7 +1800,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "generic-array", + "generic-array 0.14.7", "typenum", ] @@ -1590,7 +1890,7 @@ version = "6.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 1.0.4", "crossbeam-utils", "hashbrown 0.14.5", "lock_api", @@ -1599,56 +1899,196 @@ dependencies = [ ] [[package]] -name = "der" -version = "0.7.10" +name = "dashu" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +checksum = "85b3e5ac1e23ff1995ef05b912e2b012a8784506987a2651552db2c73fb3d7e0" dependencies = [ - "const-oid 0.9.6", - "zeroize", + "dashu-base", + "dashu-float", + "dashu-int", + "dashu-macros", + "dashu-ratio", + "rustversion", ] [[package]] -name = "deranged" -version = "0.5.5" +name = "dashu-base" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" +checksum = "c0b80bf6b85aa68c58ffea2ddb040109943049ce3fbdf4385d0380aef08ef289" + +[[package]] +name = "dashu-float" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85078445a8dbd2e1bd21f04a816f352db8d333643f0c9b78ca7c3d1df71063e7" dependencies = [ - "powerfmt", - "serde_core", + "dashu-base", + "dashu-int", + "num-modular", + "num-order", + "rustversion", + "static_assertions", ] [[package]] -name = "derivative" -version = "2.2.0" +name = "dashu-int" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +checksum = "ee99d08031ca34a4d044efbbb21dff9b8c54bb9d8c82a189187c0651ffdb9fbf" dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", + "cfg-if 1.0.4", + "dashu-base", + "num-modular", + "num-order", + "rustversion", + "static_assertions", ] [[package]] -name = "derive_more" -version = "0.99.18" +name = "dashu-macros" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" +checksum = "93381c3ef6366766f6e9ed9cf09e4ef9dec69499baf04f0c60e70d653cf0ab10" dependencies = [ - "convert_case 0.4.0", + "dashu-base", + "dashu-float", + "dashu-int", + "dashu-ratio", + "paste", + "proc-macro2", + "quote", + "rustversion", +] + +[[package]] +name = "dashu-ratio" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47e33b04dd7ce1ccf8a02a69d3419e354f2bbfdf4eb911a0b7465487248764c9" +dependencies = [ + "dashu-base", + "dashu-float", + "dashu-int", + "num-modular", + "num-order", + "rustversion", +] + +[[package]] +name = "debugid" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d" +dependencies = [ + "uuid", +] + +[[package]] +name = "deepsize2" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b5184084af9beed35eecbf4c36baf6e26b9dc47b61b74e02f930c72a58e71b" +dependencies = [ + "deepsize_derive2", + "hashbrown 0.14.5", +] + +[[package]] +name = "deepsize_derive2" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0f8817865cacf3b93b943ca06b0fc5fd8e99eabfdb7ea5d296efcbc4afc4f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid 0.9.6", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "deranged" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" +dependencies = [ + "powerfmt", + "serde_core", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive-where" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d08b3a0bcc0d079199cd476b2cae8435016ec11d1c0986c6901c5ac223041534" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "derive_more" +version = "0.99.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" +dependencies = [ + "convert_case 0.4.0", "proc-macro2", "quote", "rustc_version 0.4.0", "syn 2.0.117", ] +[[package]] +name = "derive_more" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" +dependencies = [ + "derive_more-impl 1.0.0", +] + [[package]] name = "derive_more" version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" dependencies = [ - "derive_more-impl", + "derive_more-impl 2.1.1", +] + +[[package]] +name = "derive_more-impl" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", ] [[package]] @@ -1671,7 +2111,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "generic-array", + "generic-array 0.14.7", ] [[package]] @@ -1697,6 +2137,27 @@ dependencies = [ "crypto-common 0.2.1", ] +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + [[package]] name = "displaydoc" version = "0.2.5" @@ -1708,12 +2169,47 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + +[[package]] +name = "downloader" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ac1e888d6830712d565b2f3a974be3200be9296bc1b03db8251a4cbf18a4a34" +dependencies = [ + "digest 0.10.7", + "futures", + "rand 0.8.5", + "reqwest 0.12.28", + "thiserror 1.0.63", + "tokio", +] + [[package]] name = "dunce" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" +[[package]] +name = "dynasm" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7d4c414c94bc830797115b8e5f434d58e7e80cb42ba88508c14bc6ea270625" +dependencies = [ + "bitflags 2.11.0", + "byteorder", + "lazy_static", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "dynasm" version = "5.0.0" @@ -1729,6 +2225,18 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "dynasmrt" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "602f7458a3859195fb840e6e0cce5f4330dd9dfbfece0edaf31fe427af346f55" +dependencies = [ + "byteorder", + "dynasm 3.2.1", + "fnv", + "memmap2 0.9.10", +] + [[package]] name = "dynasmrt" version = "5.0.0" @@ -1736,7 +2244,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b38e5331d851567729d892ed28d898d22f49a96940b29e23b5c3e681bd30ffb3" dependencies = [ "byteorder", - "dynasm", + "dynasm 5.0.0", "fnv", "memmap2 0.9.10", ] @@ -1750,12 +2258,25 @@ dependencies = [ "der", "digest 0.10.7", "elliptic-curve", - "rfc6979", + "rfc6979 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "serdect", "signature", "spki", ] +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "git+https://github.com/sp1-patches/signatures?tag=sp1-skip-verify-on-recovery#1880299a48fe7ef249edaa616fd411239fb5daf1" +dependencies = [ + "der", + "digest 0.10.7", + "elliptic-curve", + "rfc6979 0.4.0 (git+https://github.com/sp1-patches/signatures?tag=sp1-skip-verify-on-recovery)", + "signature", + "spki", +] + [[package]] name = "educe" version = "0.6.0" @@ -1777,6 +2298,12 @@ dependencies = [ "serde", ] +[[package]] +name = "elf" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4445909572dbd556c457c849c4ca58623d84b27c8fff1e74b0b4227d8b90d17b" + [[package]] name = "elliptic-curve" version = "0.13.8" @@ -1786,9 +2313,11 @@ dependencies = [ "base16ct", "crypto-bigint", "digest 0.10.7", - "ff", - "generic-array", - "group", + "ff 0.13.1", + "generic-array 0.14.7", + "group 0.13.0", + "hkdf", + "pem-rfc7468", "pkcs8", "rand_core 0.6.4", "sec1", @@ -1797,13 +2326,31 @@ dependencies = [ "zeroize", ] +[[package]] +name = "embedded-alloc" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f2de9133f68db0d4627ad69db767726c99ff8585272716708227008d3f1bddd" +dependencies = [ + "const-default", + "critical-section", + "linked_list_allocator", + "rlsf", +] + +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" + [[package]] name = "encoding_rs" version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 1.0.4", ] [[package]] @@ -1826,6 +2373,27 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "enum-map" +version = "2.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6866f3bfdf8207509a033af1a75a7b08abda06bbaaeae6669323fd5a097df2e9" +dependencies = [ + "enum-map-derive", + "serde", +] + +[[package]] +name = "enum-map-derive" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "enum-ordinalize" version = "4.3.2" @@ -1893,6 +2461,17 @@ dependencies = [ "version_check", ] +[[package]] +name = "eventsource-stream" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74fef4569247a5f429d9156b9d0a2599914385dd189c539334c625d8099d90ab" +dependencies = [ + "futures-core", + "nom", + "pin-project-lite", +] + [[package]] name = "eyre" version = "0.6.12" @@ -1931,23 +2510,52 @@ dependencies = [ "bytes", ] +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "bitvec", + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "ff" version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" dependencies = [ + "bitvec", + "byteorder", + "ff_derive", "rand_core 0.6.4", "subtle", ] +[[package]] +name = "ff_derive" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f10d12652036b0e99197587c6ba87a8fc3031986499973c030d8b44fcc151b60" +dependencies = [ + "addchain", + "num-bigint 0.3.3", + "num-integer", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "filetime" version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 1.0.4", "libc", "libredox", ] @@ -1970,6 +2578,12 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "fixedbitset" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" + [[package]] name = "flate2" version = "1.1.9" @@ -2027,6 +2641,21 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + [[package]] name = "futures-channel" version = "0.3.31" @@ -2034,6 +2663,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", + "futures-sink", ] [[package]] @@ -2042,6 +2672,34 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "futures-sink" version = "0.3.31" @@ -2060,12 +2718,41 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ + "futures-channel", "futures-core", + "futures-io", + "futures-macro", + "futures-sink", "futures-task", + "memchr", "pin-project-lite", "pin-utils", + "slab", +] + +[[package]] +name = "gcd" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a" + +[[package]] +name = "gecko_profile" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "890852c7e1e02bc6758e325d6b1e0236e4fbf21b492f585ce4d4715be54b4c6a" +dependencies = [ + "debugid", + "serde", + "serde_json", ] +[[package]] +name = "gen_ops" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "304de19db7028420975a296ab0fcbbc8e69438c4ed254a1e41e2a7f37d5f0e0a" + [[package]] name = "generic-array" version = "0.14.7" @@ -2077,13 +2764,23 @@ dependencies = [ "zeroize", ] +[[package]] +name = "generic-array" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96512db27971c2c3eece70a1e106fbe6c87760234e31e8f7e5634912fe52794a" +dependencies = [ + "serde", + "typenum", +] + [[package]] name = "getrandom" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 1.0.4", "js-sys", "libc", "wasi", @@ -2096,7 +2793,7 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 1.0.4", "js-sys", "libc", "r-efi 5.3.0", @@ -2110,7 +2807,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 1.0.4", "js-sys", "libc", "r-efi 6.0.0", @@ -2154,13 +2851,25 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff 0.12.1", + "memuse", + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "group" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ - "ff", + "ff 0.13.1", "rand_core 0.6.4", "subtle", ] @@ -2190,10 +2899,33 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 1.0.4", "crunchy", ] +[[package]] +name = "halo2" +version = "0.1.0-beta.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a23c779b38253fe1538102da44ad5bd5378495a61d2c4ee18d64eaa61ae5995" +dependencies = [ + "halo2_proofs", +] + +[[package]] +name = "halo2_proofs" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e925780549adee8364c7f2b685c753f6f3df23bde520c67416e93bf615933760" +dependencies = [ + "blake2b_simd", + "ff 0.12.1", + "group 0.12.1", + "pasta_curves 0.4.1", + "rand_core 0.6.4", + "rayon", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -2205,6 +2937,11 @@ name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", + "serde", +] [[package]] name = "hashbrown" @@ -2212,6 +2949,8 @@ version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ + "allocator-api2", + "equivalent", "foldhash 0.1.5", ] @@ -2234,7 +2973,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3314d5adb5d94bcdf56771f2e50dbbc80bb4bdf88967526706205ac9eff24eb" dependencies = [ - "base64", + "base64 0.22.1", "bytes", "headers-core", "http", @@ -2303,6 +3042,15 @@ dependencies = [ "arrayvec", ] +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + [[package]] name = "hmac" version = "0.12.1" @@ -2411,6 +3159,20 @@ dependencies = [ "tokio", "tokio-rustls", "tower-service", + "webpki-roots", +] + +[[package]] +name = "hyper-timeout" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" +dependencies = [ + "hyper", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", ] [[package]] @@ -2419,7 +3181,7 @@ version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f" dependencies = [ - "base64", + "base64 0.22.1", "bytes", "futures-channel", "futures-core", @@ -2431,7 +3193,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2", + "socket2 0.6.1", "system-configuration", "tokio", "tower-service", @@ -2625,6 +3387,19 @@ dependencies = [ "serde_core", ] +[[package]] +name = "indicatif" +version = "0.17.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "183b3088984b400f4cfac3620d5e076c84da5364016b4f49473de574b2586235" +dependencies = [ + "console", + "number_prefix", + "portable-atomic", + "unicode-width 0.2.2", + "web-time", +] + [[package]] name = "inkwell" version = "0.8.0" @@ -2691,6 +3466,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 = "itertools" version = "0.13.0" @@ -2746,7 +3530,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" dependencies = [ "cesu8", - "cfg-if 1.0.0", + "cfg-if 1.0.4", "combine", "jni-sys", "log", @@ -2787,7 +3571,7 @@ version = "9.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a87cc7a48537badeae96744432de36f4be2b4a34a05a5ef32e9dd8a1c169dde" dependencies = [ - "base64", + "base64 0.22.1", "js-sys", "pem", "ring", @@ -2796,18 +3580,48 @@ dependencies = [ "simple_asn1", ] +[[package]] +name = "jubjub" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a575df5f985fe1cd5b2b05664ff6accfc46559032b954529fd225a2168d27b0f" +dependencies = [ + "bitvec", + "bls12_381", + "ff 0.12.1", + "group 0.12.1", + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "k256" version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" dependencies = [ - "cfg-if 1.0.0", - "ecdsa", + "cfg-if 1.0.4", + "ecdsa 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", "elliptic-curve", "once_cell", "serdect", "sha2 0.10.9", + "signature", +] + +[[package]] +name = "k256" +version = "0.13.4" +source = "git+https://github.com/sp1-patches/elliptic-curves?tag=patch-k256-13.4-sp1-6.0.0#0efe186cee5930a0d23501651c226bd81fcc2c15" +dependencies = [ + "cfg-if 1.0.4", + "ecdsa 0.16.9 (git+https://github.com/sp1-patches/signatures?tag=sp1-skip-verify-on-recovery)", + "elliptic-curve", + "hex", + "once_cell", + "sha2 0.10.9", + "signature", + "sp1-lib 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2834,6 +3648,9 @@ name = "lazy_static" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin 0.9.8", +] [[package]] name = "leb128" @@ -2859,7 +3676,7 @@ version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 1.0.4", "windows-link", ] @@ -2887,6 +3704,12 @@ version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c6639b70a7ce854b79c70d7e83f16b5dc0137cc914f3d7d03803b513ecc67ac" +[[package]] +name = "linked_list_allocator" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afa463f5405ee81cdb9cc2baf37e08ec7e4c8209442b5d72c04cfb2cd6e6286" + [[package]] name = "linux-raw-sys" version = "0.11.0" @@ -2910,7 +3733,7 @@ dependencies = [ "lazy_static", "libc", "regex-lite", - "semver 1.0.23", + "semver 1.0.27", ] [[package]] @@ -2929,6 +3752,15 @@ version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +[[package]] +name = "lru" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" +dependencies = [ + "hashbrown 0.15.5", +] + [[package]] name = "lru" version = "0.16.3" @@ -2979,18 +3811,43 @@ dependencies = [ "regex-automata", ] +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + [[package]] name = "matchit" version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if 1.0.4", + "digest 0.10.7", +] + [[package]] name = "memchr" version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "memfd" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad38eb12aea514a0466ea40a80fd8cc83637065948eb4a426e4aa46261175227" +dependencies = [ + "rustix", +] + [[package]] name = "memmap2" version = "0.6.2" @@ -3024,6 +3881,12 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" +[[package]] +name = "memuse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d97bbf43eb4f088f8ca469930cde17fa036207c9a5e02ccc5107c4e8b17c964" + [[package]] name = "mime" version = "0.3.17" @@ -3072,6 +3935,22 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fafa6961cabd9c63bcd77a45d7e3b7f3b552b70417831fb0f56db717e72407e" +[[package]] +name = "mti" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9563a7d5556636e74bbd8773241fbcbc5c89b9f6bfdc97b29b56e740c2c74b9" +dependencies = [ + "typeid_prefix", + "typeid_suffix", +] + +[[package]] +name = "multimap" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084" + [[package]] name = "munge" version = "0.4.7" @@ -3102,6 +3981,15 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "ntapi" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3b335231dfd352ffb0f8017f3b6027a4917f7df785ea2143d8af2adc66980ae" +dependencies = [ + "winapi", +] + [[package]] name = "nu-ansi-term" version = "0.50.3" @@ -3117,7 +4005,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" dependencies = [ - "num-bigint", + "num-bigint 0.4.6", "num-complex", "num-integer", "num-iter", @@ -3125,6 +4013,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-bigint" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6f7833f2cbf2360a6cfd58cd41a53aa7a90bd4c202f5b1c7dd2ed73c57b2c3" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-bigint" version = "0.4.6" @@ -3181,13 +4080,28 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-modular" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17bb261bf36fa7d83f4c294f834e91256769097b3cb505d44831e0a179ac647f" + +[[package]] +name = "num-order" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "537b596b97c40fcf8056d153049eb22f481c17ebce72a513ec9286e4986d1bb6" +dependencies = [ + "num-modular", +] + [[package]] name = "num-rational" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" dependencies = [ - "num-bigint", + "num-bigint 0.4.6", "num-integer", "num-traits", ] @@ -3212,13 +4126,34 @@ dependencies = [ "libc", ] +[[package]] +name = "num_enum" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +dependencies = [ + "num_enum_derive 0.5.11", +] + [[package]] name = "num_enum" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" dependencies = [ - "num_enum_derive", + "num_enum_derive 0.7.3", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] @@ -3227,12 +4162,18 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 3.3.0", "proc-macro2", "quote", "syn 2.0.117", ] +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + [[package]] name = "nybbles" version = "0.4.8" @@ -3240,7 +4181,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d49ff0c0d00d4a502b39df9af3a525e1efeb14b9dabb5bb83335284c1309210" dependencies = [ "alloy-rlp", - "cfg-if 1.0.0", + "cfg-if 1.0.4", "proptest", "ruint", "serde", @@ -3256,6 +4197,20 @@ dependencies = [ "memchr", ] +[[package]] +name = "object" +version = "0.37.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" +dependencies = [ + "crc32fast", + "flate2", + "hashbrown 0.15.5", + "indexmap 2.13.0", + "memchr", + "ruzstd", +] + [[package]] name = "object" version = "0.38.1" @@ -3289,1388 +4244,3463 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" [[package]] -name = "parity-scale-codec" -version = "3.6.12" +name = "opentelemetry" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" +checksum = "1b69a91d4893e713e06f724597ad630f1fa76057a5e1026c0ca67054a9032a76" dependencies = [ - "arrayvec", - "bitvec", - "byte-slice-cast", - "impl-trait-for-tuples", - "parity-scale-codec-derive", - "serde", + "futures-core", + "futures-sink", + "js-sys", + "once_cell", + "pin-project-lite", + "thiserror 1.0.63", ] [[package]] -name = "parity-scale-codec-derive" -version = "3.6.12" +name = "option-ext" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 1.0.109", -] +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] -name = "parking_lot" -version = "0.12.3" +name = "p256" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" dependencies = [ - "lock_api", - "parking_lot_core", + "ecdsa 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", + "elliptic-curve", + "primeorder", + "sha2 0.10.9", ] [[package]] -name = "parking_lot_core" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +name = "p3-air" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" dependencies = [ - "cfg-if 1.0.0", - "libc", - "redox_syscall 0.5.3", - "smallvec", - "windows-targets 0.52.6", + "p3-field 0.1.0", + "p3-matrix 0.1.0", + "serde", ] [[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +name = "p3-baby-bear" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" +dependencies = [ + "num-bigint 0.4.6", + "p3-field 0.1.0", + "p3-mds 0.1.0", + "p3-poseidon2 0.1.0", + "p3-symmetric 0.1.0", + "rand 0.8.5", + "serde", +] [[package]] -name = "pem" -version = "3.0.6" +name = "p3-baby-bear" +version = "0.2.3-succinct" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be" +checksum = "7521838ecab2ddf4f7bc4ceebad06ec02414729598485c1ada516c39900820e8" dependencies = [ - "base64", - "serde_core", + "num-bigint 0.4.6", + "p3-field 0.2.3-succinct", + "p3-mds 0.2.3-succinct", + "p3-poseidon2 0.2.3-succinct", + "p3-symmetric 0.2.3-succinct", + "rand 0.8.5", + "serde", ] [[package]] -name = "percent-encoding" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" +name = "p3-bn254-fr" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" +dependencies = [ + "ff 0.13.1", + "num-bigint 0.4.6", + "p3-field 0.1.0", + "p3-poseidon2 0.1.0", + "p3-symmetric 0.1.0", + "rand 0.8.5", + "serde", +] [[package]] -name = "pest" -version = "2.8.6" +name = "p3-bn254-fr" +version = "0.3.1-succinct" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0848c601009d37dfa3430c4666e147e49cdcf1b92ecd3e63657d8a5f19da662" +checksum = "ebf15b2e55afdfc5ef84bb0a2508a96a924f3d86b8b616053ee727293a02121d" dependencies = [ - "memchr", - "ucd-trie", + "ff 0.13.1", + "num-bigint 0.4.6", + "p3-field 0.3.1-succinct", + "p3-poseidon2 0.3.1-succinct", + "p3-symmetric 0.3.1-succinct", + "rand 0.8.5", + "serde", ] [[package]] -name = "phf" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" +name = "p3-challenger" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" dependencies = [ - "phf_macros", - "phf_shared", + "p3-field 0.1.0", + "p3-maybe-rayon 0.1.0", + "p3-symmetric 0.1.0", + "p3-util 0.1.0", "serde", + "tracing", ] [[package]] -name = "phf_generator" -version = "0.13.1" +name = "p3-challenger" +version = "0.3.1-succinct" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737" +checksum = "16b647fe6cb51bb873d09aab77cecf3afe38bd94284fc14d04d57d52f0d26666" dependencies = [ - "fastrand", - "phf_shared", + "p3-field 0.3.1-succinct", + "p3-maybe-rayon 0.3.1-succinct", + "p3-symmetric 0.3.1-succinct", + "p3-util 0.3.1-succinct", + "serde", + "tracing", ] [[package]] -name = "phf_macros" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef" +name = "p3-commit" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" dependencies = [ - "phf_generator", - "phf_shared", - "proc-macro2", - "quote", - "syn 2.0.117", + "itertools 0.12.1", + "p3-challenger 0.1.0", + "p3-field 0.1.0", + "p3-matrix 0.1.0", + "p3-util 0.1.0", + "serde", ] [[package]] -name = "phf_shared" -version = "0.13.1" +name = "p3-dft" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" +dependencies = [ + "p3-field 0.1.0", + "p3-matrix 0.1.0", + "p3-maybe-rayon 0.1.0", + "p3-util 0.1.0", + "tracing", +] + +[[package]] +name = "p3-dft" +version = "0.2.3-succinct" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266" +checksum = "46414daedd796f1eefcdc1811c0484e4bced5729486b6eaba9521c572c76761a" dependencies = [ - "siphasher 1.0.2", + "p3-field 0.2.3-succinct", + "p3-matrix 0.2.3-succinct", + "p3-maybe-rayon 0.2.3-succinct", + "p3-util 0.2.3-succinct", + "tracing", ] [[package]] -name = "pin-project-lite" -version = "0.2.14" +name = "p3-dft" +version = "0.3.1-succinct" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "8169aac0ed2575c6c44953a7fa162e3dd07f9a22021e36b4db9d8bd15a3373b8" +dependencies = [ + "p3-field 0.3.1-succinct", + "p3-matrix 0.3.1-succinct", + "p3-maybe-rayon 0.3.1-succinct", + "p3-util 0.3.1-succinct", + "tracing", +] [[package]] -name = "pin-utils" +name = "p3-field" version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" +dependencies = [ + "itertools 0.12.1", + "num-bigint 0.4.6", + "num-traits", + "p3-util 0.1.0", + "rand 0.8.5", + "serde", +] [[package]] -name = "pkcs8" -version = "0.10.2" +name = "p3-field" +version = "0.2.3-succinct" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +checksum = "48948a0516b349e9d1cdb95e7236a6ee010c44e68c5cc78b4b92bf1c4022a0d9" dependencies = [ - "der", - "spki", + "itertools 0.12.1", + "num-bigint 0.4.6", + "num-traits", + "p3-util 0.2.3-succinct", + "rand 0.8.5", + "serde", ] [[package]] -name = "pkg-config" -version = "0.3.30" +name = "p3-field" +version = "0.3.1-succinct" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "3f82ed2dfd1e7d6e8759a9605c71b8a2a543069017dfdb6dafe71e7a2ccca937" +dependencies = [ + "itertools 0.12.1", + "num-bigint 0.4.6", + "num-traits", + "p3-util 0.3.1-succinct", + "rand 0.8.5", + "serde", +] [[package]] -name = "plain" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" +name = "p3-fri" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" +dependencies = [ + "itertools 0.12.1", + "p3-challenger 0.1.0", + "p3-commit", + "p3-dft 0.1.0", + "p3-field 0.1.0", + "p3-interpolation", + "p3-matrix 0.1.0", + "p3-maybe-rayon 0.1.0", + "p3-util 0.1.0", + "serde", + "tracing", +] [[package]] -name = "plotters" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15b6eccb8484002195a3e44fe65a4ce8e93a625797a063735536fd59cb01cf3" +name = "p3-interpolation" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" dependencies = [ - "num-traits", - "plotters-backend", - "plotters-svg", - "wasm-bindgen", - "web-sys", + "p3-field 0.1.0", + "p3-matrix 0.1.0", + "p3-util 0.1.0", ] [[package]] -name = "plotters-backend" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "414cec62c6634ae900ea1c56128dfe87cf63e7caece0852ec76aba307cebadb7" +name = "p3-keccak-air" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" +dependencies = [ + "p3-air", + "p3-field 0.1.0", + "p3-matrix 0.1.0", + "p3-maybe-rayon 0.1.0", + "p3-util 0.1.0", + "tracing", +] [[package]] -name = "plotters-svg" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81b30686a7d9c3e010b84284bdd26a29f2138574f52f5eb6f794fc0ad924e705" +name = "p3-koala-bear" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" dependencies = [ - "plotters-backend", + "num-bigint 0.4.6", + "p3-field 0.1.0", + "p3-mds 0.1.0", + "p3-poseidon2 0.1.0", + "p3-symmetric 0.1.0", + "rand 0.8.5", + "serde", ] [[package]] -name = "potential_utf" -version = "0.1.4" +name = "p3-koala-bear" +version = "0.3.1-succinct" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +checksum = "60e2d5bc3601f6115afd9a55a718bdab49e98d44710438008204d2084d5d70d0" dependencies = [ - "zerovec", + "num-bigint 0.4.6", + "p3-field 0.3.1-succinct", + "p3-mds 0.3.1-succinct", + "p3-poseidon2 0.3.1-succinct", + "p3-symmetric 0.3.1-succinct", + "rand 0.8.5", + "serde", ] [[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" +name = "p3-matrix" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" +dependencies = [ + "itertools 0.12.1", + "p3-field 0.1.0", + "p3-maybe-rayon 0.1.0", + "p3-util 0.1.0", + "rand 0.8.5", + "serde", + "tracing", +] [[package]] -name = "ppv-lite86" -version = "0.2.21" +name = "p3-matrix" +version = "0.2.3-succinct" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +checksum = "3e4de3f373589477cb735ea58e125898ed20935e03664b4614c7fac258b3c42f" dependencies = [ - "zerocopy", + "itertools 0.12.1", + "p3-field 0.2.3-succinct", + "p3-maybe-rayon 0.2.3-succinct", + "p3-util 0.2.3-succinct", + "rand 0.8.5", + "serde", + "tracing", ] [[package]] -name = "prettyplease" -version = "0.2.37" +name = "p3-matrix" +version = "0.3.1-succinct" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +checksum = "2ef05490e47c906f102e08493986b1d3c6b6e2c6be9937eaab2c970ccf5385e8" dependencies = [ - "proc-macro2", - "syn 2.0.117", + "itertools 0.12.1", + "p3-field 0.3.1-succinct", + "p3-maybe-rayon 0.3.1-succinct", + "p3-util 0.3.1-succinct", + "rand 0.8.5", + "serde", + "tracing", ] [[package]] -name = "primitive-types" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" +name = "p3-maybe-rayon" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" dependencies = [ - "fixed-hash", - "impl-codec", - "uint", + "rayon", ] [[package]] -name = "proc-macro-crate" -version = "3.3.0" +name = "p3-maybe-rayon" +version = "0.2.3-succinct" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" -dependencies = [ - "toml_edit", +checksum = "c3968ad1160310296eb04f91a5f4edfa38fe1d6b2b8cd6b5c64e6f9b7370979e" + +[[package]] +name = "p3-maybe-rayon" +version = "0.3.1-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d38c20290b92011f12a3fc040a999197e71e1663614998393a24aee4d430da" + +[[package]] +name = "p3-mds" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" +dependencies = [ + "itertools 0.12.1", + "p3-dft 0.1.0", + "p3-field 0.1.0", + "p3-matrix 0.1.0", + "p3-symmetric 0.1.0", + "p3-util 0.1.0", + "rand 0.8.5", ] [[package]] -name = "proc-macro-error" -version = "1.0.4" +name = "p3-mds" +version = "0.2.3-succinct" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +checksum = "2356b1ed0add6d5dfbf7a338ce534a6fde827374394a52cec16a0840af6e97c9" dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", + "itertools 0.12.1", + "p3-dft 0.2.3-succinct", + "p3-field 0.2.3-succinct", + "p3-matrix 0.2.3-succinct", + "p3-symmetric 0.2.3-succinct", + "p3-util 0.2.3-succinct", + "rand 0.8.5", ] [[package]] -name = "proc-macro-error-attr" -version = "1.0.4" +name = "p3-mds" +version = "0.3.1-succinct" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +checksum = "b707ec6432a15661ce67e5fc3abb1c2653e0064030d99c8cece4a049b31ebb1a" dependencies = [ - "proc-macro2", - "quote", - "version_check", + "itertools 0.12.1", + "p3-dft 0.3.1-succinct", + "p3-field 0.3.1-succinct", + "p3-matrix 0.3.1-succinct", + "p3-symmetric 0.3.1-succinct", + "p3-util 0.3.1-succinct", + "rand 0.8.5", ] [[package]] -name = "proc-macro-error-attr2" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +name = "p3-merkle-tree" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" +dependencies = [ + "itertools 0.12.1", + "p3-commit", + "p3-field 0.1.0", + "p3-matrix 0.1.0", + "p3-maybe-rayon 0.1.0", + "p3-symmetric 0.1.0", + "p3-util 0.1.0", + "serde", + "tracing", +] + +[[package]] +name = "p3-poseidon2" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" dependencies = [ - "proc-macro2", - "quote", + "gcd", + "p3-field 0.1.0", + "p3-mds 0.1.0", + "p3-symmetric 0.1.0", + "rand 0.8.5", + "serde", ] [[package]] -name = "proc-macro-error2" -version = "2.0.1" +name = "p3-poseidon2" +version = "0.2.3-succinct" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +checksum = "7da1eec7e1b6900581bedd95e76e1ef4975608dd55be9872c9d257a8a9651c3a" dependencies = [ - "proc-macro-error-attr2", - "proc-macro2", - "quote", - "syn 2.0.117", + "gcd", + "p3-field 0.2.3-succinct", + "p3-mds 0.2.3-succinct", + "p3-symmetric 0.2.3-succinct", + "rand 0.8.5", + "serde", ] [[package]] -name = "proc-macro2" -version = "1.0.106" +name = "p3-poseidon2" +version = "0.3.1-succinct" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +checksum = "f9c6dbf170a3fb4d7556023315a525e08c4b94b572bc307eadbf9065bddaf489" dependencies = [ - "unicode-ident", + "gcd", + "p3-field 0.3.1-succinct", + "p3-mds 0.3.1-succinct", + "p3-symmetric 0.3.1-succinct", + "rand 0.8.5", + "serde", ] [[package]] -name = "program-exec" +name = "p3-symmetric" version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" +dependencies = [ + "itertools 0.12.1", + "p3-field 0.1.0", + "serde", +] [[package]] -name = "proptest" -version = "1.10.0" +name = "p3-symmetric" +version = "0.2.3-succinct" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37566cb3fdacef14c0737f9546df7cfeadbfbc9fef10991038bf5015d0c80532" +checksum = "edb439bea1d822623b41ff4b51e3309e80d13cadf8b86d16ffd5e6efb9fdc360" dependencies = [ - "bit-set", - "bit-vec", - "bitflags 2.11.0", - "num-traits", - "rand 0.9.2", - "rand_chacha 0.9.0", - "rand_xorshift", - "regex-syntax", - "rusty-fork", - "tempfile", - "unarray", + "itertools 0.12.1", + "p3-field 0.2.3-succinct", + "serde", ] [[package]] -name = "prover" -version = "0.1.0" +name = "p3-symmetric" +version = "0.3.1-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7ec3a99c3dc3d55d0e78ef7041e0d90bdfbf03451e4f0bae3f9877af99cabb3" dependencies = [ - "arbutil", - "bincode", - "bitvec", - "brotli", - "c-kzg", - "criterion", - "derivative", - "digest 0.10.7", - "enum-iterator", - "eyre", - "fnv", - "forward", - "hex", - "lazy_static", - "libc", - "lru", - "nom", - "num", - "num-derive", - "num-traits", - "once_cell", - "parking_lot", - "rand 0.8.5", - "rayon", - "rustc-demangle", + "itertools 0.12.1", + "p3-field 0.3.1-succinct", "serde", - "serde_json", - "serde_with", - "sha2 0.10.9", - "sha3", - "smallvec", - "static_assertions", - "structopt", - "validation", - "wasmer", - "wasmer-compiler-singlepass", - "wasmer-types", - "wasmparser 0.245.1", - "wat", ] [[package]] -name = "ptr_meta" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9a0cf95a1196af61d4f1cbdab967179516d9a4a4312af1f31948f8f6224a79" -dependencies = [ - "ptr_meta_derive", +name = "p3-uni-stark" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" +dependencies = [ + "itertools 0.12.1", + "p3-air", + "p3-challenger 0.1.0", + "p3-commit", + "p3-dft 0.1.0", + "p3-field 0.1.0", + "p3-matrix 0.1.0", + "p3-maybe-rayon 0.1.0", + "p3-util 0.1.0", + "serde", + "tracing", ] [[package]] -name = "ptr_meta_derive" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7347867d0a7e1208d93b46767be83e2b8f978c3dad35f775ac8d8847551d6fe1" +name = "p3-util" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", + "serde", ] [[package]] -name = "quick-error" -version = "1.2.3" +name = "p3-util" +version = "0.2.3-succinct" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" +checksum = "b6c2c2010678b9332b563eaa38364915b585c1a94b5ca61e2c7541c087ddda5c" +dependencies = [ + "serde", +] [[package]] -name = "quinn" -version = "0.11.9" +name = "p3-util" +version = "0.3.1-succinct" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +checksum = "712473f2a848b672eee90c3b9cd4bfcd3da042112c53a0dc6b088fc3964538ab" dependencies = [ - "bytes", - "cfg_aliases", - "pin-project-lite", - "quinn-proto", - "quinn-udp", - "rustc-hash", - "rustls", - "socket2", - "thiserror 2.0.18", - "tokio", - "tracing", - "web-time", + "serde", ] [[package]] -name = "quinn-proto" -version = "0.11.14" +name = "pairing" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" +checksum = "135590d8bdba2b31346f9cd1fb2a912329f5135e832a4f422942eb6ead8b6b3b" dependencies = [ - "aws-lc-rs", - "bytes", - "getrandom 0.3.4", - "lru-slab", - "rand 0.9.2", - "ring", - "rustc-hash", - "rustls", - "rustls-pki-types", - "slab", - "thiserror 2.0.18", - "tinyvec", - "tracing", - "web-time", + "group 0.12.1", ] [[package]] -name = "quinn-udp" -version = "0.5.14" +name = "parity-scale-codec" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" +checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" dependencies = [ - "cfg_aliases", - "libc", - "once_cell", - "socket2", - "tracing", - "windows-sys 0.60.2", + "arrayvec", + "bitvec", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "serde", ] [[package]] -name = "quote" -version = "1.0.45" +name = "parity-scale-codec-derive" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" dependencies = [ + "proc-macro-crate 3.3.0", "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] -name = "r-efi" -version = "5.3.0" +name = "parking_lot" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] [[package]] -name = "r-efi" -version = "6.0.0" +name = "parking_lot_core" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if 1.0.4", + "libc", + "redox_syscall 0.5.3", + "smallvec", + "windows-targets 0.52.6", +] [[package]] -name = "radium" -version = "0.7.0" +name = "pasta_curves" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" +checksum = "5cc65faf8e7313b4b1fbaa9f7ca917a0eed499a9663be71477f87993604341d8" +dependencies = [ + "blake2b_simd", + "ff 0.12.1", + "group 0.12.1", + "lazy_static", + "rand 0.8.5", + "static_assertions", + "subtle", +] [[package]] -name = "rancor" -version = "0.1.1" +name = "pasta_curves" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a063ea72381527c2a0561da9c80000ef822bdd7c3241b1cc1b12100e3df081ee" +checksum = "d3e57598f73cc7e1b2ac63c79c517b31a0877cd7c402cdcaa311b5208de7a095" dependencies = [ - "ptr_meta", + "blake2b_simd", + "ff 0.13.1", + "group 0.13.0", + "lazy_static", + "rand 0.8.5", + "static_assertions", + "subtle", ] [[package]] -name = "rand" -version = "0.8.5" +name = "paste" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", - "serde", -] +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] -name = "rand" -version = "0.9.2" +name = "pem" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be" dependencies = [ - "rand_chacha 0.9.0", - "rand_core 0.9.5", - "serde", + "base64 0.22.1", + "serde_core", ] [[package]] -name = "rand_chacha" -version = "0.3.1" +name = "pem-rfc7468" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", + "base64ct", ] [[package]] -name = "rand_chacha" -version = "0.9.0" +name = "percent-encoding" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "pest" +version = "2.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0848c601009d37dfa3430c4666e147e49cdcf1b92ecd3e63657d8a5f19da662" dependencies = [ - "ppv-lite86", - "rand_core 0.9.5", + "memchr", + "ucd-trie", ] [[package]] -name = "rand_core" -version = "0.6.4" +name = "petgraph" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" dependencies = [ - "getrandom 0.2.15", + "fixedbitset", + "indexmap 2.13.0", ] [[package]] -name = "rand_core" -version = "0.9.5" +name = "phf" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" dependencies = [ - "getrandom 0.3.4", + "phf_macros", + "phf_shared", "serde", ] [[package]] -name = "rand_pcg" -version = "0.3.1" +name = "phf_generator" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59cad018caf63deb318e5a4586d99a24424a364f40f1e5778c29aca23f4fc73e" +checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737" dependencies = [ - "rand_core 0.6.4", + "fastrand", + "phf_shared", ] [[package]] -name = "rand_xorshift" -version = "0.4.0" +name = "phf_macros" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" +checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef" dependencies = [ - "rand_core 0.9.5", + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn 2.0.117", ] [[package]] -name = "rangemap" -version = "1.7.1" +name = "phf_shared" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "973443cf09a9c8656b574a866ab68dfa19f0867d0340648c7d2f6a71b8a8ea68" +checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266" +dependencies = [ + "siphasher 1.0.2", +] [[package]] -name = "rapidhash" -version = "4.4.1" +name = "pin-project" +version = "1.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e48930979c155e2f33aa36ab3119b5ee81332beb6482199a8ecd6029b80b59" +checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517" dependencies = [ - "rustversion", + "pin-project-internal", ] [[package]] -name = "rayon" -version = "1.10.0" +name = "pin-project-internal" +version = "1.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6" dependencies = [ - "either", - "rayon-core", + "proc-macro2", + "quote", + "syn 2.0.117", ] [[package]] -name = "rayon-core" -version = "1.12.1" +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "plain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" + +[[package]] +name = "plotters" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a15b6eccb8484002195a3e44fe65a4ce8e93a625797a063735536fd59cb01cf3" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "414cec62c6634ae900ea1c56128dfe87cf63e7caece0852ec76aba307cebadb7" + +[[package]] +name = "plotters-svg" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81b30686a7d9c3e010b84284bdd26a29f2138574f52f5eb6f794fc0ad924e705" +dependencies = [ + "plotters-backend", +] + +[[package]] +name = "portable-atomic" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" + +[[package]] +name = "potential_utf" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +dependencies = [ + "zerovec", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn 2.0.117", +] + +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + +[[package]] +name = "primitive-types" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" +dependencies = [ + "fixed-hash", + "impl-codec", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit 0.19.15", +] + +[[package]] +name = "proc-macro-crate" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" +dependencies = [ + "toml_edit 0.22.27", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "program" +version = "0.1.0" +dependencies = [ + "arbutil", + "bytes", + "caller-env", + "corosensei", + "eyre", + "hex", + "num-traits", + "once_cell", + "prover", + "rand 0.8.5", + "rand_pcg", + "ruint2", + "secp256k1", + "serde_json", + "sp1-zkvm", + "thiserror 1.0.63", + "tiny-keccak", + "validation", + "wasmer", + "wasmer-types", + "wasmer-vm", +] + +[[package]] +name = "program-exec" +version = "0.1.0" + +[[package]] +name = "proptest" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37566cb3fdacef14c0737f9546df7cfeadbfbc9fef10991038bf5015d0c80532" +dependencies = [ + "bit-set", + "bit-vec", + "bitflags 2.11.0", + "num-traits", + "rand 0.9.2", + "rand_chacha 0.9.0", + "rand_xorshift", + "regex-syntax", + "rusty-fork", + "tempfile", + "unarray", +] + +[[package]] +name = "prost" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be769465445e8c1474e9c5dac2018218498557af32d9ed057325ec9a41ae81bf" +dependencies = [ + "heck 0.5.0", + "itertools 0.14.0", + "log", + "multimap", + "once_cell", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "regex", + "syn 2.0.117", + "tempfile", +] + +[[package]] +name = "prost-derive" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" +dependencies = [ + "anyhow", + "itertools 0.14.0", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "prost-types" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52c2c1bf36ddb1a1c396b3601a3cec27c2462e45f07c386894ec3ccf5332bd16" +dependencies = [ + "prost", +] + +[[package]] +name = "prover" +version = "0.1.0" +dependencies = [ + "arbutil", + "bincode", + "bitvec", + "brotli", + "c-kzg", + "criterion", + "derivative", + "digest 0.10.7", + "enum-iterator", + "eyre", + "fnv", + "forward", + "hex", + "lazy_static", + "libc", + "lru 0.16.3", + "nom", + "num", + "num-derive", + "num-traits", + "once_cell", + "parking_lot", + "rand 0.8.5", + "rayon", + "rustc-demangle", + "serde", + "serde_json", + "serde_with", + "sha2 0.10.9", + "sha3", + "smallvec", + "static_assertions", + "structopt", + "validation", + "wasmer", + "wasmer-compiler-singlepass", + "wasmer-types", + "wasmparser 0.245.1", + "wat", +] + +[[package]] +name = "ptr_meta" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9a0cf95a1196af61d4f1cbdab967179516d9a4a4312af1f31948f8f6224a79" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7347867d0a7e1208d93b46767be83e2b8f978c3dad35f775ac8d8847551d6fe1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quinn" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +dependencies = [ + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash 2.1.1", + "rustls", + "socket2 0.6.1", + "thiserror 2.0.18", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" +dependencies = [ + "aws-lc-rs", + "bytes", + "getrandom 0.3.4", + "lru-slab", + "rand 0.9.2", + "ring", + "rustc-hash 2.1.1", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.18", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2 0.6.1", + "tracing", + "windows-sys 0.60.2", +] + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rancor" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a063ea72381527c2a0561da9c80000ef822bdd7c3241b1cc1b12100e3df081ee" +dependencies = [ + "ptr_meta", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", + "serde", +] + +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.5", + "serde", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.5", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.15", +] + +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", + "serde", +] + +[[package]] +name = "rand_pcg" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59cad018caf63deb318e5a4586d99a24424a364f40f1e5778c29aca23f4fc73e" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "rand_xorshift" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" +dependencies = [ + "rand_core 0.9.5", +] + +[[package]] +name = "range-set-blaze" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8421b5d459262eabbe49048d362897ff3e3830b44eac6cfe341d6acb2f0f13d2" +dependencies = [ + "gen_ops", + "itertools 0.12.1", + "num-integer", + "num-traits", +] + +[[package]] +name = "rangemap" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "973443cf09a9c8656b574a866ab68dfa19f0867d0340648c7d2f6a71b8a8ea68" + +[[package]] +name = "rapidhash" +version = "4.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e48930979c155e2f33aa36ab3119b5ee81332beb6482199a8ecd6029b80b59" +dependencies = [ + "rustversion", +] + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "rayon-scan" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f87cc11a0140b4b0da0ffc889885760c61b13672d80a908920b2c0df078fa14" +dependencies = [ + "rayon", +] + +[[package]] +name = "redox_syscall" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +dependencies = [ + "bitflags 2.11.0", +] + +[[package]] +name = "redox_syscall" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce70a74e890531977d37e532c34d45e9055d2409ed08ddba14529471ed0be16" +dependencies = [ + "bitflags 2.11.0", +] + +[[package]] +name = "redox_users" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +dependencies = [ + "getrandom 0.2.15", + "libredox", + "thiserror 1.0.63", +] + +[[package]] +name = "regalloc2" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08effbc1fa53aaebff69521a5c05640523fab037b34a4a2c109506bc938246fa" +dependencies = [ + "allocator-api2", + "bumpalo", + "hashbrown 0.15.5", + "log", + "rustc-hash 2.1.1", + "smallvec", +] + +[[package]] +name = "regex" +version = "1.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-lite" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab834c73d247e67f4fae452806d17d3c7501756d98c8808d7c9c7aa7d18f973" + +[[package]] +name = "regex-syntax" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" + +[[package]] +name = "region" +version = "3.0.2" +source = "git+https://github.com/OffchainLabs/region-rs?tag=v3.0.2-sp1#ece52311bd1deff19b48f861ab2abe121b55007e" +dependencies = [ + "bitflags 1.3.2", + "libc", + "mach2 0.4.2", + "sp1-primitives 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sp1-zkvm", + "windows-sys 0.52.0", +] + +[[package]] +name = "rend" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cadadef317c2f20755a64d7fdc48f9e7178ee6b0e1f7fce33fa60f1d68a276e6" +dependencies = [ + "bytecheck", +] + +[[package]] +name = "reqwest" +version = "0.12.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-rustls", + "tokio-util", + "tower 0.5.2", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "webpki-roots", +] + +[[package]] +name = "reqwest" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04e9018c9d814e5f30cc16a0f03271aeab3571e609612d9fe78c1aa8d11c2f62" +dependencies = [ + "base64 0.22.1", + "bytes", + "encoding_rs", + "futures-core", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "js-sys", + "log", + "mime", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-pki-types", + "rustls-platform-verifier", + "sync_wrapper", + "tokio", + "tokio-rustls", + "tower 0.5.2", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "git+https://github.com/sp1-patches/signatures?tag=sp1-skip-verify-on-recovery#1880299a48fe7ef249edaa616fd411239fb5daf1" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if 1.0.4", + "getrandom 0.2.15", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rkyv" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a30e631b7f4a03dee9056b8ef6982e8ba371dd5bedb74d3ec86df4499132c70" +dependencies = [ + "bytecheck", + "bytes", + "hashbrown 0.16.1", + "indexmap 2.13.0", + "munge", + "ptr_meta", + "rancor", + "rend", + "rkyv_derive", + "tinyvec", + "uuid", +] + +[[package]] +name = "rkyv_derive" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8100bb34c0a1d0f907143db3149e6b4eea3c33b9ee8b189720168e818303986f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "rlp" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" +dependencies = [ + "bytes", + "rustc-hex", +] + +[[package]] +name = "rlsf" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1646a59a9734b8b7a0ac51689388a60fe1625d4b956348e9de07591a1478457a" +dependencies = [ + "cfg-if 1.0.4", + "const-default", + "libc", + "rustversion", + "svgbobdoc", +] + +[[package]] +name = "rrs-lib" +version = "0.1.0" +source = "git+https://github.com/succinctlabs/rrs-succinct.git?branch=gautham%2Frv64executor-2#eaca3e8e1785f5b4cf55edfe670c1bf2f52eca77" +dependencies = [ + "downcast-rs", + "num_enum 0.5.11", + "paste", +] + +[[package]] +name = "ruint" +version = "1.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c141e807189ad38a07276942c6623032d3753c8859c146104ac2e4d68865945a" +dependencies = [ + "alloy-rlp", + "ark-ff 0.3.0", + "ark-ff 0.4.2", + "ark-ff 0.5.0", + "bytes", + "fastrlp 0.3.1", + "fastrlp 0.4.0", + "num-bigint 0.4.6", + "num-integer", + "num-traits", + "parity-scale-codec", + "primitive-types", + "proptest", + "rand 0.8.5", + "rand 0.9.2", + "rlp", + "ruint-macro", + "serde_core", + "valuable", + "zeroize", +] + +[[package]] +name = "ruint-macro" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" + +[[package]] +name = "ruint2" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b066b8e4fcea7fae86b6932d2449670b6b5545b7e8407841b2d3a916ff2a9f86" +dependencies = [ + "derive_more 0.99.18", + "ruint2-macro", + "rustc_version 0.4.0", + "thiserror 1.0.63", +] + +[[package]] +name = "ruint2-macro" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89dc553bc0cf4512a8b96caa2e21ed5f6e4b66bf28a1bd08fd9eb07c0b39b28c" + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver 0.11.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver 1.0.27", +] + +[[package]] +name = "rustix" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" +dependencies = [ + "bitflags 2.11.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls" +version = "0.23.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" +dependencies = [ + "aws-lc-rs", + "log", + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-native-certs" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +dependencies = [ + "web-time", + "zeroize", +] + +[[package]] +name = "rustls-platform-verifier" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784" +dependencies = [ + "core-foundation 0.10.1", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls", + "rustls-native-certs", + "rustls-platform-verifier-android", + "rustls-webpki", + "security-framework", + "security-framework-sys", + "webpki-root-certs", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" + +[[package]] +name = "rustls-webpki" +version = "0.103.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" +dependencies = [ + "aws-lc-rs", + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "rusty-fork" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc6bf79ff24e648f6da1f8d1f011e9cac26491b619e6b9280f2b47f1774e6ee2" +dependencies = [ + "fnv", + "quick-error", + "tempfile", + "wait-timeout", +] + +[[package]] +name = "ruzstd" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ff0cc5e135c8870a775d3320910cd9b564ec036b4dc0b8741629020be63f01" +dependencies = [ + "twox-hash", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scale-info" +version = "2.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "346a3b32eba2640d17a9cb5927056b08f3de90f65b72fe09402c2ad07d684d0b" +dependencies = [ + "cfg-if 1.0.4", + "derive_more 1.0.0", + "parity-scale-codec", + "scale-info-derive", +] + +[[package]] +name = "scale-info-derive" +version = "2.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6630024bf739e2179b91fb424b28898baf819414262c5d376677dbff1fe7ebf" +dependencies = [ + "proc-macro-crate 3.3.0", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "scc" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46e6f046b7fef48e2660c57ed794263155d713de679057f2d0c169bfc6e756cc" +dependencies = [ + "sdd", +] + +[[package]] +name = "schannel" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sdd" +version = "3.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490dcfcbfef26be6800d11870ff2df8774fa6e86d047e3e8c8a76b25655e41ca" + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array 0.14.7", + "pkcs8", + "serdect", + "subtle", + "zeroize", +] + +[[package]] +name = "secp256k1" +version = "0.30.0" +source = "git+https://github.com/sp1-patches/rust-secp256k1?tag=patch-0.30.0-sp1-6.0.0#8d8cabe0eff04a80f4b92da0d75c1d8cd3728e9c" +dependencies = [ + "bitcoin_hashes", + "cfg-if 1.0.4", + "k256 0.13.4 (git+https://github.com/sp1-patches/elliptic-curves?tag=patch-k256-13.4-sp1-6.0.0)", + "rand 0.8.5", + "secp256k1-sys", + "serde", +] + +[[package]] +name = "secp256k1-sys" +version = "0.10.0" +source = "git+https://github.com/sp1-patches/rust-secp256k1?tag=patch-0.30.0-sp1-6.0.0#8d8cabe0eff04a80f4b92da0d75c1d8cd3728e9c" +dependencies = [ + "cc", +] + +[[package]] +name = "security-framework" +version = "3.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" +dependencies = [ + "bitflags 2.11.0", + "core-foundation 0.10.1", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "self_cell" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d369a96f978623eb3dc28807c4852d6cc617fed53da5d3c400feff1ef34a714a" + +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +dependencies = [ + "serde", + "serde_core", +] + +[[package]] +name = "semver-parser" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9900206b54a3527fdc7b8a938bffd94a568bac4f4aa8113b209df75a09c0dec2" +dependencies = [ + "pest", +] + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde-wasm-bindgen" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "serde_arrays" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94a16b99c5ea4fe3daccd14853ad260ec00ea043b2708d1fd1da3106dcd8d9df" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "serde_json" +version = "1.0.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_path_to_error" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" +dependencies = [ + "itoa", + "serde", + "serde_core", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ - "crossbeam-deque", - "crossbeam-utils", + "form_urlencoded", + "itoa", + "ryu", + "serde", ] [[package]] -name = "redox_syscall" -version = "0.5.3" +name = "serde_with" +version = "3.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +checksum = "69cecfa94848272156ea67b2b1a53f20fc7bc638c4a46d2f8abde08f05f4b857" dependencies = [ - "bitflags 2.11.0", + "base64 0.22.1", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.13.0", + "serde", + "serde_derive", + "serde_json", + "serde_with_macros", + "time", ] [[package]] -name = "redox_syscall" -version = "0.7.3" +name = "serde_with_macros" +version = "3.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce70a74e890531977d37e532c34d45e9055d2409ed08ddba14529471ed0be16" +checksum = "a8fee4991ef4f274617a51ad4af30519438dacb2f56ac773b08a1922ff743350" dependencies = [ - "bitflags 2.11.0", + "darling 0.20.10", + "proc-macro2", + "quote", + "syn 2.0.117", ] [[package]] -name = "regalloc2" -version = "0.13.5" +name = "serdect" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08effbc1fa53aaebff69521a5c05640523fab037b34a4a2c109506bc938246fa" +checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" dependencies = [ - "allocator-api2", - "bumpalo", - "hashbrown 0.15.5", + "base16ct", + "serde", +] + +[[package]] +name = "serial_test" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "911bd979bf1070a3f3aa7b691a3b3e9968f339ceeec89e08c280a8a22207a32f" +dependencies = [ + "futures-executor", + "futures-util", "log", - "rustc-hash", - "smallvec", + "once_cell", + "parking_lot", + "scc", + "serial_test_derive", ] [[package]] -name = "regex" -version = "1.12.3" +name = "serial_test_derive" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +checksum = "0a7d91949b85b0d2fb687445e448b40d322b6b3e4af6b44a29b21d9a5f33e6d9" dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", + "proc-macro2", + "quote", + "syn 2.0.117", ] [[package]] -name = "regex-automata" -version = "0.4.14" +name = "sha1" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", + "cfg-if 1.0.4", + "cpufeatures", + "digest 0.10.7", ] [[package]] -name = "regex-lite" -version = "0.1.9" +name = "sha1_smol" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cab834c73d247e67f4fae452806d17d3c7501756d98c8808d7c9c7aa7d18f973" +checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" [[package]] -name = "regex-syntax" -version = "0.8.10" +name = "sha2" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if 1.0.4", + "cpufeatures", + "digest 0.10.7", +] [[package]] -name = "region" -version = "3.0.2" +name = "sha2" +version = "0.11.0-rc.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6b6ebd13bc009aef9cd476c1310d49ac354d36e240cf1bd753290f3dc7199a7" +checksum = "7c5f3b1e2dc8aad28310d8410bd4d7e180eca65fca176c52ab00d364475d0024" dependencies = [ - "bitflags 1.3.2", - "libc", - "mach2 0.4.2", - "windows-sys 0.52.0", + "cfg-if 1.0.4", + "cpufeatures", + "digest 0.11.2", ] [[package]] -name = "rend" -version = "0.5.3" +name = "sha3" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cadadef317c2f20755a64d7fdc48f9e7178ee6b0e1f7fce33fa60f1d68a276e6" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ - "bytecheck", + "digest 0.10.7", + "keccak", ] [[package]] -name = "reqwest" -version = "0.13.1" +name = "sha3-asm" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04e9018c9d814e5f30cc16a0f03271aeab3571e609612d9fe78c1aa8d11c2f62" +checksum = "b31139435f327c93c6038ed350ae4588e2c70a13d50599509fee6349967ba35a" dependencies = [ - "base64", - "bytes", - "encoding_rs", - "futures-core", - "h2", - "http", - "http-body", - "http-body-util", - "hyper", - "hyper-rustls", - "hyper-util", - "js-sys", - "log", - "mime", - "percent-encoding", - "pin-project-lite", - "quinn", - "rustls", - "rustls-pki-types", - "rustls-platform-verifier", - "sync_wrapper", - "tokio", - "tokio-rustls", - "tower", - "tower-http", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", + "cc", + "cfg-if 1.0.4", ] [[package]] -name = "rfc6979" -version = "0.4.0" +name = "sharded-slab" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" dependencies = [ - "hmac", - "subtle", + "lazy_static", ] [[package]] -name = "ring" -version = "0.17.14" +name = "shared-buffer" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +checksum = "f6c99835bad52957e7aa241d3975ed17c1e5f8c92026377d117a606f36b84b16" dependencies = [ - "cc", - "cfg-if 1.0.0", - "getrandom 0.2.15", + "bytes", + "memmap2 0.6.2", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +dependencies = [ + "errno", "libc", - "untrusted", - "windows-sys 0.52.0", ] [[package]] -name = "rkyv" -version = "0.8.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a30e631b7f4a03dee9056b8ef6982e8ba371dd5bedb74d3ec86df4499132c70" +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "simd-adler32" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" + +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + +[[package]] +name = "simple_asn1" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d585997b0ac10be3c5ee635f1bab02d512760d14b7c468801ac8a01d9ae5f1d" +dependencies = [ + "num-bigint 0.4.6", + "num-traits", + "thiserror 2.0.18", + "time", +] + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "siphasher" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" + +[[package]] +name = "slab" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" + +[[package]] +name = "slop-air" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "p3-air", +] + +[[package]] +name = "slop-algebra" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c99cdaa39f7db4823cf18938544a135f20bf779eb4b3561652a72ba07ac3c41" +dependencies = [ + "itertools 0.14.0", + "p3-field 0.3.1-succinct", + "serde", +] + +[[package]] +name = "slop-algebra" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "itertools 0.13.0", + "p3-field 0.1.0", + "serde", +] + +[[package]] +name = "slop-alloc" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ - "bytecheck", - "bytes", - "hashbrown 0.16.1", - "indexmap 2.13.0", - "munge", - "ptr_meta", - "rancor", - "rend", - "rkyv_derive", - "tinyvec", - "uuid", + "serde", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "thiserror 1.0.63", ] [[package]] -name = "rkyv_derive" -version = "0.8.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8100bb34c0a1d0f907143db3149e6b4eea3c33b9ee8b189720168e818303986f" +name = "slop-baby-bear" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", + "lazy_static", + "p3-baby-bear 0.1.0", + "serde", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-poseidon2 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", ] [[package]] -name = "rlp" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" +name = "slop-basefold" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ - "bytes", - "rustc-hex", + "derive-where", + "itertools 0.13.0", + "serde", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-alloc", + "slop-baby-bear", + "slop-bn254 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-koala-bear 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-merkle-tree", + "slop-multilinear", + "slop-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-tensor", + "slop-utils", + "thiserror 1.0.63", ] [[package]] -name = "ruint" -version = "1.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c141e807189ad38a07276942c6623032d3753c8859c146104ac2e4d68865945a" +name = "slop-basefold-prover" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ - "alloy-rlp", - "ark-ff 0.3.0", - "ark-ff 0.4.2", - "ark-ff 0.5.0", - "bytes", - "fastrlp 0.3.1", - "fastrlp 0.4.0", - "num-bigint", - "num-integer", - "num-traits", - "parity-scale-codec", - "primitive-types", - "proptest", + "derive-where", + "itertools 0.13.0", "rand 0.8.5", - "rand 0.9.2", - "rlp", - "ruint-macro", - "serde_core", - "valuable", - "zeroize", + "serde", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-alloc", + "slop-baby-bear", + "slop-basefold", + "slop-bn254 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-commit", + "slop-dft", + "slop-fri", + "slop-futures", + "slop-koala-bear 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-merkle-tree", + "slop-multilinear", + "slop-tensor", + "thiserror 1.0.63", + "tokio", ] [[package]] -name = "ruint-macro" -version = "1.2.1" +name = "slop-bn254" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" +checksum = "8ce30d587559808f7a984ea96af231de14f8f793836300347d1ee13d28e194ad" +dependencies = [ + "ff 0.13.1", + "p3-bn254-fr 0.3.1-succinct", + "serde", + "slop-algebra 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slop-challenger 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slop-poseidon2 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slop-symmetric 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "zkhash", +] [[package]] -name = "ruint2" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b066b8e4fcea7fae86b6932d2449670b6b5545b7e8407841b2d3a916ff2a9f86" +name = "slop-bn254" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ - "derive_more 0.99.18", - "ruint2-macro", - "rustc_version 0.4.0", - "thiserror 1.0.63", + "ff 0.13.1", + "p3-bn254-fr 0.1.0", + "serde", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-poseidon2 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "zkhash", ] [[package]] -name = "ruint2-macro" -version = "1.0.3" +name = "slop-challenger" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89dc553bc0cf4512a8b96caa2e21ed5f6e4b66bf28a1bd08fd9eb07c0b39b28c" +checksum = "15fed3b1414bd79c56a21e3ac75c5b549003a0d8f715eb501000d4ac3d7b8a9f" +dependencies = [ + "futures", + "p3-challenger 0.3.1-succinct", + "serde", + "slop-algebra 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slop-symmetric 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +name = "slop-challenger" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "futures", + "p3-challenger 0.1.0", + "serde", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", +] [[package]] -name = "rustc-hash" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" +name = "slop-commit" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "p3-commit", + "serde", + "slop-alloc", +] [[package]] -name = "rustc-hex" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" +name = "slop-dft" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "p3-dft 0.1.0", + "serde", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-alloc", + "slop-matrix", + "slop-tensor", +] [[package]] -name = "rustc_version" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +name = "slop-fri" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ - "semver 0.11.0", + "p3-fri", ] [[package]] -name = "rustc_version" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +name = "slop-futures" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ - "semver 1.0.23", + "crossbeam", + "futures", + "pin-project", + "rayon", + "thiserror 1.0.63", + "tokio", + "tracing", ] [[package]] -name = "rustix" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" +name = "slop-jagged" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ - "bitflags 2.11.0", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.61.2", + "derive-where", + "futures", + "itertools 0.13.0", + "num_cpus", + "rand 0.8.5", + "rayon", + "serde", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-alloc", + "slop-baby-bear", + "slop-basefold", + "slop-basefold-prover", + "slop-bn254 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-commit", + "slop-futures", + "slop-koala-bear 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-merkle-tree", + "slop-multilinear", + "slop-stacked", + "slop-sumcheck", + "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-tensor", + "slop-utils", + "thiserror 1.0.63", + "tokio", + "tracing", ] [[package]] -name = "rustls" -version = "0.23.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" +name = "slop-keccak-air" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ - "aws-lc-rs", - "once_cell", - "rustls-pki-types", - "rustls-webpki", - "subtle", - "zeroize", + "p3-keccak-air", ] [[package]] -name = "rustls-native-certs" -version = "0.8.3" +name = "slop-koala-bear" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" +checksum = "402c403f847e811a788882c7c5ee018ab7076c8bafbf4f46f569fe97f44610d1" dependencies = [ - "openssl-probe", - "rustls-pki-types", - "schannel", - "security-framework", + "lazy_static", + "p3-koala-bear 0.3.1-succinct", + "serde", + "slop-algebra 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slop-challenger 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slop-poseidon2 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slop-symmetric 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "rustls-pki-types" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +name = "slop-koala-bear" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ - "web-time", - "zeroize", + "lazy_static", + "p3-koala-bear 0.1.0", + "serde", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-poseidon2 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", ] [[package]] -name = "rustls-platform-verifier" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784" +name = "slop-matrix" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ - "core-foundation 0.10.1", - "core-foundation-sys", - "jni", - "log", - "once_cell", - "rustls", - "rustls-native-certs", - "rustls-platform-verifier-android", - "rustls-webpki", - "security-framework", - "security-framework-sys", - "webpki-root-certs", - "windows-sys 0.61.2", + "p3-matrix 0.1.0", ] [[package]] -name = "rustls-platform-verifier-android" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" +name = "slop-maybe-rayon" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "p3-maybe-rayon 0.1.0", +] [[package]] -name = "rustls-webpki" -version = "0.103.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" +name = "slop-merkle-tree" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ - "aws-lc-rs", - "ring", - "rustls-pki-types", - "untrusted", + "derive-where", + "ff 0.13.1", + "itertools 0.13.0", + "p3-merkle-tree", + "serde", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-alloc", + "slop-baby-bear", + "slop-bn254 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-commit", + "slop-futures", + "slop-koala-bear 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-matrix", + "slop-poseidon2 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-tensor", + "thiserror 1.0.63", + "tokio", + "zkhash", ] [[package]] -name = "rustversion" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +name = "slop-multilinear" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "derive-where", + "futures", + "num_cpus", + "rand 0.8.5", + "rayon", + "serde", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-alloc", + "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-commit", + "slop-futures", + "slop-matrix", + "slop-tensor", + "tokio", +] [[package]] -name = "rusty-fork" -version = "0.3.1" +name = "slop-poseidon2" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6bf79ff24e648f6da1f8d1f011e9cac26491b619e6b9280f2b47f1774e6ee2" +checksum = "9bc5ba869130dd0711cf7bd54f93785cd566b5c71201f38801fa3f500d508cc4" dependencies = [ - "fnv", - "quick-error", - "tempfile", - "wait-timeout", + "p3-poseidon2 0.3.1-succinct", ] [[package]] -name = "ruzstd" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ff0cc5e135c8870a775d3320910cd9b564ec036b4dc0b8741629020be63f01" +name = "slop-poseidon2" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ - "twox-hash", + "p3-poseidon2 0.1.0", ] [[package]] -name = "ryu" -version = "1.0.18" +name = "slop-primitives" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "786111f9498e8d465b39cfef062297ef4e9b688f250a39abdafaca08e772b56c" +dependencies = [ + "slop-algebra 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +name = "slop-primitives" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", +] + +[[package]] +name = "slop-stacked" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ - "winapi-util", + "derive-where", + "futures", + "itertools 0.13.0", + "serde", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-alloc", + "slop-basefold", + "slop-basefold-prover", + "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-commit", + "slop-futures", + "slop-merkle-tree", + "slop-multilinear", + "slop-tensor", + "thiserror 1.0.63", + "tokio", ] [[package]] -name = "schannel" -version = "0.1.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" +name = "slop-sumcheck" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ - "windows-sys 0.61.2", + "futures", + "itertools 0.13.0", + "rayon", + "serde", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-alloc", + "slop-baby-bear", + "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-multilinear", + "thiserror 1.0.63", ] [[package]] -name = "scopeguard" -version = "1.2.0" +name = "slop-symmetric" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +checksum = "c41115c944fdb8eec425d4515cbc1649852ab4ddcc6be67a069c8d2aa5205209" +dependencies = [ + "p3-symmetric 0.3.1-succinct", +] [[package]] -name = "sec1" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +name = "slop-symmetric" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ - "base16ct", - "der", - "generic-array", - "pkcs8", - "serdect", - "subtle", - "zeroize", + "p3-symmetric 0.1.0", ] [[package]] -name = "secp256k1" -version = "0.30.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b50c5943d326858130af85e049f2661ba3c78b26589b8ab98e65e80ae44a1252" +name = "slop-tensor" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ - "bitcoin_hashes", + "arrayvec", + "derive-where", + "itertools 0.13.0", "rand 0.8.5", - "secp256k1-sys", + "rayon", "serde", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-alloc", + "slop-futures", + "slop-matrix", + "thiserror 1.0.63", + "tokio", + "transpose", ] [[package]] -name = "secp256k1-sys" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4387882333d3aa8cb20530a17c69a3752e97837832f34f6dccc760e715001d9" +name = "slop-uni-stark" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ - "cc", + "p3-uni-stark", ] [[package]] -name = "security-framework" -version = "3.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" +name = "slop-utils" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ - "bitflags 2.11.0", - "core-foundation 0.10.1", - "core-foundation-sys", - "libc", - "security-framework-sys", + "p3-util 0.1.0", + "tracing-forest", + "tracing-subscriber", ] [[package]] -name = "security-framework-sys" -version = "2.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" +name = "slop-whir" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ - "core-foundation-sys", - "libc", + "derive-where", + "futures", + "itertools 0.13.0", + "rand 0.8.5", + "rayon", + "serde", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-alloc", + "slop-baby-bear", + "slop-basefold", + "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-commit", + "slop-dft", + "slop-jagged", + "slop-koala-bear 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-matrix", + "slop-merkle-tree", + "slop-multilinear", + "slop-stacked", + "slop-tensor", + "slop-utils", + "thiserror 1.0.63", ] [[package]] -name = "self_cell" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d369a96f978623eb3dc28807c4852d6cc617fed53da5d3c400feff1ef34a714a" - -[[package]] -name = "semver" -version = "0.11.0" +name = "smallvec" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" dependencies = [ - "semver-parser", + "serde", ] [[package]] -name = "semver" -version = "1.0.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" - -[[package]] -name = "semver-parser" -version = "0.10.3" +name = "snowbridge-amcl" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9900206b54a3527fdc7b8a938bffd94a568bac4f4aa8113b209df75a09c0dec2" +checksum = "460a9ed63cdf03c1b9847e8a12a5f5ba19c4efd5869e4a737e05be25d7c427e5" dependencies = [ - "pest", + "parity-scale-codec", + "scale-info", ] [[package]] -name = "serde" -version = "1.0.228" +name = "socket2" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" dependencies = [ - "serde_core", - "serde_derive", + "libc", + "windows-sys 0.52.0", ] [[package]] -name = "serde-wasm-bindgen" -version = "0.6.5" +name = "socket2" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b" +checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" dependencies = [ - "js-sys", - "serde", - "wasm-bindgen", + "libc", + "windows-sys 0.60.2", ] [[package]] -name = "serde_core" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +name = "sp1-build" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ - "serde_derive", + "anyhow", + "cargo_metadata", + "chrono", + "clap 4.5.53", + "dirs", + "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", ] [[package]] -name = "serde_derive" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +name = "sp1-builder" +version = "0.1.0" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", + "clap 4.5.53", + "serde_json", + "sp1-build", + "sp1-core-executor", + "sp1-sdk", + "wasmer", + "wasmparser 0.245.1", ] [[package]] -name = "serde_json" -version = "1.0.121" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ab380d7d9f22ef3f21ad3e6c1ebe8e4fc7a2000ccba2e4d71fc96f15b2cb609" +name = "sp1-core-executor" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ - "itoa", - "memchr", - "ryu", + "bincode", + "bytemuck", + "cfg-if 1.0.4", + "clap 4.5.53", + "deepsize2", + "elf", + "enum-map", + "eyre", + "gecko_profile", + "hashbrown 0.14.5", + "hex", + "indicatif", + "itertools 0.13.0", + "memmap2 0.9.10", + "num", + "object 0.37.3", + "rrs-lib", + "rustc-demangle", "serde", + "serde_arrays", + "serde_json", + "slop-air", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-maybe-rayon", + "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "sp1-curves", + "sp1-hypercube", + "sp1-jit", + "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "strum", + "subenum", + "thiserror 1.0.63", + "tiny-keccak", + "tracing", + "typenum", + "vec_map", ] [[package]] -name = "serde_path_to_error" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" +name = "sp1-core-machine" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ - "itoa", + "bincode", + "cfg-if 1.0.4", + "enum-map", + "futures", + "generic-array 1.1.0", + "hashbrown 0.14.5", + "itertools 0.13.0", + "num", + "num_cpus", + "rayon", + "rayon-scan", + "rrs-lib", "serde", - "serde_core", + "serde_json", + "slop-air", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-futures", + "slop-keccak-air", + "slop-matrix", + "slop-maybe-rayon", + "slop-uni-stark", + "snowbridge-amcl", + "sp1-core-executor", + "sp1-curves", + "sp1-derive", + "sp1-hypercube", + "sp1-jit", + "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "static_assertions", + "strum", + "sysinfo", + "tempfile", + "thiserror 1.0.63", + "tokio", + "tracing", + "tracing-forest", + "tracing-subscriber", + "typenum", ] [[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +name = "sp1-cuda" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ - "form_urlencoded", - "itoa", - "ryu", + "bincode", + "bytes", + "reqwest 0.12.28", + "semver 1.0.27", "serde", + "serde_json", + "sp1-core-executor", + "sp1-core-machine", + "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "sp1-prover", + "sp1-prover-types", + "thiserror 1.0.63", + "tokio", + "tracing", ] [[package]] -name = "serde_with" -version = "3.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cecfa94848272156ea67b2b1a53f20fc7bc638c4a46d2f8abde08f05f4b857" +name = "sp1-curves" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ - "base64", - "chrono", - "hex", - "indexmap 1.9.3", - "indexmap 2.13.0", + "cfg-if 1.0.4", + "dashu", + "elliptic-curve", + "generic-array 1.1.0", + "itertools 0.13.0", + "k256 0.13.4 (registry+https://github.com/rust-lang/crates.io-index)", + "num", + "p256", "serde", - "serde_derive", - "serde_json", - "serde_with_macros", - "time", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "snowbridge-amcl", + "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "typenum", ] [[package]] -name = "serde_with_macros" -version = "3.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8fee4991ef4f274617a51ad4af30519438dacb2f56ac773b08a1922ff743350" +name = "sp1-derive" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ - "darling 0.20.10", "proc-macro2", "quote", - "syn 2.0.117", + "syn 1.0.109", ] [[package]] -name = "serdect" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" +name = "sp1-hypercube" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ - "base16ct", + "arrayref", + "deepsize2", + "derive-where", + "futures", + "hashbrown 0.14.5", + "itertools 0.13.0", + "num-bigint 0.4.6", + "num-traits", + "num_cpus", + "rayon", + "rayon-scan", "serde", + "slop-air", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-alloc", + "slop-basefold", + "slop-basefold-prover", + "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-commit", + "slop-futures", + "slop-jagged", + "slop-koala-bear 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-matrix", + "slop-merkle-tree", + "slop-multilinear", + "slop-poseidon2 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-stacked", + "slop-sumcheck", + "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-tensor", + "slop-uni-stark", + "slop-whir", + "sp1-derive", + "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "strum", + "thiserror 1.0.63", + "thousands", + "tokio", + "tracing", ] [[package]] -name = "sha1" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +name = "sp1-jit" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ - "cfg-if 1.0.0", - "cpufeatures", - "digest 0.10.7", + "dynasmrt 3.2.1", + "hashbrown 0.14.5", + "memfd", + "memmap2 0.9.10", + "serde", + "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "tracing", + "uuid", ] [[package]] -name = "sha2" -version = "0.10.9" +name = "sp1-lib" +version = "5.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +checksum = "b73b8ff343f2405d5935440e56b7aba5cee6d87303f0051974cbd6f5de502f57" dependencies = [ - "cfg-if 1.0.0", - "cpufeatures", - "digest 0.10.7", + "bincode", + "elliptic-curve", + "serde", + "sp1-primitives 5.2.4", ] [[package]] -name = "sha2" -version = "0.11.0-rc.5" +name = "sp1-lib" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c5f3b1e2dc8aad28310d8410bd4d7e180eca65fca176c52ab00d364475d0024" +checksum = "53f179ca7ad5d0d0ca36356ef2c4851eea02226cd409e4b414e4379d79582f11" dependencies = [ - "cfg-if 1.0.0", - "cpufeatures", - "digest 0.11.2", + "bincode", + "elliptic-curve", + "serde", + "sp1-primitives 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "sha3" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +name = "sp1-lib" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ - "digest 0.10.7", - "keccak", + "bincode", + "serde", + "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", ] [[package]] -name = "sha3-asm" -version = "0.1.5" +name = "sp1-primitives" +version = "5.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b31139435f327c93c6038ed350ae4588e2c70a13d50599509fee6349967ba35a" +checksum = "7e69a03098f827102c54c31a5e57280eb45b2c085de433b3f702e4f9e3ec1641" dependencies = [ - "cc", - "cfg-if 1.0.0", + "bincode", + "blake3", + "cfg-if 1.0.4", + "hex", + "lazy_static", + "num-bigint 0.4.6", + "p3-baby-bear 0.2.3-succinct", + "p3-field 0.2.3-succinct", + "p3-poseidon2 0.2.3-succinct", + "p3-symmetric 0.2.3-succinct", + "serde", + "sha2 0.10.9", ] [[package]] -name = "sharded-slab" -version = "0.1.7" +name = "sp1-primitives" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +checksum = "9bda0eaba853f3c162e6b62dc8eb25f25100ee0792f59919ef905811809e81e5" dependencies = [ + "bincode", + "blake3", + "elf", + "hex", + "itertools 0.14.0", "lazy_static", + "num-bigint 0.4.6", + "serde", + "sha2 0.10.9", + "slop-algebra 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slop-bn254 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slop-challenger 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slop-koala-bear 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slop-poseidon2 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slop-primitives 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slop-symmetric 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "shared-buffer" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6c99835bad52957e7aa241d3975ed17c1e5f8c92026377d117a606f36b84b16" +name = "sp1-primitives" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ - "bytes", - "memmap2 0.6.2", + "bincode", + "blake3", + "elf", + "hex", + "itertools 0.13.0", + "lazy_static", + "num-bigint 0.4.6", + "serde", + "sha2 0.10.9", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-bn254 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-koala-bear 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-poseidon2 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", ] [[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +name = "sp1-prover" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "anyhow", + "bincode", + "clap 4.5.53", + "dirs", + "downloader", + "either", + "enum-map", + "eyre", + "futures", + "hashbrown 0.14.5", + "hex", + "indicatif", + "itertools 0.13.0", + "lru 0.12.5", + "mti", + "num-bigint 0.4.6", + "opentelemetry", + "pin-project", + "rand 0.8.5", + "reqwest 0.12.28", + "serde", + "serde_json", + "serial_test", + "sha2 0.10.9", + "slop-air", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-basefold", + "slop-bn254 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-futures", + "slop-jagged", + "slop-multilinear", + "slop-stacked", + "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "sp1-core-executor", + "sp1-core-machine", + "sp1-derive", + "sp1-hypercube", + "sp1-jit", + "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "sp1-prover-types", + "sp1-recursion-circuit", + "sp1-recursion-compiler", + "sp1-recursion-executor", + "sp1-recursion-gnark-ffi", + "sp1-recursion-machine", + "sp1-verifier", + "static_assertions", + "sysinfo", + "tempfile", + "thiserror 1.0.63", + "tokio", + "tonic", + "tracing", + "tracing-appender", + "tracing-subscriber", +] [[package]] -name = "signal-hook-registry" -version = "1.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +name = "sp1-prover-types" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ - "errno", - "libc", + "anyhow", + "async-scoped", + "bincode", + "chrono", + "futures-util", + "hashbrown 0.14.5", + "mti", + "prost", + "serde", + "tokio", + "tonic", + "tonic-build", + "tracing", ] [[package]] -name = "signature" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +name = "sp1-recursion-circuit" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ - "digest 0.10.7", - "rand_core 0.6.4", + "itertools 0.13.0", + "rand 0.8.5", + "rayon", + "serde", + "slop-air", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-alloc", + "slop-basefold", + "slop-basefold-prover", + "slop-bn254 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-commit", + "slop-jagged", + "slop-koala-bear 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-matrix", + "slop-merkle-tree", + "slop-multilinear", + "slop-stacked", + "slop-sumcheck", + "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-tensor", + "slop-whir", + "sp1-core-executor", + "sp1-core-machine", + "sp1-derive", + "sp1-hypercube", + "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "sp1-recursion-compiler", + "sp1-recursion-executor", + "sp1-recursion-machine", + "tracing", ] [[package]] -name = "simd-adler32" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" +name = "sp1-recursion-compiler" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "backtrace", + "cfg-if 1.0.4", + "itertools 0.13.0", + "serde", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-bn254 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "sp1-core-machine", + "sp1-hypercube", + "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "sp1-recursion-executor", + "tracing", + "vec_map", +] [[package]] -name = "simdutf8" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" +name = "sp1-recursion-executor" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "backtrace", + "cfg-if 1.0.4", + "hashbrown 0.14.5", + "itertools 0.13.0", + "range-set-blaze", + "serde", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-maybe-rayon", + "slop-poseidon2 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "smallvec", + "sp1-derive", + "sp1-hypercube", + "static_assertions", + "thiserror 1.0.63", + "tracing", +] [[package]] -name = "simple_asn1" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d585997b0ac10be3c5ee635f1bab02d512760d14b7c468801ac8a01d9ae5f1d" +name = "sp1-recursion-gnark-ffi" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ - "num-bigint", - "num-traits", - "thiserror 2.0.18", - "time", + "anyhow", + "bincode", + "bindgen 0.70.1", + "cfg-if 1.0.4", + "hex", + "num-bigint 0.4.6", + "serde", + "serde_json", + "sha2 0.10.9", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "sp1-hypercube", + "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "sp1-recursion-compiler", + "sp1-verifier", + "tempfile", + "tracing", ] [[package]] -name = "siphasher" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" +name = "sp1-recursion-machine" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "itertools 0.13.0", + "rand 0.8.5", + "slop-air", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-basefold", + "slop-matrix", + "slop-maybe-rayon", + "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "sp1-derive", + "sp1-hypercube", + "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "sp1-recursion-executor", + "strum", + "tracing", + "zkhash", +] [[package]] -name = "siphasher" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" +name = "sp1-runner" +version = "0.1.0" +dependencies = [ + "bincode", + "clap 4.5.53", + "rkyv", + "serde_json", + "sp1-core-executor", + "sp1-sdk", + "tokio", + "tracing", + "validation", +] [[package]] -name = "slab" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" +name = "sp1-sdk" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" +dependencies = [ + "anyhow", + "async-trait", + "bincode", + "cfg-if 1.0.4", + "dirs", + "eventsource-stream", + "futures", + "hex", + "indicatif", + "itertools 0.13.0", + "k256 0.13.4 (registry+https://github.com/rust-lang/crates.io-index)", + "num-bigint 0.4.6", + "serde", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "sp1-build", + "sp1-core-executor", + "sp1-core-machine", + "sp1-cuda", + "sp1-hypercube", + "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "sp1-prover", + "sp1-prover-types", + "sp1-recursion-executor", + "sp1-recursion-gnark-ffi", + "sp1-verifier", + "strum", + "tempfile", + "thiserror 1.0.63", + "tokio", + "tracing", +] [[package]] -name = "smallvec" -version = "1.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +name = "sp1-verifier" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ + "bincode", + "blake3", + "cfg-if 1.0.4", + "dirs", + "hex", + "lazy_static", "serde", + "sha2 0.10.9", + "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "sp1-hypercube", + "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "sp1-recursion-executor", + "sp1-recursion-machine", + "strum", + "substrate-bn-succinct", + "thiserror 2.0.18", ] [[package]] -name = "socket2" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +name = "sp1-zkvm" +version = "6.0.0" +source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" dependencies = [ - "libc", - "windows-sys 0.60.2", + "cfg-if 1.0.4", + "critical-section", + "embedded-alloc", + "getrandom 0.2.15", + "getrandom 0.3.4", + "lazy_static", + "libm", + "rand 0.8.5", + "sha2 0.10.9", + "sp1-lib 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", + "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", ] +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + [[package]] name = "spin" version = "0.10.0" @@ -4702,6 +7732,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "strength_reduce" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe895eb47f22e2ddd4dabc02bce419d2e643c8e3b585c78158b349195bc24d82" + [[package]] name = "strsim" version = "0.8.0" @@ -4763,26 +7799,64 @@ dependencies = [ name = "stylus" version = "0.1.0" dependencies = [ - "arbutil", - "brotli", - "caller-env", - "clru", - "derivative", - "eyre", - "hex", + "arbutil", + "brotli", + "caller-env", + "clru", + "derivative", + "eyre", + "hex", + "lazy_static", + "num-bigint 0.4.6", + "parking_lot", + "prover", + "rand 0.8.5", + "thiserror 1.0.63", + "user-host-trait", + "wasmer", + "wasmer-compiler-cranelift", + "wasmer-compiler-llvm", + "wasmer-compiler-singlepass", + "wasmer-types", + "wasmer-vm", +] + +[[package]] +name = "stylus-compiler-program" +version = "0.1.0" +dependencies = [ + "prover", + "sp1-zkvm", + "wasmer", +] + +[[package]] +name = "subenum" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3d08fe7078c57309d5c3d938e50eba95ba1d33b9c3a101a8465fc6861a5416" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "substrate-bn-succinct" +version = "0.6.0-v5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ba32f1b74728f92887c3ad17c42bf82998eb52c9091018f35294e9cd388b0c8" +dependencies = [ + "bytemuck", + "byteorder", + "cfg-if 1.0.4", + "crunchy", "lazy_static", - "num-bigint", - "parking_lot", - "prover", + "num-bigint 0.4.6", "rand 0.8.5", - "thiserror 1.0.63", - "user-host-trait", - "wasmer", - "wasmer-compiler-cranelift", - "wasmer-compiler-llvm", - "wasmer-compiler-singlepass", - "wasmer-types", - "wasmer-vm", + "rustc-hex", + "sp1-lib 5.2.4", ] [[package]] @@ -4791,6 +7865,19 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +[[package]] +name = "svgbobdoc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2c04b93fc15d79b39c63218f15e3fdffaa4c227830686e3b7c5f41244eb3e50" +dependencies = [ + "base64 0.13.1", + "proc-macro2", + "quote", + "syn 1.0.109", + "unicode-width 0.1.13", +] + [[package]] name = "syn" version = "1.0.109" @@ -4833,6 +7920,21 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "sysinfo" +version = "0.30.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a5b4ddaee55fb2bea2bf0e5000747e5f5c0de765e5a5ff87f4cd106439f4bb3" +dependencies = [ + "cfg-if 1.0.4", + "core-foundation-sys", + "libc", + "ntapi", + "once_cell", + "rayon", + "windows", +] + [[package]] name = "system-configuration" version = "0.6.1" @@ -4874,8 +7976,7 @@ dependencies = [ [[package]] name = "target-lexicon" version = "0.13.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca" +source = "git+https://github.com/OffchainLabs/target-lexicon?tag=v0.13.5-sp1#b36201fb3efd8babeb625c26217bfb4fb7af32a5" [[package]] name = "tempfile" @@ -4884,7 +7985,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0136791f7c95b1f6dd99f9cc786b91bb81c3800b639b3478e561ddb7be95e5f1" dependencies = [ "fastrand", - "getrandom 0.3.4", + "getrandom 0.4.2", "once_cell", "rustix", "windows-sys 0.61.2", @@ -4939,13 +8040,19 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "thousands" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bf63baf9f5039dadc247375c29eb13706706cfde997d0330d05aa63a77d8820" + [[package]] name = "thread_local" version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 1.0.4", ] [[package]] @@ -4991,10 +8098,11 @@ dependencies = [ [[package]] name = "tiny-keccak" version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +source = "git+https://github.com/sp1-patches/tiny-keccak?tag=patch-2.0.2-sp1-6.0.0#957430a459f7a2332ab5bab4a12f9b473bb95c87" dependencies = [ + "cfg-if 1.0.4", "crunchy", + "sp1-lib 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5043,7 +8151,7 @@ dependencies = [ "mio", "pin-project-lite", "signal-hook-registry", - "socket2", + "socket2 0.6.1", "tokio-macros", "windows-sys 0.61.2", ] @@ -5069,6 +8177,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-stream" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + [[package]] name = "tokio-util" version = "0.7.18" @@ -5088,6 +8207,17 @@ version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.13.0", + "toml_datetime", + "winnow 0.5.40", +] + [[package]] name = "toml_edit" version = "0.22.27" @@ -5096,7 +8226,73 @@ checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ "indexmap 2.13.0", "toml_datetime", - "winnow", + "winnow 0.7.13", +] + +[[package]] +name = "tonic" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52" +dependencies = [ + "async-stream", + "async-trait", + "axum 0.7.9", + "base64 0.22.1", + "bytes", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-timeout", + "hyper-util", + "percent-encoding", + "pin-project", + "prost", + "rustls-pemfile", + "socket2 0.5.10", + "tokio", + "tokio-rustls", + "tokio-stream", + "tower 0.4.13", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tonic-build" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9557ce109ea773b399c9b9e5dca39294110b74f1f342cb347a80d1fce8c26a11" +dependencies = [ + "prettyplease", + "proc-macro2", + "prost-build", + "prost-types", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "indexmap 1.9.3", + "pin-project", + "pin-project-lite", + "rand 0.8.5", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", ] [[package]] @@ -5128,7 +8324,7 @@ dependencies = [ "http-body", "iri-string", "pin-project-lite", - "tower", + "tower 0.5.2", "tower-layer", "tower-service", "tracing", @@ -5158,6 +8354,18 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "tracing-appender" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "786d480bce6247ab75f005b14ae1624ad978d3029d9113f0a22fa1ac773faeaf" +dependencies = [ + "crossbeam-channel", + "thiserror 2.0.18", + "time", + "tracing-subscriber", +] + [[package]] name = "tracing-attributes" version = "0.1.31" @@ -5179,6 +8387,19 @@ dependencies = [ "valuable", ] +[[package]] +name = "tracing-forest" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee40835db14ddd1e3ba414292272eddde9dad04d3d4b65509656414d1c42592f" +dependencies = [ + "ansi_term", + "smallvec", + "thiserror 1.0.63", + "tracing", + "tracing-subscriber", +] + [[package]] name = "tracing-log" version = "0.2.0" @@ -5221,6 +8442,16 @@ dependencies = [ "tracing-serde", ] +[[package]] +name = "transpose" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad61aed86bc3faea4300c7aee358b4c6d0c8d6ccc36524c96e4c92ccf26e77e" +dependencies = [ + "num-integer", + "strength_reduce", +] + [[package]] name = "try-lock" version = "0.2.5" @@ -5233,6 +8464,21 @@ version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ea3136b675547379c4bd395ca6b938e5ad3c3d20fad76e7fe85f9e0d011419c" +[[package]] +name = "typeid_prefix" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9da1387307fdee46aa441e4f08a1b491e659fcac1aca9cd71f2c624a0de5d1b" + +[[package]] +name = "typeid_suffix" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77b55e96f110c6db5d1a2f24072552537f0091dc90cebeaa679540bac93e7405" +dependencies = [ + "uuid", +] + [[package]] name = "typenum" version = "1.17.0" @@ -5365,9 +8611,17 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.10.0" +version = "1.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" +checksum = "a68d3c8f01c0cfa54a75291d83601161799e4a89a39e0929f4b0354d88757a37" +dependencies = [ + "atomic", + "getrandom 0.4.2", + "js-sys", + "md-5", + "sha1_smol", + "wasm-bindgen", +] [[package]] name = "validation" @@ -5388,12 +8642,12 @@ dependencies = [ "alloy-rpc-types-engine", "anyhow", "arbutil", - "axum", + "axum 0.8.8", "axum-extra", "clap 4.5.53", "jit", "rand 0.8.5", - "reqwest", + "reqwest 0.13.1", "serde", "serde_json", "tempfile", @@ -5415,6 +8669,9 @@ name = "vec_map" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" +dependencies = [ + "serde", +] [[package]] name = "version_check" @@ -5489,7 +8746,7 @@ version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 1.0.4", "once_cell", "rustversion", "wasm-bindgen-macro", @@ -5502,7 +8759,7 @@ version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 1.0.4", "js-sys", "wasm-bindgen", "web-sys", @@ -5572,13 +8829,26 @@ dependencies = [ "wasmparser 0.244.0", ] +[[package]] +name = "wasm-streams" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "wasmer" version = "7.1.0-rc.2" dependencies = [ - "bindgen", + "bindgen 0.72.1", "bytes", - "cfg-if 1.0.0", + "cfg-if 1.0.4", "cmake", "derive_more 2.1.1", "indexmap 2.13.0", @@ -5596,6 +8866,8 @@ dependencies = [ "wasm-bindgen", "wasmer-compiler", "wasmer-compiler-cranelift", + "wasmer-compiler-llvm", + "wasmer-compiler-singlepass", "wasmer-derive", "wasmer-types", "wasmer-vm", @@ -5610,7 +8882,7 @@ version = "7.1.0-rc.2" dependencies = [ "backtrace", "bytes", - "cfg-if 1.0.0", + "cfg-if 1.0.4", "crossbeam-channel", "enum-iterator", "enumset", @@ -5674,7 +8946,7 @@ dependencies = [ "rayon", "regex", "rustc_version 0.4.0", - "semver 1.0.23", + "semver 1.0.27", "smallvec", "target-lexicon", "tracing", @@ -5688,8 +8960,8 @@ name = "wasmer-compiler-singlepass" version = "7.1.0-rc.2" dependencies = [ "byteorder", - "dynasm", - "dynasmrt", + "dynasm 5.0.0", + "dynasmrt 5.0.0", "enumset", "gimli 0.33.0", "itertools 0.14.0", @@ -5736,7 +9008,7 @@ dependencies = [ "backtrace", "bytesize", "cc", - "cfg-if 1.0.0", + "cfg-if 1.0.4", "corosensei", "crossbeam-queue", "dashmap", @@ -5768,7 +9040,7 @@ dependencies = [ "bitflags 2.11.0", "hashbrown 0.15.5", "indexmap 2.13.0", - "semver 1.0.23", + "semver 1.0.27", ] [[package]] @@ -5780,7 +9052,7 @@ dependencies = [ "bitflags 2.11.0", "hashbrown 0.16.1", "indexmap 2.13.0", - "semver 1.0.23", + "semver 1.0.27", "serde", ] @@ -5817,9 +9089,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.69" +version = "0.3.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +checksum = "312e32e551d92129218ea9a2452120f4aabc03529ef03e4d0d82fb2780608598" dependencies = [ "js-sys", "wasm-bindgen", @@ -5844,6 +9116,15 @@ dependencies = [ "rustls-pki-types", ] +[[package]] +name = "webpki-roots" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "wee_alloc" version = "0.4.5" @@ -5859,8 +9140,7 @@ dependencies = [ [[package]] name = "which" version = "8.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81995fafaaaf6ae47a7d0cc83c67caf92aeb7e5331650ae6ff856f7c0c60c459" +source = "git+https://github.com/OffchainLabs/which-rs?rev=f516e8a2e5453daeab38706747a9f6be8bb058e7#f516e8a2e5453daeab38706747a9f6be8bb058e7" dependencies = [ "libc", ] @@ -5896,6 +9176,16 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core", + "windows-targets 0.52.6", +] + [[package]] name = "windows-core" version = "0.52.0" @@ -5949,6 +9239,15 @@ dependencies = [ "windows-targets 0.42.2", ] +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + [[package]] name = "windows-sys" version = "0.52.0" @@ -6000,6 +9299,21 @@ dependencies = [ "windows_x86_64_msvc 0.42.2", ] +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + [[package]] name = "windows-targets" version = "0.52.6" @@ -6039,6 +9353,12 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" @@ -6057,6 +9377,12 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + [[package]] name = "windows_aarch64_msvc" version = "0.52.6" @@ -6075,6 +9401,12 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -6105,6 +9437,12 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + [[package]] name = "windows_i686_msvc" version = "0.52.6" @@ -6123,6 +9461,12 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + [[package]] name = "windows_x86_64_gnu" version = "0.52.6" @@ -6141,6 +9485,12 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" @@ -6159,6 +9509,12 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + [[package]] name = "windows_x86_64_msvc" version = "0.52.6" @@ -6171,6 +9527,15 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + [[package]] name = "winnow" version = "0.7.13" @@ -6260,7 +9625,7 @@ dependencies = [ "id-arena", "indexmap 2.13.0", "log", - "semver 1.0.23", + "semver 1.0.27", "serde", "serde_derive", "serde_json", @@ -6409,3 +9774,36 @@ dependencies = [ "quote", "syn 2.0.117", ] + +[[package]] +name = "zkhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4352d1081da6922701401cdd4cbf29a2723feb4cfabb5771f6fee8e9276da1c7" +dependencies = [ + "ark-ff 0.4.2", + "ark-std 0.4.0", + "bitvec", + "blake2", + "bls12_381", + "byteorder", + "cfg-if 1.0.4", + "group 0.12.1", + "group 0.13.0", + "halo2", + "hex", + "jubjub", + "lazy_static", + "pasta_curves 0.5.1", + "rand 0.8.5", + "serde", + "sha2 0.10.9", + "sha3", + "subtle", +] + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/Cargo.toml b/Cargo.toml index aa8e28d0ea6..759d1e18a8d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,10 @@ members = [ "crates/wasm-libraries/user-host-trait", "crates/wasm-libraries/user-test", "crates/wasm-libraries/wasi-stub", + "crates/sp1/builder", + "crates/sp1/program", + "crates/sp1/runner", + "crates/sp1/stylus-compiler-program", ] default-members = [ "crates/jit", @@ -25,7 +29,6 @@ default-members = [ ] exclude = [ "crates/langs", - "crates/sp1", "crates/stylus/tests", "crates/tools", "crates/wasm-testsuite", @@ -48,6 +51,8 @@ axum = { version = "0.8.8" } axum-extra = { version = "0.10.3" } bincode = { version = "1.3.3" } bitvec = { version = "1.0.0" } +bytes = { version = "1" } +corosensei = { version = "0.3.0" } c-kzg = { version = "2.1.1" } # TODO: look into switching to rust-kzg (no crates.io release or hosted rustdoc yet) clap = { version = "4.4.8" } clru = { version = "0.6.2" } @@ -79,6 +84,7 @@ rkyv = { version = "0.8.8" } reqwest = { version = "0.13.1" } ruint2 = { version = "1.9.0" } rustc-demangle = { version = "0.1.21" } +secp256k1 = { version = "0.30.0" } serde = { version = "1.0.130" } serde_json = { version = "1.0.67" } serde_with = { version = "3.8.1" } @@ -116,5 +122,14 @@ wasmer-compiler-singlepass = { path = "crates/tools/wasmer/lib/compiler-singlepa wasmer-types = { path = "crates/tools/wasmer/lib/types" } wasmer-vm = { path = "crates/tools/wasmer/lib/vm" } +[patch.crates-io] +target-lexicon = { git = "https://github.com/OffchainLabs/target-lexicon", tag = "v0.13.5-sp1" } +region = { git = "https://github.com/OffchainLabs/region-rs", tag = "v3.0.2-sp1" } +corosensei = { git = "https://github.com/OffchainLabs/corosensei", rev = "6681138454747733c6adad5037024400f0c9d4e3" } # branch: v0.3.3-sp +which = { git = "https://github.com/OffchainLabs/which-rs", rev = "f516e8a2e5453daeab38706747a9f6be8bb058e7" } # branch: v0.3.3-sp1 +secp256k1 = { git = "https://github.com/sp1-patches/rust-secp256k1", tag = "patch-0.30.0-sp1-6.0.0" } +tiny-keccak = { git = "https://github.com/sp1-patches/tiny-keccak", tag = "patch-2.0.2-sp1-6.0.0" } +sp1-zkvm = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe" } + [profile.release] debug = true diff --git a/crates/brotli/build.rs b/crates/brotli/build.rs index 700f74d9565..5e0742324e1 100644 --- a/crates/brotli/build.rs +++ b/crates/brotli/build.rs @@ -4,13 +4,19 @@ #[cfg(not(feature = "cc_brotli"))] fn main() { use std::env; + use std::path::PathBuf; + let manifest_dir = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap()); + let repo_root = manifest_dir.join("../.."); let target_arch = env::var("TARGET").unwrap(); if target_arch.contains("wasm32") { println!("cargo:rustc-link-search=target/lib-wasm/"); } else if target_arch.contains("riscv64") { - println!("cargo:rustc-link-search=../../target/lib-sp1/lib"); + println!( + "cargo:rustc-link-search={}", + repo_root.join("target/lib-sp1/lib").display() + ); } else { println!("cargo:rustc-link-search=target/lib/"); println!("cargo:rustc-link-search=../../target/lib/"); diff --git a/crates/prover/Cargo.toml b/crates/prover/Cargo.toml index 6b0e2a0d6af..4e10a8e3fbc 100644 --- a/crates/prover/Cargo.toml +++ b/crates/prover/Cargo.toml @@ -39,7 +39,7 @@ sha2 = { workspace = true } sha3 = { workspace = true } smallvec = { workspace = true, features = ["serde"] } static_assertions = { workspace = true } -structopt = { workspace = true } +structopt = { workspace = true, optional = true } validation = { workspace = true } wasmer = { workspace = true, optional = true } wasmer-compiler-singlepass = { workspace = true, optional = true, features = ["std", "unwind", "avx"] } @@ -63,16 +63,13 @@ name = "prover" crate-type = ["staticlib", "lib"] [features] -default = ["native", "rayon", "singlepass_rayon"] +default = ["native", "rayon", "singlepass_rayon", "kzg", "dep:structopt"] counters = [] -native = ["dep:wasmer", "dep:wasmer-compiler-singlepass", "brotli/wasmer_traits", "dep:c-kzg"] +kzg = ["dep:c-kzg"] +native = ["dep:wasmer", "dep:wasmer-compiler-singlepass", "brotli/wasmer_traits"] singlepass_rayon = ["wasmer-compiler-singlepass?/rayon"] rayon = ["dep:rayon"] cc_brotli = ["brotli/cc_brotli"] - -# The "sp1" feature is never activated in this workspace. It exists only so that -# `#[cfg(feature = "sp1")]` gates don't produce warnings. These gates are used -# when crates/sp1/prover includes our source files via #[path] and compiles them -# with its own "sp1" feature enabled (under wasmer 6.x / wasmparser 0.224). -[lints.rust] -unexpected_cfgs = { level = "warn", check-cfg = ['cfg(feature, values("sp1"))'] } +# Activated by crates/sp1/program and crates/sp1/stylus-compiler-program +# to gate SP1-specific code paths (middleware, depth checking, metering). +sp1 = [] diff --git a/crates/prover/src/lib.rs b/crates/prover/src/lib.rs index 5289d18dbe2..c6da50d5e96 100644 --- a/crates/prover/src/lib.rs +++ b/crates/prover/src/lib.rs @@ -6,7 +6,7 @@ pub mod binary; mod host; pub(crate) mod internal_func; -#[cfg(feature = "native")] +#[cfg(feature = "kzg")] mod kzg; pub mod machine; /// cbindgen:ignore @@ -125,7 +125,7 @@ pub unsafe extern "C" fn free_rust_bytes(vec: RustBytes) { } #[no_mangle] -#[cfg(feature = "native")] +#[cfg(all(feature = "native", not(feature = "sp1")))] pub unsafe extern "C" fn arbitrator_load_machine( binary_path: *const c_char, library_paths: *const *const c_char, @@ -140,6 +140,7 @@ pub unsafe extern "C" fn arbitrator_load_machine( }) } +#[cfg(all(feature = "native", not(feature = "sp1")))] unsafe fn arbitrator_load_machine_impl( binary_path: *const c_char, library_paths: *const *const c_char, @@ -170,7 +171,7 @@ unsafe fn arbitrator_load_machine_impl( } #[no_mangle] -#[cfg(feature = "native")] +#[cfg(all(feature = "native", not(feature = "sp1")))] pub unsafe extern "C" fn arbitrator_load_wavm_binary(binary_path: *const c_char) -> *mut Machine { let binary_path = cstr_to_string(binary_path); let binary_path = Path::new(&binary_path); @@ -184,20 +185,23 @@ pub unsafe extern "C" fn arbitrator_load_wavm_binary(binary_path: *const c_char) } #[no_mangle] -#[cfg(feature = "native")] +#[cfg(all(feature = "native", not(feature = "sp1")))] pub unsafe extern "C" fn arbitrator_new_finished(gs: GlobalState) -> *mut Machine { Box::into_raw(Box::new(Machine::new_finished(gs))) } +#[cfg(not(feature = "sp1"))] unsafe fn cstr_to_string(c_str: *const c_char) -> String { CStr::from_ptr(c_str).to_string_lossy().into_owned() } +#[cfg(not(feature = "sp1"))] pub fn err_to_c_string(err: Report) -> *mut libc::c_char { str_to_c_string(&format!("{err:?}")) } /// Copies the str-data into a libc free-able C string +#[cfg(not(feature = "sp1"))] pub fn str_to_c_string(text: &str) -> *mut libc::c_char { unsafe { let buf = libc::malloc(text.len() + 1); // includes null-terminating byte @@ -211,13 +215,13 @@ pub fn str_to_c_string(text: &str) -> *mut libc::c_char { } #[no_mangle] -#[cfg(feature = "native")] +#[cfg(all(feature = "native", not(feature = "sp1")))] pub unsafe extern "C" fn arbitrator_free_machine(mach: *mut Machine) { drop(Box::from_raw(mach)); } #[no_mangle] -#[cfg(feature = "native")] +#[cfg(all(feature = "native", not(feature = "sp1")))] pub unsafe extern "C" fn arbitrator_clone_machine(mach: *mut Machine) -> *mut Machine { let new_mach = (*mach).clone(); Box::into_raw(Box::new(new_mach)) @@ -232,7 +236,7 @@ pub unsafe extern "C" fn atomic_u8_store(ptr: *mut u8, contents: u8) { /// Runs the machine while the condition variable is zero. May return early if num_steps is hit. /// Returns a c string error (freeable with libc's free) on error, or nullptr on success. #[no_mangle] -#[cfg(feature = "native")] +#[cfg(all(feature = "native", not(feature = "sp1")))] pub unsafe extern "C" fn arbitrator_step( mach: *mut Machine, num_steps: u64, @@ -256,7 +260,7 @@ pub unsafe extern "C" fn arbitrator_step( } #[no_mangle] -#[cfg(feature = "native")] +#[cfg(all(feature = "native", not(feature = "sp1")))] pub unsafe extern "C" fn arbitrator_add_inbox_message( mach: *mut Machine, inbox_identifier: u64, @@ -276,7 +280,7 @@ pub unsafe extern "C" fn arbitrator_add_inbox_message( /// Adds a user program to the machine's known set of wasms. #[no_mangle] -#[cfg(feature = "native")] +#[cfg(all(feature = "native", not(feature = "sp1")))] pub unsafe extern "C" fn arbitrator_add_user_wasm( mach: *mut Machine, module: *const u8, @@ -290,7 +294,7 @@ pub unsafe extern "C" fn arbitrator_add_user_wasm( /// Like arbitrator_step, but stops early if it hits a host io operation. /// Returns a c string error (freeable with libc's free) on error, or nullptr on success. #[no_mangle] -#[cfg(feature = "native")] +#[cfg(all(feature = "native", not(feature = "sp1")))] pub unsafe extern "C" fn arbitrator_step_until_host_io( mach: *mut Machine, condition: *const u8, @@ -315,7 +319,7 @@ pub unsafe extern "C" fn arbitrator_step_until_host_io( } #[no_mangle] -#[cfg(feature = "native")] +#[cfg(all(feature = "native", not(feature = "sp1")))] pub unsafe extern "C" fn arbitrator_serialize_state( mach: *const Machine, path: *const c_char, @@ -334,7 +338,7 @@ pub unsafe extern "C" fn arbitrator_serialize_state( } #[no_mangle] -#[cfg(feature = "native")] +#[cfg(all(feature = "native", not(feature = "sp1")))] pub unsafe extern "C" fn arbitrator_deserialize_and_replace_state( mach: *mut Machine, path: *const c_char, @@ -353,7 +357,7 @@ pub unsafe extern "C" fn arbitrator_deserialize_and_replace_state( } #[no_mangle] -#[cfg(feature = "native")] +#[cfg(all(feature = "native", not(feature = "sp1")))] pub unsafe extern "C" fn arbitrator_get_num_steps(mach: *const Machine) -> u64 { (*mach).get_steps() } @@ -383,19 +387,19 @@ const_assert_eq!( /// Returns one of ARBITRATOR_MACHINE_STATUS_* #[no_mangle] -#[cfg(feature = "native")] +#[cfg(all(feature = "native", not(feature = "sp1")))] pub unsafe extern "C" fn arbitrator_get_status(mach: *const Machine) -> u8 { (*mach).get_status() as u8 } #[no_mangle] -#[cfg(feature = "native")] +#[cfg(all(feature = "native", not(feature = "sp1")))] pub unsafe extern "C" fn arbitrator_global_state(mach: *mut Machine) -> GlobalState { (*mach).get_global_state() } #[no_mangle] -#[cfg(feature = "native")] +#[cfg(all(feature = "native", not(feature = "sp1")))] pub unsafe extern "C" fn arbitrator_set_global_state(mach: *mut Machine, gs: GlobalState) { (*mach).set_global_state(gs); } @@ -406,7 +410,7 @@ pub struct ResolvedPreimage { pub len: isize, // negative if not found } -#[cfg(feature = "native")] +#[cfg(all(feature = "native", not(feature = "sp1")))] unsafe fn handle_preimage_resolution( context: u64, ty: PreimageType, @@ -438,7 +442,7 @@ unsafe fn handle_preimage_resolution( } #[no_mangle] -#[cfg(feature = "native")] +#[cfg(all(feature = "native", not(feature = "sp1")))] pub unsafe extern "C" fn arbitrator_set_preimage_resolver( mach: *mut Machine, resolver: unsafe extern "C" fn(u64, u8, *const u8) -> ResolvedPreimage, @@ -463,25 +467,25 @@ pub unsafe extern "C" fn arbitrator_set_preimage_resolver( } #[no_mangle] -#[cfg(feature = "native")] +#[cfg(all(feature = "native", not(feature = "sp1")))] pub unsafe extern "C" fn arbitrator_set_context(mach: *mut Machine, context: u64) { (*mach).set_context(context); } #[no_mangle] -#[cfg(feature = "native")] +#[cfg(all(feature = "native", not(feature = "sp1")))] pub unsafe extern "C" fn arbitrator_hash(mach: *mut Machine) -> Bytes32 { (*mach).hash() } #[no_mangle] -#[cfg(feature = "native")] +#[cfg(all(feature = "native", not(feature = "sp1")))] pub unsafe extern "C" fn arbitrator_module_root(mach: *mut Machine) -> Bytes32 { (*mach).get_modules_root() } #[no_mangle] -#[cfg(feature = "native")] +#[cfg(all(feature = "native", not(feature = "sp1")))] pub unsafe extern "C" fn arbitrator_gen_proof(mach: *mut Machine, out: *mut RustBytes) { (*out).write((*mach).serialize_proof()); } diff --git a/crates/prover/src/machine.rs b/crates/prover/src/machine.rs index 9cf8554ad38..75d3380b60e 100644 --- a/crates/prover/src/machine.rs +++ b/crates/prover/src/machine.rs @@ -1,7 +1,7 @@ // Copyright 2021-2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md -#[cfg(feature = "native")] +#[cfg(feature = "kzg")] use crate::kzg::prove_kzg_preimage; use crate::{ binary::{ @@ -10,7 +10,7 @@ use crate::{ host, memory::Memory, merkle::{Merkle, MerkleType}, - programs::{config::CompileConfig, meter::MeteredMachine, ModuleMod, StylusData}, + programs::{config::CompileConfig, ModuleMod, StylusData}, reinterpret::{ReinterpretAsSigned, ReinterpretAsUnsigned}, utils::{file_bytes, CBytes, RemoteTableType}, value::{ArbValueType, FunctionType, IntegerValType, ProgramCounter, Value}, @@ -19,9 +19,11 @@ use crate::{ IBinOpType, IRelOpType, IUnOpType, Instruction, Opcode, }, }; +#[cfg(all(feature = "native", not(feature = "sp1")))] +use crate::programs::meter::MeteredMachine; use arbutil::{crypto, math, Bytes32, Color, DebugColor, PreimageType}; use brotli::Dictionary; -#[cfg(feature = "native")] +#[cfg(feature = "kzg")] use c_kzg::BYTES_PER_BLOB; use digest::Digest; use eyre::{bail, ensure, eyre, Result, WrapErr}; @@ -1848,7 +1850,7 @@ impl Machine { self.get_final_result() } - #[cfg(feature = "native")] + #[cfg(all(feature = "native", not(feature = "sp1")))] pub fn call_user_func( &mut self, func: &str, @@ -2527,6 +2529,7 @@ impl Machine { self.print_backtrace(true); bail!("missing requested preimage for hash {}", hash); }; + #[cfg(feature = "kzg")] if preimage_ty == PreimageType::EthVersionedHash && preimage.len() != BYTES_PER_BLOB { @@ -3125,10 +3128,15 @@ impl Machine { // The proofs for these preimage types are just the raw preimages. data.extend(preimage); } + #[cfg(feature = "kzg")] PreimageType::EthVersionedHash => { prove_kzg_preimage(hash, &preimage, offset, &mut data) .expect("Failed to generate KZG preimage proof"); } + #[cfg(not(feature = "kzg"))] + PreimageType::EthVersionedHash => { + panic!("KZG preimage proofs require the 'kzg' feature"); + } PreimageType::DACertificate => { // We do something special here; we don't create the final proof. // For DACertificate preimages, signal that this proof needs enhancement diff --git a/crates/prover/src/programs/meter.rs b/crates/prover/src/programs/meter.rs index 2f715858428..f3e5ef452e4 100644 --- a/crates/prover/src/programs/meter.rs +++ b/crates/prover/src/programs/meter.rs @@ -2,8 +2,6 @@ // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md #![allow(clippy::needless_lifetimes)] -#[cfg(feature = "sp1")] -use crate::operator::OperatorInfo; #[cfg(not(feature = "sp1"))] use crate::Machine; use crate::{ @@ -13,7 +11,6 @@ use crate::{ }, value::FunctionType, }; -#[cfg(not(feature = "sp1"))] use arbutil::operator::OperatorInfo; use arbutil::{ evm::{ diff --git a/crates/prover/src/programs/mod.rs b/crates/prover/src/programs/mod.rs index 2bc67074722..c99c1b8fda4 100644 --- a/crates/prover/src/programs/mod.rs +++ b/crates/prover/src/programs/mod.rs @@ -4,15 +4,18 @@ #[cfg(feature = "sp1")] use crate::value::MemoryType; #[cfg(not(feature = "sp1"))] -use crate::{machine::Module, memory_type::MemoryType}; +use crate::{machine::Module, memory_type::MemoryType, programs::config::CompileConfig}; +#[cfg(not(feature = "sp1"))] +use arbutil::{evm::ARBOS_VERSION_STYLUS_CHARGING_FIXES, math::SaturatingSum, Bytes32}; +#[cfg(not(feature = "sp1"))] +use eyre::WrapErr; use crate::{ binary::{ExportKind, WasmBinary}, - programs::config::CompileConfig, value::{FunctionType as ArbFunctionType, Value}, }; -use arbutil::{evm::ARBOS_VERSION_STYLUS_CHARGING_FIXES, math::SaturatingSum, Bytes32, Color}; -use eyre::{bail, eyre, Report, Result, WrapErr}; +use arbutil::Color; +use eyre::{bail, eyre, Report, Result}; use fnv::FnvHashMap as HashMap; use std::fmt::Debug; use wasmer_types::{ diff --git a/crates/prover/src/utils.rs b/crates/prover/src/utils.rs index b4183f6b329..31a2c76475d 100644 --- a/crates/prover/src/utils.rs +++ b/crates/prover/src/utils.rs @@ -1,10 +1,10 @@ // Copyright 2021-2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md -#[cfg(feature = "native")] +#[cfg(feature = "kzg")] use crate::kzg::ETHEREUM_KZG_SETTINGS; use arbutil::PreimageType; -#[cfg(feature = "native")] +#[cfg(feature = "kzg")] use c_kzg::Blob; use digest::Digest; use eyre::{eyre, Result}; @@ -55,7 +55,8 @@ impl From<&[u8]> for CBytes { return Self::default(); } unsafe { - let ptr = libc::malloc(slice.len()) as *mut u8; + let layout = std::alloc::Layout::from_size_align(slice.len(), 1).unwrap(); + let ptr = std::alloc::alloc(layout); if ptr.is_null() { panic!("Failed to allocate memory instantiating CBytes"); } @@ -118,7 +119,12 @@ pub struct RemoteTableType { impl Drop for CBytes { fn drop(&mut self) { - unsafe { libc::free(self.ptr as _) } + if !self.ptr.is_null() && self.len > 0 { + unsafe { + let layout = std::alloc::Layout::from_size_align(self.len, 1).unwrap(); + std::alloc::dealloc(self.ptr, layout); + } + } } } @@ -197,6 +203,7 @@ pub fn hash_preimage(preimage: &[u8], ty: PreimageType) -> Result<[u8; 32]> { match ty { PreimageType::Keccak256 => Ok(Keccak256::digest(preimage).into()), PreimageType::Sha2_256 => Ok(Sha256::digest(preimage).into()), + #[cfg(feature = "kzg")] PreimageType::EthVersionedHash => { // TODO: really we should also accept what version it is, // but right now only one version is supported by this hash format anyways. @@ -206,6 +213,10 @@ pub fn hash_preimage(preimage: &[u8], ty: PreimageType) -> Result<[u8; 32]> { commitment_hash[0] = 1; Ok(commitment_hash) } + #[cfg(not(feature = "kzg"))] + PreimageType::EthVersionedHash => { + eyre::bail!("EthVersionedHash preimage hashing requires the 'kzg' feature"); + } PreimageType::DACertificate => { // There is no way for us to compute the hash of the preimage for DACertificate. // For DACertificate, this is only ever called on the flat file initialization path. diff --git a/crates/sp1/.cargo/config.toml b/crates/sp1/.cargo/config.toml deleted file mode 100644 index c91c3f38b7b..00000000000 --- a/crates/sp1/.cargo/config.toml +++ /dev/null @@ -1,2 +0,0 @@ -[net] -git-fetch-with-cli = true diff --git a/crates/sp1/Cargo.lock b/crates/sp1/Cargo.lock deleted file mode 100644 index 2c038fb4860..00000000000 --- a/crates/sp1/Cargo.lock +++ /dev/null @@ -1,7839 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "addchain" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2e69442aa5628ea6951fa33e24efe8313f4321a91bd729fc2f75bdfc858570" -dependencies = [ - "num-bigint 0.3.3", - "num-integer", - "num-traits", -] - -[[package]] -name = "addr2line" -version = "0.25.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" -dependencies = [ - "gimli 0.32.3", -] - -[[package]] -name = "adler2" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" - -[[package]] -name = "ahash" -version = "0.8.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - -[[package]] -name = "aho-corasick" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" -dependencies = [ - "memchr", -] - -[[package]] -name = "allocator-api2" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - -[[package]] -name = "anstream" -version = "0.6.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is_terminal_polyfill", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" - -[[package]] -name = "anstyle-parse" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" -dependencies = [ - "windows-sys 0.61.2", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" -dependencies = [ - "anstyle", - "once_cell_polyfill", - "windows-sys 0.61.2", -] - -[[package]] -name = "anyhow" -version = "1.0.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" - -[[package]] -name = "arbutil" -version = "0.1.0" -dependencies = [ - "digest 0.10.7", - "eyre", - "fnv", - "hex", - "num-traits", - "num_enum 0.7.5", - "ruint2", - "serde", - "siphasher 0.3.11", - "tiny-keccak 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmparser 0.245.1", -] - -[[package]] -name = "ark-ff" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" -dependencies = [ - "ark-ff-asm", - "ark-ff-macros", - "ark-serialize", - "ark-std", - "derivative", - "digest 0.10.7", - "itertools 0.10.5", - "num-bigint 0.4.6", - "num-traits", - "paste", - "rustc_version", - "zeroize", -] - -[[package]] -name = "ark-ff-asm" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" -dependencies = [ - "quote", - "syn 1.0.109", -] - -[[package]] -name = "ark-ff-macros" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" -dependencies = [ - "num-bigint 0.4.6", - "num-traits", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "ark-serialize" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" -dependencies = [ - "ark-std", - "digest 0.10.7", - "num-bigint 0.4.6", -] - -[[package]] -name = "ark-std" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" -dependencies = [ - "num-traits", - "rand 0.8.5", -] - -[[package]] -name = "arrayref" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" - -[[package]] -name = "arrayvec" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" - -[[package]] -name = "async-scoped" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4042078ea593edffc452eef14e99fdb2b120caa4ad9618bcdeabc4a023b98740" -dependencies = [ - "futures", - "pin-project", - "tokio", -] - -[[package]] -name = "async-stream" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" -dependencies = [ - "async-stream-impl", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-stream-impl" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "async-trait" -version = "0.1.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "atomic" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a89cbf775b137e9b968e67227ef7f775587cde3fd31b0d8599dbd0f598a48340" -dependencies = [ - "bytemuck", -] - -[[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" - -[[package]] -name = "autocfg" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" - -[[package]] -name = "axum" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" -dependencies = [ - "async-trait", - "axum-core", - "bytes", - "futures-util", - "http", - "http-body", - "http-body-util", - "itoa", - "matchit", - "memchr", - "mime", - "percent-encoding", - "pin-project-lite", - "rustversion", - "serde", - "sync_wrapper", - "tower 0.5.2", - "tower-layer", - "tower-service", -] - -[[package]] -name = "axum-core" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" -dependencies = [ - "async-trait", - "bytes", - "futures-util", - "http", - "http-body", - "http-body-util", - "mime", - "pin-project-lite", - "rustversion", - "sync_wrapper", - "tower-layer", - "tower-service", -] - -[[package]] -name = "backtrace" -version = "0.3.76" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object 0.37.3", - "rustc-demangle", - "serde", - "windows-link", -] - -[[package]] -name = "base16ct" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" - -[[package]] -name = "base64" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" - -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - -[[package]] -name = "base64ct" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e050f626429857a27ddccb31e0aca21356bfa709c04041aefddac081a8f068a" - -[[package]] -name = "bincode" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] - -[[package]] -name = "bindgen" -version = "0.70.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" -dependencies = [ - "bitflags 2.10.0", - "cexpr", - "clang-sys", - "itertools 0.13.0", - "log", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash 1.1.0", - "shlex", - "syn 2.0.114", -] - -[[package]] -name = "bindgen" -version = "0.72.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" -dependencies = [ - "bitflags 2.10.0", - "cexpr", - "clang-sys", - "itertools 0.13.0", - "log", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash 2.1.1", - "shlex", - "syn 2.0.114", -] - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" - -[[package]] -name = "bitvec" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" -dependencies = [ - "funty", - "radium", - "tap", - "wyz", -] - -[[package]] -name = "blake2" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" -dependencies = [ - "digest 0.10.7", -] - -[[package]] -name = "blake2b_simd" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06e903a20b159e944f91ec8499fe1e55651480c541ea0a584f5d967c49ad9d99" -dependencies = [ - "arrayref", - "arrayvec", - "constant_time_eq", -] - -[[package]] -name = "blake3" -version = "1.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0" -dependencies = [ - "arrayref", - "arrayvec", - "cc", - "cfg-if", - "constant_time_eq", -] - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array 0.14.7", -] - -[[package]] -name = "block-buffer" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be" -dependencies = [ - "hybrid-array", -] - -[[package]] -name = "bls12_381" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3c196a77437e7cc2fb515ce413a6401291578b5afc8ecb29a3c7ab957f05941" -dependencies = [ - "ff 0.12.1", - "group 0.12.1", - "pairing", - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "brotli" -version = "0.1.0" -dependencies = [ - "lazy_static", - "num_enum 0.7.5", -] - -[[package]] -name = "bumpalo" -version = "3.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" - -[[package]] -name = "byte-slice-cast" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7575182f7272186991736b70173b0ea045398f984bf5ebbb3804736ce1330c9d" - -[[package]] -name = "bytecheck" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0caa33a2c0edca0419d15ac723dff03f1956f7978329b1e3b5fdaaaed9d3ca8b" -dependencies = [ - "bytecheck_derive", - "ptr_meta", - "rancor", - "simdutf8", -] - -[[package]] -name = "bytecheck_derive" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89385e82b5d1821d2219e0b095efa2cc1f246cbf99080f3be46a1a85c0d392d9" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "bytemuck" -version = "1.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" -dependencies = [ - "bytemuck_derive", -] - -[[package]] -name = "bytemuck_derive" -version = "1.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "bytes" -version = "1.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" - -[[package]] -name = "bytesize" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bd91ee7b2422bcb158d90ef4d14f75ef67f340943fc4149891dcce8f8b972a3" - -[[package]] -name = "caller-env" -version = "0.1.0" -dependencies = [ - "brotli", - "hex", - "k256 0.13.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.8.5", - "rand_pcg", - "spin 0.10.0", - "tiny-keccak 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "camino" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e629a66d692cb9ff1a1c664e41771b3dcaf961985a9774c0eb0bd1b51cf60a48" -dependencies = [ - "serde_core", -] - -[[package]] -name = "cargo-platform" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" -dependencies = [ - "serde", -] - -[[package]] -name = "cargo_metadata" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" -dependencies = [ - "camino", - "cargo-platform", - "semver", - "serde", - "serde_json", - "thiserror 1.0.69", -] - -[[package]] -name = "cc" -version = "1.2.50" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f50d563227a1c37cc0a263f64eca3334388c01c5e4c4861a9def205c614383c" -dependencies = [ - "find-msvc-tools", - "shlex", -] - -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - -[[package]] -name = "cfg-if" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" - -[[package]] -name = "cfg_aliases" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" - -[[package]] -name = "chrono" -version = "0.4.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" -dependencies = [ - "iana-time-zone", - "num-traits", - "serde", - "windows-link", -] - -[[package]] -name = "clang-sys" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" -dependencies = [ - "glob", - "libc", - "libloading", -] - -[[package]] -name = "clap" -version = "4.5.53" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap_builder" -version = "4.5.53" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.5.49" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "clap_lex" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" - -[[package]] -name = "cmake" -version = "0.1.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d" -dependencies = [ - "cc", -] - -[[package]] -name = "colorchoice" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" - -[[package]] -name = "console" -version = "0.15.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" -dependencies = [ - "encode_unicode", - "libc", - "once_cell", - "unicode-width 0.2.2", - "windows-sys 0.59.0", -] - -[[package]] -name = "const-default" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b396d1f76d455557e1218ec8066ae14bba60b4b36ecd55577ba979f5db7ecaa" - -[[package]] -name = "const-oid" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" - -[[package]] -name = "const-oid" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" - -[[package]] -name = "const_format" -version = "0.2.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7faa7469a93a566e9ccc1c73fe783b4a65c274c5ace346038dca9c39fe0030ad" -dependencies = [ - "const_format_proc_macros", -] - -[[package]] -name = "const_format_proc_macros" -version = "0.2.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "constant_time_eq" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" - -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - -[[package]] -name = "convert_case" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "corosensei" -version = "0.3.2" -source = "git+https://github.com/OffchainLabs/corosensei?tag=v0.3.2-sp1#08e582a7492621acb09318eab166a96715f3eebd" -dependencies = [ - "autocfg", - "cfg-if", - "libc", - "scopeguard", - "sp1-primitives 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sp1-zkvm", - "windows-sys 0.59.0", -] - -[[package]] -name = "cpufeatures" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] - -[[package]] -name = "crc32fast" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "critical-section" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" - -[[package]] -name = "crossbeam" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-epoch", - "crossbeam-queue", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-queue" -version = "0.3.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" - -[[package]] -name = "crunchy" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" - -[[package]] -name = "crypto-bigint" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" -dependencies = [ - "generic-array 0.14.7", - "rand_core 0.6.4", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-common" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" -dependencies = [ - "generic-array 0.14.7", - "typenum", -] - -[[package]] -name = "crypto-common" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710" -dependencies = [ - "hybrid-array", -] - -[[package]] -name = "darling" -version = "0.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 2.0.114", -] - -[[package]] -name = "darling_macro" -version = "0.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" -dependencies = [ - "darling_core", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "dashmap" -version = "6.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" -dependencies = [ - "cfg-if", - "crossbeam-utils", - "hashbrown 0.14.5", - "lock_api", - "once_cell", - "parking_lot_core", -] - -[[package]] -name = "dashu" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b3e5ac1e23ff1995ef05b912e2b012a8784506987a2651552db2c73fb3d7e0" -dependencies = [ - "dashu-base", - "dashu-float", - "dashu-int", - "dashu-macros", - "dashu-ratio", - "rustversion", -] - -[[package]] -name = "dashu-base" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0b80bf6b85aa68c58ffea2ddb040109943049ce3fbdf4385d0380aef08ef289" - -[[package]] -name = "dashu-float" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85078445a8dbd2e1bd21f04a816f352db8d333643f0c9b78ca7c3d1df71063e7" -dependencies = [ - "dashu-base", - "dashu-int", - "num-modular", - "num-order", - "rustversion", - "static_assertions", -] - -[[package]] -name = "dashu-int" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee99d08031ca34a4d044efbbb21dff9b8c54bb9d8c82a189187c0651ffdb9fbf" -dependencies = [ - "cfg-if", - "dashu-base", - "num-modular", - "num-order", - "rustversion", - "static_assertions", -] - -[[package]] -name = "dashu-macros" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93381c3ef6366766f6e9ed9cf09e4ef9dec69499baf04f0c60e70d653cf0ab10" -dependencies = [ - "dashu-base", - "dashu-float", - "dashu-int", - "dashu-ratio", - "paste", - "proc-macro2", - "quote", - "rustversion", -] - -[[package]] -name = "dashu-ratio" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47e33b04dd7ce1ccf8a02a69d3419e354f2bbfdf4eb911a0b7465487248764c9" -dependencies = [ - "dashu-base", - "dashu-float", - "dashu-int", - "num-modular", - "num-order", - "rustversion", -] - -[[package]] -name = "debugid" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d" -dependencies = [ - "uuid", -] - -[[package]] -name = "deepsize2" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b5184084af9beed35eecbf4c36baf6e26b9dc47b61b74e02f930c72a58e71b" -dependencies = [ - "deepsize_derive2", - "hashbrown 0.14.5", -] - -[[package]] -name = "deepsize_derive2" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0f8817865cacf3b93b943ca06b0fc5fd8e99eabfdb7ea5d296efcbc4afc4f69" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "der" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" -dependencies = [ - "const-oid 0.9.6", - "pem-rfc7468", - "zeroize", -] - -[[package]] -name = "deranged" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" -dependencies = [ - "powerfmt", - "serde_core", -] - -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "derive-where" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef941ded77d15ca19b40374869ac6000af1c9f2a4c0f3d4c70926287e6364a8f" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "derive_more" -version = "0.99.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" -dependencies = [ - "convert_case 0.4.0", - "proc-macro2", - "quote", - "rustc_version", - "syn 2.0.114", -] - -[[package]] -name = "derive_more" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" -dependencies = [ - "derive_more-impl 1.0.0", -] - -[[package]] -name = "derive_more" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10b768e943bed7bf2cab53df09f4bc34bfd217cdb57d971e769874c9a6710618" -dependencies = [ - "derive_more-impl 2.1.0", -] - -[[package]] -name = "derive_more-impl" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "derive_more-impl" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d286bfdaf75e988b4a78e013ecd79c581e06399ab53fbacd2d916c2f904f30b" -dependencies = [ - "convert_case 0.10.0", - "proc-macro2", - "quote", - "rustc_version", - "syn 2.0.114", - "unicode-xid", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer 0.10.4", - "const-oid 0.9.6", - "crypto-common 0.1.7", - "subtle", -] - -[[package]] -name = "digest" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4850db49bf08e663084f7fb5c87d202ef91a3907271aff24a94eb97ff039153c" -dependencies = [ - "block-buffer 0.12.0", - "const-oid 0.10.2", - "crypto-common 0.2.1", -] - -[[package]] -name = "dirs" -version = "5.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" -dependencies = [ - "libc", - "option-ext", - "redox_users", - "windows-sys 0.48.0", -] - -[[package]] -name = "displaydoc" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "downcast-rs" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" - -[[package]] -name = "downloader" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ac1e888d6830712d565b2f3a974be3200be9296bc1b03db8251a4cbf18a4a34" -dependencies = [ - "digest 0.10.7", - "futures", - "rand 0.8.5", - "reqwest", - "thiserror 1.0.69", - "tokio", -] - -[[package]] -name = "dyn-clone" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" - -[[package]] -name = "dynasm" -version = "3.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7d4c414c94bc830797115b8e5f434d58e7e80cb42ba88508c14bc6ea270625" -dependencies = [ - "bitflags 2.10.0", - "byteorder", - "lazy_static", - "proc-macro-error2", - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "dynasm" -version = "5.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df4bf11ba8aecc00489b7ec4e8963cd3860651c3ea2a114394f8ba7e92a0e94a" -dependencies = [ - "bitflags 2.10.0", - "byteorder", - "lazy_static", - "proc-macro-error2", - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "dynasmrt" -version = "3.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "602f7458a3859195fb840e6e0cce5f4330dd9dfbfece0edaf31fe427af346f55" -dependencies = [ - "byteorder", - "dynasm 3.2.1", - "fnv", - "memmap2 0.9.9", -] - -[[package]] -name = "dynasmrt" -version = "5.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b38e5331d851567729d892ed28d898d22f49a96940b29e23b5c3e681bd30ffb3" -dependencies = [ - "byteorder", - "dynasm 5.0.0", - "fnv", - "memmap2 0.9.9", -] - -[[package]] -name = "ecdsa" -version = "0.16.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" -dependencies = [ - "der", - "digest 0.10.7", - "elliptic-curve", - "rfc6979 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serdect", - "signature", - "spki", -] - -[[package]] -name = "ecdsa" -version = "0.16.9" -source = "git+https://github.com/sp1-patches/signatures?tag=sp1-skip-verify-on-recovery#1880299a48fe7ef249edaa616fd411239fb5daf1" -dependencies = [ - "der", - "digest 0.10.7", - "elliptic-curve", - "rfc6979 0.4.0 (git+https://github.com/sp1-patches/signatures?tag=sp1-skip-verify-on-recovery)", - "signature", - "spki", -] - -[[package]] -name = "either" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" -dependencies = [ - "serde", -] - -[[package]] -name = "elf" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4445909572dbd556c457c849c4ca58623d84b27c8fff1e74b0b4227d8b90d17b" - -[[package]] -name = "elliptic-curve" -version = "0.13.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" -dependencies = [ - "base16ct", - "crypto-bigint", - "digest 0.10.7", - "ff 0.13.1", - "generic-array 0.14.7", - "group 0.13.0", - "hkdf", - "pem-rfc7468", - "pkcs8", - "rand_core 0.6.4", - "sec1", - "serdect", - "subtle", - "zeroize", -] - -[[package]] -name = "embedded-alloc" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f2de9133f68db0d4627ad69db767726c99ff8585272716708227008d3f1bddd" -dependencies = [ - "const-default", - "critical-section", - "linked_list_allocator", - "rlsf", -] - -[[package]] -name = "encode_unicode" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" - -[[package]] -name = "enum-iterator" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4549325971814bda7a44061bf3fe7e487d447cba01e4220a4b454d630d7a016" -dependencies = [ - "enum-iterator-derive", -] - -[[package]] -name = "enum-iterator-derive" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "685adfa4d6f3d765a26bc5dbc936577de9abf756c1feeb3089b01dd395034842" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "enum-map" -version = "2.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6866f3bfdf8207509a033af1a75a7b08abda06bbaaeae6669323fd5a097df2e9" -dependencies = [ - "enum-map-derive", - "serde", -] - -[[package]] -name = "enum-map-derive" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "enumset" -version = "1.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b07a8dfbbbfc0064c0a6bdf9edcf966de6b1c33ce344bdeca3b41615452634" -dependencies = [ - "enumset_derive", -] - -[[package]] -name = "enumset_derive" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43e744e4ea338060faee68ed933e46e722fb7f3617e722a5772d7e856d8b3ce" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "env_home" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7f84e12ccf0a7ddc17a6c41c93326024c42920d7ee630d04950e6926645c0fe" - -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - -[[package]] -name = "errno" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" -dependencies = [ - "libc", - "windows-sys 0.61.2", -] - -[[package]] -name = "eventsource-stream" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74fef4569247a5f429d9156b9d0a2599914385dd189c539334c625d8099d90ab" -dependencies = [ - "futures-core", - "nom", - "pin-project-lite", -] - -[[package]] -name = "eyre" -version = "0.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" -dependencies = [ - "indenter", - "once_cell", -] - -[[package]] -name = "fastrand" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" - -[[package]] -name = "ff" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" -dependencies = [ - "bitvec", - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "ff" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" -dependencies = [ - "bitvec", - "byteorder", - "ff_derive", - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "ff_derive" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f10d12652036b0e99197587c6ba87a8fc3031986499973c030d8b44fcc151b60" -dependencies = [ - "addchain", - "num-bigint 0.3.3", - "num-integer", - "num-traits", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "filetime" -version = "0.2.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc0505cd1b6fa6580283f6bdf70a73fcf4aba1184038c90902b92b3dd0df63ed" -dependencies = [ - "cfg-if", - "libc", - "libredox", - "windows-sys 0.60.2", -] - -[[package]] -name = "find-msvc-tools" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" - -[[package]] -name = "fixedbitset" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" - -[[package]] -name = "flate2" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foldhash" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" - -[[package]] -name = "foldhash" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" - -[[package]] -name = "form_urlencoded" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "funty" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" - -[[package]] -name = "futures" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" - -[[package]] -name = "futures-executor" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" - -[[package]] -name = "futures-macro" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "futures-sink" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" - -[[package]] -name = "futures-task" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" - -[[package]] -name = "futures-util" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "gcd" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a" - -[[package]] -name = "gecko_profile" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "890852c7e1e02bc6758e325d6b1e0236e4fbf21b492f585ce4d4715be54b4c6a" -dependencies = [ - "debugid", - "serde", - "serde_json", -] - -[[package]] -name = "gen_ops" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "304de19db7028420975a296ab0fcbbc8e69438c4ed254a1e41e2a7f37d5f0e0a" - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", - "zeroize", -] - -[[package]] -name = "generic-array" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96512db27971c2c3eece70a1e106fbe6c87760234e31e8f7e5634912fe52794a" -dependencies = [ - "serde", - "typenum", -] - -[[package]] -name = "getrandom" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "wasi", - "wasm-bindgen", -] - -[[package]] -name = "getrandom" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "r-efi 5.3.0", - "wasip2", - "wasm-bindgen", -] - -[[package]] -name = "getrandom" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "r-efi 6.0.0", - "wasip2", - "wasip3", - "wasm-bindgen", -] - -[[package]] -name = "gimli" -version = "0.32.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" - -[[package]] -name = "gimli" -version = "0.33.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf7f043f89559805f8c7cacc432749b2fa0d0a0a9ee46ce47164ed5ba7f126c" -dependencies = [ - "fnv", - "hashbrown 0.16.1", - "indexmap 2.13.0", - "stable_deref_trait", -] - -[[package]] -name = "glob" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" - -[[package]] -name = "group" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" -dependencies = [ - "ff 0.12.1", - "memuse", - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "group" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" -dependencies = [ - "ff 0.13.1", - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "h2" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" -dependencies = [ - "atomic-waker", - "bytes", - "fnv", - "futures-core", - "futures-sink", - "http", - "indexmap 2.13.0", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "halo2" -version = "0.1.0-beta.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a23c779b38253fe1538102da44ad5bd5378495a61d2c4ee18d64eaa61ae5995" -dependencies = [ - "halo2_proofs", -] - -[[package]] -name = "halo2_proofs" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e925780549adee8364c7f2b685c753f6f3df23bde520c67416e93bf615933760" -dependencies = [ - "blake2b_simd", - "ff 0.12.1", - "group 0.12.1", - "pasta_curves 0.4.1", - "rand_core 0.6.4", - "rayon", -] - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "hashbrown" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" -dependencies = [ - "ahash", - "allocator-api2", - "serde", -] - -[[package]] -name = "hashbrown" -version = "0.15.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" -dependencies = [ - "allocator-api2", - "equivalent", - "foldhash 0.1.5", -] - -[[package]] -name = "hashbrown" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" -dependencies = [ - "foldhash 0.2.0", - "serde", - "serde_core", -] - -[[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.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hkdf" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" -dependencies = [ - "hmac", -] - -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest 0.10.7", -] - -[[package]] -name = "http" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" -dependencies = [ - "bytes", - "itoa", -] - -[[package]] -name = "http-body" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" -dependencies = [ - "bytes", - "http", -] - -[[package]] -name = "http-body-util" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" -dependencies = [ - "bytes", - "futures-core", - "http", - "http-body", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" - -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - -[[package]] -name = "hybrid-array" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8655f91cd07f2b9d0c24137bd650fe69617773435ee5ec83022377777ce65ef1" -dependencies = [ - "typenum", -] - -[[package]] -name = "hyper" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" -dependencies = [ - "atomic-waker", - "bytes", - "futures-channel", - "futures-core", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "pin-utils", - "smallvec", - "tokio", - "want", -] - -[[package]] -name = "hyper-rustls" -version = "0.27.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" -dependencies = [ - "http", - "hyper", - "hyper-util", - "rustls", - "rustls-pki-types", - "tokio", - "tokio-rustls", - "tower-service", - "webpki-roots", -] - -[[package]] -name = "hyper-timeout" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" -dependencies = [ - "hyper", - "hyper-util", - "pin-project-lite", - "tokio", - "tower-service", -] - -[[package]] -name = "hyper-util" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f" -dependencies = [ - "base64 0.22.1", - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "http", - "http-body", - "hyper", - "ipnet", - "libc", - "percent-encoding", - "pin-project-lite", - "socket2 0.6.1", - "tokio", - "tower-service", - "tracing", -] - -[[package]] -name = "iana-time-zone" -version = "0.1.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "log", - "wasm-bindgen", - "windows-core 0.62.2", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] -name = "icu_collections" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" -dependencies = [ - "displaydoc", - "potential_utf", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_locale_core" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" -dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", -] - -[[package]] -name = "icu_normalizer" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" -dependencies = [ - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "zerovec", -] - -[[package]] -name = "icu_normalizer_data" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" - -[[package]] -name = "icu_properties" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" -dependencies = [ - "icu_collections", - "icu_locale_core", - "icu_properties_data", - "icu_provider", - "zerotrie", - "zerovec", -] - -[[package]] -name = "icu_properties_data" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" - -[[package]] -name = "icu_provider" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" -dependencies = [ - "displaydoc", - "icu_locale_core", - "writeable", - "yoke", - "zerofrom", - "zerotrie", - "zerovec", -] - -[[package]] -name = "id-arena" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" - -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - -[[package]] -name = "idna" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" -dependencies = [ - "idna_adapter", - "smallvec", - "utf8_iter", -] - -[[package]] -name = "idna_adapter" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" -dependencies = [ - "icu_normalizer", - "icu_properties", -] - -[[package]] -name = "impl-trait-for-tuples" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "indenter" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5" - -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", - "serde", -] - -[[package]] -name = "indexmap" -version = "2.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" -dependencies = [ - "equivalent", - "hashbrown 0.16.1", - "serde", - "serde_core", -] - -[[package]] -name = "indicatif" -version = "0.17.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "183b3088984b400f4cfac3620d5e076c84da5364016b4f49473de574b2586235" -dependencies = [ - "console", - "number_prefix", - "portable-atomic", - "unicode-width 0.2.2", - "web-time", -] - -[[package]] -name = "inkwell" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1def4112dfb2ce2993db7027f7acdb43c1f4ee1c70a082a2eef306ed5d0df365" -dependencies = [ - "inkwell_internals", - "libc", - "llvm-sys", - "once_cell", - "thiserror 2.0.17", -] - -[[package]] -name = "inkwell_internals" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63736175c9a30ea123f7018de9f26163e0b39cd6978990ae486b510c4f3bad69" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "ipnet" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" - -[[package]] -name = "iri-string" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f867b9d1d896b67beb18518eda36fdb77a32ea590de864f1325b294a6d14397" -dependencies = [ - "memchr", - "serde", -] - -[[package]] -name = "is_terminal_polyfill" -version = "1.70.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -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 = "itertools" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ee5b5339afb4c41626dde77b7a611bd4f2c202b897852b4bcf5d03eddc61010" - -[[package]] -name = "js-sys" -version = "0.3.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" -dependencies = [ - "once_cell", - "wasm-bindgen", -] - -[[package]] -name = "jubjub" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a575df5f985fe1cd5b2b05664ff6accfc46559032b954529fd225a2168d27b0f" -dependencies = [ - "bitvec", - "bls12_381", - "ff 0.12.1", - "group 0.12.1", - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "k256" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" -dependencies = [ - "cfg-if", - "ecdsa 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", - "elliptic-curve", - "once_cell", - "serdect", - "sha2 0.10.9", - "signature", -] - -[[package]] -name = "k256" -version = "0.13.4" -source = "git+https://github.com/sp1-patches/elliptic-curves?tag=patch-k256-13.4-sp1-6.0.0#0efe186cee5930a0d23501651c226bd81fcc2c15" -dependencies = [ - "cfg-if", - "ecdsa 0.16.9 (git+https://github.com/sp1-patches/signatures?tag=sp1-skip-verify-on-recovery)", - "elliptic-curve", - "hex", - "once_cell", - "sha2 0.10.9", - "signature", - "sp1-lib 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "keccak" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" -dependencies = [ - "cpufeatures", -] - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" -dependencies = [ - "spin 0.9.8", -] - -[[package]] -name = "leb128" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" - -[[package]] -name = "leb128fmt" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" - -[[package]] -name = "libc" -version = "0.2.178" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" - -[[package]] -name = "libloading" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" -dependencies = [ - "cfg-if", - "windows-link", -] - -[[package]] -name = "libm" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" - -[[package]] -name = "libredox" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df15f6eac291ed1cf25865b1ee60399f57e7c227e7f51bdbd4c5270396a9ed50" -dependencies = [ - "bitflags 2.10.0", - "libc", - "redox_syscall 0.6.0", -] - -[[package]] -name = "libunwind" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c6639b70a7ce854b79c70d7e83f16b5dc0137cc914f3d7d03803b513ecc67ac" - -[[package]] -name = "linked_list_allocator" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afa463f5405ee81cdb9cc2baf37e08ec7e4c8209442b5d72c04cfb2cd6e6286" - -[[package]] -name = "linux-raw-sys" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" - -[[package]] -name = "litemap" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" - -[[package]] -name = "llvm-sys" -version = "211.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "108b3ad2b2eaf2a561fc74196273b20e3436e4a688b8b44e250d83974dc1b2e2" -dependencies = [ - "anyhow", - "cc", - "lazy_static", - "libc", - "regex-lite", - "semver", -] - -[[package]] -name = "lock_api" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" -dependencies = [ - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" - -[[package]] -name = "lru" -version = "0.12.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" -dependencies = [ - "hashbrown 0.15.5", -] - -[[package]] -name = "lru-slab" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" - -[[package]] -name = "mach2" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d640282b302c0bb0a2a8e0233ead9035e3bed871f0b7e81fe4a1ec829765db44" -dependencies = [ - "libc", -] - -[[package]] -name = "mach2" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dae608c151f68243f2b000364e1f7b186d9c29845f7d2d85bd31b9ad77ad552b" - -[[package]] -name = "macho-unwind-info" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb4bdc8b0ce69932332cf76d24af69c3a155242af95c226b2ab6c2e371ed1149" -dependencies = [ - "thiserror 2.0.17", - "zerocopy", - "zerocopy-derive", -] - -[[package]] -name = "matchers" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" -dependencies = [ - "regex-automata", -] - -[[package]] -name = "matchit" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" - -[[package]] -name = "md-5" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" -dependencies = [ - "cfg-if", - "digest 0.10.7", -] - -[[package]] -name = "memchr" -version = "2.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" - -[[package]] -name = "memfd" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad38eb12aea514a0466ea40a80fd8cc83637065948eb4a426e4aa46261175227" -dependencies = [ - "rustix", -] - -[[package]] -name = "memmap2" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d28bba84adfe6646737845bc5ebbfa2c08424eb1c37e94a1fd2a82adb56a872" -dependencies = [ - "libc", -] - -[[package]] -name = "memmap2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744133e4a0e0a658e1374cf3bf8e415c4052a15a111acd372764c55b4177d490" -dependencies = [ - "libc", -] - -[[package]] -name = "memoffset" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" -dependencies = [ - "autocfg", -] - -[[package]] -name = "memuse" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d97bbf43eb4f088f8ca469930cde17fa036207c9a5e02ccc5107c4e8b17c964" - -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] -name = "miniz_oxide" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" -dependencies = [ - "adler2", - "simd-adler32", -] - -[[package]] -name = "mio" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" -dependencies = [ - "libc", - "wasi", - "windows-sys 0.61.2", -] - -[[package]] -name = "more-asserts" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fafa6961cabd9c63bcd77a45d7e3b7f3b552b70417831fb0f56db717e72407e" - -[[package]] -name = "mti" -version = "1.0.7-beta.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73e89058909957124fd8271ac984c38733f080e0f0edd93322f82d7bd6a0010a" -dependencies = [ - "typeid_prefix", - "typeid_suffix", -] - -[[package]] -name = "multimap" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084" - -[[package]] -name = "munge" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e17401f259eba956ca16491461b6e8f72913a0a114e39736ce404410f915a0c" -dependencies = [ - "munge_macro", -] - -[[package]] -name = "munge_macro" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4568f25ccbd45ab5d5603dc34318c1ec56b117531781260002151b8530a9f931" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "ntapi" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c70f219e21142367c70c0b30c6a9e3a14d55b4d12a204d897fbec83a0363f081" -dependencies = [ - "winapi", -] - -[[package]] -name = "nu-ansi-term" -version = "0.50.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" -dependencies = [ - "windows-sys 0.61.2", -] - -[[package]] -name = "num" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" -dependencies = [ - "num-bigint 0.4.6", - "num-complex", - "num-integer", - "num-iter", - "num-rational", - "num-traits", -] - -[[package]] -name = "num-bigint" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6f7833f2cbf2360a6cfd58cd41a53aa7a90bd4c202f5b1c7dd2ed73c57b2c3" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-bigint" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" -dependencies = [ - "num-integer", - "num-traits", -] - -[[package]] -name = "num-complex" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-conv" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" - -[[package]] -name = "num-derive" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-iter" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-modular" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17bb261bf36fa7d83f4c294f834e91256769097b3cb505d44831e0a179ac647f" - -[[package]] -name = "num-order" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "537b596b97c40fcf8056d153049eb22f481c17ebce72a513ec9286e4986d1bb6" -dependencies = [ - "num-modular", -] - -[[package]] -name = "num-rational" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" -dependencies = [ - "num-bigint 0.4.6", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "num_enum" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" -dependencies = [ - "num_enum_derive 0.5.11", -] - -[[package]] -name = "num_enum" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c" -dependencies = [ - "num_enum_derive 0.7.5", - "rustversion", -] - -[[package]] -name = "num_enum_derive" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" -dependencies = [ - "proc-macro-crate 1.3.1", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "num_enum_derive" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" -dependencies = [ - "proc-macro-crate 3.4.0", - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "number_prefix" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" - -[[package]] -name = "object" -version = "0.37.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" -dependencies = [ - "crc32fast", - "flate2", - "hashbrown 0.15.5", - "indexmap 2.13.0", - "memchr", - "ruzstd", -] - -[[package]] -name = "object" -version = "0.38.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271638cd5fa9cca89c4c304675ca658efc4e64a66c716b7cfe1afb4b9611dbbc" -dependencies = [ - "crc32fast", - "flate2", - "hashbrown 0.16.1", - "indexmap 2.13.0", - "memchr", - "ruzstd", -] - -[[package]] -name = "once_cell" -version = "1.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" - -[[package]] -name = "once_cell_polyfill" -version = "1.70.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" - -[[package]] -name = "opentelemetry" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b69a91d4893e713e06f724597ad630f1fa76057a5e1026c0ca67054a9032a76" -dependencies = [ - "futures-core", - "futures-sink", - "js-sys", - "once_cell", - "pin-project-lite", - "thiserror 1.0.69", -] - -[[package]] -name = "option-ext" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" - -[[package]] -name = "p256" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" -dependencies = [ - "ecdsa 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", - "elliptic-curve", - "primeorder", - "sha2 0.10.9", -] - -[[package]] -name = "p3-air" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" -dependencies = [ - "p3-field 0.1.0", - "p3-matrix 0.1.0", - "serde", -] - -[[package]] -name = "p3-baby-bear" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" -dependencies = [ - "num-bigint 0.4.6", - "p3-field 0.1.0", - "p3-mds 0.1.0", - "p3-poseidon2 0.1.0", - "p3-symmetric 0.1.0", - "rand 0.8.5", - "serde", -] - -[[package]] -name = "p3-baby-bear" -version = "0.2.3-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7521838ecab2ddf4f7bc4ceebad06ec02414729598485c1ada516c39900820e8" -dependencies = [ - "num-bigint 0.4.6", - "p3-field 0.2.3-succinct", - "p3-mds 0.2.3-succinct", - "p3-poseidon2 0.2.3-succinct", - "p3-symmetric 0.2.3-succinct", - "rand 0.8.5", - "serde", -] - -[[package]] -name = "p3-bn254-fr" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" -dependencies = [ - "ff 0.13.1", - "num-bigint 0.4.6", - "p3-field 0.1.0", - "p3-poseidon2 0.1.0", - "p3-symmetric 0.1.0", - "rand 0.8.5", - "serde", -] - -[[package]] -name = "p3-bn254-fr" -version = "0.3.1-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebf15b2e55afdfc5ef84bb0a2508a96a924f3d86b8b616053ee727293a02121d" -dependencies = [ - "ff 0.13.1", - "num-bigint 0.4.6", - "p3-field 0.3.1-succinct", - "p3-poseidon2 0.3.1-succinct", - "p3-symmetric 0.3.1-succinct", - "rand 0.8.5", - "serde", -] - -[[package]] -name = "p3-challenger" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" -dependencies = [ - "p3-field 0.1.0", - "p3-maybe-rayon 0.1.0", - "p3-symmetric 0.1.0", - "p3-util 0.1.0", - "serde", - "tracing", -] - -[[package]] -name = "p3-challenger" -version = "0.3.1-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b647fe6cb51bb873d09aab77cecf3afe38bd94284fc14d04d57d52f0d26666" -dependencies = [ - "p3-field 0.3.1-succinct", - "p3-maybe-rayon 0.3.1-succinct", - "p3-symmetric 0.3.1-succinct", - "p3-util 0.3.1-succinct", - "serde", - "tracing", -] - -[[package]] -name = "p3-commit" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" -dependencies = [ - "itertools 0.12.1", - "p3-challenger 0.1.0", - "p3-field 0.1.0", - "p3-matrix 0.1.0", - "p3-util 0.1.0", - "serde", -] - -[[package]] -name = "p3-dft" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" -dependencies = [ - "p3-field 0.1.0", - "p3-matrix 0.1.0", - "p3-maybe-rayon 0.1.0", - "p3-util 0.1.0", - "tracing", -] - -[[package]] -name = "p3-dft" -version = "0.2.3-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46414daedd796f1eefcdc1811c0484e4bced5729486b6eaba9521c572c76761a" -dependencies = [ - "p3-field 0.2.3-succinct", - "p3-matrix 0.2.3-succinct", - "p3-maybe-rayon 0.2.3-succinct", - "p3-util 0.2.3-succinct", - "tracing", -] - -[[package]] -name = "p3-dft" -version = "0.3.1-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8169aac0ed2575c6c44953a7fa162e3dd07f9a22021e36b4db9d8bd15a3373b8" -dependencies = [ - "p3-field 0.3.1-succinct", - "p3-matrix 0.3.1-succinct", - "p3-maybe-rayon 0.3.1-succinct", - "p3-util 0.3.1-succinct", - "tracing", -] - -[[package]] -name = "p3-field" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" -dependencies = [ - "itertools 0.12.1", - "num-bigint 0.4.6", - "num-traits", - "p3-util 0.1.0", - "rand 0.8.5", - "serde", -] - -[[package]] -name = "p3-field" -version = "0.2.3-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48948a0516b349e9d1cdb95e7236a6ee010c44e68c5cc78b4b92bf1c4022a0d9" -dependencies = [ - "itertools 0.12.1", - "num-bigint 0.4.6", - "num-traits", - "p3-util 0.2.3-succinct", - "rand 0.8.5", - "serde", -] - -[[package]] -name = "p3-field" -version = "0.3.1-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f82ed2dfd1e7d6e8759a9605c71b8a2a543069017dfdb6dafe71e7a2ccca937" -dependencies = [ - "itertools 0.12.1", - "num-bigint 0.4.6", - "num-traits", - "p3-util 0.3.1-succinct", - "rand 0.8.5", - "serde", -] - -[[package]] -name = "p3-fri" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" -dependencies = [ - "itertools 0.12.1", - "p3-challenger 0.1.0", - "p3-commit", - "p3-dft 0.1.0", - "p3-field 0.1.0", - "p3-interpolation", - "p3-matrix 0.1.0", - "p3-maybe-rayon 0.1.0", - "p3-util 0.1.0", - "serde", - "tracing", -] - -[[package]] -name = "p3-interpolation" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" -dependencies = [ - "p3-field 0.1.0", - "p3-matrix 0.1.0", - "p3-util 0.1.0", -] - -[[package]] -name = "p3-keccak-air" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" -dependencies = [ - "p3-air", - "p3-field 0.1.0", - "p3-matrix 0.1.0", - "p3-maybe-rayon 0.1.0", - "p3-util 0.1.0", - "tracing", -] - -[[package]] -name = "p3-koala-bear" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" -dependencies = [ - "num-bigint 0.4.6", - "p3-field 0.1.0", - "p3-mds 0.1.0", - "p3-poseidon2 0.1.0", - "p3-symmetric 0.1.0", - "rand 0.8.5", - "serde", -] - -[[package]] -name = "p3-koala-bear" -version = "0.3.1-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60e2d5bc3601f6115afd9a55a718bdab49e98d44710438008204d2084d5d70d0" -dependencies = [ - "num-bigint 0.4.6", - "p3-field 0.3.1-succinct", - "p3-mds 0.3.1-succinct", - "p3-poseidon2 0.3.1-succinct", - "p3-symmetric 0.3.1-succinct", - "rand 0.8.5", - "serde", -] - -[[package]] -name = "p3-matrix" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" -dependencies = [ - "itertools 0.12.1", - "p3-field 0.1.0", - "p3-maybe-rayon 0.1.0", - "p3-util 0.1.0", - "rand 0.8.5", - "serde", - "tracing", -] - -[[package]] -name = "p3-matrix" -version = "0.2.3-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4de3f373589477cb735ea58e125898ed20935e03664b4614c7fac258b3c42f" -dependencies = [ - "itertools 0.12.1", - "p3-field 0.2.3-succinct", - "p3-maybe-rayon 0.2.3-succinct", - "p3-util 0.2.3-succinct", - "rand 0.8.5", - "serde", - "tracing", -] - -[[package]] -name = "p3-matrix" -version = "0.3.1-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ef05490e47c906f102e08493986b1d3c6b6e2c6be9937eaab2c970ccf5385e8" -dependencies = [ - "itertools 0.12.1", - "p3-field 0.3.1-succinct", - "p3-maybe-rayon 0.3.1-succinct", - "p3-util 0.3.1-succinct", - "rand 0.8.5", - "serde", - "tracing", -] - -[[package]] -name = "p3-maybe-rayon" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" -dependencies = [ - "rayon", -] - -[[package]] -name = "p3-maybe-rayon" -version = "0.2.3-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3968ad1160310296eb04f91a5f4edfa38fe1d6b2b8cd6b5c64e6f9b7370979e" - -[[package]] -name = "p3-maybe-rayon" -version = "0.3.1-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3d38c20290b92011f12a3fc040a999197e71e1663614998393a24aee4d430da" - -[[package]] -name = "p3-mds" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" -dependencies = [ - "itertools 0.12.1", - "p3-dft 0.1.0", - "p3-field 0.1.0", - "p3-matrix 0.1.0", - "p3-symmetric 0.1.0", - "p3-util 0.1.0", - "rand 0.8.5", -] - -[[package]] -name = "p3-mds" -version = "0.2.3-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2356b1ed0add6d5dfbf7a338ce534a6fde827374394a52cec16a0840af6e97c9" -dependencies = [ - "itertools 0.12.1", - "p3-dft 0.2.3-succinct", - "p3-field 0.2.3-succinct", - "p3-matrix 0.2.3-succinct", - "p3-symmetric 0.2.3-succinct", - "p3-util 0.2.3-succinct", - "rand 0.8.5", -] - -[[package]] -name = "p3-mds" -version = "0.3.1-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b707ec6432a15661ce67e5fc3abb1c2653e0064030d99c8cece4a049b31ebb1a" -dependencies = [ - "itertools 0.12.1", - "p3-dft 0.3.1-succinct", - "p3-field 0.3.1-succinct", - "p3-matrix 0.3.1-succinct", - "p3-symmetric 0.3.1-succinct", - "p3-util 0.3.1-succinct", - "rand 0.8.5", -] - -[[package]] -name = "p3-merkle-tree" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" -dependencies = [ - "itertools 0.12.1", - "p3-commit", - "p3-field 0.1.0", - "p3-matrix 0.1.0", - "p3-maybe-rayon 0.1.0", - "p3-symmetric 0.1.0", - "p3-util 0.1.0", - "serde", - "tracing", -] - -[[package]] -name = "p3-poseidon2" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" -dependencies = [ - "gcd", - "p3-field 0.1.0", - "p3-mds 0.1.0", - "p3-symmetric 0.1.0", - "rand 0.8.5", - "serde", -] - -[[package]] -name = "p3-poseidon2" -version = "0.2.3-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da1eec7e1b6900581bedd95e76e1ef4975608dd55be9872c9d257a8a9651c3a" -dependencies = [ - "gcd", - "p3-field 0.2.3-succinct", - "p3-mds 0.2.3-succinct", - "p3-symmetric 0.2.3-succinct", - "rand 0.8.5", - "serde", -] - -[[package]] -name = "p3-poseidon2" -version = "0.3.1-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9c6dbf170a3fb4d7556023315a525e08c4b94b572bc307eadbf9065bddaf489" -dependencies = [ - "gcd", - "p3-field 0.3.1-succinct", - "p3-mds 0.3.1-succinct", - "p3-symmetric 0.3.1-succinct", - "rand 0.8.5", - "serde", -] - -[[package]] -name = "p3-symmetric" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" -dependencies = [ - "itertools 0.12.1", - "p3-field 0.1.0", - "serde", -] - -[[package]] -name = "p3-symmetric" -version = "0.2.3-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edb439bea1d822623b41ff4b51e3309e80d13cadf8b86d16ffd5e6efb9fdc360" -dependencies = [ - "itertools 0.12.1", - "p3-field 0.2.3-succinct", - "serde", -] - -[[package]] -name = "p3-symmetric" -version = "0.3.1-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7ec3a99c3dc3d55d0e78ef7041e0d90bdfbf03451e4f0bae3f9877af99cabb3" -dependencies = [ - "itertools 0.12.1", - "p3-field 0.3.1-succinct", - "serde", -] - -[[package]] -name = "p3-uni-stark" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" -dependencies = [ - "itertools 0.12.1", - "p3-air", - "p3-challenger 0.1.0", - "p3-commit", - "p3-dft 0.1.0", - "p3-field 0.1.0", - "p3-matrix 0.1.0", - "p3-maybe-rayon 0.1.0", - "p3-util 0.1.0", - "serde", - "tracing", -] - -[[package]] -name = "p3-util" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3/?branch=sp1-v6#ce9cdfa52326beb93d77669cee52e23287fdb16d" -dependencies = [ - "serde", -] - -[[package]] -name = "p3-util" -version = "0.2.3-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c2c2010678b9332b563eaa38364915b585c1a94b5ca61e2c7541c087ddda5c" -dependencies = [ - "serde", -] - -[[package]] -name = "p3-util" -version = "0.3.1-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712473f2a848b672eee90c3b9cd4bfcd3da042112c53a0dc6b088fc3964538ab" -dependencies = [ - "serde", -] - -[[package]] -name = "pairing" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "135590d8bdba2b31346f9cd1fb2a912329f5135e832a4f422942eb6ead8b6b3b" -dependencies = [ - "group 0.12.1", -] - -[[package]] -name = "parity-scale-codec" -version = "3.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "799781ae679d79a948e13d4824a40970bfa500058d245760dd857301059810fa" -dependencies = [ - "arrayvec", - "byte-slice-cast", - "const_format", - "impl-trait-for-tuples", - "parity-scale-codec-derive", - "rustversion", -] - -[[package]] -name = "parity-scale-codec-derive" -version = "3.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34b4653168b563151153c9e4c08ebed57fb8262bebfa79711552fa983c623e7a" -dependencies = [ - "proc-macro-crate 3.4.0", - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "parking_lot" -version = "0.12.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall 0.5.18", - "smallvec", - "windows-link", -] - -[[package]] -name = "pasta_curves" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc65faf8e7313b4b1fbaa9f7ca917a0eed499a9663be71477f87993604341d8" -dependencies = [ - "blake2b_simd", - "ff 0.12.1", - "group 0.12.1", - "lazy_static", - "rand 0.8.5", - "static_assertions", - "subtle", -] - -[[package]] -name = "pasta_curves" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e57598f73cc7e1b2ac63c79c517b31a0877cd7c402cdcaa311b5208de7a095" -dependencies = [ - "blake2b_simd", - "ff 0.13.1", - "group 0.13.0", - "lazy_static", - "rand 0.8.5", - "static_assertions", - "subtle", -] - -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - -[[package]] -name = "pem-rfc7468" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" -dependencies = [ - "base64ct", -] - -[[package]] -name = "percent-encoding" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" - -[[package]] -name = "petgraph" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" -dependencies = [ - "fixedbitset", - "indexmap 2.13.0", -] - -[[package]] -name = "phf" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" -dependencies = [ - "phf_macros", - "phf_shared", - "serde", -] - -[[package]] -name = "phf_generator" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737" -dependencies = [ - "fastrand", - "phf_shared", -] - -[[package]] -name = "phf_macros" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef" -dependencies = [ - "phf_generator", - "phf_shared", - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "phf_shared" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266" -dependencies = [ - "siphasher 1.0.1", -] - -[[package]] -name = "pin-project" -version = "1.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkcs8" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der", - "spki", -] - -[[package]] -name = "portable-atomic" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f59e70c4aef1e55797c2e8fd94a4f2a973fc972cfde0e0b05f683667b0cd39dd" - -[[package]] -name = "potential_utf" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" -dependencies = [ - "zerovec", -] - -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - -[[package]] -name = "ppv-lite86" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "prettyplease" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" -dependencies = [ - "proc-macro2", - "syn 2.0.114", -] - -[[package]] -name = "primeorder" -version = "0.13.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" -dependencies = [ - "elliptic-curve", -] - -[[package]] -name = "proc-macro-crate" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" -dependencies = [ - "once_cell", - "toml_edit 0.19.15", -] - -[[package]] -name = "proc-macro-crate" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" -dependencies = [ - "toml_edit 0.23.10+spec-1.0.0", -] - -[[package]] -name = "proc-macro-error-attr2" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" -dependencies = [ - "proc-macro2", - "quote", -] - -[[package]] -name = "proc-macro-error2" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" -dependencies = [ - "proc-macro-error-attr2", - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "proc-macro2" -version = "1.0.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "program" -version = "0.1.0" -dependencies = [ - "arbutil", - "bytes", - "caller-env", - "corosensei", - "eyre", - "hex", - "num-traits", - "once_cell", - "prover", - "rand 0.8.5", - "rand_pcg", - "ruint2", - "secp256k1", - "serde_json", - "sp1-zkvm", - "thiserror 1.0.69", - "tiny-keccak 2.0.2 (git+https://github.com/sp1-patches/tiny-keccak?tag=patch-2.0.2-sp1-6.0.0)", - "validation", - "wasmer", - "wasmer-types", - "wasmer-vm", -] - -[[package]] -name = "prost" -version = "0.13.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5" -dependencies = [ - "bytes", - "prost-derive", -] - -[[package]] -name = "prost-build" -version = "0.13.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be769465445e8c1474e9c5dac2018218498557af32d9ed057325ec9a41ae81bf" -dependencies = [ - "heck", - "itertools 0.14.0", - "log", - "multimap", - "once_cell", - "petgraph", - "prettyplease", - "prost", - "prost-types", - "regex", - "syn 2.0.114", - "tempfile", -] - -[[package]] -name = "prost-derive" -version = "0.13.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" -dependencies = [ - "anyhow", - "itertools 0.14.0", - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "prost-types" -version = "0.13.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52c2c1bf36ddb1a1c396b3601a3cec27c2462e45f07c386894ec3ccf5332bd16" -dependencies = [ - "prost", -] - -[[package]] -name = "prover" -version = "0.1.0" -dependencies = [ - "arbutil", - "brotli", - "derivative", - "digest 0.10.7", - "eyre", - "fnv", - "lazy_static", - "nom", - "num-derive", - "num-traits", - "parking_lot", - "serde", - "serde_with", - "sha3", - "wasmer", - "wasmer-types", - "wasmparser 0.245.1", -] - -[[package]] -name = "ptr_meta" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9a0cf95a1196af61d4f1cbdab967179516d9a4a4312af1f31948f8f6224a79" -dependencies = [ - "ptr_meta_derive", -] - -[[package]] -name = "ptr_meta_derive" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7347867d0a7e1208d93b46767be83e2b8f978c3dad35f775ac8d8847551d6fe1" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "quinn" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" -dependencies = [ - "bytes", - "cfg_aliases", - "pin-project-lite", - "quinn-proto", - "quinn-udp", - "rustc-hash 2.1.1", - "rustls", - "socket2 0.6.1", - "thiserror 2.0.17", - "tokio", - "tracing", - "web-time", -] - -[[package]] -name = "quinn-proto" -version = "0.11.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" -dependencies = [ - "bytes", - "getrandom 0.3.4", - "lru-slab", - "rand 0.9.2", - "ring", - "rustc-hash 2.1.1", - "rustls", - "rustls-pki-types", - "slab", - "thiserror 2.0.17", - "tinyvec", - "tracing", - "web-time", -] - -[[package]] -name = "quinn-udp" -version = "0.5.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" -dependencies = [ - "cfg_aliases", - "libc", - "once_cell", - "socket2 0.6.1", - "tracing", - "windows-sys 0.60.2", -] - -[[package]] -name = "quote" -version = "1.0.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "r-efi" -version = "5.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" - -[[package]] -name = "r-efi" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" - -[[package]] -name = "radium" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" - -[[package]] -name = "rancor" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a063ea72381527c2a0561da9c80000ef822bdd7c3241b1cc1b12100e3df081ee" -dependencies = [ - "ptr_meta", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" -dependencies = [ - "rand_chacha 0.9.0", - "rand_core 0.9.3", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" -dependencies = [ - "ppv-lite86", - "rand_core 0.9.3", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.16", -] - -[[package]] -name = "rand_core" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" -dependencies = [ - "getrandom 0.3.4", -] - -[[package]] -name = "rand_pcg" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59cad018caf63deb318e5a4586d99a24424a364f40f1e5778c29aca23f4fc73e" -dependencies = [ - "rand_core 0.6.4", -] - -[[package]] -name = "range-set-blaze" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8421b5d459262eabbe49048d362897ff3e3830b44eac6cfe341d6acb2f0f13d2" -dependencies = [ - "gen_ops", - "itertools 0.12.1", - "num-integer", - "num-traits", -] - -[[package]] -name = "rangemap" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "973443cf09a9c8656b574a866ab68dfa19f0867d0340648c7d2f6a71b8a8ea68" - -[[package]] -name = "rayon" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] - -[[package]] -name = "rayon-scan" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f87cc11a0140b4b0da0ffc889885760c61b13672d80a908920b2c0df078fa14" -dependencies = [ - "rayon", -] - -[[package]] -name = "redox_syscall" -version = "0.5.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" -dependencies = [ - "bitflags 2.10.0", -] - -[[package]] -name = "redox_syscall" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec96166dafa0886eb81fe1c0a388bece180fbef2135f97c1e2cf8302e74b43b5" -dependencies = [ - "bitflags 2.10.0", -] - -[[package]] -name = "redox_users" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" -dependencies = [ - "getrandom 0.2.16", - "libredox", - "thiserror 1.0.69", -] - -[[package]] -name = "ref-cast" -version = "1.0.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" -dependencies = [ - "ref-cast-impl", -] - -[[package]] -name = "ref-cast-impl" -version = "1.0.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "regex" -version = "1.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-lite" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d942b98df5e658f56f20d592c7f868833fe38115e65c33003d8cd224b0155da" - -[[package]] -name = "regex-syntax" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" - -[[package]] -name = "region" -version = "3.0.2" -source = "git+https://github.com/OffchainLabs/region-rs?tag=v3.0.2-sp1#ece52311bd1deff19b48f861ab2abe121b55007e" -dependencies = [ - "bitflags 1.3.2", - "libc", - "mach2 0.4.3", - "sp1-primitives 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sp1-zkvm", - "windows-sys 0.52.0", -] - -[[package]] -name = "rend" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cadadef317c2f20755a64d7fdc48f9e7178ee6b0e1f7fce33fa60f1d68a276e6" -dependencies = [ - "bytecheck", -] - -[[package]] -name = "reqwest" -version = "0.12.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b4c14b2d9afca6a60277086b0cc6a6ae0b568f6f7916c943a8cdc79f8be240f" -dependencies = [ - "base64 0.22.1", - "bytes", - "futures-core", - "futures-util", - "http", - "http-body", - "http-body-util", - "hyper", - "hyper-rustls", - "hyper-util", - "js-sys", - "log", - "percent-encoding", - "pin-project-lite", - "quinn", - "rustls", - "rustls-pki-types", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "tokio", - "tokio-rustls", - "tokio-util", - "tower 0.5.2", - "tower-http", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-streams", - "web-sys", - "webpki-roots", -] - -[[package]] -name = "rfc6979" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" -dependencies = [ - "hmac", - "subtle", -] - -[[package]] -name = "rfc6979" -version = "0.4.0" -source = "git+https://github.com/sp1-patches/signatures?tag=sp1-skip-verify-on-recovery#1880299a48fe7ef249edaa616fd411239fb5daf1" -dependencies = [ - "hmac", - "subtle", -] - -[[package]] -name = "ring" -version = "0.17.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" -dependencies = [ - "cc", - "cfg-if", - "getrandom 0.2.16", - "libc", - "untrusted", - "windows-sys 0.52.0", -] - -[[package]] -name = "rkyv" -version = "0.8.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a30e631b7f4a03dee9056b8ef6982e8ba371dd5bedb74d3ec86df4499132c70" -dependencies = [ - "bytecheck", - "bytes", - "hashbrown 0.16.1", - "indexmap 2.13.0", - "munge", - "ptr_meta", - "rancor", - "rend", - "rkyv_derive", - "tinyvec", - "uuid", -] - -[[package]] -name = "rkyv_derive" -version = "0.8.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8100bb34c0a1d0f907143db3149e6b4eea3c33b9ee8b189720168e818303986f" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "rlsf" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "222fb240c3286247ecdee6fa5341e7cdad0ffdf8e7e401d9937f2d58482a20bf" -dependencies = [ - "cfg-if", - "const-default", - "libc", - "svgbobdoc", -] - -[[package]] -name = "rrs-lib" -version = "0.1.0" -source = "git+https://github.com/succinctlabs/rrs-succinct.git?branch=gautham%2Frv64executor-2#eaca3e8e1785f5b4cf55edfe670c1bf2f52eca77" -dependencies = [ - "downcast-rs", - "num_enum 0.5.11", - "paste", -] - -[[package]] -name = "ruint2" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b066b8e4fcea7fae86b6932d2449670b6b5545b7e8407841b2d3a916ff2a9f86" -dependencies = [ - "derive_more 0.99.20", - "ruint2-macro", - "rustc_version", - "thiserror 1.0.69", -] - -[[package]] -name = "ruint2-macro" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89dc553bc0cf4512a8b96caa2e21ed5f6e4b66bf28a1bd08fd9eb07c0b39b28c" - -[[package]] -name = "rustc-demangle" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustc-hash" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" - -[[package]] -name = "rustc-hex" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" - -[[package]] -name = "rustc_version" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" -dependencies = [ - "semver", -] - -[[package]] -name = "rustix" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" -dependencies = [ - "bitflags 2.10.0", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.61.2", -] - -[[package]] -name = "rustls" -version = "0.23.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "533f54bc6a7d4f647e46ad909549eda97bf5afc1585190ef692b4286b198bd8f" -dependencies = [ - "log", - "once_cell", - "ring", - "rustls-pki-types", - "rustls-webpki", - "subtle", - "zeroize", -] - -[[package]] -name = "rustls-pemfile" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" -dependencies = [ - "rustls-pki-types", -] - -[[package]] -name = "rustls-pki-types" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e6f2ab2928ca4291b86736a8bd920a277a399bba1589409d72154ff87c1282" -dependencies = [ - "web-time", - "zeroize", -] - -[[package]] -name = "rustls-webpki" -version = "0.103.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52" -dependencies = [ - "ring", - "rustls-pki-types", - "untrusted", -] - -[[package]] -name = "rustversion" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" - -[[package]] -name = "ruzstd" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ff0cc5e135c8870a775d3320910cd9b564ec036b4dc0b8741629020be63f01" -dependencies = [ - "twox-hash", -] - -[[package]] -name = "ryu" -version = "1.0.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62049b2877bf12821e8f9ad256ee38fdc31db7387ec2d3b3f403024de2034aea" - -[[package]] -name = "scale-info" -version = "2.11.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "346a3b32eba2640d17a9cb5927056b08f3de90f65b72fe09402c2ad07d684d0b" -dependencies = [ - "cfg-if", - "derive_more 1.0.0", - "parity-scale-codec", - "scale-info-derive", -] - -[[package]] -name = "scale-info-derive" -version = "2.11.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6630024bf739e2179b91fb424b28898baf819414262c5d376677dbff1fe7ebf" -dependencies = [ - "proc-macro-crate 3.4.0", - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "scc" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46e6f046b7fef48e2660c57ed794263155d713de679057f2d0c169bfc6e756cc" -dependencies = [ - "sdd", -] - -[[package]] -name = "schemars" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" -dependencies = [ - "dyn-clone", - "ref-cast", - "serde", - "serde_json", -] - -[[package]] -name = "schemars" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9558e172d4e8533736ba97870c4b2cd63f84b382a3d6eb063da41b91cce17289" -dependencies = [ - "dyn-clone", - "ref-cast", - "serde", - "serde_json", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "sdd" -version = "3.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "490dcfcbfef26be6800d11870ff2df8774fa6e86d047e3e8c8a76b25655e41ca" - -[[package]] -name = "sec1" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" -dependencies = [ - "base16ct", - "der", - "generic-array 0.14.7", - "pkcs8", - "serdect", - "subtle", - "zeroize", -] - -[[package]] -name = "secp256k1" -version = "0.29.1" -source = "git+https://github.com/sp1-patches/rust-secp256k1?tag=patch-0.29.1-sp1-6.0.0#5daf12595f56cb549d1516d8139cb7935d79de7a" -dependencies = [ - "cfg-if", - "k256 0.13.4 (git+https://github.com/sp1-patches/elliptic-curves?tag=patch-k256-13.4-sp1-6.0.0)", - "secp256k1-sys", -] - -[[package]] -name = "secp256k1-sys" -version = "0.10.0" -source = "git+https://github.com/sp1-patches/rust-secp256k1?tag=patch-0.29.1-sp1-6.0.0#5daf12595f56cb549d1516d8139cb7935d79de7a" -dependencies = [ - "cc", -] - -[[package]] -name = "self_cell" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16c2f82143577edb4921b71ede051dac62ca3c16084e918bf7b40c96ae10eb33" - -[[package]] -name = "semver" -version = "1.0.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" -dependencies = [ - "serde", - "serde_core", -] - -[[package]] -name = "serde" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" -dependencies = [ - "serde_core", - "serde_derive", -] - -[[package]] -name = "serde-wasm-bindgen" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b" -dependencies = [ - "js-sys", - "serde", - "wasm-bindgen", -] - -[[package]] -name = "serde_arrays" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94a16b99c5ea4fe3daccd14853ad260ec00ea043b2708d1fd1da3106dcd8d9df" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_core" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "serde_json" -version = "1.0.145" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" -dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", - "serde_core", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_with" -version = "3.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fa237f2807440d238e0364a218270b98f767a00d3dada77b1c53ae88940e2e7" -dependencies = [ - "base64 0.22.1", - "chrono", - "hex", - "indexmap 1.9.3", - "indexmap 2.13.0", - "schemars 0.9.0", - "schemars 1.1.0", - "serde_core", - "serde_json", - "serde_with_macros", - "time", -] - -[[package]] -name = "serde_with_macros" -version = "3.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52a8e3ca0ca629121f70ab50f95249e5a6f925cc0f6ffe8256c45b728875706c" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "serdect" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" -dependencies = [ - "base16ct", - "serde", -] - -[[package]] -name = "serial_test" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b258109f244e1d6891bf1053a55d63a5cd4f8f4c30cf9a1280989f80e7a1fa9" -dependencies = [ - "futures", - "log", - "once_cell", - "parking_lot", - "scc", - "serial_test_derive", -] - -[[package]] -name = "serial_test_derive" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d69265a08751de7844521fd15003ae0a888e035773ba05695c5c759a6f89eef" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "sha1_smol" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" - -[[package]] -name = "sha2" -version = "0.10.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest 0.10.7", -] - -[[package]] -name = "sha2" -version = "0.11.0-rc.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c5f3b1e2dc8aad28310d8410bd4d7e180eca65fca176c52ab00d364475d0024" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest 0.11.2", -] - -[[package]] -name = "sha3" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" -dependencies = [ - "digest 0.10.7", - "keccak", -] - -[[package]] -name = "sharded-slab" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "shared-buffer" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6c99835bad52957e7aa241d3975ed17c1e5f8c92026377d117a606f36b84b16" -dependencies = [ - "bytes", - "memmap2 0.6.2", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "signal-hook-registry" -version = "1.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7664a098b8e616bdfcc2dc0e9ac44eb231eedf41db4e9fe95d8d32ec728dedad" -dependencies = [ - "libc", -] - -[[package]] -name = "signature" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" -dependencies = [ - "digest 0.10.7", - "rand_core 0.6.4", -] - -[[package]] -name = "simd-adler32" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" - -[[package]] -name = "simdutf8" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" - -[[package]] -name = "siphasher" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" - -[[package]] -name = "siphasher" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" - -[[package]] -name = "slab" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" - -[[package]] -name = "slop-air" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "p3-air", -] - -[[package]] -name = "slop-algebra" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c99cdaa39f7db4823cf18938544a135f20bf779eb4b3561652a72ba07ac3c41" -dependencies = [ - "itertools 0.14.0", - "p3-field 0.3.1-succinct", - "serde", -] - -[[package]] -name = "slop-algebra" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "itertools 0.13.0", - "p3-field 0.1.0", - "serde", -] - -[[package]] -name = "slop-alloc" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "serde", - "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "thiserror 1.0.69", -] - -[[package]] -name = "slop-baby-bear" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "lazy_static", - "p3-baby-bear 0.1.0", - "serde", - "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-poseidon2 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", -] - -[[package]] -name = "slop-basefold" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "derive-where", - "itertools 0.13.0", - "serde", - "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-alloc", - "slop-baby-bear", - "slop-bn254 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-koala-bear 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-merkle-tree", - "slop-multilinear", - "slop-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-tensor", - "slop-utils", - "thiserror 1.0.69", -] - -[[package]] -name = "slop-basefold-prover" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "derive-where", - "itertools 0.13.0", - "rand 0.8.5", - "serde", - "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-alloc", - "slop-baby-bear", - "slop-basefold", - "slop-bn254 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-commit", - "slop-dft", - "slop-fri", - "slop-futures", - "slop-koala-bear 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-merkle-tree", - "slop-multilinear", - "slop-tensor", - "thiserror 1.0.69", - "tokio", -] - -[[package]] -name = "slop-bn254" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce30d587559808f7a984ea96af231de14f8f793836300347d1ee13d28e194ad" -dependencies = [ - "ff 0.13.1", - "p3-bn254-fr 0.3.1-succinct", - "serde", - "slop-algebra 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slop-challenger 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slop-poseidon2 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slop-symmetric 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "zkhash", -] - -[[package]] -name = "slop-bn254" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "ff 0.13.1", - "p3-bn254-fr 0.1.0", - "serde", - "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-poseidon2 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "zkhash", -] - -[[package]] -name = "slop-challenger" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15fed3b1414bd79c56a21e3ac75c5b549003a0d8f715eb501000d4ac3d7b8a9f" -dependencies = [ - "futures", - "p3-challenger 0.3.1-succinct", - "serde", - "slop-algebra 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slop-symmetric 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "slop-challenger" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "futures", - "p3-challenger 0.1.0", - "serde", - "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", -] - -[[package]] -name = "slop-commit" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "p3-commit", - "serde", - "slop-alloc", -] - -[[package]] -name = "slop-dft" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "p3-dft 0.1.0", - "serde", - "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-alloc", - "slop-matrix", - "slop-tensor", -] - -[[package]] -name = "slop-fri" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "p3-fri", -] - -[[package]] -name = "slop-futures" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "crossbeam", - "futures", - "pin-project", - "rayon", - "thiserror 1.0.69", - "tokio", - "tracing", -] - -[[package]] -name = "slop-jagged" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "derive-where", - "futures", - "itertools 0.13.0", - "num_cpus", - "rand 0.8.5", - "rayon", - "serde", - "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-alloc", - "slop-baby-bear", - "slop-basefold", - "slop-basefold-prover", - "slop-bn254 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-commit", - "slop-futures", - "slop-koala-bear 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-merkle-tree", - "slop-multilinear", - "slop-stacked", - "slop-sumcheck", - "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-tensor", - "slop-utils", - "thiserror 1.0.69", - "tokio", - "tracing", -] - -[[package]] -name = "slop-keccak-air" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "p3-keccak-air", -] - -[[package]] -name = "slop-koala-bear" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "402c403f847e811a788882c7c5ee018ab7076c8bafbf4f46f569fe97f44610d1" -dependencies = [ - "lazy_static", - "p3-koala-bear 0.3.1-succinct", - "serde", - "slop-algebra 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slop-challenger 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slop-poseidon2 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slop-symmetric 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "slop-koala-bear" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "lazy_static", - "p3-koala-bear 0.1.0", - "serde", - "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-poseidon2 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", -] - -[[package]] -name = "slop-matrix" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "p3-matrix 0.1.0", -] - -[[package]] -name = "slop-maybe-rayon" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "p3-maybe-rayon 0.1.0", -] - -[[package]] -name = "slop-merkle-tree" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "derive-where", - "ff 0.13.1", - "itertools 0.13.0", - "p3-merkle-tree", - "serde", - "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-alloc", - "slop-baby-bear", - "slop-bn254 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-commit", - "slop-futures", - "slop-koala-bear 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-matrix", - "slop-poseidon2 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-tensor", - "thiserror 1.0.69", - "tokio", - "zkhash", -] - -[[package]] -name = "slop-multilinear" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "derive-where", - "futures", - "num_cpus", - "rand 0.8.5", - "rayon", - "serde", - "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-alloc", - "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-commit", - "slop-futures", - "slop-matrix", - "slop-tensor", - "tokio", -] - -[[package]] -name = "slop-poseidon2" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bc5ba869130dd0711cf7bd54f93785cd566b5c71201f38801fa3f500d508cc4" -dependencies = [ - "p3-poseidon2 0.3.1-succinct", -] - -[[package]] -name = "slop-poseidon2" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "p3-poseidon2 0.1.0", -] - -[[package]] -name = "slop-primitives" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "786111f9498e8d465b39cfef062297ef4e9b688f250a39abdafaca08e772b56c" -dependencies = [ - "slop-algebra 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "slop-primitives" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", -] - -[[package]] -name = "slop-stacked" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "derive-where", - "futures", - "itertools 0.13.0", - "serde", - "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-alloc", - "slop-basefold", - "slop-basefold-prover", - "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-commit", - "slop-futures", - "slop-merkle-tree", - "slop-multilinear", - "slop-tensor", - "thiserror 1.0.69", - "tokio", -] - -[[package]] -name = "slop-sumcheck" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "futures", - "itertools 0.13.0", - "rayon", - "serde", - "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-alloc", - "slop-baby-bear", - "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-multilinear", - "thiserror 1.0.69", -] - -[[package]] -name = "slop-symmetric" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c41115c944fdb8eec425d4515cbc1649852ab4ddcc6be67a069c8d2aa5205209" -dependencies = [ - "p3-symmetric 0.3.1-succinct", -] - -[[package]] -name = "slop-symmetric" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "p3-symmetric 0.1.0", -] - -[[package]] -name = "slop-tensor" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "arrayvec", - "derive-where", - "itertools 0.13.0", - "rand 0.8.5", - "rayon", - "serde", - "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-alloc", - "slop-futures", - "slop-matrix", - "thiserror 1.0.69", - "tokio", - "transpose", -] - -[[package]] -name = "slop-uni-stark" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "p3-uni-stark", -] - -[[package]] -name = "slop-utils" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "p3-util 0.1.0", - "tracing-forest", - "tracing-subscriber", -] - -[[package]] -name = "slop-whir" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "derive-where", - "futures", - "itertools 0.13.0", - "rand 0.8.5", - "rayon", - "serde", - "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-alloc", - "slop-baby-bear", - "slop-basefold", - "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-commit", - "slop-dft", - "slop-jagged", - "slop-koala-bear 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-matrix", - "slop-merkle-tree", - "slop-multilinear", - "slop-stacked", - "slop-tensor", - "slop-utils", - "thiserror 1.0.69", -] - -[[package]] -name = "smallvec" -version = "1.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" -dependencies = [ - "serde", -] - -[[package]] -name = "snowbridge-amcl" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "460a9ed63cdf03c1b9847e8a12a5f5ba19c4efd5869e4a737e05be25d7c427e5" -dependencies = [ - "parity-scale-codec", - "scale-info", -] - -[[package]] -name = "socket2" -version = "0.5.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "socket2" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" -dependencies = [ - "libc", - "windows-sys 0.60.2", -] - -[[package]] -name = "sp1-build" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "anyhow", - "cargo_metadata", - "chrono", - "clap", - "dirs", - "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", -] - -[[package]] -name = "sp1-builder" -version = "0.1.0" -dependencies = [ - "clap", - "serde_json", - "sp1-build", - "sp1-core-executor", - "sp1-sdk", - "wasmer", - "wasmparser 0.245.1", -] - -[[package]] -name = "sp1-core-executor" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "bincode", - "bytemuck", - "cfg-if", - "clap", - "deepsize2", - "elf", - "enum-map", - "eyre", - "gecko_profile", - "hashbrown 0.14.5", - "hex", - "indicatif", - "itertools 0.13.0", - "memmap2 0.9.9", - "num", - "object 0.37.3", - "rrs-lib", - "rustc-demangle", - "serde", - "serde_arrays", - "serde_json", - "slop-air", - "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-maybe-rayon", - "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "sp1-curves", - "sp1-hypercube", - "sp1-jit", - "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "strum", - "subenum", - "thiserror 1.0.69", - "tiny-keccak 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tracing", - "typenum", - "vec_map", -] - -[[package]] -name = "sp1-core-machine" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "bincode", - "cfg-if", - "enum-map", - "futures", - "generic-array 1.1.0", - "hashbrown 0.14.5", - "itertools 0.13.0", - "num", - "num_cpus", - "rayon", - "rayon-scan", - "rrs-lib", - "serde", - "serde_json", - "slop-air", - "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-futures", - "slop-keccak-air", - "slop-matrix", - "slop-maybe-rayon", - "slop-uni-stark", - "snowbridge-amcl", - "sp1-core-executor", - "sp1-curves", - "sp1-derive", - "sp1-hypercube", - "sp1-jit", - "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "static_assertions", - "strum", - "sysinfo", - "tempfile", - "thiserror 1.0.69", - "tokio", - "tracing", - "tracing-forest", - "tracing-subscriber", - "typenum", -] - -[[package]] -name = "sp1-cuda" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "bincode", - "bytes", - "reqwest", - "semver", - "serde", - "serde_json", - "sp1-core-executor", - "sp1-core-machine", - "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "sp1-prover", - "sp1-prover-types", - "thiserror 1.0.69", - "tokio", - "tracing", -] - -[[package]] -name = "sp1-curves" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "cfg-if", - "dashu", - "elliptic-curve", - "generic-array 1.1.0", - "itertools 0.13.0", - "k256 0.13.4 (registry+https://github.com/rust-lang/crates.io-index)", - "num", - "p256", - "serde", - "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "snowbridge-amcl", - "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "typenum", -] - -[[package]] -name = "sp1-derive" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "sp1-hypercube" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "arrayref", - "deepsize2", - "derive-where", - "futures", - "hashbrown 0.14.5", - "itertools 0.13.0", - "num-bigint 0.4.6", - "num-traits", - "num_cpus", - "rayon", - "rayon-scan", - "serde", - "slop-air", - "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-alloc", - "slop-basefold", - "slop-basefold-prover", - "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-commit", - "slop-futures", - "slop-jagged", - "slop-koala-bear 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-matrix", - "slop-merkle-tree", - "slop-multilinear", - "slop-poseidon2 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-stacked", - "slop-sumcheck", - "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-tensor", - "slop-uni-stark", - "slop-whir", - "sp1-derive", - "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "strum", - "thiserror 1.0.69", - "thousands", - "tokio", - "tracing", -] - -[[package]] -name = "sp1-jit" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "dynasmrt 3.2.1", - "hashbrown 0.14.5", - "memfd", - "memmap2 0.9.9", - "serde", - "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "tracing", - "uuid", -] - -[[package]] -name = "sp1-lib" -version = "5.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b73b8ff343f2405d5935440e56b7aba5cee6d87303f0051974cbd6f5de502f57" -dependencies = [ - "bincode", - "elliptic-curve", - "serde", - "sp1-primitives 5.2.4", -] - -[[package]] -name = "sp1-lib" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53f179ca7ad5d0d0ca36356ef2c4851eea02226cd409e4b414e4379d79582f11" -dependencies = [ - "bincode", - "elliptic-curve", - "serde", - "sp1-primitives 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sp1-lib" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "bincode", - "serde", - "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", -] - -[[package]] -name = "sp1-primitives" -version = "5.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e69a03098f827102c54c31a5e57280eb45b2c085de433b3f702e4f9e3ec1641" -dependencies = [ - "bincode", - "blake3", - "cfg-if", - "hex", - "lazy_static", - "num-bigint 0.4.6", - "p3-baby-bear 0.2.3-succinct", - "p3-field 0.2.3-succinct", - "p3-poseidon2 0.2.3-succinct", - "p3-symmetric 0.2.3-succinct", - "serde", - "sha2 0.10.9", -] - -[[package]] -name = "sp1-primitives" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bda0eaba853f3c162e6b62dc8eb25f25100ee0792f59919ef905811809e81e5" -dependencies = [ - "bincode", - "blake3", - "elf", - "hex", - "itertools 0.14.0", - "lazy_static", - "num-bigint 0.4.6", - "serde", - "sha2 0.10.9", - "slop-algebra 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slop-bn254 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slop-challenger 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slop-koala-bear 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slop-poseidon2 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slop-primitives 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slop-symmetric 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sp1-primitives" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "bincode", - "blake3", - "elf", - "hex", - "itertools 0.13.0", - "lazy_static", - "num-bigint 0.4.6", - "serde", - "sha2 0.10.9", - "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-bn254 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-koala-bear 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-poseidon2 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", -] - -[[package]] -name = "sp1-prover" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "anyhow", - "bincode", - "clap", - "dirs", - "downloader", - "either", - "enum-map", - "eyre", - "futures", - "hashbrown 0.14.5", - "hex", - "indicatif", - "itertools 0.13.0", - "lru", - "mti", - "num-bigint 0.4.6", - "opentelemetry", - "pin-project", - "rand 0.8.5", - "reqwest", - "serde", - "serde_json", - "serial_test", - "sha2 0.10.9", - "slop-air", - "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-basefold", - "slop-bn254 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-futures", - "slop-jagged", - "slop-multilinear", - "slop-stacked", - "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "sp1-core-executor", - "sp1-core-machine", - "sp1-derive", - "sp1-hypercube", - "sp1-jit", - "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "sp1-prover-types", - "sp1-recursion-circuit", - "sp1-recursion-compiler", - "sp1-recursion-executor", - "sp1-recursion-gnark-ffi", - "sp1-recursion-machine", - "sp1-verifier", - "static_assertions", - "sysinfo", - "tempfile", - "thiserror 1.0.69", - "tokio", - "tonic", - "tracing", - "tracing-appender", - "tracing-subscriber", -] - -[[package]] -name = "sp1-prover-types" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "anyhow", - "async-scoped", - "bincode", - "chrono", - "futures-util", - "hashbrown 0.14.5", - "mti", - "prost", - "serde", - "tokio", - "tonic", - "tonic-build", - "tracing", -] - -[[package]] -name = "sp1-recursion-circuit" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "itertools 0.13.0", - "rand 0.8.5", - "rayon", - "serde", - "slop-air", - "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-alloc", - "slop-basefold", - "slop-basefold-prover", - "slop-bn254 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-challenger 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-commit", - "slop-jagged", - "slop-koala-bear 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-matrix", - "slop-merkle-tree", - "slop-multilinear", - "slop-stacked", - "slop-sumcheck", - "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-tensor", - "slop-whir", - "sp1-core-executor", - "sp1-core-machine", - "sp1-derive", - "sp1-hypercube", - "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "sp1-recursion-compiler", - "sp1-recursion-executor", - "sp1-recursion-machine", - "tracing", -] - -[[package]] -name = "sp1-recursion-compiler" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "backtrace", - "cfg-if", - "itertools 0.13.0", - "serde", - "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-bn254 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "sp1-core-machine", - "sp1-hypercube", - "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "sp1-recursion-executor", - "tracing", - "vec_map", -] - -[[package]] -name = "sp1-recursion-executor" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "backtrace", - "cfg-if", - "hashbrown 0.14.5", - "itertools 0.13.0", - "range-set-blaze", - "serde", - "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-maybe-rayon", - "slop-poseidon2 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "smallvec", - "sp1-derive", - "sp1-hypercube", - "static_assertions", - "thiserror 1.0.69", - "tracing", -] - -[[package]] -name = "sp1-recursion-gnark-ffi" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "anyhow", - "bincode", - "bindgen 0.70.1", - "cfg-if", - "hex", - "num-bigint 0.4.6", - "serde", - "serde_json", - "sha2 0.10.9", - "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "sp1-hypercube", - "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "sp1-recursion-compiler", - "sp1-verifier", - "tempfile", - "tracing", -] - -[[package]] -name = "sp1-recursion-machine" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "itertools 0.13.0", - "rand 0.8.5", - "slop-air", - "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-basefold", - "slop-matrix", - "slop-maybe-rayon", - "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "sp1-derive", - "sp1-hypercube", - "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "sp1-recursion-executor", - "strum", - "tracing", - "zkhash", -] - -[[package]] -name = "sp1-runner" -version = "0.1.0" -dependencies = [ - "bincode", - "clap", - "rkyv", - "serde_json", - "sp1-core-executor", - "sp1-sdk", - "tokio", - "tracing", - "validation", -] - -[[package]] -name = "sp1-sdk" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "anyhow", - "async-trait", - "bincode", - "cfg-if", - "dirs", - "eventsource-stream", - "futures", - "hex", - "indicatif", - "itertools 0.13.0", - "k256 0.13.4 (registry+https://github.com/rust-lang/crates.io-index)", - "num-bigint 0.4.6", - "serde", - "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "sp1-build", - "sp1-core-executor", - "sp1-core-machine", - "sp1-cuda", - "sp1-hypercube", - "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "sp1-prover", - "sp1-prover-types", - "sp1-recursion-executor", - "sp1-recursion-gnark-ffi", - "sp1-verifier", - "strum", - "tempfile", - "thiserror 1.0.69", - "tokio", - "tracing", -] - -[[package]] -name = "sp1-verifier" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "bincode", - "blake3", - "cfg-if", - "dirs", - "hex", - "lazy_static", - "serde", - "sha2 0.10.9", - "slop-algebra 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "slop-symmetric 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "sp1-hypercube", - "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "sp1-recursion-executor", - "sp1-recursion-machine", - "strum", - "substrate-bn-succinct", - "thiserror 2.0.17", -] - -[[package]] -name = "sp1-zkvm" -version = "6.0.0" -source = "git+https://github.com/succinctlabs/sp1?rev=be6ebfe#be6ebfe1412e4f7b2175cd767f60bf67dec67ac5" -dependencies = [ - "cfg-if", - "critical-section", - "embedded-alloc", - "getrandom 0.2.16", - "getrandom 0.3.4", - "lazy_static", - "libm", - "rand 0.8.5", - "sha2 0.10.9", - "sp1-lib 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", - "sp1-primitives 6.0.0 (git+https://github.com/succinctlabs/sp1?rev=be6ebfe)", -] - -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" - -[[package]] -name = "spin" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591" -dependencies = [ - "lock_api", -] - -[[package]] -name = "spki" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" -dependencies = [ - "base64ct", - "der", -] - -[[package]] -name = "stable_deref_trait" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "strength_reduce" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe895eb47f22e2ddd4dabc02bce419d2e643c8e3b585c78158b349195bc24d82" - -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - -[[package]] -name = "strum" -version = "0.27.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" -dependencies = [ - "strum_macros", -] - -[[package]] -name = "strum_macros" -version = "0.27.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "stylus-compiler-program" -version = "0.1.0" -dependencies = [ - "prover", - "sp1-zkvm", - "wasmer", -] - -[[package]] -name = "subenum" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3d08fe7078c57309d5c3d938e50eba95ba1d33b9c3a101a8465fc6861a5416" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "substrate-bn-succinct" -version = "0.6.0-v5.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ba32f1b74728f92887c3ad17c42bf82998eb52c9091018f35294e9cd388b0c8" -dependencies = [ - "bytemuck", - "byteorder", - "cfg-if", - "crunchy", - "lazy_static", - "num-bigint 0.4.6", - "rand 0.8.5", - "rustc-hex", - "sp1-lib 5.2.4", -] - -[[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - -[[package]] -name = "svgbobdoc" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2c04b93fc15d79b39c63218f15e3fdffaa4c227830686e3b7c5f41244eb3e50" -dependencies = [ - "base64 0.13.1", - "proc-macro2", - "quote", - "syn 1.0.109", - "unicode-width 0.1.14", -] - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.114" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "sync_wrapper" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" -dependencies = [ - "futures-core", -] - -[[package]] -name = "synstructure" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "sysinfo" -version = "0.30.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a5b4ddaee55fb2bea2bf0e5000747e5f5c0de765e5a5ff87f4cd106439f4bb3" -dependencies = [ - "cfg-if", - "core-foundation-sys", - "libc", - "ntapi", - "once_cell", - "rayon", - "windows", -] - -[[package]] -name = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - -[[package]] -name = "tar" -version = "0.4.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a" -dependencies = [ - "filetime", - "libc", - "xattr", -] - -[[package]] -name = "target-lexicon" -version = "0.13.5" -source = "git+https://github.com/OffchainLabs/target-lexicon?tag=v0.13.5-sp1#b36201fb3efd8babeb625c26217bfb4fb7af32a5" - -[[package]] -name = "tempfile" -version = "3.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" -dependencies = [ - "fastrand", - "getrandom 0.3.4", - "once_cell", - "rustix", - "windows-sys 0.61.2", -] - -[[package]] -name = "thiserror" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" -dependencies = [ - "thiserror-impl 1.0.69", -] - -[[package]] -name = "thiserror" -version = "2.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" -dependencies = [ - "thiserror-impl 2.0.17", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "thiserror-impl" -version = "2.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "thousands" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bf63baf9f5039dadc247375c29eb13706706cfde997d0330d05aa63a77d8820" - -[[package]] -name = "thread_local" -version = "1.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "time" -version = "0.3.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" -dependencies = [ - "deranged", - "itoa", - "num-conv", - "powerfmt", - "serde", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" - -[[package]] -name = "time-macros" -version = "0.2.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" -dependencies = [ - "num-conv", - "time-core", -] - -[[package]] -name = "tiny-keccak" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" -dependencies = [ - "crunchy", -] - -[[package]] -name = "tiny-keccak" -version = "2.0.2" -source = "git+https://github.com/sp1-patches/tiny-keccak?tag=patch-2.0.2-sp1-6.0.0#957430a459f7a2332ab5bab4a12f9b473bb95c87" -dependencies = [ - "cfg-if", - "crunchy", - "sp1-lib 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tinystr" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" -dependencies = [ - "displaydoc", - "zerovec", -] - -[[package]] -name = "tinyvec" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "tokio" -version = "1.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" -dependencies = [ - "bytes", - "libc", - "mio", - "pin-project-lite", - "signal-hook-registry", - "socket2 0.6.1", - "tokio-macros", - "windows-sys 0.61.2", -] - -[[package]] -name = "tokio-macros" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "tokio-rustls" -version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" -dependencies = [ - "rustls", - "tokio", -] - -[[package]] -name = "tokio-stream" -version = "0.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "toml_datetime" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" - -[[package]] -name = "toml_datetime" -version = "0.7.5+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" -dependencies = [ - "serde_core", -] - -[[package]] -name = "toml_edit" -version = "0.19.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" -dependencies = [ - "indexmap 2.13.0", - "toml_datetime 0.6.11", - "winnow 0.5.40", -] - -[[package]] -name = "toml_edit" -version = "0.23.10+spec-1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" -dependencies = [ - "indexmap 2.13.0", - "toml_datetime 0.7.5+spec-1.1.0", - "toml_parser", - "winnow 0.7.14", -] - -[[package]] -name = "toml_parser" -version = "1.0.6+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" -dependencies = [ - "winnow 0.7.14", -] - -[[package]] -name = "tonic" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52" -dependencies = [ - "async-stream", - "async-trait", - "axum", - "base64 0.22.1", - "bytes", - "h2", - "http", - "http-body", - "http-body-util", - "hyper", - "hyper-timeout", - "hyper-util", - "percent-encoding", - "pin-project", - "prost", - "rustls-pemfile", - "socket2 0.5.10", - "tokio", - "tokio-rustls", - "tokio-stream", - "tower 0.4.13", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tonic-build" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9557ce109ea773b399c9b9e5dca39294110b74f1f342cb347a80d1fce8c26a11" -dependencies = [ - "prettyplease", - "proc-macro2", - "prost-build", - "prost-types", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "indexmap 1.9.3", - "pin-project", - "pin-project-lite", - "rand 0.8.5", - "slab", - "tokio", - "tokio-util", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" -dependencies = [ - "futures-core", - "futures-util", - "pin-project-lite", - "sync_wrapper", - "tokio", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-http" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" -dependencies = [ - "bitflags 2.10.0", - "bytes", - "futures-util", - "http", - "http-body", - "iri-string", - "pin-project-lite", - "tower 0.5.2", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-layer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" - -[[package]] -name = "tower-service" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" - -[[package]] -name = "tracing" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" -dependencies = [ - "log", - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-appender" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "786d480bce6247ab75f005b14ae1624ad978d3029d9113f0a22fa1ac773faeaf" -dependencies = [ - "crossbeam-channel", - "thiserror 2.0.17", - "time", - "tracing-subscriber", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "tracing-core" -version = "0.1.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" -dependencies = [ - "once_cell", - "valuable", -] - -[[package]] -name = "tracing-forest" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee40835db14ddd1e3ba414292272eddde9dad04d3d4b65509656414d1c42592f" -dependencies = [ - "ansi_term", - "smallvec", - "thiserror 1.0.69", - "tracing", - "tracing-subscriber", -] - -[[package]] -name = "tracing-log" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" -dependencies = [ - "log", - "once_cell", - "tracing-core", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" -dependencies = [ - "matchers", - "nu-ansi-term", - "once_cell", - "regex-automata", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log", -] - -[[package]] -name = "transpose" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad61aed86bc3faea4300c7aee358b4c6d0c8d6ccc36524c96e4c92ccf26e77e" -dependencies = [ - "num-integer", - "strength_reduce", -] - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - -[[package]] -name = "twox-hash" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ea3136b675547379c4bd395ca6b938e5ad3c3d20fad76e7fe85f9e0d011419c" - -[[package]] -name = "typeid_prefix" -version = "1.1.1-beta.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "257608c6fd0cbb5a8e00fe11ef14e9c285eb02f9e29624aaaba79e59a829a9e2" - -[[package]] -name = "typeid_suffix" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d46b723d74f5ede0160048deba99670a898b7905682a7a77be7cf8e8b75df50" -dependencies = [ - "uuid", -] - -[[package]] -name = "typenum" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" - -[[package]] -name = "unicode-ident" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" - -[[package]] -name = "unicode-segmentation" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" - -[[package]] -name = "unicode-width" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" - -[[package]] -name = "unicode-width" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" - -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - -[[package]] -name = "url" -version = "2.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", - "serde", -] - -[[package]] -name = "utf8_iter" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" - -[[package]] -name = "utf8parse" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" - -[[package]] -name = "uuid" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" -dependencies = [ - "atomic", - "getrandom 0.3.4", - "js-sys", - "md-5", - "sha1_smol", - "wasm-bindgen", -] - -[[package]] -name = "validation" -version = "0.1.0" -dependencies = [ - "arbutil", - "brotli", - "rkyv", - "serde", - "serde_json", - "serde_with", -] - -[[package]] -name = "valuable" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" - -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" -dependencies = [ - "serde", -] - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - -[[package]] -name = "wasi" -version = "0.11.1+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" - -[[package]] -name = "wasip2" -version = "1.0.1+wasi-0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" -dependencies = [ - "wit-bindgen 0.46.0", -] - -[[package]] -name = "wasip3" -version = "0.4.0+wasi-0.3.0-rc-2026-01-06" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" -dependencies = [ - "wit-bindgen 0.51.0", -] - -[[package]] -name = "wasm-bindgen" -version = "0.2.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" -dependencies = [ - "cfg-if", - "once_cell", - "rustversion", - "wasm-bindgen-macro", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.56" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c" -dependencies = [ - "cfg-if", - "js-sys", - "once_cell", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" -dependencies = [ - "bumpalo", - "proc-macro2", - "quote", - "syn 2.0.114", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "wasm-encoder" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" -dependencies = [ - "leb128fmt", - "wasmparser 0.244.0", -] - -[[package]] -name = "wasm-metadata" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" -dependencies = [ - "anyhow", - "indexmap 2.13.0", - "wasm-encoder", - "wasmparser 0.244.0", -] - -[[package]] -name = "wasm-streams" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" -dependencies = [ - "futures-util", - "js-sys", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - -[[package]] -name = "wasmer" -version = "7.1.0-rc.2" -dependencies = [ - "bindgen 0.72.1", - "bytes", - "cfg-if", - "cmake", - "derive_more 2.1.0", - "indexmap 2.13.0", - "js-sys", - "more-asserts", - "paste", - "rustc-demangle", - "serde", - "serde-wasm-bindgen", - "shared-buffer", - "tar", - "target-lexicon", - "thiserror 2.0.17", - "tracing", - "wasm-bindgen", - "wasmer-compiler", - "wasmer-compiler-llvm", - "wasmer-compiler-singlepass", - "wasmer-derive", - "wasmer-types", - "wasmer-vm", - "wasmparser 0.245.1", - "windows-sys 0.61.2", -] - -[[package]] -name = "wasmer-compiler" -version = "7.1.0-rc.2" -dependencies = [ - "backtrace", - "bytes", - "cfg-if", - "crossbeam-channel", - "enum-iterator", - "enumset", - "itertools 0.14.0", - "leb128", - "libc", - "macho-unwind-info", - "memmap2 0.9.9", - "more-asserts", - "object 0.38.1", - "rangemap", - "rayon", - "region", - "rkyv", - "self_cell", - "shared-buffer", - "smallvec", - "target-lexicon", - "tempfile", - "thiserror 2.0.17", - "wasmer-types", - "wasmer-vm", - "wasmparser 0.245.1", - "which", - "windows-sys 0.61.2", -] - -[[package]] -name = "wasmer-compiler-llvm" -version = "7.1.0-rc.2" -dependencies = [ - "byteorder", - "cc", - "crossbeam-channel", - "enumset", - "inkwell", - "itertools 0.14.0", - "libc", - "object 0.38.1", - "phf", - "rayon", - "regex", - "rustc_version", - "semver", - "smallvec", - "target-lexicon", - "tracing", - "wasmer-compiler", - "wasmer-types", - "wasmer-vm", -] - -[[package]] -name = "wasmer-compiler-singlepass" -version = "7.1.0-rc.2" -dependencies = [ - "byteorder", - "dynasm 5.0.0", - "dynasmrt 5.0.0", - "enumset", - "gimli 0.33.0", - "itertools 0.14.0", - "more-asserts", - "smallvec", - "target-lexicon", - "tempfile", - "wasmer-compiler", - "wasmer-types", -] - -[[package]] -name = "wasmer-derive" -version = "7.1.0-rc.2" -dependencies = [ - "proc-macro-error2", - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "wasmer-types" -version = "7.1.0-rc.2" -dependencies = [ - "bytecheck", - "enum-iterator", - "enumset", - "getrandom 0.4.2", - "hex", - "indexmap 2.13.0", - "more-asserts", - "rkyv", - "sha2 0.11.0-rc.5", - "target-lexicon", - "thiserror 2.0.17", -] - -[[package]] -name = "wasmer-vm" -version = "7.1.0-rc.2" -dependencies = [ - "backtrace", - "bytesize", - "cc", - "cfg-if", - "corosensei", - "crossbeam-queue", - "dashmap", - "enum-iterator", - "fnv", - "gimli 0.33.0", - "indexmap 2.13.0", - "itertools 0.14.0", - "libc", - "libunwind", - "mach2 0.6.0", - "memoffset", - "more-asserts", - "parking_lot", - "region", - "rustversion", - "scopeguard", - "thiserror 2.0.17", - "wasmer-types", - "windows-sys 0.61.2", -] - -[[package]] -name = "wasmparser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" -dependencies = [ - "bitflags 2.10.0", - "hashbrown 0.15.5", - "indexmap 2.13.0", - "semver", -] - -[[package]] -name = "wasmparser" -version = "0.245.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f08c9adee0428b7bddf3890fc27e015ac4b761cc608c822667102b8bfd6995e" -dependencies = [ - "bitflags 2.10.0", - "hashbrown 0.16.1", - "indexmap 2.13.0", - "semver", - "serde", -] - -[[package]] -name = "web-sys" -version = "0.3.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "web-time" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "webpki-roots" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2878ef029c47c6e8cf779119f20fcf52bde7ad42a731b2a304bc221df17571e" -dependencies = [ - "rustls-pki-types", -] - -[[package]] -name = "which" -version = "8.0.0" -source = "git+https://github.com/OffchainLabs/which-rs?tag=v8.0.0-sp1#8b6efc73303047db5b2c8a014cb36cf2804ee3d3" -dependencies = [ - "env_home", - "rustix", - "winsafe", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" -dependencies = [ - "windows-core 0.52.0", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-core" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-core" -version = "0.62.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" -dependencies = [ - "windows-implement", - "windows-interface", - "windows-link", - "windows-result", - "windows-strings", -] - -[[package]] -name = "windows-implement" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "windows-interface" -version = "0.59.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "windows-link" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" - -[[package]] -name = "windows-result" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-strings" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.5", -] - -[[package]] -name = "windows-sys" -version = "0.61.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.53.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" -dependencies = [ - "windows-link", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm 0.53.1", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_i686_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" - -[[package]] -name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - -[[package]] -name = "winnow" -version = "0.7.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" -dependencies = [ - "memchr", -] - -[[package]] -name = "winsafe" -version = "0.0.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" - -[[package]] -name = "wit-bindgen" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" - -[[package]] -name = "wit-bindgen" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" -dependencies = [ - "wit-bindgen-rust-macro", -] - -[[package]] -name = "wit-bindgen-core" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" -dependencies = [ - "anyhow", - "heck", - "wit-parser", -] - -[[package]] -name = "wit-bindgen-rust" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" -dependencies = [ - "anyhow", - "heck", - "indexmap 2.13.0", - "prettyplease", - "syn 2.0.114", - "wasm-metadata", - "wit-bindgen-core", - "wit-component", -] - -[[package]] -name = "wit-bindgen-rust-macro" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" -dependencies = [ - "anyhow", - "prettyplease", - "proc-macro2", - "quote", - "syn 2.0.114", - "wit-bindgen-core", - "wit-bindgen-rust", -] - -[[package]] -name = "wit-component" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" -dependencies = [ - "anyhow", - "bitflags 2.10.0", - "indexmap 2.13.0", - "log", - "serde", - "serde_derive", - "serde_json", - "wasm-encoder", - "wasm-metadata", - "wasmparser 0.244.0", - "wit-parser", -] - -[[package]] -name = "wit-parser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" -dependencies = [ - "anyhow", - "id-arena", - "indexmap 2.13.0", - "log", - "semver", - "serde", - "serde_derive", - "serde_json", - "unicode-xid", - "wasmparser 0.244.0", -] - -[[package]] -name = "writeable" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" - -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - -[[package]] -name = "xattr" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156" -dependencies = [ - "libc", - "rustix", -] - -[[package]] -name = "yoke" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" -dependencies = [ - "stable_deref_trait", - "yoke-derive", - "zerofrom", -] - -[[package]] -name = "yoke-derive" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", - "synstructure", -] - -[[package]] -name = "zerocopy" -version = "0.8.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "zerofrom" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" -dependencies = [ - "zerofrom-derive", -] - -[[package]] -name = "zerofrom-derive" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", - "synstructure", -] - -[[package]] -name = "zeroize" -version = "1.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "zerotrie" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", -] - -[[package]] -name = "zerovec" -version = "0.11.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" -dependencies = [ - "yoke", - "zerofrom", - "zerovec-derive", -] - -[[package]] -name = "zerovec-derive" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "zkhash" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4352d1081da6922701401cdd4cbf29a2723feb4cfabb5771f6fee8e9276da1c7" -dependencies = [ - "ark-ff", - "ark-std", - "bitvec", - "blake2", - "bls12_381", - "byteorder", - "cfg-if", - "group 0.12.1", - "group 0.13.0", - "halo2", - "hex", - "jubjub", - "lazy_static", - "pasta_curves 0.5.1", - "rand 0.8.5", - "serde", - "sha2 0.10.9", - "sha3", - "subtle", -] diff --git a/crates/sp1/Cargo.toml b/crates/sp1/Cargo.toml deleted file mode 100644 index 6077208295c..00000000000 --- a/crates/sp1/Cargo.toml +++ /dev/null @@ -1,61 +0,0 @@ -[workspace] -resolver = "3" - -members = ["program", "builder", "stylus-compiler-program", "prover", "runner"] - -[workspace.dependencies] -arbutil = { path = "../arbutil" } -brotli = { path = "../brotli" } -caller-env = { path = "../caller-env", default-features = false } -prover = { path = "prover", default-features = false, features = ["sp1"] } -validation = { path = "../validation", default-features = false } - -bincode = { version = "1.3.3" } -bytes = { version = "1" } -clap = { version = "4.5.53", features = ["cargo", "derive"] } -corosensei = { version = "0.3.0" } -derivative = { version = "2.2.0" } -digest = { version = "0.10.7" } -eyre = { version = "0.6.5" } -fnv = { version = "1.0.7" } -hex = { version = "0.4.3" } -lazy_static = { version = "1.4.0" } -nom = { version = "7.0.0" } -num-derive = { version = "0.4.1" } -num-traits = { version = "0.2.17" } -once_cell = { version = "1.21.3" } -parking_lot = { version = "0.12.1" } -rand = { version = "0.8.4", default-features = false } -rand_pcg = { version = "0.3.1", default-features = false } -rkyv = { version = "0.8.8", features = ["indexmap-2", "bytes-1"] } -ruint2 = { version = "1.9.0" } -serde = { version = "1.0.130" } -serde_json = { version = "1.0.67" } -serde_with = { version = "3.8.1" } -sha3 = { version = "0.10.8" } -sp1-build = { version = "6.0.0", features = ["may_dump_elf"] } -sp1-core-executor = { version = "6.0.0" } -sp1-sdk = { version = "6.0.0", features = ["profiling"] } -sp1-zkvm = { version = "6.0.0", features = ["untrusted_programs", "may_dump_elf"] } -thiserror = { version = "1.0.33" } -tokio = { version = "1.42.0" } -tracing = { version = "0.1.40" } -wasmparser = { version = "0.245.0" } - -secp256k1 = { git = "https://github.com/sp1-patches/rust-secp256k1", tag = "patch-0.29.1-sp1-6.0.0", features = ["recovery", "global-context"] } -tiny-keccak = { git = "https://github.com/sp1-patches/tiny-keccak", tag = "patch-2.0.2-sp1-6.0.0", features = ["keccak"] } - -wasmer = { path = "../tools/wasmer/lib/api", default-features = false, features = ["sys", "compiler", "singlepass", "wasmparser"] } -wasmer-types = { path = "../tools/wasmer/lib/types" } -wasmer-vm = { path = "../tools/wasmer/lib/vm", features = ["force-baremetal"] } - -[patch.crates-io] -target-lexicon = { git = "https://github.com/OffchainLabs/target-lexicon", tag = "v0.13.5-sp1" } -region = { git = "https://github.com/OffchainLabs/region-rs", tag = "v3.0.2-sp1" } -corosensei = { git = "https://github.com/OffchainLabs/corosensei", tag = "v0.3.2-sp1" } -which = { git = "https://github.com/OffchainLabs/which-rs", tag = "v8.0.0-sp1" } - -sp1-build = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe" } -sp1-core-executor = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe" } -sp1-sdk = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe" } -sp1-zkvm = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe" } diff --git a/crates/sp1/README.md b/crates/sp1/README.md index b577417b6a0..71a0f8b76df 100644 --- a/crates/sp1/README.md +++ b/crates/sp1/README.md @@ -1,6 +1,6 @@ -This folder adds a new Arbitrum block runner(like `jit` and `prover` in `arbitrator` folder), powered by [Succinct SP1](https://github.com/succinctlabs/sp1). For now we are only showcasing the executor powered by SP1, but the same code should be able to generate zero knowledge proofs for validating an Arbitrum block. +This folder adds a new Arbitrum block runner (like `jit` and `prover`), powered by [Succinct SP1](https://github.com/succinctlabs/sp1). For now we are only showcasing the executor powered by SP1, but the same code should be able to generate zero knowledge proofs for validating an Arbitrum block. -Ideally, the crates in this folder shall be merged into `arbitrator`. But for now, the differences in wasmer and Rust versions prevent us from doing this. Later when all the issues have been tackled we will likely merge both Rust workspaces. +These crates are part of the root Cargo workspace. ## Usage diff --git a/crates/sp1/builder/Cargo.toml b/crates/sp1/builder/Cargo.toml index d1ce116a97e..bb6dbd3db0e 100644 --- a/crates/sp1/builder/Cargo.toml +++ b/crates/sp1/builder/Cargo.toml @@ -5,13 +5,13 @@ version = "0.1.0" edition = "2024" [dependencies] -sp1-core-executor = { workspace = true } -sp1-sdk = { workspace = true } +sp1-core-executor = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe" } +sp1-sdk = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe", features = ["profiling"] } -clap = { workspace = true } +clap = { workspace = true, features = ["cargo", "derive"] } serde_json = { workspace = true } wasmer = { workspace = true, features = ["llvm"] } wasmparser = { workspace = true } [build-dependencies] -sp1-build = { workspace = true } +sp1-build = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe", features = ["may_dump_elf"] } diff --git a/crates/sp1/program/Cargo.toml b/crates/sp1/program/Cargo.toml index e9b7b9a467f..1b338c1a780 100644 --- a/crates/sp1/program/Cargo.toml +++ b/crates/sp1/program/Cargo.toml @@ -7,12 +7,12 @@ edition = "2024" [dependencies] arbutil = { workspace = true } caller-env = { workspace = true, features = ["brotli"] } -prover = { workspace = true, features = ["native"] } -sp1-zkvm = { workspace = true } +prover = { workspace = true, features = ["sp1", "native"] } +sp1-zkvm = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe", features = ["untrusted_programs", "may_dump_elf"] } validation = { workspace = true, features = ["rkyv"] } -wasmer = { workspace = true } +wasmer = { workspace = true, features = ["sys", "compiler", "singlepass", "wasmparser"] } wasmer-types = { workspace = true } -wasmer-vm = { workspace = true } +wasmer-vm = { workspace = true, features = ["force-baremetal"] } bytes = { workspace = true } corosensei = { workspace = true } @@ -23,7 +23,7 @@ once_cell = { workspace = true } rand_pcg = { workspace = true } rand = { workspace = true } ruint2 = { workspace = true } -secp256k1 = { workspace = true } +secp256k1 = { workspace = true, features = ["recovery", "global-context"] } serde_json = { workspace = true } thiserror = { workspace = true } -tiny-keccak = { workspace = true } +tiny-keccak = { workspace = true, features = ["keccak"] } diff --git a/crates/sp1/program/src/imports/precompiles.rs b/crates/sp1/program/src/imports/precompiles.rs index 0e8ff45e90a..c9438f826d4 100644 --- a/crates/sp1/program/src/imports/precompiles.rs +++ b/crates/sp1/program/src/imports/precompiles.rs @@ -15,7 +15,10 @@ pub fn ecrecover( output: Ptr, ) -> Result { assert_eq!(hash_len, 32, "Hash length must be 32 bytes"); - assert_eq!(sig_len, 65, "Signature length must be 65 bytes (64 for signature + 1 for recovery id)"); + assert_eq!( + sig_len, 65, + "Signature length must be 65 bytes (64 for signature + 1 for recovery id)" + ); let (data, store) = ctx.data_and_store_mut(); let memory = data.memory.clone().unwrap().view(&store); @@ -24,7 +27,7 @@ pub fn ecrecover( let sig = read_slice(sig, 65, &memory)?; let message = Message::from_digest(hash.try_into().unwrap()); - let Ok(recovery_id) = RecoveryId::from_i32(sig[64] as i32) else { + let Ok(recovery_id) = RecoveryId::try_from(sig[64] as i32) else { return Ok(1); }; let Ok(signature) = RecoverableSignature::from_compact(&sig[0..64], recovery_id) else { diff --git a/crates/sp1/program/src/imports/wasi_stub.rs b/crates/sp1/program/src/imports/wasi_stub.rs index 88deb09c0ef..2b0e346f2c9 100644 --- a/crates/sp1/program/src/imports/wasi_stub.rs +++ b/crates/sp1/program/src/imports/wasi_stub.rs @@ -1,6 +1,10 @@ //! WASI stubs — thin wrappers delegating to caller_env::wasip1_stub. -use crate::{Ptr, platform, replay::CustomEnvData, state::{gp, sp1_env}}; +use crate::{ + Ptr, platform, + replay::CustomEnvData, + state::{gp, sp1_env}, +}; use wasmer::FunctionEnvMut; pub fn proc_exit(mut ctx: FunctionEnvMut, code: u32) { diff --git a/crates/sp1/program/src/imports/wavmio.rs b/crates/sp1/program/src/imports/wavmio.rs index 4d8b63e2f7d..43b9a71236c 100644 --- a/crates/sp1/program/src/imports/wavmio.rs +++ b/crates/sp1/program/src/imports/wavmio.rs @@ -1,56 +1,122 @@ //! wavmio functions — thin wrappers delegating to caller_env::wavmio. use crate::{ - Escape, MaybeEscape, Ptr, state::{sp1_env, gp}, read_bytes32, + Escape, MaybeEscape, Ptr, read_bytes32, replay::CustomEnvData, + state::{gp, sp1_env}, }; use ::caller_env::wavmio as caller_env; use core::ops::Deref; use wasmer::{FunctionEnvMut, MemoryView}; -pub fn get_global_state_bytes32(mut ctx: FunctionEnvMut, idx: u32, out_ptr: Ptr) -> MaybeEscape { +pub fn get_global_state_bytes32( + mut ctx: FunctionEnvMut, + idx: u32, + out_ptr: Ptr, +) -> MaybeEscape { let (mut mem, state) = sp1_env(&mut ctx); caller_env::get_global_state_bytes32(&mut mem, state, idx, gp(out_ptr)).map_err(Escape::Logical) } -pub fn set_global_state_bytes32(mut ctx: FunctionEnvMut, idx: u32, src_ptr: Ptr) -> MaybeEscape { +pub fn set_global_state_bytes32( + mut ctx: FunctionEnvMut, + idx: u32, + src_ptr: Ptr, +) -> MaybeEscape { let (mem, state) = sp1_env(&mut ctx); caller_env::set_global_state_bytes32(&mem, state, idx, gp(src_ptr)).map_err(Escape::Logical) } -pub fn get_global_state_u64(mut ctx: FunctionEnvMut, idx: u32) -> Result { +pub fn get_global_state_u64( + mut ctx: FunctionEnvMut, + idx: u32, +) -> Result { let (_mem, state) = sp1_env(&mut ctx); caller_env::get_global_state_u64(state, idx).map_err(Escape::Logical) } -pub fn set_global_state_u64(mut ctx: FunctionEnvMut, idx: u32, val: u64) -> MaybeEscape { +pub fn set_global_state_u64( + mut ctx: FunctionEnvMut, + idx: u32, + val: u64, +) -> MaybeEscape { let (_mem, state) = sp1_env(&mut ctx); caller_env::set_global_state_u64(state, idx, val).map_err(Escape::Logical) } -pub fn read_inbox_message(mut ctx: FunctionEnvMut, msg_num: u64, offset: u32, out_ptr: Ptr) -> Result { +pub fn read_inbox_message( + mut ctx: FunctionEnvMut, + msg_num: u64, + offset: u32, + out_ptr: Ptr, +) -> Result { let (mut mem, state) = sp1_env(&mut ctx); - caller_env::read_inbox_message(&mut mem, state, msg_num, offset, gp(out_ptr)).map_err(Escape::Logical) + caller_env::read_inbox_message(&mut mem, state, msg_num, offset, gp(out_ptr)) + .map_err(Escape::Logical) } -pub fn read_delayed_inbox_message(mut ctx: FunctionEnvMut, msg_num: u64, offset: u32, out_ptr: Ptr) -> Result { +pub fn read_delayed_inbox_message( + mut ctx: FunctionEnvMut, + msg_num: u64, + offset: u32, + out_ptr: Ptr, +) -> Result { let (mut mem, state) = sp1_env(&mut ctx); - caller_env::read_delayed_inbox_message(&mut mem, state, msg_num, offset, gp(out_ptr)).map_err(Escape::Logical) + caller_env::read_delayed_inbox_message(&mut mem, state, msg_num, offset, gp(out_ptr)) + .map_err(Escape::Logical) } -pub fn resolve_keccak_preimage(mut ctx: FunctionEnvMut, hash_ptr: Ptr, offset: u32, out_ptr: Ptr) -> Result { +pub fn resolve_keccak_preimage( + mut ctx: FunctionEnvMut, + hash_ptr: Ptr, + offset: u32, + out_ptr: Ptr, +) -> Result { let (mut mem, state) = sp1_env(&mut ctx); - caller_env::resolve_preimage(&mut mem, state, 0, gp(hash_ptr), offset, gp(out_ptr), "wavmio.ResolvePreImage").map_err(Escape::Logical) + caller_env::resolve_preimage( + &mut mem, + state, + 0, + gp(hash_ptr), + offset, + gp(out_ptr), + "wavmio.ResolvePreImage", + ) + .map_err(Escape::Logical) } -pub fn resolve_typed_preimage(mut ctx: FunctionEnvMut, preimage_type: u8, hash_ptr: Ptr, offset: u32, out_ptr: Ptr) -> Result { +pub fn resolve_typed_preimage( + mut ctx: FunctionEnvMut, + preimage_type: u8, + hash_ptr: Ptr, + offset: u32, + out_ptr: Ptr, +) -> Result { let (mut mem, state) = sp1_env(&mut ctx); - caller_env::resolve_preimage(&mut mem, state, preimage_type, gp(hash_ptr), offset, gp(out_ptr), "wavmio.ResolveTypedPreimage").map_err(Escape::Logical) + caller_env::resolve_preimage( + &mut mem, + state, + preimage_type, + gp(hash_ptr), + offset, + gp(out_ptr), + "wavmio.ResolveTypedPreimage", + ) + .map_err(Escape::Logical) } -pub fn validate_certificate(mut ctx: FunctionEnvMut, preimage_type: u8, hash_ptr: Ptr) -> Result { +pub fn validate_certificate( + mut ctx: FunctionEnvMut, + preimage_type: u8, + hash_ptr: Ptr, +) -> Result { let (mem, state) = sp1_env(&mut ctx); - Ok(caller_env::validate_certificate(&mem, state, preimage_type, gp(hash_ptr))) + Ok(caller_env::validate_certificate( + &mem, + state, + preimage_type, + gp(hash_ptr), + )) } // Greedy preimage resolution — kept separate, will be refactored independently. diff --git a/crates/sp1/program/src/lib.rs b/crates/sp1/program/src/lib.rs index 007b777b639..a0e9e542d5d 100644 --- a/crates/sp1/program/src/lib.rs +++ b/crates/sp1/program/src/lib.rs @@ -1,9 +1,9 @@ pub mod imports; +mod memory; pub mod platform; pub mod replay; -pub mod stylus; mod state; -mod memory; +pub mod stylus; use arbutil::{ Bytes20, Bytes32, diff --git a/crates/sp1/program/src/main.rs b/crates/sp1/program/src/main.rs index ab375c647e3..7c43fe9c62f 100644 --- a/crates/sp1/program/src/main.rs +++ b/crates/sp1/program/src/main.rs @@ -30,7 +30,7 @@ pub extern "C" fn __negsf2(_x: f32) -> f32 { // in C can rely on Rust for memory management. // Use `alloc::` instead of `std::` if you are in a `#![no_std]` environment. -use std::alloc::{alloc, alloc_zeroed, dealloc, realloc as rust_realloc, Layout}; +use std::alloc::{Layout, alloc, alloc_zeroed, dealloc, realloc as rust_realloc}; use std::ptr; // Alignment and header size (use 16 for 64-bit systems or SIMD requirements) diff --git a/crates/sp1/program/src/replay.rs b/crates/sp1/program/src/replay.rs index 1d352dd8af5..531d2613d36 100644 --- a/crates/sp1/program/src/replay.rs +++ b/crates/sp1/program/src/replay.rs @@ -11,10 +11,10 @@ use bytes::Bytes; use corosensei::{Coroutine, CoroutineResult, Yielder, stack::DefaultStack}; use once_cell::unsync::Lazy; use prover::programs::meter::MeteredMachine; -use validation::ValidationInput; use rand_pcg::Pcg32; use std::marker::PhantomData; use std::ops::{Deref, DerefMut}; +use validation::ValidationInput; use wasmer::{ Engine, Function, FunctionEnv, Imports, Instance, Memory, Module, RuntimeError, Store, Value, imports, sys::NativeEngineExt, diff --git a/crates/sp1/program/src/state.rs b/crates/sp1/program/src/state.rs index b08fbf92e7d..2a5f5876013 100644 --- a/crates/sp1/program/src/state.rs +++ b/crates/sp1/program/src/state.rs @@ -33,7 +33,9 @@ impl WavmIo for CustomEnvData { } fn set_u64_global(&mut self, idx: usize, val: u64) -> bool { - let Some(g) = self.input_mut().small_globals.get_mut(idx) else { return false }; + let Some(g) = self.input_mut().small_globals.get_mut(idx) else { + return false; + }; *g = val; true } @@ -43,17 +45,25 @@ impl WavmIo for CustomEnvData { } fn set_bytes32_global(&mut self, idx: usize, val: [u8; 32]) -> bool { - let Some(g) = self.input_mut().large_globals.get_mut(idx) else { return false }; + let Some(g) = self.input_mut().large_globals.get_mut(idx) else { + return false; + }; *g = val; true } fn get_sequencer_message(&self, num: u64) -> Option<&[u8]> { - self.input().sequencer_messages.get(&num).map(|v| v.as_slice()) + self.input() + .sequencer_messages + .get(&num) + .map(|v| v.as_slice()) } fn get_delayed_message(&self, num: u64) -> Option<&[u8]> { - self.input().delayed_messages.get(&num).map(|v| v.as_slice()) + self.input() + .delayed_messages + .get(&num) + .map(|v| v.as_slice()) } fn get_preimage(&self, preimage_type: u8, hash: &[u8; 32]) -> Option<&[u8]> { diff --git a/crates/sp1/prover/Cargo.toml b/crates/sp1/prover/Cargo.toml deleted file mode 100644 index fbf7f7066f9..00000000000 --- a/crates/sp1/prover/Cargo.toml +++ /dev/null @@ -1,28 +0,0 @@ -[package] -name = "prover" -version = "0.1.0" -edition = "2024" - -[dependencies] -arbutil = { workspace = true } -brotli = { workspace = true } -derivative = { workspace = true } -digest = { workspace = true } -eyre = { workspace = true } -fnv = { workspace = true } -lazy_static = { workspace = true } -nom = { workspace = true } -num-derive = { workspace = true } -num-traits = { workspace = true } -parking_lot = { workspace = true } -serde = { workspace = true, features = ["derive", "rc"] } -serde_with = { workspace = true, features = ["base64"] } -sha3 = { workspace = true } -wasmer = { workspace = true, optional = true } -wasmer-types = { workspace = true, optional = true } -wasmparser = { workspace = true, optional = true } - -[features] -default = ["native", "sp1"] -sp1 = [] -native = ["dep:wasmer", "dep:wasmer-types", "dep:wasmparser"] diff --git a/crates/sp1/prover/src/lib.rs b/crates/sp1/prover/src/lib.rs deleted file mode 100644 index 6a3b2cd0cd5..00000000000 --- a/crates/sp1/prover/src/lib.rs +++ /dev/null @@ -1,22 +0,0 @@ -//! Ideally, we should just use crates/prover. This crate has no -//! reason to exist. But at the moment, nitro uses wasmer 4.x, while SP1 -//! requires wasmer 6.1.x. The 2 wasmer versions are hardly compatible. -//! On the other hand, we would want to borrow common definitions in -//! crates/prover so we don't have to define them twice. -//! This crate serves as a workaround till we can upgrade wasmer in nitro. -#![allow(unexpected_cfgs)] - -#[cfg(feature = "native")] -#[path = "../../../prover/src/binary.rs"] -pub mod binary; -#[cfg(feature = "native")] -#[path = "../../../prover/src/programs/mod.rs"] -pub mod programs; -#[cfg(feature = "native")] -#[path = "../../../prover/src/value.rs"] -pub mod value; - -#[cfg(feature = "native")] -#[path = "../../../arbutil/src/operator.rs"] -pub mod operator; - diff --git a/crates/sp1/runner/Cargo.toml b/crates/sp1/runner/Cargo.toml index 3240115c1d8..53859077a7e 100644 --- a/crates/sp1/runner/Cargo.toml +++ b/crates/sp1/runner/Cargo.toml @@ -5,13 +5,13 @@ version = "0.1.0" edition = "2024" [dependencies] -sp1-core-executor = { workspace = true } -sp1-sdk = { workspace = true } +sp1-core-executor = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe" } +sp1-sdk = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe", features = ["profiling"] } validation = { workspace = true, features = ["rkyv", "sp1"] } bincode = { workspace = true } -clap = { workspace = true } -rkyv = { workspace = true } +clap = { workspace = true, features = ["cargo", "derive"] } +rkyv = { workspace = true, features = ["indexmap-2", "bytes-1"] } serde_json = { workspace = true } tracing = { workspace = true } tokio = { workspace = true } diff --git a/crates/sp1/runner/src/main.rs b/crates/sp1/runner/src/main.rs index 385a825f639..710bfea4d62 100644 --- a/crates/sp1/runner/src/main.rs +++ b/crates/sp1/runner/src/main.rs @@ -113,9 +113,10 @@ async fn main() { // Build SP1 input from Arbitrum block. It is serialized to Vec, so // we can easily inject debugging code to dump stdin when needed. fn build_input(cli: &Cli) -> Vec { - let req = - serde_json::from_slice::(&std::fs::read(&cli.block_file).expect("read input block")) - .expect("parse input block"); + let req = serde_json::from_slice::( + &std::fs::read(&cli.block_file).expect("read input block"), + ) + .expect("parse input block"); let mut input = ValidationInput::from_request(&req, "rv64").expect("request validation input"); diff --git a/crates/sp1/rust-toolchain.toml b/crates/sp1/rust-toolchain.toml deleted file mode 100644 index 075062e5e6b..00000000000 --- a/crates/sp1/rust-toolchain.toml +++ /dev/null @@ -1,2 +0,0 @@ -[toolchain] -channel = "1.93.0" diff --git a/crates/sp1/stylus-compiler-program/Cargo.toml b/crates/sp1/stylus-compiler-program/Cargo.toml index 525f5196d78..9684a404ea2 100644 --- a/crates/sp1/stylus-compiler-program/Cargo.toml +++ b/crates/sp1/stylus-compiler-program/Cargo.toml @@ -5,6 +5,6 @@ version = "0.1.0" edition = "2024" [dependencies] -sp1-zkvm = { workspace = true } -wasmer = { workspace = true } -prover = { workspace = true, features = ["native"] } +sp1-zkvm = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe", features = ["untrusted_programs", "may_dump_elf"] } +wasmer = { workspace = true, features = ["sys", "compiler", "singlepass"] } +prover = { workspace = true, features = ["sp1", "native"] } From c75e802340fa1e6381166fd9efc651768ef3c4db Mon Sep 17 00:00:00 2001 From: Igor Braga <5835477+bragaigor@users.noreply.github.com> Date: Tue, 24 Mar 2026 17:13:16 -0400 Subject: [PATCH 135/189] move sp1 deps to root Cargo.toml Signed-off-by: Igor Braga <5835477+bragaigor@users.noreply.github.com> --- Cargo.toml | 13 +++++++++++++ crates/sp1/builder/Cargo.toml | 6 +++--- crates/sp1/program/Cargo.toml | 2 +- crates/sp1/runner/Cargo.toml | 4 ++-- crates/sp1/stylus-compiler-program/Cargo.toml | 2 +- 5 files changed, 20 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 759d1e18a8d..2b1ecdbf80d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -115,6 +115,8 @@ prover = { path = "crates/prover", default-features = false } stylus = { path = "crates/stylus", default-features = false } user-host-trait = { path = "crates/wasm-libraries/user-host-trait" } validation = { path = "crates/validation" } + +# wasmer wasmer = { path = "crates/tools/wasmer/lib/api" } wasmer-compiler-cranelift = { path = "crates/tools/wasmer/lib/compiler-cranelift" } wasmer-compiler-llvm = { path = "crates/tools/wasmer/lib/compiler-llvm" } @@ -122,6 +124,13 @@ wasmer-compiler-singlepass = { path = "crates/tools/wasmer/lib/compiler-singlepa wasmer-types = { path = "crates/tools/wasmer/lib/types" } wasmer-vm = { path = "crates/tools/wasmer/lib/vm" } +# sp1 +sp1-build = { version = "6.0.0", features = ["may_dump_elf"] } +sp1-core-executor = { version = "6.0.0" } +sp1-sdk = { version = "6.0.0", features = ["profiling"] } +sp1-zkvm = { version = "6.0.0", features = ["untrusted_programs", "may_dump_elf"] } + + [patch.crates-io] target-lexicon = { git = "https://github.com/OffchainLabs/target-lexicon", tag = "v0.13.5-sp1" } region = { git = "https://github.com/OffchainLabs/region-rs", tag = "v3.0.2-sp1" } @@ -129,6 +138,10 @@ corosensei = { git = "https://github.com/OffchainLabs/corosensei", rev = "668113 which = { git = "https://github.com/OffchainLabs/which-rs", rev = "f516e8a2e5453daeab38706747a9f6be8bb058e7" } # branch: v0.3.3-sp1 secp256k1 = { git = "https://github.com/sp1-patches/rust-secp256k1", tag = "patch-0.30.0-sp1-6.0.0" } tiny-keccak = { git = "https://github.com/sp1-patches/tiny-keccak", tag = "patch-2.0.2-sp1-6.0.0" } + +sp1-build = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe" } +sp1-core-executor = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe" } +sp1-sdk = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe" } sp1-zkvm = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe" } [profile.release] diff --git a/crates/sp1/builder/Cargo.toml b/crates/sp1/builder/Cargo.toml index bb6dbd3db0e..3431bc13f52 100644 --- a/crates/sp1/builder/Cargo.toml +++ b/crates/sp1/builder/Cargo.toml @@ -5,8 +5,8 @@ version = "0.1.0" edition = "2024" [dependencies] -sp1-core-executor = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe" } -sp1-sdk = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe", features = ["profiling"] } +sp1-core-executor = { workspace = true } +sp1-sdk = { workspace = true } clap = { workspace = true, features = ["cargo", "derive"] } serde_json = { workspace = true } @@ -14,4 +14,4 @@ wasmer = { workspace = true, features = ["llvm"] } wasmparser = { workspace = true } [build-dependencies] -sp1-build = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe", features = ["may_dump_elf"] } +sp1-build = { workspace = true } diff --git a/crates/sp1/program/Cargo.toml b/crates/sp1/program/Cargo.toml index 1b338c1a780..1c9495aeb46 100644 --- a/crates/sp1/program/Cargo.toml +++ b/crates/sp1/program/Cargo.toml @@ -8,7 +8,7 @@ edition = "2024" arbutil = { workspace = true } caller-env = { workspace = true, features = ["brotli"] } prover = { workspace = true, features = ["sp1", "native"] } -sp1-zkvm = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe", features = ["untrusted_programs", "may_dump_elf"] } +sp1-zkvm = { workspace = true } validation = { workspace = true, features = ["rkyv"] } wasmer = { workspace = true, features = ["sys", "compiler", "singlepass", "wasmparser"] } wasmer-types = { workspace = true } diff --git a/crates/sp1/runner/Cargo.toml b/crates/sp1/runner/Cargo.toml index 53859077a7e..739c6c4c3b1 100644 --- a/crates/sp1/runner/Cargo.toml +++ b/crates/sp1/runner/Cargo.toml @@ -5,8 +5,8 @@ version = "0.1.0" edition = "2024" [dependencies] -sp1-core-executor = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe" } -sp1-sdk = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe", features = ["profiling"] } +sp1-core-executor = { workspace = true } +sp1-sdk = { workspace = true } validation = { workspace = true, features = ["rkyv", "sp1"] } bincode = { workspace = true } diff --git a/crates/sp1/stylus-compiler-program/Cargo.toml b/crates/sp1/stylus-compiler-program/Cargo.toml index 9684a404ea2..7f37fe1c91b 100644 --- a/crates/sp1/stylus-compiler-program/Cargo.toml +++ b/crates/sp1/stylus-compiler-program/Cargo.toml @@ -5,6 +5,6 @@ version = "0.1.0" edition = "2024" [dependencies] -sp1-zkvm = { git = "https://github.com/succinctlabs/sp1", rev = "be6ebfe", features = ["untrusted_programs", "may_dump_elf"] } +sp1-zkvm = { workspace = true } wasmer = { workspace = true, features = ["sys", "compiler", "singlepass"] } prover = { workspace = true, features = ["sp1", "native"] } From a19bfc18c57995d0e74f314dc50a9a28186cd965 Mon Sep 17 00:00:00 2001 From: Igor Braga <5835477+bragaigor@users.noreply.github.com> Date: Tue, 24 Mar 2026 17:44:20 -0400 Subject: [PATCH 136/189] Make fmt and clippy happy Signed-off-by: Igor Braga <5835477+bragaigor@users.noreply.github.com> --- .github/workflows/_rust-tests.yml | 7 +++++-- crates/prover/src/lib.rs | 22 ++++++++++++++-------- crates/prover/src/machine.rs | 4 ++-- crates/prover/src/value.rs | 10 ++-------- crates/sp1/builder/src/main.rs | 13 +++++-------- crates/sp1/program/src/imports/vm_hooks.rs | 2 +- crates/sp1/program/src/imports/wavmio.rs | 2 +- crates/sp1/program/src/main.rs | 1 + crates/sp1/program/src/replay.rs | 8 ++++---- crates/sp1/program/src/stylus.rs | 10 +++++----- 10 files changed, 40 insertions(+), 39 deletions(-) diff --git a/.github/workflows/_rust-tests.yml b/.github/workflows/_rust-tests.yml index 5b437714ba8..0db07e20f12 100644 --- a/.github/workflows/_rust-tests.yml +++ b/.github/workflows/_rust-tests.yml @@ -55,8 +55,11 @@ jobs: - name: Prepare replay.wasm env run: make build-replay-env - - name: Clippy check - run: cargo clippy --all -- -D warnings -A static_mut_refs + - name: Clippy check (non-SP1) + run: cargo clippy --workspace --exclude program --exclude sp1-builder --exclude sp1-runner --exclude stylus-compiler-program -- -D warnings -A static_mut_refs + + - name: Clippy check (SP1) + run: cargo clippy -p program -p sp1-builder -p sp1-runner -p stylus-compiler-program -- -D warnings -A static_mut_refs -A clippy::too_many_arguments -A clippy::mut_from_ref - name: Run rust tests id: run-rust-tests diff --git a/crates/prover/src/lib.rs b/crates/prover/src/lib.rs index c6da50d5e96..6dc381b373f 100644 --- a/crates/prover/src/lib.rs +++ b/crates/prover/src/lib.rs @@ -26,22 +26,28 @@ mod test; pub use machine::Machine; -use arbutil::{Bytes32, PreimageType}; +use arbutil::Bytes32; +#[cfg(not(feature = "sp1"))] +use arbutil::PreimageType; +#[cfg(not(feature = "sp1"))] use eyre::{Report, Result}; use lru::LruCache; -use machine::{ - argument_data_to_inbox, get_empty_preimage_resolver, GlobalState, MachineStatus, - PreimageResolver, -}; +use machine::MachineStatus; +#[cfg(not(feature = "sp1"))] +use machine::{argument_data_to_inbox, get_empty_preimage_resolver, GlobalState, PreimageResolver}; use once_cell::sync::OnceCell; use static_assertions::const_assert_eq; +#[cfg(not(feature = "sp1"))] use std::{ ffi::CStr, - marker::PhantomData, - num::NonZeroUsize, os::raw::{c_char, c_int}, path::Path, - ptr, slice, + slice, +}; +use std::{ + marker::PhantomData, + num::NonZeroUsize, + ptr, sync::{ atomic::{self, AtomicU8}, Arc, Mutex, diff --git a/crates/prover/src/machine.rs b/crates/prover/src/machine.rs index 75d3380b60e..548c977ed70 100644 --- a/crates/prover/src/machine.rs +++ b/crates/prover/src/machine.rs @@ -3,6 +3,8 @@ #[cfg(feature = "kzg")] use crate::kzg::prove_kzg_preimage; +#[cfg(all(feature = "native", not(feature = "sp1")))] +use crate::programs::meter::MeteredMachine; use crate::{ binary::{ self, parse, ExportKind, ExportMap, FloatInstruction, Local, NameCustomSection, WasmBinary, @@ -19,8 +21,6 @@ use crate::{ IBinOpType, IRelOpType, IUnOpType, Instruction, Opcode, }, }; -#[cfg(all(feature = "native", not(feature = "sp1")))] -use crate::programs::meter::MeteredMachine; use arbutil::{crypto, math, Bytes32, Color, DebugColor, PreimageType}; use brotli::Dictionary; #[cfg(feature = "kzg")] diff --git a/crates/prover/src/value.rs b/crates/prover/src/value.rs index f1d9a953434..d90c007cc03 100644 --- a/crates/prover/src/value.rs +++ b/crates/prover/src/value.rs @@ -498,13 +498,7 @@ impl Display for ArbValueType { } #[cfg(feature = "sp1")] -#[path = "internal_func.rs"] -mod internal_func; -#[cfg(feature = "sp1")] -pub use internal_func::InternalFunc; +pub use crate::internal_func::InternalFunc; #[cfg(feature = "sp1")] -#[path = "memory_type.rs"] -mod memory_type; -#[cfg(feature = "sp1")] -pub use memory_type::MemoryType; +pub use crate::memory_type::MemoryType; diff --git a/crates/sp1/builder/src/main.rs b/crates/sp1/builder/src/main.rs index 78216c7b4e2..4254eb2ba76 100644 --- a/crates/sp1/builder/src/main.rs +++ b/crates/sp1/builder/src/main.rs @@ -41,14 +41,11 @@ fn main() { let name_reader = NameSectionReader::new(BinaryReader::new(s.data(), s.data_offset())); for name in name_reader { - match name.expect("name") { - Name::Function(name_map) => { - for naming in name_map { - let naming = naming.expect("naming"); - name_mapping.insert(naming.index, naming.name.to_string()); - } + if let Name::Function(name_map) = name.expect("name") { + for naming in name_map { + let naming = naming.expect("naming"); + name_mapping.insert(naming.index, naming.name.to_string()); } - _ => (), } } } @@ -57,7 +54,7 @@ fn main() { } // names might be sparse, we need more processing work here. - let min_index = name_mapping.iter().map(|(index, _)| *index).min().unwrap(); + let min_index = name_mapping.keys().copied().min().unwrap(); let name_mapping: Vec<(usize, String)> = name_mapping .into_iter() .map(|(index, name)| ((index - min_index) as usize, name)) diff --git a/crates/sp1/program/src/imports/vm_hooks.rs b/crates/sp1/program/src/imports/vm_hooks.rs index 419eebebdb9..9660670c78b 100644 --- a/crates/sp1/program/src/imports/vm_hooks.rs +++ b/crates/sp1/program/src/imports/vm_hooks.rs @@ -556,7 +556,7 @@ type U256 = ruint2::Uint<256, 4>; fn read_u256(ptr: Ptr, memory: &MemoryView) -> Result<(U256, Bytes32), Escape> { let bytes = read_bytes32(ptr, memory)?; - Ok((bytes.clone().into(), bytes)) + Ok((bytes.into(), bytes)) } pub fn math_div( diff --git a/crates/sp1/program/src/imports/wavmio.rs b/crates/sp1/program/src/imports/wavmio.rs index 43b9a71236c..07feca6a1d4 100644 --- a/crates/sp1/program/src/imports/wavmio.rs +++ b/crates/sp1/program/src/imports/wavmio.rs @@ -180,5 +180,5 @@ fn greedy_resolve_typed_preimage_impl( hex::encode(hash) )); }; - greedy_read(&preimage, &memory, offset, available, out_ptr) + greedy_read(preimage, &memory, offset, available, out_ptr) } diff --git a/crates/sp1/program/src/main.rs b/crates/sp1/program/src/main.rs index 7c43fe9c62f..322dde88276 100644 --- a/crates/sp1/program/src/main.rs +++ b/crates/sp1/program/src/main.rs @@ -1,4 +1,5 @@ #![cfg_attr(target_os = "zkvm", no_main)] +#![allow(unsafe_op_in_unsafe_fn, clippy::missing_safety_doc)] #[cfg(target_os = "zkvm")] sp1_zkvm::entrypoint!(main); diff --git a/crates/sp1/program/src/replay.rs b/crates/sp1/program/src/replay.rs index 531d2613d36..e4620de8ef6 100644 --- a/crates/sp1/program/src/replay.rs +++ b/crates/sp1/program/src/replay.rs @@ -27,10 +27,10 @@ use wasmer_vm::install_unwinder; // will leave it to another time to debate which is a better option. static mut COTHREADS: Vec = Vec::new(); fn cothreads_mut() -> &'static mut Vec { - unsafe { &mut *&raw mut COTHREADS } + unsafe { &mut *std::ptr::addr_of_mut!(COTHREADS) } } fn cothreads() -> &'static [Cothread] { - unsafe { &*&raw const COTHREADS } + unsafe { &*std::ptr::addr_of!(COTHREADS) } } /// This provides a single-threaded Send yielder since corosensei's @@ -105,7 +105,7 @@ impl CustomEnvData { memory: None, time: 0, pcg, - input: Lazy::new(|| read_input()), + input: Lazy::new(read_input), yielder: SendYielder::new(yielder), } } @@ -402,7 +402,7 @@ fn align_bytes(data: &[u8]) -> Bytes { use bytes::BytesMut; let mut buffer = BytesMut::zeroed(data.len() + 7); let p = buffer.as_ptr() as usize; - let aligned_p = (p + 7) / 8 * 8; + let aligned_p = p.div_ceil(8) * 8; let offset = aligned_p - p; buffer[offset..offset + data.len()].copy_from_slice(data); let bytes = buffer.freeze(); diff --git a/crates/sp1/program/src/stylus.rs b/crates/sp1/program/src/stylus.rs index f5e952e6a21..69d2c435fe2 100644 --- a/crates/sp1/program/src/stylus.rs +++ b/crates/sp1/program/src/stylus.rs @@ -95,7 +95,7 @@ impl Cothread { panic!("name not found global"); }; let StoreObjects::Sys(objects) = store.objects_mut(); - sh.get(&objects).vmglobal() + sh.get(objects).vmglobal() }; ( expect_global(STYLUS_INK_LEFT), @@ -371,10 +371,10 @@ impl StylusCustomEnvData { address: Bytes20, gas_left: Gas, ) -> (Vec, Gas) { - if let Some((stored_address, data)) = self.last_code.as_ref() { - if address == *stored_address { - return (data.clone(), Gas(0)); - } + if let Some((stored_address, data)) = self.last_code.as_ref() + && address == *stored_address + { + return (data.clone(), Gas(0)); } let mut req = Vec::with_capacity(20 + 8); req.extend(address); From 355d83e22ae84bcbb6eb2d224ce0ddc7a4f49607 Mon Sep 17 00:00:00 2001 From: Igor Braga <5835477+bragaigor@users.noreply.github.com> Date: Tue, 24 Mar 2026 18:18:50 -0400 Subject: [PATCH 137/189] Improve code readability and update comments Signed-off-by: Igor Braga <5835477+bragaigor@users.noreply.github.com> --- .github/workflows/_rust-tests.yml | 3 -- .github/workflows/zk-proving.yml | 5 +++ Cargo.toml | 5 +++ crates/brotli/src/dicts/mod.rs | 7 +++- crates/prover/src/utils.rs | 37 +++++++++++++++++- crates/sp1/build.sh | 2 +- crates/sp1/builder/src/main.rs | 15 +++++--- crates/sp1/program/src/imports/debug.rs | 6 ++- crates/sp1/program/src/imports/programs.rs | 15 +++++--- crates/sp1/program/src/imports/vm_hooks.rs | 7 ++-- crates/sp1/program/src/main.rs | 3 +- crates/sp1/program/src/memory.rs | 44 ++++++++++++++++------ crates/sp1/program/src/replay.rs | 28 ++++++++------ crates/sp1/program/src/stylus.rs | 11 +++++- crates/sp1/runner/src/main.rs | 20 ++++++++-- 15 files changed, 157 insertions(+), 51 deletions(-) diff --git a/.github/workflows/_rust-tests.yml b/.github/workflows/_rust-tests.yml index 0db07e20f12..d0be3131445 100644 --- a/.github/workflows/_rust-tests.yml +++ b/.github/workflows/_rust-tests.yml @@ -58,9 +58,6 @@ jobs: - name: Clippy check (non-SP1) run: cargo clippy --workspace --exclude program --exclude sp1-builder --exclude sp1-runner --exclude stylus-compiler-program -- -D warnings -A static_mut_refs - - name: Clippy check (SP1) - run: cargo clippy -p program -p sp1-builder -p sp1-runner -p stylus-compiler-program -- -D warnings -A static_mut_refs -A clippy::too_many_arguments -A clippy::mut_from_ref - - name: Run rust tests id: run-rust-tests continue-on-error: true diff --git a/.github/workflows/zk-proving.yml b/.github/workflows/zk-proving.yml index 1fda6fd7ff7..c627c4085c4 100644 --- a/.github/workflows/zk-proving.yml +++ b/.github/workflows/zk-proving.yml @@ -47,6 +47,11 @@ jobs: - name: Build binaries and record block run: ./crates/sp1/build.sh + # Clippy runs after build because sp1-builder uses include_elf!(), + # which requires the SP1 ELF to exist at compile time. + - name: Clippy check (SP1) + run: cargo clippy -p program -p sp1-builder -p sp1-runner -p stylus-compiler-program -- -D warnings -A static_mut_refs -A clippy::too_many_arguments + - name: Run validation run: | # Exit if any command in a pipe fails diff --git a/Cargo.toml b/Cargo.toml index 2b1ecdbf80d..46b7104e61e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -132,6 +132,11 @@ sp1-zkvm = { version = "6.0.0", features = ["untrusted_programs", "may_dump_elf" [patch.crates-io] +# SP1 patches: these apply workspace-wide because Cargo does not support +# target-scoped or feature-scoped patches. The SP1-patched forks add RISC-V +# (riscv64) support while preserving identical behavior on native x86/ARM +# targets. Non-SP1 crates (prover, JIT, stylus) are unaffected on native builds. +# If SP1 is ever split into a separate workspace, these patches can be removed. target-lexicon = { git = "https://github.com/OffchainLabs/target-lexicon", tag = "v0.13.5-sp1" } region = { git = "https://github.com/OffchainLabs/region-rs", tag = "v3.0.2-sp1" } corosensei = { git = "https://github.com/OffchainLabs/corosensei", rev = "6681138454747733c6adad5037024400f0c9d4e3" } # branch: v0.3.3-sp diff --git a/crates/brotli/src/dicts/mod.rs b/crates/brotli/src/dicts/mod.rs index db474317dfa..a3b5fd53561 100644 --- a/crates/brotli/src/dicts/mod.rs +++ b/crates/brotli/src/dicts/mod.rs @@ -27,9 +27,14 @@ extern "C" { ) -> usize; } -/// Forces a type to implement [`Sync`]. +/// Forces a type to implement [`Sync`] and [`Send`]. +/// Only used to wrap static dictionary pointers (`*const EncoderPreparedDictionary`) +/// which point to immutable, process-lifetime data initialized once via `lazy_static`. struct ForceSync(T); +// SAFETY: ForceSync only wraps raw pointers to immutable, static dictionary data. +// The data is initialized once (via lazy_static) and never mutated or freed, +// so sharing across threads is safe. unsafe impl Sync for ForceSync {} unsafe impl Send for ForceSync {} diff --git a/crates/prover/src/utils.rs b/crates/prover/src/utils.rs index 31a2c76475d..71d9635e29c 100644 --- a/crates/prover/src/utils.rs +++ b/crates/prover/src/utils.rs @@ -14,7 +14,9 @@ use sha3::Keccak256; use std::{borrow::Borrow, convert::TryInto, fmt, fs::File, io::Read, ops::Deref, path::Path}; use wasmparser::{RefType, TableType}; -/// A Vec allocated with libc::malloc +/// A Vec with manual allocation. +/// On native builds, uses libc malloc/free for FFI compatibility. +/// On SP1 (no libc), uses Rust's global allocator. pub struct CBytes { ptr: *mut u8, len: usize, @@ -49,6 +51,27 @@ impl fmt::Debug for CBytes { } } +#[cfg(not(feature = "sp1"))] +impl From<&[u8]> for CBytes { + fn from(slice: &[u8]) -> Self { + if slice.is_empty() { + return Self::default(); + } + unsafe { + let ptr = libc::malloc(slice.len()) as *mut u8; + if ptr.is_null() { + panic!("Failed to allocate memory instantiating CBytes"); + } + std::ptr::copy_nonoverlapping(slice.as_ptr(), ptr, slice.len()); + Self { + ptr, + len: slice.len(), + } + } + } +} + +#[cfg(feature = "sp1")] impl From<&[u8]> for CBytes { fn from(slice: &[u8]) -> Self { if slice.is_empty() { @@ -117,6 +140,18 @@ pub struct RemoteTableType { pub shared: bool, } +#[cfg(not(feature = "sp1"))] +impl Drop for CBytes { + fn drop(&mut self) { + if !self.ptr.is_null() && self.len > 0 { + unsafe { + libc::free(self.ptr as *mut _); + } + } + } +} + +#[cfg(feature = "sp1")] impl Drop for CBytes { fn drop(&mut self) { if !self.ptr.is_null() && self.len > 0 { diff --git a/crates/sp1/build.sh b/crates/sp1/build.sh index 3a08746b6d8..e90c8519bd1 100755 --- a/crates/sp1/build.sh +++ b/crates/sp1/build.sh @@ -60,7 +60,7 @@ cargo run --release -p sp1-builder -- --replay-wasm "$OUTPUT_DIR"/replay.wasm -- # Build the SP1 runner cargo build --release -p sp1-runner -# Copy relavant files to target folder +# Copy relevant files to target folder cp target/elf-compilation/riscv64im-succinct-zkvm-elf/release/stylus-compiler-program "$OUTPUT_DIR" cp target/release/sp1-runner "$OUTPUT_DIR" diff --git a/crates/sp1/builder/src/main.rs b/crates/sp1/builder/src/main.rs index 4254eb2ba76..e886f5b11c0 100644 --- a/crates/sp1/builder/src/main.rs +++ b/crates/sp1/builder/src/main.rs @@ -116,14 +116,19 @@ fn main() { // before reading this input. executor.with_input(&[]); - assert!(executor.execute_chunk().is_none()); + // The executor will fail after bootloading completes because + // the empty input buffer cannot be parsed as an Arbitrum block. + // This is expected — we only need the bootloading side-effect (ELF dump). + let _ = executor.execute_chunk(); if let Ok(true) = std::fs::exists(&output) { - println!( - "SP1 bootloading process completes. It's fine if you are seeing some errors, please ignore them" - ); + println!("SP1 bootloading process completed successfully."); } else { - panic!("Something is wrong with SP1 bootloading process, please check the logs."); + panic!( + "SP1 bootloading failed: expected output at '{}' was not produced. \ + Check logs above for the root cause.", + output + ); } println!("Bootloaded program is written to {}", output); diff --git a/crates/sp1/program/src/imports/debug.rs b/crates/sp1/program/src/imports/debug.rs index 2aa32a27001..e8ace46e607 100644 --- a/crates/sp1/program/src/imports/debug.rs +++ b/crates/sp1/program/src/imports/debug.rs @@ -35,9 +35,11 @@ pub fn console_tee + Copy>( pub fn null_host(_ctx: FunctionEnvMut) {} pub fn start_benchmark(_ctx: FunctionEnvMut) -> MaybeEscape { - unimplemented!() + // Benchmarking is not supported in SP1 zkVM execution + Ok(()) } pub fn end_benchmark(_ctx: FunctionEnvMut) -> MaybeEscape { - unimplemented!() + // Benchmarking is not supported in SP1 zkVM execution + Ok(()) } diff --git a/crates/sp1/program/src/imports/programs.rs b/crates/sp1/program/src/imports/programs.rs index e54edf4d2ff..964b461ff8f 100644 --- a/crates/sp1/program/src/imports/programs.rs +++ b/crates/sp1/program/src/imports/programs.rs @@ -14,6 +14,9 @@ use arbutil::evm::{EvmData, api::Gas}; use prover::programs::config::{CompileConfig, PricingParams, StylusConfig}; use wasmer::{FunctionEnvMut, WasmPtr}; +/// Hardcoded message ID used by the Arbitrator protocol for program communication. +const ARBITRATOR_MSG_ID: u32 = 0x33333333; + pub fn new_program( mut ctx: FunctionEnvMut, compiled_hash_ptr: Ptr, @@ -55,7 +58,7 @@ pub fn set_response( // Arbitrator for now only uses hardcoded id, we can ignore // ids safely. - assert_eq!(id, 0x33333333); + assert_eq!(id, ARBITRATOR_MSG_ID); let result = read_slice(result_ptr, result_len as usize, &memory)?; let raw_data = read_slice(raw_data_ptr, raw_data_len as usize, &memory)?; @@ -79,7 +82,7 @@ pub fn get_request( // Arbitrator for now only uses hardcoded id, we can ignore // ids safely. - assert_eq!(id, 0x33333333); + assert_eq!(id, ARBITRATOR_MSG_ID); let msg = data.get_last_msg(); len_ptr.write(&memory, msg.req_data.len() as u32)?; @@ -97,7 +100,7 @@ pub fn get_request_data( // Arbitrator for now only uses hardcoded id, we can ignore // ids safely. - assert_eq!(id, 0x33333333); + assert_eq!(id, ARBITRATOR_MSG_ID); let msg = data.get_last_msg(); memory.write(data_ptr.offset() as u64, &msg.req_data)?; @@ -113,7 +116,7 @@ pub fn start_program(mut ctx: FunctionEnvMut, module: u32) -> u32 // Arbitrator for now only uses hardcoded id, we can ignore // ids safely. - 0x33333333 + ARBITRATOR_MSG_ID } pub fn send_response(mut ctx: FunctionEnvMut, req_id: u32) -> u32 { @@ -121,12 +124,12 @@ pub fn send_response(mut ctx: FunctionEnvMut, req_id: u32) -> u32 // Arbitrator for now only uses hardcoded id, we can ignore // ids safely. - assert_eq!(req_id, 0x33333333); + assert_eq!(req_id, ARBITRATOR_MSG_ID); data.wait_next_message(None); let _ = data.get_last_msg(); - 0x33333333 + ARBITRATOR_MSG_ID } pub fn create_stylus_config( diff --git a/crates/sp1/program/src/imports/vm_hooks.rs b/crates/sp1/program/src/imports/vm_hooks.rs index 9660670c78b..95bb271ab2c 100644 --- a/crates/sp1/program/src/imports/vm_hooks.rs +++ b/crates/sp1/program/src/imports/vm_hooks.rs @@ -14,12 +14,11 @@ use eyre::eyre; use prover::programs::meter::{GasMeteredMachine, MeteredMachine}; use wasmer::{FunctionEnvMut, MemoryView}; -pub fn msg_reentrant(mut ctx: FunctionEnvMut) -> u32 { +pub fn msg_reentrant(mut ctx: FunctionEnvMut) -> Result { let data = ctx.data_mut(); - data.buy_ink(hostio::MSG_REENTRANT_BASE_INK) - .expect("buy ink"); + data.buy_ink(hostio::MSG_REENTRANT_BASE_INK)?; - data.evm_data.reentrant + Ok(data.evm_data.reentrant) } pub fn read_args(mut ctx: FunctionEnvMut, ptr: Ptr) -> MaybeEscape { diff --git a/crates/sp1/program/src/main.rs b/crates/sp1/program/src/main.rs index 322dde88276..02f8b343ec1 100644 --- a/crates/sp1/program/src/main.rs +++ b/crates/sp1/program/src/main.rs @@ -34,7 +34,8 @@ pub extern "C" fn __negsf2(_x: f32) -> f32 { use std::alloc::{Layout, alloc, alloc_zeroed, dealloc, realloc as rust_realloc}; use std::ptr; -// Alignment and header size (use 16 for 64-bit systems or SIMD requirements) +// Alignment for the custom allocator header. 8 bytes is sufficient for +// storing the size header (usize) on both 32-bit and 64-bit targets. const ALIGN: usize = 8; const HEADER_SIZE: usize = 8; diff --git a/crates/sp1/program/src/memory.rs b/crates/sp1/program/src/memory.rs index 4d7b40ebaaf..f64133e2495 100644 --- a/crates/sp1/program/src/memory.rs +++ b/crates/sp1/program/src/memory.rs @@ -19,57 +19,79 @@ impl Sp1MemAccess<'_> { impl MemAccess for Sp1MemAccess<'_> { fn read_u8(&self, ptr: GuestPtr) -> u8 { let mut buf = [0u8; 1]; - self.view().read(ptr.to_u64(), &mut buf).unwrap(); + self.view() + .read(ptr.to_u64(), &mut buf) + .expect("failed to read u8 from guest memory"); buf[0] } fn read_u16(&self, ptr: GuestPtr) -> u16 { let mut buf = [0u8; 2]; - self.view().read(ptr.to_u64(), &mut buf).unwrap(); + self.view() + .read(ptr.to_u64(), &mut buf) + .expect("failed to read u16 from guest memory"); u16::from_le_bytes(buf) } fn read_u32(&self, ptr: GuestPtr) -> u32 { let mut buf = [0u8; 4]; - self.view().read(ptr.to_u64(), &mut buf).unwrap(); + self.view() + .read(ptr.to_u64(), &mut buf) + .expect("failed to read u32 from guest memory"); u32::from_le_bytes(buf) } fn read_u64(&self, ptr: GuestPtr) -> u64 { let mut buf = [0u8; 8]; - self.view().read(ptr.to_u64(), &mut buf).unwrap(); + self.view() + .read(ptr.to_u64(), &mut buf) + .expect("failed to read u64 from guest memory"); u64::from_le_bytes(buf) } fn write_u8(&mut self, ptr: GuestPtr, x: u8) { - self.view().write(ptr.to_u64(), &[x]).unwrap(); + self.view() + .write(ptr.to_u64(), &[x]) + .expect("failed to write u8 to guest memory"); } fn write_u16(&mut self, ptr: GuestPtr, x: u16) { - self.view().write(ptr.to_u64(), &x.to_le_bytes()).unwrap(); + self.view() + .write(ptr.to_u64(), &x.to_le_bytes()) + .expect("failed to write u16 to guest memory"); } fn write_u32(&mut self, ptr: GuestPtr, x: u32) { - self.view().write(ptr.to_u64(), &x.to_le_bytes()).unwrap(); + self.view() + .write(ptr.to_u64(), &x.to_le_bytes()) + .expect("failed to write u32 to guest memory"); } fn write_u64(&mut self, ptr: GuestPtr, x: u64) { - self.view().write(ptr.to_u64(), &x.to_le_bytes()).unwrap(); + self.view() + .write(ptr.to_u64(), &x.to_le_bytes()) + .expect("failed to write u64 to guest memory"); } fn read_slice(&self, ptr: GuestPtr, len: usize) -> Vec { let mut data = vec![0u8; len]; - self.view().read(ptr.to_u64(), &mut data).unwrap(); + self.view() + .read(ptr.to_u64(), &mut data) + .expect("failed to read slice from guest memory"); data } fn read_fixed(&self, ptr: GuestPtr) -> [u8; N] { let mut buf = [0u8; N]; - self.view().read(ptr.to_u64(), &mut buf).unwrap(); + self.view() + .read(ptr.to_u64(), &mut buf) + .expect("failed to read fixed bytes from guest memory"); buf } fn write_slice(&mut self, ptr: GuestPtr, data: &[u8]) { - self.view().write(ptr.to_u64(), data).unwrap(); + self.view() + .write(ptr.to_u64(), data) + .expect("failed to write slice to guest memory"); } } diff --git a/crates/sp1/program/src/replay.rs b/crates/sp1/program/src/replay.rs index e4620de8ef6..c9a18c50897 100644 --- a/crates/sp1/program/src/replay.rs +++ b/crates/sp1/program/src/replay.rs @@ -154,15 +154,20 @@ impl CustomEnvData { let queue = &cothreads().last().unwrap().queue; queue.lock().expect("lock").mark_read_from_cothread(); - // Bound the number of loops for ease of debuging - for _ in 0..10 { + // Bound the number of loops for ease of debugging. + // 10 iterations should be more than enough for any single message exchange. + const MAX_YIELD_ITERATIONS: usize = 10; + for _ in 0..MAX_YIELD_ITERATIONS { if queue.lock().expect("lock").peek_from_cothread().is_some() { return; } self.yielder.suspend(MainYieldMessage::RunLastChild); } - panic!("did not receive message"); + panic!( + "did not receive message from cothread after {MAX_YIELD_ITERATIONS} iterations (module={module:?}, num_cothreads={})", + cothreads().len() + ); } // For now, message id in arbitrator is hardcoded to 0x33333333, @@ -410,13 +415,14 @@ fn align_bytes(data: &[u8]) -> Bytes { } pub(crate) fn handle_result(result: Result, RuntimeError>) -> ! { - let message = match result { - Ok(value) => format!("Machine exited prematurely with: {:?}", value), - Err(e) => format!("Runtime error: {}", e), - }; - - if !message.is_empty() { - println!("{message}"); + match result { + Ok(value) => { + println!("Machine exited prematurely with: {:?}", value); + exit(0); + } + Err(e) => { + println!("Runtime error: {}", e); + exit(1); + } } - exit(1); } diff --git a/crates/sp1/program/src/stylus.rs b/crates/sp1/program/src/stylus.rs index 69d2c435fe2..d36cf4e9c57 100644 --- a/crates/sp1/program/src/stylus.rs +++ b/crates/sp1/program/src/stylus.rs @@ -170,10 +170,16 @@ impl Cothread { } impl CothreadInput { + // SAFETY: CothreadInput stores raw pointers (as usize) to fields owned by + // the parent Cothread, which outlives all uses. SP1 is single-threaded, + // so there are no data races. The &self -> &mut pattern is required because + // the coroutine API doesn't allow passing &mut across yield boundaries. + #[allow(clippy::mut_from_ref)] pub fn store_mut(&self) -> &mut Store { unsafe { &mut *(self.store as *mut _) } } + #[allow(clippy::mut_from_ref)] pub fn function_env_mut(&self) -> &mut FunctionEnv { unsafe { &mut *(self.function_env as *mut _) } } @@ -243,13 +249,14 @@ impl StylusCustomEnvData { } fn wait_next_message(&mut self) -> MessageToCothread { - for _ in 0..10 { + const MAX_YIELD_ITERATIONS: usize = 10; + for _ in 0..MAX_YIELD_ITERATIONS { if let Some(msg) = self.queue.lock().expect("lock").read_to_cothread() { return msg; } self.yielder.as_ref().unwrap().suspend(None); } - panic!("did not receive message to cothread"); + panic!("did not receive message to cothread after {MAX_YIELD_ITERATIONS} iterations"); } pub fn request( diff --git a/crates/sp1/runner/src/main.rs b/crates/sp1/runner/src/main.rs index 710bfea4d62..d32cb4cf864 100644 --- a/crates/sp1/runner/src/main.rs +++ b/crates/sp1/runner/src/main.rs @@ -67,7 +67,12 @@ async fn main() { } let a = SystemTime::now(); - assert!(executor.execute_chunk().is_none()); + if executor.execute_chunk().is_some() { + eprintln!( + "Fast-mode execution failed: executor returned a trace chunk unexpectedly" + ); + std::process::exit(2); + } let b = SystemTime::now(); tracing::info!( "Exit code: {}, cycles: {}, execution time: {:?}", @@ -156,10 +161,19 @@ fn run_in_sp1(cli: &Cli, wasm: &[u8]) -> Vec { } let a = SystemTime::now(); - assert!(executor.execute_chunk().is_none()); + if executor.execute_chunk().is_some() { + eprintln!("Stylus compilation in SP1 failed: executor returned a trace chunk unexpectedly"); + std::process::exit(2); + } let b = SystemTime::now(); - assert_eq!(executor.exit_code(), 0); + if executor.exit_code() != 0 { + eprintln!( + "Stylus compiler exited with non-zero code: {}", + executor.exit_code() + ); + std::process::exit(executor.exit_code() as i32); + } tracing::info!( "Completed stylus compilation in SP1, cycles: {}, execution time: {:?}", executor.global_clk(), From 1dc2644c4904343c0301348a4675ef42032b0904 Mon Sep 17 00:00:00 2001 From: Igor Braga <5835477+bragaigor@users.noreply.github.com> Date: Tue, 24 Mar 2026 19:06:54 -0400 Subject: [PATCH 138/189] add warning comment and fix build.sh Signed-off-by: Igor Braga <5835477+bragaigor@users.noreply.github.com> --- Cargo.toml | 24 +++++++++++++++++++----- crates/sp1/build.sh | 4 ++-- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 46b7104e61e..ef8dd76690e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -132,11 +132,25 @@ sp1-zkvm = { version = "6.0.0", features = ["untrusted_programs", "may_dump_elf" [patch.crates-io] -# SP1 patches: these apply workspace-wide because Cargo does not support -# target-scoped or feature-scoped patches. The SP1-patched forks add RISC-V -# (riscv64) support while preserving identical behavior on native x86/ARM -# targets. Non-SP1 crates (prover, JIT, stylus) are unaffected on native builds. -# If SP1 is ever split into a separate workspace, these patches can be removed. +# ┌──────────────────────────────────────────────────────────────────────────────┐ +# │ WARNING: CONSENSUS-SAFETY CONCERN │ +# │ │ +# │ The secp256k1 and tiny-keccak patches below replace these crates │ +# │ WORKSPACE-WIDE, including in consensus-critical crates (arbutil, │ +# │ caller-env, prover, JIT, stylus) that use tiny-keccak for hashing. │ +# │ │ +# │ The SP1-patched forks add RISC-V accelerated precompile syscalls for the │ +# │ zkVM. On native x86/ARM targets these syscalls should be no-ops, but any │ +# │ accidental behavioral difference would silently break consensus. │ +# │ │ +# │ To be discussed: │ +# | - Should we move SP1 crates into their own workspace (crates/sp1/Cargo.toml) | +# | so these patches are scoped to SP1 only. he crates/langs/ directory │ +# │ already follows this pattern. │ +# | - or should we keep as is and conduct tests to make sure this does not │ +# | affect consensus e.g. Add a CI check that verifies the fork diff is scoped │ +# │ │ +# └──────────────────────────────────────────────────────────────────────────────┘ target-lexicon = { git = "https://github.com/OffchainLabs/target-lexicon", tag = "v0.13.5-sp1" } region = { git = "https://github.com/OffchainLabs/region-rs", tag = "v3.0.2-sp1" } corosensei = { git = "https://github.com/OffchainLabs/corosensei", rev = "6681138454747733c6adad5037024400f0c9d4e3" } # branch: v0.3.3-sp diff --git a/crates/sp1/build.sh b/crates/sp1/build.sh index e90c8519bd1..4dc73d115cf 100755 --- a/crates/sp1/build.sh +++ b/crates/sp1/build.sh @@ -61,7 +61,7 @@ cargo run --release -p sp1-builder -- --replay-wasm "$OUTPUT_DIR"/replay.wasm -- cargo build --release -p sp1-runner # Copy relevant files to target folder -cp target/elf-compilation/riscv64im-succinct-zkvm-elf/release/stylus-compiler-program "$OUTPUT_DIR" -cp target/release/sp1-runner "$OUTPUT_DIR" +cp "$TOP/target/elf-compilation/riscv64im-succinct-zkvm-elf/release/stylus-compiler-program" "$OUTPUT_DIR" +cp "$TOP/target/release/sp1-runner" "$OUTPUT_DIR" echo "SP1 runner is successfully built!" From 2e86c206aca47f40aebff9ecf77a9762ce50785f Mon Sep 17 00:00:00 2001 From: Igor Braga <5835477+bragaigor@users.noreply.github.com> Date: Wed, 25 Mar 2026 09:07:29 -0400 Subject: [PATCH 139/189] remove Cargo.toml comment Signed-off-by: Igor Braga <5835477+bragaigor@users.noreply.github.com> --- Cargo.toml | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ef8dd76690e..2b1ecdbf80d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -132,25 +132,6 @@ sp1-zkvm = { version = "6.0.0", features = ["untrusted_programs", "may_dump_elf" [patch.crates-io] -# ┌──────────────────────────────────────────────────────────────────────────────┐ -# │ WARNING: CONSENSUS-SAFETY CONCERN │ -# │ │ -# │ The secp256k1 and tiny-keccak patches below replace these crates │ -# │ WORKSPACE-WIDE, including in consensus-critical crates (arbutil, │ -# │ caller-env, prover, JIT, stylus) that use tiny-keccak for hashing. │ -# │ │ -# │ The SP1-patched forks add RISC-V accelerated precompile syscalls for the │ -# │ zkVM. On native x86/ARM targets these syscalls should be no-ops, but any │ -# │ accidental behavioral difference would silently break consensus. │ -# │ │ -# │ To be discussed: │ -# | - Should we move SP1 crates into their own workspace (crates/sp1/Cargo.toml) | -# | so these patches are scoped to SP1 only. he crates/langs/ directory │ -# │ already follows this pattern. │ -# | - or should we keep as is and conduct tests to make sure this does not │ -# | affect consensus e.g. Add a CI check that verifies the fork diff is scoped │ -# │ │ -# └──────────────────────────────────────────────────────────────────────────────┘ target-lexicon = { git = "https://github.com/OffchainLabs/target-lexicon", tag = "v0.13.5-sp1" } region = { git = "https://github.com/OffchainLabs/region-rs", tag = "v3.0.2-sp1" } corosensei = { git = "https://github.com/OffchainLabs/corosensei", rev = "6681138454747733c6adad5037024400f0c9d4e3" } # branch: v0.3.3-sp From 9bf9b7afdbbe384f26bdbaa17fda3694452ffde1 Mon Sep 17 00:00:00 2001 From: Igor Braga <5835477+bragaigor@users.noreply.github.com> Date: Wed, 25 Mar 2026 10:23:23 -0400 Subject: [PATCH 140/189] revert handle_result and delete .gitignore Signed-off-by: Igor Braga <5835477+bragaigor@users.noreply.github.com> --- crates/brotli/build.rs | 8 +------- crates/sp1/.gitignore | 1 - crates/sp1/program/src/imports/debug.rs | 6 ++---- crates/sp1/program/src/replay.rs | 17 ++++++++--------- 4 files changed, 11 insertions(+), 21 deletions(-) delete mode 100644 crates/sp1/.gitignore diff --git a/crates/brotli/build.rs b/crates/brotli/build.rs index 5e0742324e1..0a28ac26942 100644 --- a/crates/brotli/build.rs +++ b/crates/brotli/build.rs @@ -4,19 +4,13 @@ #[cfg(not(feature = "cc_brotli"))] fn main() { use std::env; - use std::path::PathBuf; - let manifest_dir = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap()); - let repo_root = manifest_dir.join("../.."); let target_arch = env::var("TARGET").unwrap(); if target_arch.contains("wasm32") { println!("cargo:rustc-link-search=target/lib-wasm/"); } else if target_arch.contains("riscv64") { - println!( - "cargo:rustc-link-search={}", - repo_root.join("target/lib-sp1/lib").display() - ); + println!("cargo:rustc-link-search=target/lib-sp1/lib"); } else { println!("cargo:rustc-link-search=target/lib/"); println!("cargo:rustc-link-search=../../target/lib/"); diff --git a/crates/sp1/.gitignore b/crates/sp1/.gitignore deleted file mode 100644 index eb5a316cbd1..00000000000 --- a/crates/sp1/.gitignore +++ /dev/null @@ -1 +0,0 @@ -target diff --git a/crates/sp1/program/src/imports/debug.rs b/crates/sp1/program/src/imports/debug.rs index e8ace46e607..a24e3a8a379 100644 --- a/crates/sp1/program/src/imports/debug.rs +++ b/crates/sp1/program/src/imports/debug.rs @@ -35,11 +35,9 @@ pub fn console_tee + Copy>( pub fn null_host(_ctx: FunctionEnvMut) {} pub fn start_benchmark(_ctx: FunctionEnvMut) -> MaybeEscape { - // Benchmarking is not supported in SP1 zkVM execution - Ok(()) + unimplemented!("start_benchmark is not implemented in debug host imports") } pub fn end_benchmark(_ctx: FunctionEnvMut) -> MaybeEscape { - // Benchmarking is not supported in SP1 zkVM execution - Ok(()) + unimplemented!("end_benchmark is not implemented in debug host imports") } diff --git a/crates/sp1/program/src/replay.rs b/crates/sp1/program/src/replay.rs index c9a18c50897..b2d409381e1 100644 --- a/crates/sp1/program/src/replay.rs +++ b/crates/sp1/program/src/replay.rs @@ -415,14 +415,13 @@ fn align_bytes(data: &[u8]) -> Bytes { } pub(crate) fn handle_result(result: Result, RuntimeError>) -> ! { - match result { - Ok(value) => { - println!("Machine exited prematurely with: {:?}", value); - exit(0); - } - Err(e) => { - println!("Runtime error: {}", e); - exit(1); - } + let message = match result { + Ok(value) => format!("Machine exited prematurely with: {:?}", value), + Err(e) => format!("Runtime error: {}", e), + }; + + if !message.is_empty() { + println!("{message}"); } + exit(1); } From 192cc83a5320fb842d513466eedd60a5f7c8ed6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Thu, 26 Mar 2026 15:16:49 +0100 Subject: [PATCH 141/189] Remove leftovers --- crates/prover/src/programs/depth.rs | 4 ---- crates/prover/src/programs/mod.rs | 5 ++--- crates/prover/src/value.rs | 6 ------ 3 files changed, 2 insertions(+), 13 deletions(-) diff --git a/crates/prover/src/programs/depth.rs b/crates/prover/src/programs/depth.rs index 7d9f4cee13f..5b095256c9b 100644 --- a/crates/prover/src/programs/depth.rs +++ b/crates/prover/src/programs/depth.rs @@ -9,10 +9,6 @@ use super::{ use crate::Machine; use crate::value::FunctionType; -#[cfg(feature = "sp1")] -use crate::value::InternalFunc; - -#[cfg(not(feature = "sp1"))] use crate::internal_func::InternalFunc; use arbutil::Color; diff --git a/crates/prover/src/programs/mod.rs b/crates/prover/src/programs/mod.rs index c99c1b8fda4..fce90d7d4b4 100644 --- a/crates/prover/src/programs/mod.rs +++ b/crates/prover/src/programs/mod.rs @@ -1,16 +1,15 @@ // Copyright 2022-2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md -#[cfg(feature = "sp1")] -use crate::value::MemoryType; #[cfg(not(feature = "sp1"))] -use crate::{machine::Module, memory_type::MemoryType, programs::config::CompileConfig}; +use crate::{machine::Module, programs::config::CompileConfig}; #[cfg(not(feature = "sp1"))] use arbutil::{evm::ARBOS_VERSION_STYLUS_CHARGING_FIXES, math::SaturatingSum, Bytes32}; #[cfg(not(feature = "sp1"))] use eyre::WrapErr; use crate::{ + memory_type::MemoryType, binary::{ExportKind, WasmBinary}, value::{FunctionType as ArbFunctionType, Value}, }; diff --git a/crates/prover/src/value.rs b/crates/prover/src/value.rs index d90c007cc03..61bee87f670 100644 --- a/crates/prover/src/value.rs +++ b/crates/prover/src/value.rs @@ -496,9 +496,3 @@ impl Display for ArbValueType { } } } - -#[cfg(feature = "sp1")] -pub use crate::internal_func::InternalFunc; - -#[cfg(feature = "sp1")] -pub use crate::memory_type::MemoryType; From 7ef4a28bfd64faa7a63915febe64ed81f3a26290 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Thu, 26 Mar 2026 17:42:18 +0100 Subject: [PATCH 142/189] Create a new prover-ffi crate. Move C exports from prover/lib.rs there. --- Cargo.lock | 15 ++ Cargo.toml | 2 + Makefile | 3 +- crates/prover-ffi/Cargo.toml | 24 +++ crates/prover-ffi/src/lib.rs | 365 ++++++++++++++++++++++++++++++++ crates/prover/src/lib.rs | 400 ----------------------------------- crates/stylus/Cargo.toml | 1 + crates/stylus/src/lib.rs | 1 + 8 files changed, 410 insertions(+), 401 deletions(-) create mode 100644 crates/prover-ffi/Cargo.toml create mode 100644 crates/prover-ffi/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 3bab50d9239..457f52fce4e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5318,6 +5318,20 @@ dependencies = [ "wat", ] +[[package]] +name = "prover-ffi" +version = "0.1.0" +dependencies = [ + "arbutil", + "eyre", + "lazy_static", + "libc", + "lru 0.16.3", + "once_cell", + "prover", + "static_assertions", +] + [[package]] name = "ptr_meta" version = "0.3.1" @@ -7810,6 +7824,7 @@ dependencies = [ "num-bigint 0.4.6", "parking_lot", "prover", + "prover-ffi", "rand 0.8.5", "thiserror 1.0.63", "user-host-trait", diff --git a/Cargo.toml b/Cargo.toml index 2b1ecdbf80d..b6a6c1812dd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ members = [ "crates/jit", "crates/validation", "crates/prover", + "crates/prover-ffi", "crates/stylus", "crates/validator", "crates/wasm-libraries/arbcompress", @@ -112,6 +113,7 @@ caller-env = { path = "crates/caller-env", default-features = false } forward = { path = "crates/wasm-libraries/forward" } jit = { path = "crates/jit" } prover = { path = "crates/prover", default-features = false } +prover-ffi = { path = "crates/prover-ffi" } stylus = { path = "crates/stylus", default-features = false } user-host-trait = { path = "crates/wasm-libraries/user-host-trait" } validation = { path = "crates/validation" } diff --git a/Makefile b/Makefile index d4ca8723fe8..e12cdc687ad 100644 --- a/Makefile +++ b/Makefile @@ -87,7 +87,8 @@ rust_arbutil_files = $(wildcard crates/arbutil/src/*.* crates/arbutil/src/*/*.* prover_direct_includes = $(patsubst %,$(output_latest)/%.wasm, forward forward_stub) prover_dir = crates/prover/ -rust_prover_files = $(wildcard $(prover_dir)/src/*.* $(prover_dir)/src/*/*.* $(prover_dir)/*.toml $(prover_dir)/*.rs) $(rust_arbutil_files) $(prover_direct_includes) $(arb_brotli_files) +prover_ffi_dir = crates/prover-ffi/ +rust_prover_files = $(wildcard $(prover_dir)/src/*.* $(prover_dir)/src/*/*.* $(prover_dir)/*.toml $(prover_dir)/*.rs) $(wildcard $(prover_ffi_dir)/src/*.rs $(prover_ffi_dir)/*.toml) $(rust_arbutil_files) $(prover_direct_includes) $(arb_brotli_files) wasm_lib = crates/wasm-libraries wasm_lib_cargo = $(wasm_lib)/.cargo/config.toml diff --git a/crates/prover-ffi/Cargo.toml b/crates/prover-ffi/Cargo.toml new file mode 100644 index 00000000000..19c9bd182e8 --- /dev/null +++ b/crates/prover-ffi/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "prover-ffi" +version = "0.1.0" +authors.workspace = true +edition.workspace = true +homepage.workspace = true +license.workspace = true +publish.workspace = true +repository.workspace = true +rust-version.workspace = true + +[lib] +name = "prover_ffi" +crate-type = ["lib"] + +[dependencies] +arbutil = { workspace = true } +eyre = { workspace = true } +lazy_static = { workspace = true } +libc = { workspace = true } +lru = { workspace = true } +once_cell = { workspace = true } +prover = { workspace = true, features = ["native"] } +static_assertions = { workspace = true } diff --git a/crates/prover-ffi/src/lib.rs b/crates/prover-ffi/src/lib.rs new file mode 100644 index 00000000000..4b1176bc1ec --- /dev/null +++ b/crates/prover-ffi/src/lib.rs @@ -0,0 +1,365 @@ +use arbutil::{Bytes32, PreimageType}; +use eyre::{ + Report, + Result +}; +use lru::LruCache; +use once_cell::sync::OnceCell; +use prover::{machine::{get_empty_preimage_resolver, GlobalState}, utils, utils::CBytes, CByteArray, Machine, ResolvedPreimage, RustBytes}; +use std::{ffi::CStr, num::NonZeroUsize, os::raw::c_char, path::Path, ptr, slice, sync::{Arc, Mutex}}; +use std::os::raw::c_int; +use std::sync::atomic; +use std::sync::atomic::AtomicU8; +use static_assertions::const_assert_eq; +use prover::machine::{argument_data_to_inbox, MachineStatus, PreimageResolver}; + +lazy_static::lazy_static! { + static ref BLOBHASH_PREIMAGE_CACHE: Mutex>>> = Mutex::new(LruCache::new(NonZeroUsize::new(12).unwrap())); +} + +/// Frees the vector. Does nothing when the vector is null. +/// +/// # Safety +/// +/// Must only be called once per vec. +#[no_mangle] +pub unsafe extern "C" fn free_rust_bytes(vec: RustBytes) { + if !vec.ptr.is_null() { + drop(vec.into_vec()) + } +} + +#[no_mangle] +pub unsafe extern "C" fn arbitrator_load_machine( + binary_path: *const c_char, + library_paths: *const *const c_char, + library_paths_size: isize, + debug_chain: usize, +) -> *mut Machine { + let debug_chain = debug_chain != 0; + arbitrator_load_machine_impl(binary_path, library_paths, library_paths_size, debug_chain) + .unwrap_or_else(|err| { + eprintln!("Error loading binary: {err:?}"); + ptr::null_mut() + }) +} + +unsafe fn arbitrator_load_machine_impl( + binary_path: *const c_char, + library_paths: *const *const c_char, + library_paths_size: isize, + debug_chain: bool, +) -> Result<*mut Machine> { + let binary_path = cstr_to_string(binary_path); + let binary_path = Path::new(&binary_path); + + let mut libraries = vec![]; + for i in 0..library_paths_size { + let path = cstr_to_string(*(library_paths.offset(i))); + libraries.push(Path::new(&path).to_owned()); + } + + let mach = Machine::from_paths( + &libraries, + binary_path, + true, + true, + debug_chain, + debug_chain, + Default::default(), + Default::default(), + get_empty_preimage_resolver(), + )?; + Ok(Box::into_raw(Box::new(mach))) +} + +#[no_mangle] +pub unsafe extern "C" fn arbitrator_load_wavm_binary(binary_path: *const c_char) -> *mut Machine { + let binary_path = cstr_to_string(binary_path); + let binary_path = Path::new(&binary_path); + match Machine::new_from_wavm(binary_path) { + Ok(mach) => Box::into_raw(Box::new(mach)), + Err(err) => { + eprintln!("Error loading binary: {err}"); + ptr::null_mut() + } + } +} + +#[no_mangle] +pub unsafe extern "C" fn arbitrator_new_finished(gs: GlobalState) -> *mut Machine { + Box::into_raw(Box::new(Machine::new_finished(gs))) +} + +unsafe fn cstr_to_string(c_str: *const c_char) -> String { + CStr::from_ptr(c_str).to_string_lossy().into_owned() +} + +pub fn err_to_c_string(err: Report) -> *mut libc::c_char { + str_to_c_string(&format!("{err:?}")) +} + +/// Copies the str-data into a libc free-able C string +pub fn str_to_c_string(text: &str) -> *mut libc::c_char { + unsafe { + let buf = libc::malloc(text.len() + 1); // includes null-terminating byte + if buf.is_null() { + panic!("Failed to allocate memory for error string"); + } + ptr::copy_nonoverlapping(text.as_ptr(), buf as *mut u8, text.len()); + *(buf as *mut u8).add(text.len()) = 0; + buf as *mut libc::c_char + } +} + +#[no_mangle] +pub unsafe extern "C" fn arbitrator_free_machine(mach: *mut Machine) { + drop(Box::from_raw(mach)); +} + +#[no_mangle] +pub unsafe extern "C" fn arbitrator_clone_machine(mach: *mut Machine) -> *mut Machine { + let new_mach = (*mach).clone(); + Box::into_raw(Box::new(new_mach)) +} + +/// Go doesn't have this functionality builtin for whatever reason. Uses relaxed ordering. +#[no_mangle] +pub unsafe extern "C" fn atomic_u8_store(ptr: *mut u8, contents: u8) { + (*(ptr as *mut AtomicU8)).store(contents, atomic::Ordering::Relaxed); +} + +/// Runs the machine while the condition variable is zero. May return early if num_steps is hit. +/// Returns a c string error (freeable with libc's free) on error, or nullptr on success. +#[no_mangle] +pub unsafe extern "C" fn arbitrator_step( + mach: *mut Machine, + num_steps: u64, + condition: *const u8, +) -> *mut libc::c_char { + let mach = &mut *mach; + let condition = &*(condition as *const AtomicU8); + let mut remaining_steps = num_steps; + while condition.load(atomic::Ordering::Relaxed) == 0 { + if remaining_steps == 0 || mach.is_halted() { + break; + } + let stepping = std::cmp::min(remaining_steps, 1_000_000); + match mach.step_n(stepping) { + Ok(()) => {} + Err(err) => return err_to_c_string(err), + } + remaining_steps -= stepping; + } + ptr::null_mut() +} + +#[no_mangle] +pub unsafe extern "C" fn arbitrator_add_inbox_message( + mach: *mut Machine, + inbox_identifier: u64, + index: u64, + data: CByteArray, +) -> c_int { + let mach = &mut *mach; + if let Some(identifier) = argument_data_to_inbox(inbox_identifier) { + let slice = slice::from_raw_parts(data.ptr, data.len); + let data = slice.to_vec(); + mach.add_inbox_msg(identifier, index, data); + 0 + } else { + 1 + } +} + +/// Adds a user program to the machine's known set of wasms. +#[no_mangle] +pub unsafe extern "C" fn arbitrator_add_user_wasm( + mach: *mut Machine, + module: *const u8, + module_len: usize, + module_hash: *const Bytes32, +) { + let module = slice::from_raw_parts(module, module_len); + (*mach).add_stylus_module(*module_hash, module.to_owned()); +} + +/// Like arbitrator_step, but stops early if it hits a host io operation. +/// Returns a c string error (freeable with libc's free) on error, or nullptr on success. +#[no_mangle] +pub unsafe extern "C" fn arbitrator_step_until_host_io( + mach: *mut Machine, + condition: *const u8, +) -> *mut libc::c_char { + let mach = &mut *mach; + let condition = &*(condition as *const AtomicU8); + while condition.load(atomic::Ordering::Relaxed) == 0 { + for _ in 0..1_000_000 { + if mach.is_halted() { + return ptr::null_mut(); + } + if mach.next_instruction_is_host_io() { + return ptr::null_mut(); + } + match mach.step_n(1) { + Ok(()) => {} + Err(err) => return err_to_c_string(err), + } + } + } + ptr::null_mut() +} + +#[no_mangle] +pub unsafe extern "C" fn arbitrator_serialize_state( + mach: *const Machine, + path: *const c_char, +) -> c_int { + let mach = &*mach; + let res = CStr::from_ptr(path) + .to_str() + .map_err(Report::from) + .and_then(|path| mach.serialize_state(path)); + if let Err(err) = res { + eprintln!("Failed to serialize machine state: {err}"); + 1 + } else { + 0 + } +} + +#[no_mangle] +pub unsafe extern "C" fn arbitrator_deserialize_and_replace_state( + mach: *mut Machine, + path: *const c_char, +) -> c_int { + let mach = &mut *mach; + let res = CStr::from_ptr(path) + .to_str() + .map_err(Report::from) + .and_then(|path| mach.deserialize_and_replace_state(path)); + if let Err(err) = res { + eprintln!("Failed to deserialize machine state: {err}"); + 1 + } else { + 0 + } +} + +#[no_mangle] +pub unsafe extern "C" fn arbitrator_get_num_steps(mach: *const Machine) -> u64 { + (*mach).get_steps() +} + +pub const ARBITRATOR_MACHINE_STATUS_RUNNING: u8 = 0; +pub const ARBITRATOR_MACHINE_STATUS_FINISHED: u8 = 1; +pub const ARBITRATOR_MACHINE_STATUS_ERRORED: u8 = 2; +pub const ARBITRATOR_MACHINE_STATUS_TOO_FAR: u8 = 3; + +// Unfortunately, cbindgen doesn't support constants with non-literal values, so we assert that they're correct. +const_assert_eq!( + ARBITRATOR_MACHINE_STATUS_RUNNING, + MachineStatus::Running as u8, +); +const_assert_eq!( + ARBITRATOR_MACHINE_STATUS_FINISHED, + MachineStatus::Finished as u8, +); +const_assert_eq!( + ARBITRATOR_MACHINE_STATUS_ERRORED, + MachineStatus::Errored as u8, +); +const_assert_eq!( + ARBITRATOR_MACHINE_STATUS_TOO_FAR, + MachineStatus::TooFar as u8, +); + +/// Returns one of ARBITRATOR_MACHINE_STATUS_* +#[no_mangle] +pub unsafe extern "C" fn arbitrator_get_status(mach: *const Machine) -> u8 { + (*mach).get_status() as u8 +} + +#[no_mangle] +pub unsafe extern "C" fn arbitrator_global_state(mach: *mut Machine) -> GlobalState { + (*mach).get_global_state() +} + +#[no_mangle] +pub unsafe extern "C" fn arbitrator_set_global_state(mach: *mut Machine, gs: GlobalState) { + (*mach).set_global_state(gs); +} + +unsafe fn handle_preimage_resolution( + context: u64, + ty: PreimageType, + hash: Bytes32, + resolver: unsafe extern "C" fn(u64, u8, *const u8) -> ResolvedPreimage, +) -> Option { + let res = resolver(context, ty.into(), hash.as_ptr()); + if res.len < 0 { + return None; + } + let data = CBytes::from_raw_parts(res.ptr, res.len as usize); + + // Hash may not have a direct link to the data for DACertificate + if ty == PreimageType::DACertificate { + return Some(data); + } + + // Check if preimage rehashes to the provided hash + match utils::hash_preimage(&data, ty) { + Ok(have_hash) if have_hash.as_slice() == *hash => {} + Ok(got_hash) => panic!( + "Resolved incorrect data for hash {} (rehashed to {})", + hash, + Bytes32(got_hash), + ), + Err(err) => panic!("Failed to hash preimage from resolver (expecting hash {hash}): {err}",), + } + Some(data) +} + +#[no_mangle] +pub unsafe extern "C" fn arbitrator_set_preimage_resolver( + mach: *mut Machine, + resolver: unsafe extern "C" fn(u64, u8, *const u8) -> ResolvedPreimage, +) { + (*mach).set_preimage_resolver(Arc::new( + move |context: u64, ty: PreimageType, hash: Bytes32| -> Option { + if ty == PreimageType::EthVersionedHash { + let cache: Arc> = { + let mut locked = BLOBHASH_PREIMAGE_CACHE.lock().unwrap(); + locked.get_or_insert(hash, Default::default).clone() + }; + return cache + .get_or_try_init(|| { + handle_preimage_resolution(context, ty, hash, resolver).ok_or(()) + }) + .ok() + .cloned(); + } + handle_preimage_resolution(context, ty, hash, resolver) + }, + ) as PreimageResolver); +} + +#[no_mangle] +pub unsafe extern "C" fn arbitrator_set_context(mach: *mut Machine, context: u64) { + (*mach).set_context(context); +} + +#[no_mangle] +pub unsafe extern "C" fn arbitrator_hash(mach: *mut Machine) -> Bytes32 { + (*mach).hash() +} + +#[no_mangle] +pub unsafe extern "C" fn arbitrator_module_root(mach: *mut Machine) -> Bytes32 { + (*mach).get_modules_root() +} + +#[no_mangle] +pub unsafe extern "C" fn arbitrator_gen_proof(mach: *mut Machine, out: *mut RustBytes) { + (*out).write((*mach).serialize_proof()); +} diff --git a/crates/prover/src/lib.rs b/crates/prover/src/lib.rs index 6dc381b373f..f39ec201078 100644 --- a/crates/prover/src/lib.rs +++ b/crates/prover/src/lib.rs @@ -26,38 +26,10 @@ mod test; pub use machine::Machine; -use arbutil::Bytes32; -#[cfg(not(feature = "sp1"))] -use arbutil::PreimageType; -#[cfg(not(feature = "sp1"))] -use eyre::{Report, Result}; -use lru::LruCache; -use machine::MachineStatus; -#[cfg(not(feature = "sp1"))] -use machine::{argument_data_to_inbox, get_empty_preimage_resolver, GlobalState, PreimageResolver}; -use once_cell::sync::OnceCell; -use static_assertions::const_assert_eq; -#[cfg(not(feature = "sp1"))] -use std::{ - ffi::CStr, - os::raw::{c_char, c_int}, - path::Path, - slice, -}; use std::{ marker::PhantomData, - num::NonZeroUsize, ptr, - sync::{ - atomic::{self, AtomicU8}, - Arc, Mutex, - }, }; -use utils::CBytes; - -lazy_static::lazy_static! { - static ref BLOBHASH_PREIMAGE_CACHE: Mutex>>> = Mutex::new(LruCache::new(NonZeroUsize::new(12).unwrap())); -} #[repr(C)] #[derive(Clone, Copy)] @@ -118,380 +90,8 @@ impl RustBytes { } } -/// Frees the vector. Does nothing when the vector is null. -/// -/// # Safety -/// -/// Must only be called once per vec. -#[no_mangle] -pub unsafe extern "C" fn free_rust_bytes(vec: RustBytes) { - if !vec.ptr.is_null() { - drop(vec.into_vec()) - } -} - -#[no_mangle] -#[cfg(all(feature = "native", not(feature = "sp1")))] -pub unsafe extern "C" fn arbitrator_load_machine( - binary_path: *const c_char, - library_paths: *const *const c_char, - library_paths_size: isize, - debug_chain: usize, -) -> *mut Machine { - let debug_chain = debug_chain != 0; - arbitrator_load_machine_impl(binary_path, library_paths, library_paths_size, debug_chain) - .unwrap_or_else(|err| { - eprintln!("Error loading binary: {err:?}"); - ptr::null_mut() - }) -} - -#[cfg(all(feature = "native", not(feature = "sp1")))] -unsafe fn arbitrator_load_machine_impl( - binary_path: *const c_char, - library_paths: *const *const c_char, - library_paths_size: isize, - debug_chain: bool, -) -> Result<*mut Machine> { - let binary_path = cstr_to_string(binary_path); - let binary_path = Path::new(&binary_path); - - let mut libraries = vec![]; - for i in 0..library_paths_size { - let path = cstr_to_string(*(library_paths.offset(i))); - libraries.push(Path::new(&path).to_owned()); - } - - let mach = Machine::from_paths( - &libraries, - binary_path, - true, - true, - debug_chain, - debug_chain, - Default::default(), - Default::default(), - get_empty_preimage_resolver(), - )?; - Ok(Box::into_raw(Box::new(mach))) -} - -#[no_mangle] -#[cfg(all(feature = "native", not(feature = "sp1")))] -pub unsafe extern "C" fn arbitrator_load_wavm_binary(binary_path: *const c_char) -> *mut Machine { - let binary_path = cstr_to_string(binary_path); - let binary_path = Path::new(&binary_path); - match Machine::new_from_wavm(binary_path) { - Ok(mach) => Box::into_raw(Box::new(mach)), - Err(err) => { - eprintln!("Error loading binary: {err}"); - ptr::null_mut() - } - } -} - -#[no_mangle] -#[cfg(all(feature = "native", not(feature = "sp1")))] -pub unsafe extern "C" fn arbitrator_new_finished(gs: GlobalState) -> *mut Machine { - Box::into_raw(Box::new(Machine::new_finished(gs))) -} - -#[cfg(not(feature = "sp1"))] -unsafe fn cstr_to_string(c_str: *const c_char) -> String { - CStr::from_ptr(c_str).to_string_lossy().into_owned() -} - -#[cfg(not(feature = "sp1"))] -pub fn err_to_c_string(err: Report) -> *mut libc::c_char { - str_to_c_string(&format!("{err:?}")) -} - -/// Copies the str-data into a libc free-able C string -#[cfg(not(feature = "sp1"))] -pub fn str_to_c_string(text: &str) -> *mut libc::c_char { - unsafe { - let buf = libc::malloc(text.len() + 1); // includes null-terminating byte - if buf.is_null() { - panic!("Failed to allocate memory for error string"); - } - ptr::copy_nonoverlapping(text.as_ptr(), buf as *mut u8, text.len()); - *(buf as *mut u8).add(text.len()) = 0; - buf as *mut libc::c_char - } -} - -#[no_mangle] -#[cfg(all(feature = "native", not(feature = "sp1")))] -pub unsafe extern "C" fn arbitrator_free_machine(mach: *mut Machine) { - drop(Box::from_raw(mach)); -} - -#[no_mangle] -#[cfg(all(feature = "native", not(feature = "sp1")))] -pub unsafe extern "C" fn arbitrator_clone_machine(mach: *mut Machine) -> *mut Machine { - let new_mach = (*mach).clone(); - Box::into_raw(Box::new(new_mach)) -} - -/// Go doesn't have this functionality builtin for whatever reason. Uses relaxed ordering. -#[no_mangle] -pub unsafe extern "C" fn atomic_u8_store(ptr: *mut u8, contents: u8) { - (*(ptr as *mut AtomicU8)).store(contents, atomic::Ordering::Relaxed); -} - -/// Runs the machine while the condition variable is zero. May return early if num_steps is hit. -/// Returns a c string error (freeable with libc's free) on error, or nullptr on success. -#[no_mangle] -#[cfg(all(feature = "native", not(feature = "sp1")))] -pub unsafe extern "C" fn arbitrator_step( - mach: *mut Machine, - num_steps: u64, - condition: *const u8, -) -> *mut libc::c_char { - let mach = &mut *mach; - let condition = &*(condition as *const AtomicU8); - let mut remaining_steps = num_steps; - while condition.load(atomic::Ordering::Relaxed) == 0 { - if remaining_steps == 0 || mach.is_halted() { - break; - } - let stepping = std::cmp::min(remaining_steps, 1_000_000); - match mach.step_n(stepping) { - Ok(()) => {} - Err(err) => return err_to_c_string(err), - } - remaining_steps -= stepping; - } - ptr::null_mut() -} - -#[no_mangle] -#[cfg(all(feature = "native", not(feature = "sp1")))] -pub unsafe extern "C" fn arbitrator_add_inbox_message( - mach: *mut Machine, - inbox_identifier: u64, - index: u64, - data: CByteArray, -) -> c_int { - let mach = &mut *mach; - if let Some(identifier) = argument_data_to_inbox(inbox_identifier) { - let slice = slice::from_raw_parts(data.ptr, data.len); - let data = slice.to_vec(); - mach.add_inbox_msg(identifier, index, data); - 0 - } else { - 1 - } -} - -/// Adds a user program to the machine's known set of wasms. -#[no_mangle] -#[cfg(all(feature = "native", not(feature = "sp1")))] -pub unsafe extern "C" fn arbitrator_add_user_wasm( - mach: *mut Machine, - module: *const u8, - module_len: usize, - module_hash: *const Bytes32, -) { - let module = slice::from_raw_parts(module, module_len); - (*mach).add_stylus_module(*module_hash, module.to_owned()); -} - -/// Like arbitrator_step, but stops early if it hits a host io operation. -/// Returns a c string error (freeable with libc's free) on error, or nullptr on success. -#[no_mangle] -#[cfg(all(feature = "native", not(feature = "sp1")))] -pub unsafe extern "C" fn arbitrator_step_until_host_io( - mach: *mut Machine, - condition: *const u8, -) -> *mut libc::c_char { - let mach = &mut *mach; - let condition = &*(condition as *const AtomicU8); - while condition.load(atomic::Ordering::Relaxed) == 0 { - for _ in 0..1_000_000 { - if mach.is_halted() { - return ptr::null_mut(); - } - if mach.next_instruction_is_host_io() { - return ptr::null_mut(); - } - match mach.step_n(1) { - Ok(()) => {} - Err(err) => return err_to_c_string(err), - } - } - } - ptr::null_mut() -} - -#[no_mangle] -#[cfg(all(feature = "native", not(feature = "sp1")))] -pub unsafe extern "C" fn arbitrator_serialize_state( - mach: *const Machine, - path: *const c_char, -) -> c_int { - let mach = &*mach; - let res = CStr::from_ptr(path) - .to_str() - .map_err(Report::from) - .and_then(|path| mach.serialize_state(path)); - if let Err(err) = res { - eprintln!("Failed to serialize machine state: {err}"); - 1 - } else { - 0 - } -} - -#[no_mangle] -#[cfg(all(feature = "native", not(feature = "sp1")))] -pub unsafe extern "C" fn arbitrator_deserialize_and_replace_state( - mach: *mut Machine, - path: *const c_char, -) -> c_int { - let mach = &mut *mach; - let res = CStr::from_ptr(path) - .to_str() - .map_err(Report::from) - .and_then(|path| mach.deserialize_and_replace_state(path)); - if let Err(err) = res { - eprintln!("Failed to deserialize machine state: {err}"); - 1 - } else { - 0 - } -} - -#[no_mangle] -#[cfg(all(feature = "native", not(feature = "sp1")))] -pub unsafe extern "C" fn arbitrator_get_num_steps(mach: *const Machine) -> u64 { - (*mach).get_steps() -} - -pub const ARBITRATOR_MACHINE_STATUS_RUNNING: u8 = 0; -pub const ARBITRATOR_MACHINE_STATUS_FINISHED: u8 = 1; -pub const ARBITRATOR_MACHINE_STATUS_ERRORED: u8 = 2; -pub const ARBITRATOR_MACHINE_STATUS_TOO_FAR: u8 = 3; - -// Unfortunately, cbindgen doesn't support constants with non-literal values, so we assert that they're correct. -const_assert_eq!( - ARBITRATOR_MACHINE_STATUS_RUNNING, - MachineStatus::Running as u8, -); -const_assert_eq!( - ARBITRATOR_MACHINE_STATUS_FINISHED, - MachineStatus::Finished as u8, -); -const_assert_eq!( - ARBITRATOR_MACHINE_STATUS_ERRORED, - MachineStatus::Errored as u8, -); -const_assert_eq!( - ARBITRATOR_MACHINE_STATUS_TOO_FAR, - MachineStatus::TooFar as u8, -); - -/// Returns one of ARBITRATOR_MACHINE_STATUS_* -#[no_mangle] -#[cfg(all(feature = "native", not(feature = "sp1")))] -pub unsafe extern "C" fn arbitrator_get_status(mach: *const Machine) -> u8 { - (*mach).get_status() as u8 -} - -#[no_mangle] -#[cfg(all(feature = "native", not(feature = "sp1")))] -pub unsafe extern "C" fn arbitrator_global_state(mach: *mut Machine) -> GlobalState { - (*mach).get_global_state() -} - -#[no_mangle] -#[cfg(all(feature = "native", not(feature = "sp1")))] -pub unsafe extern "C" fn arbitrator_set_global_state(mach: *mut Machine, gs: GlobalState) { - (*mach).set_global_state(gs); -} - #[repr(C)] pub struct ResolvedPreimage { pub ptr: *mut u8, pub len: isize, // negative if not found } - -#[cfg(all(feature = "native", not(feature = "sp1")))] -unsafe fn handle_preimage_resolution( - context: u64, - ty: PreimageType, - hash: Bytes32, - resolver: unsafe extern "C" fn(u64, u8, *const u8) -> ResolvedPreimage, -) -> Option { - let res = resolver(context, ty.into(), hash.as_ptr()); - if res.len < 0 { - return None; - } - let data = CBytes::from_raw_parts(res.ptr, res.len as usize); - - // Hash may not have a direct link to the data for DACertificate - if ty == PreimageType::DACertificate { - return Some(data); - } - - // Check if preimage rehashes to the provided hash - match utils::hash_preimage(&data, ty) { - Ok(have_hash) if have_hash.as_slice() == *hash => {} - Ok(got_hash) => panic!( - "Resolved incorrect data for hash {} (rehashed to {})", - hash, - Bytes32(got_hash), - ), - Err(err) => panic!("Failed to hash preimage from resolver (expecting hash {hash}): {err}",), - } - Some(data) -} - -#[no_mangle] -#[cfg(all(feature = "native", not(feature = "sp1")))] -pub unsafe extern "C" fn arbitrator_set_preimage_resolver( - mach: *mut Machine, - resolver: unsafe extern "C" fn(u64, u8, *const u8) -> ResolvedPreimage, -) { - (*mach).set_preimage_resolver(Arc::new( - move |context: u64, ty: PreimageType, hash: Bytes32| -> Option { - if ty == PreimageType::EthVersionedHash { - let cache: Arc> = { - let mut locked = BLOBHASH_PREIMAGE_CACHE.lock().unwrap(); - locked.get_or_insert(hash, Default::default).clone() - }; - return cache - .get_or_try_init(|| { - handle_preimage_resolution(context, ty, hash, resolver).ok_or(()) - }) - .ok() - .cloned(); - } - handle_preimage_resolution(context, ty, hash, resolver) - }, - ) as PreimageResolver); -} - -#[no_mangle] -#[cfg(all(feature = "native", not(feature = "sp1")))] -pub unsafe extern "C" fn arbitrator_set_context(mach: *mut Machine, context: u64) { - (*mach).set_context(context); -} - -#[no_mangle] -#[cfg(all(feature = "native", not(feature = "sp1")))] -pub unsafe extern "C" fn arbitrator_hash(mach: *mut Machine) -> Bytes32 { - (*mach).hash() -} - -#[no_mangle] -#[cfg(all(feature = "native", not(feature = "sp1")))] -pub unsafe extern "C" fn arbitrator_module_root(mach: *mut Machine) -> Bytes32 { - (*mach).get_modules_root() -} - -#[no_mangle] -#[cfg(all(feature = "native", not(feature = "sp1")))] -pub unsafe extern "C" fn arbitrator_gen_proof(mach: *mut Machine, out: *mut RustBytes) { - (*out).write((*mach).serialize_proof()); -} diff --git a/crates/stylus/Cargo.toml b/crates/stylus/Cargo.toml index 232d9f51472..cdc76b97894 100644 --- a/crates/stylus/Cargo.toml +++ b/crates/stylus/Cargo.toml @@ -20,6 +20,7 @@ hex = { workspace = true } lazy_static = { workspace = true } parking_lot = { workspace = true } prover = { workspace = true, features = ["native"] } +prover-ffi = { workspace = true } rand = { workspace = true } thiserror = { workspace = true } user-host-trait = { workspace = true } diff --git a/crates/stylus/src/lib.rs b/crates/stylus/src/lib.rs index bd257df9caf..3f9fc708592 100644 --- a/crates/stylus/src/lib.rs +++ b/crates/stylus/src/lib.rs @@ -25,6 +25,7 @@ use target_cache::{target_cache_get, target_cache_set}; pub use brotli; pub use prover; +pub use prover_ffi; pub mod env; pub mod host; From 9ad8a482c82dc5a82a202abbb806d5db46bc97ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Thu, 26 Mar 2026 17:48:19 +0100 Subject: [PATCH 143/189] fmt --- crates/prover-ffi/src/lib.rs | 27 +++++++++++++++++++-------- crates/prover/src/lib.rs | 5 +---- crates/prover/src/programs/depth.rs | 2 +- crates/prover/src/programs/mod.rs | 2 +- 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/crates/prover-ffi/src/lib.rs b/crates/prover-ffi/src/lib.rs index 4b1176bc1ec..7cba542ad99 100644 --- a/crates/prover-ffi/src/lib.rs +++ b/crates/prover-ffi/src/lib.rs @@ -1,17 +1,28 @@ +#![allow(clippy::missing_safety_doc, clippy::too_many_arguments)] + use arbutil::{Bytes32, PreimageType}; -use eyre::{ - Report, - Result -}; +use eyre::{Report, Result}; use lru::LruCache; use once_cell::sync::OnceCell; -use prover::{machine::{get_empty_preimage_resolver, GlobalState}, utils, utils::CBytes, CByteArray, Machine, ResolvedPreimage, RustBytes}; -use std::{ffi::CStr, num::NonZeroUsize, os::raw::c_char, path::Path, ptr, slice, sync::{Arc, Mutex}}; +use prover::machine::{argument_data_to_inbox, MachineStatus, PreimageResolver}; +use prover::{ + machine::{get_empty_preimage_resolver, GlobalState}, + utils, + utils::CBytes, + CByteArray, Machine, ResolvedPreimage, RustBytes, +}; +use static_assertions::const_assert_eq; use std::os::raw::c_int; use std::sync::atomic; use std::sync::atomic::AtomicU8; -use static_assertions::const_assert_eq; -use prover::machine::{argument_data_to_inbox, MachineStatus, PreimageResolver}; +use std::{ + ffi::CStr, + num::NonZeroUsize, + os::raw::c_char, + path::Path, + ptr, slice, + sync::{Arc, Mutex}, +}; lazy_static::lazy_static! { static ref BLOBHASH_PREIMAGE_CACHE: Mutex>>> = Mutex::new(LruCache::new(NonZeroUsize::new(12).unwrap())); diff --git a/crates/prover/src/lib.rs b/crates/prover/src/lib.rs index f39ec201078..e14b810b433 100644 --- a/crates/prover/src/lib.rs +++ b/crates/prover/src/lib.rs @@ -26,10 +26,7 @@ mod test; pub use machine::Machine; -use std::{ - marker::PhantomData, - ptr, -}; +use std::{marker::PhantomData, ptr}; #[repr(C)] #[derive(Clone, Copy)] diff --git a/crates/prover/src/programs/depth.rs b/crates/prover/src/programs/depth.rs index 5b095256c9b..d4d56c7279d 100644 --- a/crates/prover/src/programs/depth.rs +++ b/crates/prover/src/programs/depth.rs @@ -8,8 +8,8 @@ use super::{ #[cfg(not(feature = "sp1"))] use crate::Machine; -use crate::value::FunctionType; use crate::internal_func::InternalFunc; +use crate::value::FunctionType; use arbutil::Color; use eyre::{bail, Result}; diff --git a/crates/prover/src/programs/mod.rs b/crates/prover/src/programs/mod.rs index fce90d7d4b4..c021da0c50d 100644 --- a/crates/prover/src/programs/mod.rs +++ b/crates/prover/src/programs/mod.rs @@ -9,8 +9,8 @@ use arbutil::{evm::ARBOS_VERSION_STYLUS_CHARGING_FIXES, math::SaturatingSum, Byt use eyre::WrapErr; use crate::{ - memory_type::MemoryType, binary::{ExportKind, WasmBinary}, + memory_type::MemoryType, value::{FunctionType as ArbFunctionType, Value}, }; use arbutil::Color; From aadf75c98fa11bf77d835e9e145f05e70254ae73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Thu, 26 Mar 2026 17:58:17 +0100 Subject: [PATCH 144/189] extract c_string utils --- crates/prover-ffi/src/c_strings.rs | 26 ++++++++++++++++++++++++++ crates/prover-ffi/src/lib.rs | 23 +++-------------------- 2 files changed, 29 insertions(+), 20 deletions(-) create mode 100644 crates/prover-ffi/src/c_strings.rs diff --git a/crates/prover-ffi/src/c_strings.rs b/crates/prover-ffi/src/c_strings.rs new file mode 100644 index 00000000000..a2a18c40c34 --- /dev/null +++ b/crates/prover-ffi/src/c_strings.rs @@ -0,0 +1,26 @@ +// Copyright 2021-2026, Offchain Labs, Inc. +// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md + +use eyre::Report; +use std::{ffi::CStr, os::raw::c_char, ptr}; + +pub unsafe fn cstr_to_string(c_str: *const c_char) -> String { + CStr::from_ptr(c_str).to_string_lossy().into_owned() +} + +/// Copies the str-data into a libc free-able C string. +pub fn str_to_c_string(text: &str) -> *mut libc::c_char { + unsafe { + let buf = libc::malloc(text.len() + 1); // includes null-terminating byte + if buf.is_null() { + panic!("Failed to allocate memory for error string"); + } + ptr::copy_nonoverlapping(text.as_ptr(), buf as *mut u8, text.len()); + *(buf as *mut u8).add(text.len()) = 0; + buf as *mut libc::c_char + } +} + +pub fn err_to_c_string(err: Report) -> *mut libc::c_char { + str_to_c_string(&format!("{err:?}")) +} diff --git a/crates/prover-ffi/src/lib.rs b/crates/prover-ffi/src/lib.rs index 7cba542ad99..687f201671b 100644 --- a/crates/prover-ffi/src/lib.rs +++ b/crates/prover-ffi/src/lib.rs @@ -23,6 +23,9 @@ use std::{ ptr, slice, sync::{Arc, Mutex}, }; +use crate::c_strings::{cstr_to_string, err_to_c_string}; + +pub mod c_strings; lazy_static::lazy_static! { static ref BLOBHASH_PREIMAGE_CACHE: Mutex>>> = Mutex::new(LruCache::new(NonZeroUsize::new(12).unwrap())); @@ -102,26 +105,6 @@ pub unsafe extern "C" fn arbitrator_new_finished(gs: GlobalState) -> *mut Machin Box::into_raw(Box::new(Machine::new_finished(gs))) } -unsafe fn cstr_to_string(c_str: *const c_char) -> String { - CStr::from_ptr(c_str).to_string_lossy().into_owned() -} - -pub fn err_to_c_string(err: Report) -> *mut libc::c_char { - str_to_c_string(&format!("{err:?}")) -} - -/// Copies the str-data into a libc free-able C string -pub fn str_to_c_string(text: &str) -> *mut libc::c_char { - unsafe { - let buf = libc::malloc(text.len() + 1); // includes null-terminating byte - if buf.is_null() { - panic!("Failed to allocate memory for error string"); - } - ptr::copy_nonoverlapping(text.as_ptr(), buf as *mut u8, text.len()); - *(buf as *mut u8).add(text.len()) = 0; - buf as *mut libc::c_char - } -} #[no_mangle] pub unsafe extern "C" fn arbitrator_free_machine(mach: *mut Machine) { From a39abff0cf9aa09c2ec86cae021eb819fe85c630 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Thu, 26 Mar 2026 17:59:22 +0100 Subject: [PATCH 145/189] consistent naming --- crates/prover-ffi/src/c_strings.rs | 2 +- crates/prover-ffi/src/lib.rs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/prover-ffi/src/c_strings.rs b/crates/prover-ffi/src/c_strings.rs index a2a18c40c34..edfdb1ad3aa 100644 --- a/crates/prover-ffi/src/c_strings.rs +++ b/crates/prover-ffi/src/c_strings.rs @@ -4,7 +4,7 @@ use eyre::Report; use std::{ffi::CStr, os::raw::c_char, ptr}; -pub unsafe fn cstr_to_string(c_str: *const c_char) -> String { +pub unsafe fn c_string_to_string(c_str: *const c_char) -> String { CStr::from_ptr(c_str).to_string_lossy().into_owned() } diff --git a/crates/prover-ffi/src/lib.rs b/crates/prover-ffi/src/lib.rs index 687f201671b..402e91a2977 100644 --- a/crates/prover-ffi/src/lib.rs +++ b/crates/prover-ffi/src/lib.rs @@ -23,7 +23,7 @@ use std::{ ptr, slice, sync::{Arc, Mutex}, }; -use crate::c_strings::{cstr_to_string, err_to_c_string}; +use crate::c_strings::{c_string_to_string, err_to_c_string}; pub mod c_strings; @@ -64,12 +64,12 @@ unsafe fn arbitrator_load_machine_impl( library_paths_size: isize, debug_chain: bool, ) -> Result<*mut Machine> { - let binary_path = cstr_to_string(binary_path); + let binary_path = c_string_to_string(binary_path); let binary_path = Path::new(&binary_path); let mut libraries = vec![]; for i in 0..library_paths_size { - let path = cstr_to_string(*(library_paths.offset(i))); + let path = c_string_to_string(*(library_paths.offset(i))); libraries.push(Path::new(&path).to_owned()); } @@ -89,7 +89,7 @@ unsafe fn arbitrator_load_machine_impl( #[no_mangle] pub unsafe extern "C" fn arbitrator_load_wavm_binary(binary_path: *const c_char) -> *mut Machine { - let binary_path = cstr_to_string(binary_path); + let binary_path = c_string_to_string(binary_path); let binary_path = Path::new(&binary_path); match Machine::new_from_wavm(binary_path) { Ok(mach) => Box::into_raw(Box::new(mach)), From 38bd844c1b548b29aec6cd1c64aca3c6490c13f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Thu, 26 Mar 2026 18:06:31 +0100 Subject: [PATCH 146/189] machine-related utils --- crates/prover-ffi/src/lib.rs | 298 +------------------------------ crates/prover-ffi/src/machine.rs | 296 ++++++++++++++++++++++++++++++ 2 files changed, 304 insertions(+), 290 deletions(-) create mode 100644 crates/prover-ffi/src/machine.rs diff --git a/crates/prover-ffi/src/lib.rs b/crates/prover-ffi/src/lib.rs index 402e91a2977..20ff17856c1 100644 --- a/crates/prover-ffi/src/lib.rs +++ b/crates/prover-ffi/src/lib.rs @@ -1,31 +1,26 @@ #![allow(clippy::missing_safety_doc, clippy::too_many_arguments)] use arbutil::{Bytes32, PreimageType}; -use eyre::{Report, Result}; use lru::LruCache; use once_cell::sync::OnceCell; -use prover::machine::{argument_data_to_inbox, MachineStatus, PreimageResolver}; +use prover::machine::MachineStatus; use prover::{ - machine::{get_empty_preimage_resolver, GlobalState}, utils, - utils::CBytes, - CByteArray, Machine, ResolvedPreimage, RustBytes, + utils::CBytes + , ResolvedPreimage, RustBytes, }; use static_assertions::const_assert_eq; -use std::os::raw::c_int; use std::sync::atomic; use std::sync::atomic::AtomicU8; use std::{ - ffi::CStr, - num::NonZeroUsize, - os::raw::c_char, - path::Path, - ptr, slice, + num::NonZeroUsize + + + , sync::{Arc, Mutex}, }; -use crate::c_strings::{c_string_to_string, err_to_c_string}; - pub mod c_strings; +pub mod machine; lazy_static::lazy_static! { static ref BLOBHASH_PREIMAGE_CACHE: Mutex>>> = Mutex::new(LruCache::new(NonZeroUsize::new(12).unwrap())); @@ -43,79 +38,6 @@ pub unsafe extern "C" fn free_rust_bytes(vec: RustBytes) { } } -#[no_mangle] -pub unsafe extern "C" fn arbitrator_load_machine( - binary_path: *const c_char, - library_paths: *const *const c_char, - library_paths_size: isize, - debug_chain: usize, -) -> *mut Machine { - let debug_chain = debug_chain != 0; - arbitrator_load_machine_impl(binary_path, library_paths, library_paths_size, debug_chain) - .unwrap_or_else(|err| { - eprintln!("Error loading binary: {err:?}"); - ptr::null_mut() - }) -} - -unsafe fn arbitrator_load_machine_impl( - binary_path: *const c_char, - library_paths: *const *const c_char, - library_paths_size: isize, - debug_chain: bool, -) -> Result<*mut Machine> { - let binary_path = c_string_to_string(binary_path); - let binary_path = Path::new(&binary_path); - - let mut libraries = vec![]; - for i in 0..library_paths_size { - let path = c_string_to_string(*(library_paths.offset(i))); - libraries.push(Path::new(&path).to_owned()); - } - - let mach = Machine::from_paths( - &libraries, - binary_path, - true, - true, - debug_chain, - debug_chain, - Default::default(), - Default::default(), - get_empty_preimage_resolver(), - )?; - Ok(Box::into_raw(Box::new(mach))) -} - -#[no_mangle] -pub unsafe extern "C" fn arbitrator_load_wavm_binary(binary_path: *const c_char) -> *mut Machine { - let binary_path = c_string_to_string(binary_path); - let binary_path = Path::new(&binary_path); - match Machine::new_from_wavm(binary_path) { - Ok(mach) => Box::into_raw(Box::new(mach)), - Err(err) => { - eprintln!("Error loading binary: {err}"); - ptr::null_mut() - } - } -} - -#[no_mangle] -pub unsafe extern "C" fn arbitrator_new_finished(gs: GlobalState) -> *mut Machine { - Box::into_raw(Box::new(Machine::new_finished(gs))) -} - - -#[no_mangle] -pub unsafe extern "C" fn arbitrator_free_machine(mach: *mut Machine) { - drop(Box::from_raw(mach)); -} - -#[no_mangle] -pub unsafe extern "C" fn arbitrator_clone_machine(mach: *mut Machine) -> *mut Machine { - let new_mach = (*mach).clone(); - Box::into_raw(Box::new(new_mach)) -} /// Go doesn't have this functionality builtin for whatever reason. Uses relaxed ordering. #[no_mangle] @@ -123,167 +45,6 @@ pub unsafe extern "C" fn atomic_u8_store(ptr: *mut u8, contents: u8) { (*(ptr as *mut AtomicU8)).store(contents, atomic::Ordering::Relaxed); } -/// Runs the machine while the condition variable is zero. May return early if num_steps is hit. -/// Returns a c string error (freeable with libc's free) on error, or nullptr on success. -#[no_mangle] -pub unsafe extern "C" fn arbitrator_step( - mach: *mut Machine, - num_steps: u64, - condition: *const u8, -) -> *mut libc::c_char { - let mach = &mut *mach; - let condition = &*(condition as *const AtomicU8); - let mut remaining_steps = num_steps; - while condition.load(atomic::Ordering::Relaxed) == 0 { - if remaining_steps == 0 || mach.is_halted() { - break; - } - let stepping = std::cmp::min(remaining_steps, 1_000_000); - match mach.step_n(stepping) { - Ok(()) => {} - Err(err) => return err_to_c_string(err), - } - remaining_steps -= stepping; - } - ptr::null_mut() -} - -#[no_mangle] -pub unsafe extern "C" fn arbitrator_add_inbox_message( - mach: *mut Machine, - inbox_identifier: u64, - index: u64, - data: CByteArray, -) -> c_int { - let mach = &mut *mach; - if let Some(identifier) = argument_data_to_inbox(inbox_identifier) { - let slice = slice::from_raw_parts(data.ptr, data.len); - let data = slice.to_vec(); - mach.add_inbox_msg(identifier, index, data); - 0 - } else { - 1 - } -} - -/// Adds a user program to the machine's known set of wasms. -#[no_mangle] -pub unsafe extern "C" fn arbitrator_add_user_wasm( - mach: *mut Machine, - module: *const u8, - module_len: usize, - module_hash: *const Bytes32, -) { - let module = slice::from_raw_parts(module, module_len); - (*mach).add_stylus_module(*module_hash, module.to_owned()); -} - -/// Like arbitrator_step, but stops early if it hits a host io operation. -/// Returns a c string error (freeable with libc's free) on error, or nullptr on success. -#[no_mangle] -pub unsafe extern "C" fn arbitrator_step_until_host_io( - mach: *mut Machine, - condition: *const u8, -) -> *mut libc::c_char { - let mach = &mut *mach; - let condition = &*(condition as *const AtomicU8); - while condition.load(atomic::Ordering::Relaxed) == 0 { - for _ in 0..1_000_000 { - if mach.is_halted() { - return ptr::null_mut(); - } - if mach.next_instruction_is_host_io() { - return ptr::null_mut(); - } - match mach.step_n(1) { - Ok(()) => {} - Err(err) => return err_to_c_string(err), - } - } - } - ptr::null_mut() -} - -#[no_mangle] -pub unsafe extern "C" fn arbitrator_serialize_state( - mach: *const Machine, - path: *const c_char, -) -> c_int { - let mach = &*mach; - let res = CStr::from_ptr(path) - .to_str() - .map_err(Report::from) - .and_then(|path| mach.serialize_state(path)); - if let Err(err) = res { - eprintln!("Failed to serialize machine state: {err}"); - 1 - } else { - 0 - } -} - -#[no_mangle] -pub unsafe extern "C" fn arbitrator_deserialize_and_replace_state( - mach: *mut Machine, - path: *const c_char, -) -> c_int { - let mach = &mut *mach; - let res = CStr::from_ptr(path) - .to_str() - .map_err(Report::from) - .and_then(|path| mach.deserialize_and_replace_state(path)); - if let Err(err) = res { - eprintln!("Failed to deserialize machine state: {err}"); - 1 - } else { - 0 - } -} - -#[no_mangle] -pub unsafe extern "C" fn arbitrator_get_num_steps(mach: *const Machine) -> u64 { - (*mach).get_steps() -} - -pub const ARBITRATOR_MACHINE_STATUS_RUNNING: u8 = 0; -pub const ARBITRATOR_MACHINE_STATUS_FINISHED: u8 = 1; -pub const ARBITRATOR_MACHINE_STATUS_ERRORED: u8 = 2; -pub const ARBITRATOR_MACHINE_STATUS_TOO_FAR: u8 = 3; - -// Unfortunately, cbindgen doesn't support constants with non-literal values, so we assert that they're correct. -const_assert_eq!( - ARBITRATOR_MACHINE_STATUS_RUNNING, - MachineStatus::Running as u8, -); -const_assert_eq!( - ARBITRATOR_MACHINE_STATUS_FINISHED, - MachineStatus::Finished as u8, -); -const_assert_eq!( - ARBITRATOR_MACHINE_STATUS_ERRORED, - MachineStatus::Errored as u8, -); -const_assert_eq!( - ARBITRATOR_MACHINE_STATUS_TOO_FAR, - MachineStatus::TooFar as u8, -); - -/// Returns one of ARBITRATOR_MACHINE_STATUS_* -#[no_mangle] -pub unsafe extern "C" fn arbitrator_get_status(mach: *const Machine) -> u8 { - (*mach).get_status() as u8 -} - -#[no_mangle] -pub unsafe extern "C" fn arbitrator_global_state(mach: *mut Machine) -> GlobalState { - (*mach).get_global_state() -} - -#[no_mangle] -pub unsafe extern "C" fn arbitrator_set_global_state(mach: *mut Machine, gs: GlobalState) { - (*mach).set_global_state(gs); -} - unsafe fn handle_preimage_resolution( context: u64, ty: PreimageType, @@ -314,46 +75,3 @@ unsafe fn handle_preimage_resolution( Some(data) } -#[no_mangle] -pub unsafe extern "C" fn arbitrator_set_preimage_resolver( - mach: *mut Machine, - resolver: unsafe extern "C" fn(u64, u8, *const u8) -> ResolvedPreimage, -) { - (*mach).set_preimage_resolver(Arc::new( - move |context: u64, ty: PreimageType, hash: Bytes32| -> Option { - if ty == PreimageType::EthVersionedHash { - let cache: Arc> = { - let mut locked = BLOBHASH_PREIMAGE_CACHE.lock().unwrap(); - locked.get_or_insert(hash, Default::default).clone() - }; - return cache - .get_or_try_init(|| { - handle_preimage_resolution(context, ty, hash, resolver).ok_or(()) - }) - .ok() - .cloned(); - } - handle_preimage_resolution(context, ty, hash, resolver) - }, - ) as PreimageResolver); -} - -#[no_mangle] -pub unsafe extern "C" fn arbitrator_set_context(mach: *mut Machine, context: u64) { - (*mach).set_context(context); -} - -#[no_mangle] -pub unsafe extern "C" fn arbitrator_hash(mach: *mut Machine) -> Bytes32 { - (*mach).hash() -} - -#[no_mangle] -pub unsafe extern "C" fn arbitrator_module_root(mach: *mut Machine) -> Bytes32 { - (*mach).get_modules_root() -} - -#[no_mangle] -pub unsafe extern "C" fn arbitrator_gen_proof(mach: *mut Machine, out: *mut RustBytes) { - (*out).write((*mach).serialize_proof()); -} diff --git a/crates/prover-ffi/src/machine.rs b/crates/prover-ffi/src/machine.rs new file mode 100644 index 00000000000..779dffe1bab --- /dev/null +++ b/crates/prover-ffi/src/machine.rs @@ -0,0 +1,296 @@ +// Copyright 2021-2026, Offchain Labs, Inc. +// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md + +use std::ffi::CStr; +use std::os::raw::{c_char, c_int}; +use std::{ptr, slice}; +use std::path::Path; +use std::sync::{atomic, Arc}; +use std::sync::atomic::AtomicU8; +use arbutil::{Bytes32, PreimageType}; +use eyre::Report; +use once_cell::sync::OnceCell; +use static_assertions::const_assert_eq; +use prover::{CByteArray, Machine, ResolvedPreimage, RustBytes}; +use prover::machine::{argument_data_to_inbox, get_empty_preimage_resolver, GlobalState, MachineStatus, PreimageResolver}; +use prover::utils::CBytes; +use crate::BLOBHASH_PREIMAGE_CACHE; +use crate::c_strings::{c_string_to_string, err_to_c_string}; + +pub const ARBITRATOR_MACHINE_STATUS_RUNNING: u8 = 0; +pub const ARBITRATOR_MACHINE_STATUS_FINISHED: u8 = 1; +pub const ARBITRATOR_MACHINE_STATUS_ERRORED: u8 = 2; +pub const ARBITRATOR_MACHINE_STATUS_TOO_FAR: u8 = 3; + +// Unfortunately, cbindgen doesn't support constants with non-literal values, so we assert that they're correct. +const_assert_eq!( + ARBITRATOR_MACHINE_STATUS_RUNNING, + MachineStatus::Running as u8, +); +const_assert_eq!( + ARBITRATOR_MACHINE_STATUS_FINISHED, + MachineStatus::Finished as u8, +); +const_assert_eq!( + ARBITRATOR_MACHINE_STATUS_ERRORED, + MachineStatus::Errored as u8, +); +const_assert_eq!( + ARBITRATOR_MACHINE_STATUS_TOO_FAR, + MachineStatus::TooFar as u8, +); + +#[no_mangle] +pub unsafe extern "C" fn arbitrator_load_machine( + binary_path: *const c_char, + library_paths: *const *const c_char, + library_paths_size: isize, + debug_chain: usize, +) -> *mut Machine { + let debug_chain = debug_chain != 0; + arbitrator_load_machine_impl(binary_path, library_paths, library_paths_size, debug_chain) + .unwrap_or_else(|err| { + eprintln!("Error loading binary: {err:?}"); + ptr::null_mut() + }) +} + +unsafe fn arbitrator_load_machine_impl( + binary_path: *const c_char, + library_paths: *const *const c_char, + library_paths_size: isize, + debug_chain: bool, +) -> eyre::Result<*mut Machine> { + let binary_path = c_string_to_string(binary_path); + let binary_path = Path::new(&binary_path); + + let mut libraries = vec![]; + for i in 0..library_paths_size { + let path = c_string_to_string(*(library_paths.offset(i))); + libraries.push(Path::new(&path).to_owned()); + } + + let mach = Machine::from_paths( + &libraries, + binary_path, + true, + true, + debug_chain, + debug_chain, + Default::default(), + Default::default(), + get_empty_preimage_resolver(), + )?; + Ok(Box::into_raw(Box::new(mach))) +} + +#[no_mangle] +pub unsafe extern "C" fn arbitrator_load_wavm_binary(binary_path: *const c_char) -> *mut Machine { + let binary_path = c_string_to_string(binary_path); + let binary_path = Path::new(&binary_path); + match Machine::new_from_wavm(binary_path) { + Ok(mach) => Box::into_raw(Box::new(mach)), + Err(err) => { + eprintln!("Error loading binary: {err}"); + ptr::null_mut() + } + } +} + +#[no_mangle] +pub unsafe extern "C" fn arbitrator_new_finished(gs: GlobalState) -> *mut Machine { + Box::into_raw(Box::new(Machine::new_finished(gs))) +} + +#[no_mangle] +pub unsafe extern "C" fn arbitrator_free_machine(mach: *mut Machine) { + drop(Box::from_raw(mach)); +} + +#[no_mangle] +pub unsafe extern "C" fn arbitrator_clone_machine(mach: *mut Machine) -> *mut Machine { + let new_mach = (*mach).clone(); + Box::into_raw(Box::new(new_mach)) +} + +/// Runs the machine while the condition variable is zero. May return early if num_steps is hit. +/// Returns a c string error (freeable with libc's free) on error, or nullptr on success. +#[no_mangle] +pub unsafe extern "C" fn arbitrator_step( + mach: *mut Machine, + num_steps: u64, + condition: *const u8, +) -> *mut libc::c_char { + let mach = &mut *mach; + let condition = &*(condition as *const AtomicU8); + let mut remaining_steps = num_steps; + while condition.load(atomic::Ordering::Relaxed) == 0 { + if remaining_steps == 0 || mach.is_halted() { + break; + } + let stepping = std::cmp::min(remaining_steps, 1_000_000); + match mach.step_n(stepping) { + Ok(()) => {} + Err(err) => return err_to_c_string(err), + } + remaining_steps -= stepping; + } + ptr::null_mut() +} + +#[no_mangle] +pub unsafe extern "C" fn arbitrator_add_inbox_message( + mach: *mut Machine, + inbox_identifier: u64, + index: u64, + data: CByteArray, +) -> c_int { + let mach = &mut *mach; + if let Some(identifier) = argument_data_to_inbox(inbox_identifier) { + let slice = slice::from_raw_parts(data.ptr, data.len); + let data = slice.to_vec(); + mach.add_inbox_msg(identifier, index, data); + 0 + } else { + 1 + } +} + +/// Adds a user program to the machine's known set of wasms. +#[no_mangle] +pub unsafe extern "C" fn arbitrator_add_user_wasm( + mach: *mut Machine, + module: *const u8, + module_len: usize, + module_hash: *const Bytes32, +) { + let module = slice::from_raw_parts(module, module_len); + (*mach).add_stylus_module(*module_hash, module.to_owned()); +} + +/// Like arbitrator_step, but stops early if it hits a host io operation. +/// Returns a c string error (freeable with libc's free) on error, or nullptr on success. +#[no_mangle] +pub unsafe extern "C" fn arbitrator_step_until_host_io( + mach: *mut Machine, + condition: *const u8, +) -> *mut libc::c_char { + let mach = &mut *mach; + let condition = &*(condition as *const AtomicU8); + while condition.load(atomic::Ordering::Relaxed) == 0 { + for _ in 0..1_000_000 { + if mach.is_halted() { + return ptr::null_mut(); + } + if mach.next_instruction_is_host_io() { + return ptr::null_mut(); + } + match mach.step_n(1) { + Ok(()) => {} + Err(err) => return err_to_c_string(err), + } + } + } + ptr::null_mut() +} + +#[no_mangle] +pub unsafe extern "C" fn arbitrator_serialize_state( + mach: *const Machine, + path: *const c_char, +) -> c_int { + let mach = &*mach; + let res = CStr::from_ptr(path) + .to_str() + .map_err(Report::from) + .and_then(|path| mach.serialize_state(path)); + if let Err(err) = res { + eprintln!("Failed to serialize machine state: {err}"); + 1 + } else { + 0 + } +} + +#[no_mangle] +pub unsafe extern "C" fn arbitrator_deserialize_and_replace_state( + mach: *mut Machine, + path: *const c_char, +) -> c_int { + let mach = &mut *mach; + let res = CStr::from_ptr(path) + .to_str() + .map_err(Report::from) + .and_then(|path| mach.deserialize_and_replace_state(path)); + if let Err(err) = res { + eprintln!("Failed to deserialize machine state: {err}"); + 1 + } else { + 0 + } +} + +#[no_mangle] +pub unsafe extern "C" fn arbitrator_get_num_steps(mach: *const Machine) -> u64 { + (*mach).get_steps() +} + +/// Returns one of ARBITRATOR_MACHINE_STATUS_* +#[no_mangle] +pub unsafe extern "C" fn arbitrator_get_status(mach: *const Machine) -> u8 { + (*mach).get_status() as u8 +} + +#[no_mangle] +pub unsafe extern "C" fn arbitrator_global_state(mach: *mut Machine) -> GlobalState { + (*mach).get_global_state() +} + +#[no_mangle] +pub unsafe extern "C" fn arbitrator_set_global_state(mach: *mut Machine, gs: GlobalState) { + (*mach).set_global_state(gs); +} + +#[no_mangle] +pub unsafe extern "C" fn arbitrator_set_preimage_resolver( + mach: *mut Machine, + resolver: unsafe extern "C" fn(u64, u8, *const u8) -> ResolvedPreimage, +) { + (*mach).set_preimage_resolver(Arc::new( + move |context: u64, ty: PreimageType, hash: Bytes32| -> Option { + if ty == PreimageType::EthVersionedHash { + let cache: Arc> = { + let mut locked = BLOBHASH_PREIMAGE_CACHE.lock().unwrap(); + locked.get_or_insert(hash, Default::default).clone() + }; + return cache + .get_or_try_init(|| { + crate::handle_preimage_resolution(context, ty, hash, resolver).ok_or(()) + }) + .ok() + .cloned(); + } + crate::handle_preimage_resolution(context, ty, hash, resolver) + }, + ) as PreimageResolver); +} + +#[no_mangle] +pub unsafe extern "C" fn arbitrator_set_context(mach: *mut Machine, context: u64) { + (*mach).set_context(context); +} + +#[no_mangle] +pub unsafe extern "C" fn arbitrator_hash(mach: *mut Machine) -> Bytes32 { + (*mach).hash() +} + +#[no_mangle] +pub unsafe extern "C" fn arbitrator_module_root(mach: *mut Machine) -> Bytes32 { + (*mach).get_modules_root() +} + +#[no_mangle] +pub unsafe extern "C" fn arbitrator_gen_proof(mach: *mut Machine, out: *mut RustBytes) { + (*out).write((*mach).serialize_proof()); +} \ No newline at end of file From 93601bc442db66ab4f9e4c8397d9f928ad918b37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Thu, 26 Mar 2026 18:10:03 +0100 Subject: [PATCH 147/189] extract preimage utils --- crates/prover-ffi/src/lib.rs | 41 ++----------------- crates/prover-ffi/src/machine.rs | 35 ++-------------- crates/prover-ffi/src/preimage.rs | 66 +++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 69 deletions(-) create mode 100644 crates/prover-ffi/src/preimage.rs diff --git a/crates/prover-ffi/src/lib.rs b/crates/prover-ffi/src/lib.rs index 20ff17856c1..413403c2213 100644 --- a/crates/prover-ffi/src/lib.rs +++ b/crates/prover-ffi/src/lib.rs @@ -1,15 +1,11 @@ #![allow(clippy::missing_safety_doc, clippy::too_many_arguments)] -use arbutil::{Bytes32, PreimageType}; +use arbutil::{Bytes32}; use lru::LruCache; use once_cell::sync::OnceCell; -use prover::machine::MachineStatus; use prover::{ - utils, - utils::CBytes - , ResolvedPreimage, RustBytes, + utils::CBytes, RustBytes, }; -use static_assertions::const_assert_eq; use std::sync::atomic; use std::sync::atomic::AtomicU8; use std::{ @@ -21,6 +17,7 @@ use std::{ }; pub mod c_strings; pub mod machine; +pub mod preimage; lazy_static::lazy_static! { static ref BLOBHASH_PREIMAGE_CACHE: Mutex>>> = Mutex::new(LruCache::new(NonZeroUsize::new(12).unwrap())); @@ -38,40 +35,8 @@ pub unsafe extern "C" fn free_rust_bytes(vec: RustBytes) { } } - /// Go doesn't have this functionality builtin for whatever reason. Uses relaxed ordering. #[no_mangle] pub unsafe extern "C" fn atomic_u8_store(ptr: *mut u8, contents: u8) { (*(ptr as *mut AtomicU8)).store(contents, atomic::Ordering::Relaxed); } - -unsafe fn handle_preimage_resolution( - context: u64, - ty: PreimageType, - hash: Bytes32, - resolver: unsafe extern "C" fn(u64, u8, *const u8) -> ResolvedPreimage, -) -> Option { - let res = resolver(context, ty.into(), hash.as_ptr()); - if res.len < 0 { - return None; - } - let data = CBytes::from_raw_parts(res.ptr, res.len as usize); - - // Hash may not have a direct link to the data for DACertificate - if ty == PreimageType::DACertificate { - return Some(data); - } - - // Check if preimage rehashes to the provided hash - match utils::hash_preimage(&data, ty) { - Ok(have_hash) if have_hash.as_slice() == *hash => {} - Ok(got_hash) => panic!( - "Resolved incorrect data for hash {} (rehashed to {})", - hash, - Bytes32(got_hash), - ), - Err(err) => panic!("Failed to hash preimage from resolver (expecting hash {hash}): {err}",), - } - Some(data) -} - diff --git a/crates/prover-ffi/src/machine.rs b/crates/prover-ffi/src/machine.rs index 779dffe1bab..ddb675efec1 100644 --- a/crates/prover-ffi/src/machine.rs +++ b/crates/prover-ffi/src/machine.rs @@ -5,16 +5,13 @@ use std::ffi::CStr; use std::os::raw::{c_char, c_int}; use std::{ptr, slice}; use std::path::Path; -use std::sync::{atomic, Arc}; +use std::sync::{atomic}; use std::sync::atomic::AtomicU8; -use arbutil::{Bytes32, PreimageType}; +use arbutil::{Bytes32}; use eyre::Report; -use once_cell::sync::OnceCell; use static_assertions::const_assert_eq; -use prover::{CByteArray, Machine, ResolvedPreimage, RustBytes}; -use prover::machine::{argument_data_to_inbox, get_empty_preimage_resolver, GlobalState, MachineStatus, PreimageResolver}; -use prover::utils::CBytes; -use crate::BLOBHASH_PREIMAGE_CACHE; +use prover::{CByteArray, Machine, RustBytes}; +use prover::machine::{argument_data_to_inbox, get_empty_preimage_resolver, GlobalState, MachineStatus}; use crate::c_strings::{c_string_to_string, err_to_c_string}; pub const ARBITRATOR_MACHINE_STATUS_RUNNING: u8 = 0; @@ -251,30 +248,6 @@ pub unsafe extern "C" fn arbitrator_set_global_state(mach: *mut Machine, gs: Glo (*mach).set_global_state(gs); } -#[no_mangle] -pub unsafe extern "C" fn arbitrator_set_preimage_resolver( - mach: *mut Machine, - resolver: unsafe extern "C" fn(u64, u8, *const u8) -> ResolvedPreimage, -) { - (*mach).set_preimage_resolver(Arc::new( - move |context: u64, ty: PreimageType, hash: Bytes32| -> Option { - if ty == PreimageType::EthVersionedHash { - let cache: Arc> = { - let mut locked = BLOBHASH_PREIMAGE_CACHE.lock().unwrap(); - locked.get_or_insert(hash, Default::default).clone() - }; - return cache - .get_or_try_init(|| { - crate::handle_preimage_resolution(context, ty, hash, resolver).ok_or(()) - }) - .ok() - .cloned(); - } - crate::handle_preimage_resolution(context, ty, hash, resolver) - }, - ) as PreimageResolver); -} - #[no_mangle] pub unsafe extern "C" fn arbitrator_set_context(mach: *mut Machine, context: u64) { (*mach).set_context(context); diff --git a/crates/prover-ffi/src/preimage.rs b/crates/prover-ffi/src/preimage.rs new file mode 100644 index 00000000000..78c665e6fdd --- /dev/null +++ b/crates/prover-ffi/src/preimage.rs @@ -0,0 +1,66 @@ +// Copyright 2021-2026, Offchain Labs, Inc. +// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md + +use arbutil::{Bytes32, PreimageType}; +use once_cell::sync::OnceCell; +use prover::machine::PreimageResolver; +use prover::utils::{self, CBytes}; +use prover::{Machine, ResolvedPreimage}; +use std::{ + sync::{Arc}, +}; +use crate::BLOBHASH_PREIMAGE_CACHE; + +#[no_mangle] +pub unsafe extern "C" fn arbitrator_set_preimage_resolver( + mach: *mut Machine, + resolver: unsafe extern "C" fn(u64, u8, *const u8) -> ResolvedPreimage, +) { + (*mach).set_preimage_resolver(Arc::new( + move |context: u64, ty: PreimageType, hash: Bytes32| -> Option { + if ty == PreimageType::EthVersionedHash { + let cache: Arc> = { + let mut locked = BLOBHASH_PREIMAGE_CACHE.lock().unwrap(); + locked.get_or_insert(hash, Default::default).clone() + }; + return cache + .get_or_try_init(|| { + handle_preimage_resolution(context, ty, hash, resolver).ok_or(()) + }) + .ok() + .cloned(); + } + handle_preimage_resolution(context, ty, hash, resolver) + }, + ) as PreimageResolver); +} + +unsafe fn handle_preimage_resolution( + context: u64, + ty: PreimageType, + hash: Bytes32, + resolver: unsafe extern "C" fn(u64, u8, *const u8) -> ResolvedPreimage, +) -> Option { + let res = resolver(context, ty.into(), hash.as_ptr()); + if res.len < 0 { + return None; + } + let data = CBytes::from_raw_parts(res.ptr, res.len as usize); + + // Hash may not have a direct link to the data for DACertificate + if ty == PreimageType::DACertificate { + return Some(data); + } + + // Check if preimage rehashes to the provided hash + match utils::hash_preimage(&data, ty) { + Ok(have_hash) if have_hash.as_slice() == *hash => {} + Ok(got_hash) => panic!( + "Resolved incorrect data for hash {} (rehashed to {})", + hash, + Bytes32(got_hash), + ), + Err(err) => panic!("Failed to hash preimage from resolver (expecting hash {hash}): {err}",), + } + Some(data) +} From 1e94d4e6cb3b7bc3defe344c5dd9603b958de887 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 27 Mar 2026 09:21:10 +0100 Subject: [PATCH 148/189] move static --- crates/prover-ffi/src/lib.rs | 18 +----------------- crates/prover-ffi/src/preimage.rs | 8 +++++++- 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/crates/prover-ffi/src/lib.rs b/crates/prover-ffi/src/lib.rs index 413403c2213..6fcfac860ab 100644 --- a/crates/prover-ffi/src/lib.rs +++ b/crates/prover-ffi/src/lib.rs @@ -1,28 +1,12 @@ #![allow(clippy::missing_safety_doc, clippy::too_many_arguments)] -use arbutil::{Bytes32}; -use lru::LruCache; -use once_cell::sync::OnceCell; -use prover::{ - utils::CBytes, RustBytes, -}; +use prover::RustBytes; use std::sync::atomic; use std::sync::atomic::AtomicU8; -use std::{ - num::NonZeroUsize - - - , - sync::{Arc, Mutex}, -}; pub mod c_strings; pub mod machine; pub mod preimage; -lazy_static::lazy_static! { - static ref BLOBHASH_PREIMAGE_CACHE: Mutex>>> = Mutex::new(LruCache::new(NonZeroUsize::new(12).unwrap())); -} - /// Frees the vector. Does nothing when the vector is null. /// /// # Safety diff --git a/crates/prover-ffi/src/preimage.rs b/crates/prover-ffi/src/preimage.rs index 78c665e6fdd..3c8ad13178a 100644 --- a/crates/prover-ffi/src/preimage.rs +++ b/crates/prover-ffi/src/preimage.rs @@ -9,7 +9,13 @@ use prover::{Machine, ResolvedPreimage}; use std::{ sync::{Arc}, }; -use crate::BLOBHASH_PREIMAGE_CACHE; +use std::num::NonZeroUsize; +use std::sync::Mutex; +use lru::LruCache; + +lazy_static::lazy_static! { + static ref BLOBHASH_PREIMAGE_CACHE: Mutex>>> = Mutex::new(LruCache::new(NonZeroUsize::new(12).unwrap())); +} #[no_mangle] pub unsafe extern "C" fn arbitrator_set_preimage_resolver( From d2666968993e9107a4a9b8e0af4b2a65e7bdebdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 27 Mar 2026 10:27:28 +0100 Subject: [PATCH 149/189] extract cbytes into module --- crates/prover/src/cbytes.rs | 168 ++++++++++++++++++++++++++++++++++++ crates/prover/src/lib.rs | 1 + crates/prover/src/utils.rs | 166 +---------------------------------- 3 files changed, 171 insertions(+), 164 deletions(-) create mode 100644 crates/prover/src/cbytes.rs diff --git a/crates/prover/src/cbytes.rs b/crates/prover/src/cbytes.rs new file mode 100644 index 00000000000..15f43e6d0fa --- /dev/null +++ b/crates/prover/src/cbytes.rs @@ -0,0 +1,168 @@ +// Copyright 2021-2026, Offchain Labs, Inc. +// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md + +use std::{borrow::Borrow, fmt, ops::Deref}; + +/// A Vec with manual allocation. +/// On native builds, uses libc malloc/free for FFI compatibility. +/// On SP1 (no libc), uses Rust's global allocator. +pub struct CBytes { + ptr: *mut u8, + len: usize, +} + +impl CBytes { + pub fn new() -> Self { + Self::default() + } + + pub fn as_slice(&self) -> &[u8] { + unsafe { std::slice::from_raw_parts(self.ptr, self.len) } + } + + pub unsafe fn from_raw_parts(ptr: *mut u8, len: usize) -> Self { + Self { ptr, len } + } +} + +impl Default for CBytes { + fn default() -> Self { + Self { + ptr: std::ptr::null_mut(), + len: 0, + } + } +} + +impl fmt::Debug for CBytes { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:?}", self.as_slice()) + } +} + +#[cfg(not(feature = "sp1"))] +impl From<&[u8]> for CBytes { + fn from(slice: &[u8]) -> Self { + if slice.is_empty() { + return Self::default(); + } + unsafe { + let ptr = libc::malloc(slice.len()) as *mut u8; + if ptr.is_null() { + panic!("Failed to allocate memory instantiating CBytes"); + } + std::ptr::copy_nonoverlapping(slice.as_ptr(), ptr, slice.len()); + Self { + ptr, + len: slice.len(), + } + } + } +} + +#[cfg(feature = "sp1")] +impl From<&[u8]> for CBytes { + fn from(slice: &[u8]) -> Self { + if slice.is_empty() { + return Self::default(); + } + unsafe { + let layout = std::alloc::Layout::from_size_align(slice.len(), 1).unwrap(); + let ptr = std::alloc::alloc(layout); + if ptr.is_null() { + panic!("Failed to allocate memory instantiating CBytes"); + } + std::ptr::copy_nonoverlapping(slice.as_ptr(), ptr, slice.len()); + Self { + ptr, + len: slice.len(), + } + } + } +} + +// There's no thread safety concerns for CBytes. +// This type is basically a Box<[u8]> (which is Send + Sync) with libc as an allocator. +// Any data races between threads are prevented by Rust borrowing rules, +// and the data isn't thread-local so there's no concern moving it between threads. +unsafe impl Send for CBytes {} +unsafe impl Sync for CBytes {} + +#[cfg(not(feature = "sp1"))] +impl Drop for CBytes { + fn drop(&mut self) { + if !self.ptr.is_null() && self.len > 0 { + unsafe { + libc::free(self.ptr as *mut _); + } + } + } +} + +#[cfg(feature = "sp1")] +impl Drop for CBytes { + fn drop(&mut self) { + if !self.ptr.is_null() && self.len > 0 { + unsafe { + let layout = std::alloc::Layout::from_size_align(self.len, 1).unwrap(); + std::alloc::dealloc(self.ptr, layout); + } + } + } +} + +impl Clone for CBytes { + fn clone(&self) -> Self { + self.as_slice().into() + } +} + +impl Deref for CBytes { + type Target = [u8]; + + fn deref(&self) -> &[u8] { + self.as_slice() + } +} + +impl AsRef<[u8]> for CBytes { + fn as_ref(&self) -> &[u8] { + self.as_slice() + } +} + +impl Borrow<[u8]> for CBytes { + fn borrow(&self) -> &[u8] { + self.as_slice() + } +} + +#[derive(Clone)] +pub struct CBytesIntoIter(CBytes, usize); + +impl Iterator for CBytesIntoIter { + type Item = u8; + + fn next(&mut self) -> Option { + if self.1 >= self.0.len { + return None; + } + let byte = self.0[self.1]; + self.1 += 1; + Some(byte) + } + + fn size_hint(&self) -> (usize, Option) { + let len = self.0.len - self.1; + (len, Some(len)) + } +} + +impl IntoIterator for CBytes { + type Item = u8; + type IntoIter = CBytesIntoIter; + + fn into_iter(self) -> CBytesIntoIter { + CBytesIntoIter(self, 0) + } +} diff --git a/crates/prover/src/lib.rs b/crates/prover/src/lib.rs index e14b810b433..77b0189cb19 100644 --- a/crates/prover/src/lib.rs +++ b/crates/prover/src/lib.rs @@ -4,6 +4,7 @@ #![allow(clippy::missing_safety_doc, clippy::too_many_arguments)] pub mod binary; +pub mod cbytes; mod host; pub(crate) mod internal_func; #[cfg(feature = "kzg")] diff --git a/crates/prover/src/utils.rs b/crates/prover/src/utils.rs index 71d9635e29c..8525085ac71 100644 --- a/crates/prover/src/utils.rs +++ b/crates/prover/src/utils.rs @@ -11,93 +11,10 @@ use eyre::{eyre, Result}; use serde::{Deserialize, Serialize}; use sha2::Sha256; use sha3::Keccak256; -use std::{borrow::Borrow, convert::TryInto, fmt, fs::File, io::Read, ops::Deref, path::Path}; +use std::{convert::TryInto, fs::File, io::Read, path::Path}; use wasmparser::{RefType, TableType}; -/// A Vec with manual allocation. -/// On native builds, uses libc malloc/free for FFI compatibility. -/// On SP1 (no libc), uses Rust's global allocator. -pub struct CBytes { - ptr: *mut u8, - len: usize, -} - -impl CBytes { - pub fn new() -> Self { - Self::default() - } - - pub fn as_slice(&self) -> &[u8] { - unsafe { std::slice::from_raw_parts(self.ptr, self.len) } - } - - pub unsafe fn from_raw_parts(ptr: *mut u8, len: usize) -> Self { - Self { ptr, len } - } -} - -impl Default for CBytes { - fn default() -> Self { - Self { - ptr: std::ptr::null_mut(), - len: 0, - } - } -} - -impl fmt::Debug for CBytes { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{:?}", self.as_slice()) - } -} - -#[cfg(not(feature = "sp1"))] -impl From<&[u8]> for CBytes { - fn from(slice: &[u8]) -> Self { - if slice.is_empty() { - return Self::default(); - } - unsafe { - let ptr = libc::malloc(slice.len()) as *mut u8; - if ptr.is_null() { - panic!("Failed to allocate memory instantiating CBytes"); - } - std::ptr::copy_nonoverlapping(slice.as_ptr(), ptr, slice.len()); - Self { - ptr, - len: slice.len(), - } - } - } -} - -#[cfg(feature = "sp1")] -impl From<&[u8]> for CBytes { - fn from(slice: &[u8]) -> Self { - if slice.is_empty() { - return Self::default(); - } - unsafe { - let layout = std::alloc::Layout::from_size_align(slice.len(), 1).unwrap(); - let ptr = std::alloc::alloc(layout); - if ptr.is_null() { - panic!("Failed to allocate memory instantiating CBytes"); - } - std::ptr::copy_nonoverlapping(slice.as_ptr(), ptr, slice.len()); - Self { - ptr, - len: slice.len(), - } - } - } -} - -// There's no thread safety concerns for CBytes. -// This type is basically a Box<[u8]> (which is Send + Sync) with libc as an allocator. -// Any data races between threads are prevented by Rust borrowing rules, -// and the data isn't thread-local so there's no concern moving it between threads. -unsafe impl Send for CBytes {} -unsafe impl Sync for CBytes {} +pub use crate::cbytes::{CBytes, CBytesIntoIter}; /// Unfortunately, [`wasmparser::RefType`] isn't serde and its contents aren't public. /// This type enables serde via a 1:1 transmute. @@ -140,85 +57,6 @@ pub struct RemoteTableType { pub shared: bool, } -#[cfg(not(feature = "sp1"))] -impl Drop for CBytes { - fn drop(&mut self) { - if !self.ptr.is_null() && self.len > 0 { - unsafe { - libc::free(self.ptr as *mut _); - } - } - } -} - -#[cfg(feature = "sp1")] -impl Drop for CBytes { - fn drop(&mut self) { - if !self.ptr.is_null() && self.len > 0 { - unsafe { - let layout = std::alloc::Layout::from_size_align(self.len, 1).unwrap(); - std::alloc::dealloc(self.ptr, layout); - } - } - } -} - -impl Clone for CBytes { - fn clone(&self) -> Self { - self.as_slice().into() - } -} - -impl Deref for CBytes { - type Target = [u8]; - - fn deref(&self) -> &[u8] { - self.as_slice() - } -} - -impl AsRef<[u8]> for CBytes { - fn as_ref(&self) -> &[u8] { - self.as_slice() - } -} - -impl Borrow<[u8]> for CBytes { - fn borrow(&self) -> &[u8] { - self.as_slice() - } -} - -#[derive(Clone)] -pub struct CBytesIntoIter(CBytes, usize); - -impl Iterator for CBytesIntoIter { - type Item = u8; - - fn next(&mut self) -> Option { - if self.1 >= self.0.len { - return None; - } - let byte = self.0[self.1]; - self.1 += 1; - Some(byte) - } - - fn size_hint(&self) -> (usize, Option) { - let len = self.0.len - self.1; - (len, Some(len)) - } -} - -impl IntoIterator for CBytes { - type Item = u8; - type IntoIter = CBytesIntoIter; - - fn into_iter(self) -> CBytesIntoIter { - CBytesIntoIter(self, 0) - } -} - pub fn file_bytes(path: &Path) -> Result> { let mut f = File::open(path)?; let mut buf = Vec::new(); From 62a2fc3ce88e914b3ce76103c8c95d652d354aab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 27 Mar 2026 10:51:33 +0100 Subject: [PATCH 150/189] new libc feature --- Cargo.lock | 4 ---- crates/prover-ffi/Cargo.toml | 2 +- crates/prover/Cargo.toml | 7 ++----- crates/prover/src/cbytes.rs | 16 ++++++++-------- 4 files changed, 11 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 457f52fce4e..8de3c3fb3fb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5292,12 +5292,9 @@ dependencies = [ "hex", "lazy_static", "libc", - "lru 0.16.3", "nom", - "num", "num-derive", "num-traits", - "once_cell", "parking_lot", "rand 0.8.5", "rayon", @@ -5308,7 +5305,6 @@ dependencies = [ "sha2 0.10.9", "sha3", "smallvec", - "static_assertions", "structopt", "validation", "wasmer", diff --git a/crates/prover-ffi/Cargo.toml b/crates/prover-ffi/Cargo.toml index 19c9bd182e8..43e3a5bb895 100644 --- a/crates/prover-ffi/Cargo.toml +++ b/crates/prover-ffi/Cargo.toml @@ -20,5 +20,5 @@ lazy_static = { workspace = true } libc = { workspace = true } lru = { workspace = true } once_cell = { workspace = true } -prover = { workspace = true, features = ["native"] } +prover = { workspace = true, features = ["native", "libc"] } static_assertions = { workspace = true } diff --git a/crates/prover/Cargo.toml b/crates/prover/Cargo.toml index 4e10a8e3fbc..ca1be7b6ae6 100644 --- a/crates/prover/Cargo.toml +++ b/crates/prover/Cargo.toml @@ -22,13 +22,10 @@ eyre = { workspace = true } fnv = { workspace = true } hex = { workspace = true } lazy_static = { workspace = true } -libc = { workspace = true } -lru = { workspace = true } +libc = { workspace = true, optional = true } nom = { workspace = true } -num = { workspace = true } num-derive = { workspace = true } num-traits = { workspace = true } -once_cell = { workspace = true } parking_lot = { workspace = true } rayon = { workspace = true, optional = true } rustc-demangle = { workspace = true } @@ -38,7 +35,6 @@ serde_with = { workspace = true, features = ["base64"] } sha2 = { workspace = true } sha3 = { workspace = true } smallvec = { workspace = true, features = ["serde"] } -static_assertions = { workspace = true } structopt = { workspace = true, optional = true } validation = { workspace = true } wasmer = { workspace = true, optional = true } @@ -66,6 +62,7 @@ crate-type = ["staticlib", "lib"] default = ["native", "rayon", "singlepass_rayon", "kzg", "dep:structopt"] counters = [] kzg = ["dep:c-kzg"] +libc = ["dep:libc"] native = ["dep:wasmer", "dep:wasmer-compiler-singlepass", "brotli/wasmer_traits"] singlepass_rayon = ["wasmer-compiler-singlepass?/rayon"] rayon = ["dep:rayon"] diff --git a/crates/prover/src/cbytes.rs b/crates/prover/src/cbytes.rs index 15f43e6d0fa..a712963efdf 100644 --- a/crates/prover/src/cbytes.rs +++ b/crates/prover/src/cbytes.rs @@ -3,9 +3,9 @@ use std::{borrow::Borrow, fmt, ops::Deref}; -/// A Vec with manual allocation. -/// On native builds, uses libc malloc/free for FFI compatibility. -/// On SP1 (no libc), uses Rust's global allocator. +/// A `Vec`-equivalent with manual allocation. +/// With the `libc` feature (enabled by `native`), uses `libc::malloc/free` for FFI compatibility. +/// Without it, uses Rust's global allocator. pub struct CBytes { ptr: *mut u8, len: usize, @@ -40,7 +40,7 @@ impl fmt::Debug for CBytes { } } -#[cfg(not(feature = "sp1"))] +#[cfg(feature = "libc")] impl From<&[u8]> for CBytes { fn from(slice: &[u8]) -> Self { if slice.is_empty() { @@ -60,7 +60,7 @@ impl From<&[u8]> for CBytes { } } -#[cfg(feature = "sp1")] +#[cfg(not(feature = "libc"))] impl From<&[u8]> for CBytes { fn from(slice: &[u8]) -> Self { if slice.is_empty() { @@ -82,13 +82,13 @@ impl From<&[u8]> for CBytes { } // There's no thread safety concerns for CBytes. -// This type is basically a Box<[u8]> (which is Send + Sync) with libc as an allocator. +// This type is basically a Box<[u8]> (which is Send + Sync) with a manual allocator. // Any data races between threads are prevented by Rust borrowing rules, // and the data isn't thread-local so there's no concern moving it between threads. unsafe impl Send for CBytes {} unsafe impl Sync for CBytes {} -#[cfg(not(feature = "sp1"))] +#[cfg(feature = "libc")] impl Drop for CBytes { fn drop(&mut self) { if !self.ptr.is_null() && self.len > 0 { @@ -99,7 +99,7 @@ impl Drop for CBytes { } } -#[cfg(feature = "sp1")] +#[cfg(not(feature = "libc"))] impl Drop for CBytes { fn drop(&mut self) { if !self.ptr.is_null() && self.len > 0 { From 8de06ff4bfd5aec1a75508c89111dcae28d3287f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 27 Mar 2026 10:57:32 +0100 Subject: [PATCH 151/189] use alias in general case --- Cargo.lock | 1 + crates/prover/Cargo.toml | 1 + crates/prover/src/cbytes.rs | 218 ++++++++++++++++-------------------- crates/prover/src/utils.rs | 4 +- 4 files changed, 102 insertions(+), 122 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8de3c3fb3fb..2aea47cd460 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5293,6 +5293,7 @@ dependencies = [ "lazy_static", "libc", "nom", + "num", "num-derive", "num-traits", "parking_lot", diff --git a/crates/prover/Cargo.toml b/crates/prover/Cargo.toml index ca1be7b6ae6..0bfbb1423ee 100644 --- a/crates/prover/Cargo.toml +++ b/crates/prover/Cargo.toml @@ -24,6 +24,7 @@ hex = { workspace = true } lazy_static = { workspace = true } libc = { workspace = true, optional = true } nom = { workspace = true } +num = { workspace = true } num-derive = { workspace = true } num-traits = { workspace = true } parking_lot = { workspace = true } diff --git a/crates/prover/src/cbytes.rs b/crates/prover/src/cbytes.rs index a712963efdf..2a64c6ecda9 100644 --- a/crates/prover/src/cbytes.rs +++ b/crates/prover/src/cbytes.rs @@ -1,168 +1,144 @@ // Copyright 2021-2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md -use std::{borrow::Borrow, fmt, ops::Deref}; - -/// A `Vec`-equivalent with manual allocation. -/// With the `libc` feature (enabled by `native`), uses `libc::malloc/free` for FFI compatibility. -/// Without it, uses Rust's global allocator. -pub struct CBytes { - ptr: *mut u8, - len: usize, -} +/// Without the `libc` feature, `CBytes` is just `Vec`. +/// With `libc`, it is a manually-allocated buffer using `libc::malloc/free` — necessary for FFI +/// where Go allocates memory that Rust must free. +#[cfg(not(feature = "libc"))] +pub type CBytes = Vec; -impl CBytes { - pub fn new() -> Self { - Self::default() - } +#[cfg(feature = "libc")] +pub use libc_cbytes::{CBytes, CBytesIntoIter}; - pub fn as_slice(&self) -> &[u8] { - unsafe { std::slice::from_raw_parts(self.ptr, self.len) } - } +#[cfg(feature = "libc")] +mod libc_cbytes { + use std::{borrow::Borrow, fmt, ops::Deref}; - pub unsafe fn from_raw_parts(ptr: *mut u8, len: usize) -> Self { - Self { ptr, len } + pub struct CBytes { + ptr: *mut u8, + len: usize, } -} -impl Default for CBytes { - fn default() -> Self { - Self { - ptr: std::ptr::null_mut(), - len: 0, + impl CBytes { + pub fn new() -> Self { + Self::default() } - } -} - -impl fmt::Debug for CBytes { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{:?}", self.as_slice()) - } -} -#[cfg(feature = "libc")] -impl From<&[u8]> for CBytes { - fn from(slice: &[u8]) -> Self { - if slice.is_empty() { - return Self::default(); + pub fn as_slice(&self) -> &[u8] { + unsafe { std::slice::from_raw_parts(self.ptr, self.len) } } - unsafe { - let ptr = libc::malloc(slice.len()) as *mut u8; - if ptr.is_null() { - panic!("Failed to allocate memory instantiating CBytes"); - } - std::ptr::copy_nonoverlapping(slice.as_ptr(), ptr, slice.len()); - Self { - ptr, - len: slice.len(), - } + + /// Takes ownership of a pointer allocated with `libc::malloc`. + /// The caller must ensure `ptr` was allocated with `libc::malloc` and won't be + /// freed elsewhere. + pub unsafe fn from_raw_parts(ptr: *mut u8, len: usize) -> Self { + Self { ptr, len } } } -} -#[cfg(not(feature = "libc"))] -impl From<&[u8]> for CBytes { - fn from(slice: &[u8]) -> Self { - if slice.is_empty() { - return Self::default(); - } - unsafe { - let layout = std::alloc::Layout::from_size_align(slice.len(), 1).unwrap(); - let ptr = std::alloc::alloc(layout); - if ptr.is_null() { - panic!("Failed to allocate memory instantiating CBytes"); - } - std::ptr::copy_nonoverlapping(slice.as_ptr(), ptr, slice.len()); + impl Default for CBytes { + fn default() -> Self { Self { - ptr, - len: slice.len(), + ptr: std::ptr::null_mut(), + len: 0, } } } -} -// There's no thread safety concerns for CBytes. -// This type is basically a Box<[u8]> (which is Send + Sync) with a manual allocator. -// Any data races between threads are prevented by Rust borrowing rules, -// and the data isn't thread-local so there's no concern moving it between threads. -unsafe impl Send for CBytes {} -unsafe impl Sync for CBytes {} + impl fmt::Debug for CBytes { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:?}", self.as_slice()) + } + } -#[cfg(feature = "libc")] -impl Drop for CBytes { - fn drop(&mut self) { - if !self.ptr.is_null() && self.len > 0 { + impl From<&[u8]> for CBytes { + fn from(slice: &[u8]) -> Self { + if slice.is_empty() { + return Self::default(); + } unsafe { - libc::free(self.ptr as *mut _); + let ptr = libc::malloc(slice.len()) as *mut u8; + if ptr.is_null() { + panic!("Failed to allocate memory instantiating CBytes"); + } + std::ptr::copy_nonoverlapping(slice.as_ptr(), ptr, slice.len()); + Self { + ptr, + len: slice.len(), + } } } } -} -#[cfg(not(feature = "libc"))] -impl Drop for CBytes { - fn drop(&mut self) { - if !self.ptr.is_null() && self.len > 0 { - unsafe { - let layout = std::alloc::Layout::from_size_align(self.len, 1).unwrap(); - std::alloc::dealloc(self.ptr, layout); + // This type is basically a Box<[u8]> (which is Send + Sync) with libc as an allocator. + // Any data races between threads are prevented by Rust borrowing rules, + // and the data isn't thread-local so there's no concern moving it between threads. + unsafe impl Send for CBytes {} + unsafe impl Sync for CBytes {} + + impl Drop for CBytes { + fn drop(&mut self) { + if !self.ptr.is_null() && self.len > 0 { + unsafe { + libc::free(self.ptr as *mut _); + } } } } -} -impl Clone for CBytes { - fn clone(&self) -> Self { - self.as_slice().into() + impl Clone for CBytes { + fn clone(&self) -> Self { + self.as_slice().into() + } } -} -impl Deref for CBytes { - type Target = [u8]; + impl Deref for CBytes { + type Target = [u8]; - fn deref(&self) -> &[u8] { - self.as_slice() + fn deref(&self) -> &[u8] { + self.as_slice() + } } -} -impl AsRef<[u8]> for CBytes { - fn as_ref(&self) -> &[u8] { - self.as_slice() + impl AsRef<[u8]> for CBytes { + fn as_ref(&self) -> &[u8] { + self.as_slice() + } } -} -impl Borrow<[u8]> for CBytes { - fn borrow(&self) -> &[u8] { - self.as_slice() + impl Borrow<[u8]> for CBytes { + fn borrow(&self) -> &[u8] { + self.as_slice() + } } -} -#[derive(Clone)] -pub struct CBytesIntoIter(CBytes, usize); + #[derive(Clone)] + pub struct CBytesIntoIter(CBytes, usize); -impl Iterator for CBytesIntoIter { - type Item = u8; + impl Iterator for CBytesIntoIter { + type Item = u8; - fn next(&mut self) -> Option { - if self.1 >= self.0.len { - return None; + fn next(&mut self) -> Option { + if self.1 >= self.0.len { + return None; + } + let byte = self.0[self.1]; + self.1 += 1; + Some(byte) } - let byte = self.0[self.1]; - self.1 += 1; - Some(byte) - } - fn size_hint(&self) -> (usize, Option) { - let len = self.0.len - self.1; - (len, Some(len)) + fn size_hint(&self) -> (usize, Option) { + let len = self.0.len - self.1; + (len, Some(len)) + } } -} -impl IntoIterator for CBytes { - type Item = u8; - type IntoIter = CBytesIntoIter; + impl IntoIterator for CBytes { + type Item = u8; + type IntoIter = CBytesIntoIter; - fn into_iter(self) -> CBytesIntoIter { - CBytesIntoIter(self, 0) + fn into_iter(self) -> CBytesIntoIter { + CBytesIntoIter(self, 0) + } } } diff --git a/crates/prover/src/utils.rs b/crates/prover/src/utils.rs index 8525085ac71..3b1dca1dca4 100644 --- a/crates/prover/src/utils.rs +++ b/crates/prover/src/utils.rs @@ -14,7 +14,9 @@ use sha3::Keccak256; use std::{convert::TryInto, fs::File, io::Read, path::Path}; use wasmparser::{RefType, TableType}; -pub use crate::cbytes::{CBytes, CBytesIntoIter}; +pub use crate::cbytes::CBytes; +#[cfg(feature = "libc")] +pub use crate::cbytes::CBytesIntoIter; /// Unfortunately, [`wasmparser::RefType`] isn't serde and its contents aren't public. /// This type enables serde via a 1:1 transmute. From d7ba77a34d32525b96236337194b5059cc4e28e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 27 Mar 2026 10:58:02 +0100 Subject: [PATCH 152/189] fmt --- crates/prover-ffi/src/machine.rs | 20 +++++++++++--------- crates/prover-ffi/src/preimage.rs | 6 ++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/crates/prover-ffi/src/machine.rs b/crates/prover-ffi/src/machine.rs index ddb675efec1..4d6c70439ed 100644 --- a/crates/prover-ffi/src/machine.rs +++ b/crates/prover-ffi/src/machine.rs @@ -1,18 +1,20 @@ // Copyright 2021-2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md +use crate::c_strings::{c_string_to_string, err_to_c_string}; +use arbutil::Bytes32; +use eyre::Report; +use prover::machine::{ + argument_data_to_inbox, get_empty_preimage_resolver, GlobalState, MachineStatus, +}; +use prover::{CByteArray, Machine, RustBytes}; +use static_assertions::const_assert_eq; use std::ffi::CStr; use std::os::raw::{c_char, c_int}; -use std::{ptr, slice}; use std::path::Path; -use std::sync::{atomic}; +use std::sync::atomic; use std::sync::atomic::AtomicU8; -use arbutil::{Bytes32}; -use eyre::Report; -use static_assertions::const_assert_eq; -use prover::{CByteArray, Machine, RustBytes}; -use prover::machine::{argument_data_to_inbox, get_empty_preimage_resolver, GlobalState, MachineStatus}; -use crate::c_strings::{c_string_to_string, err_to_c_string}; +use std::{ptr, slice}; pub const ARBITRATOR_MACHINE_STATUS_RUNNING: u8 = 0; pub const ARBITRATOR_MACHINE_STATUS_FINISHED: u8 = 1; @@ -266,4 +268,4 @@ pub unsafe extern "C" fn arbitrator_module_root(mach: *mut Machine) -> Bytes32 { #[no_mangle] pub unsafe extern "C" fn arbitrator_gen_proof(mach: *mut Machine, out: *mut RustBytes) { (*out).write((*mach).serialize_proof()); -} \ No newline at end of file +} diff --git a/crates/prover-ffi/src/preimage.rs b/crates/prover-ffi/src/preimage.rs index 3c8ad13178a..90f8f742373 100644 --- a/crates/prover-ffi/src/preimage.rs +++ b/crates/prover-ffi/src/preimage.rs @@ -2,16 +2,14 @@ // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md use arbutil::{Bytes32, PreimageType}; +use lru::LruCache; use once_cell::sync::OnceCell; use prover::machine::PreimageResolver; use prover::utils::{self, CBytes}; use prover::{Machine, ResolvedPreimage}; -use std::{ - sync::{Arc}, -}; use std::num::NonZeroUsize; +use std::sync::Arc; use std::sync::Mutex; -use lru::LruCache; lazy_static::lazy_static! { static ref BLOBHASH_PREIMAGE_CACHE: Mutex>>> = Mutex::new(LruCache::new(NonZeroUsize::new(12).unwrap())); From 850c2c5fc38a00a731e4b5ace6b3efc660a457ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 27 Mar 2026 11:07:14 +0100 Subject: [PATCH 153/189] remove sp1 feature --- crates/prover/Cargo.toml | 3 --- crates/prover/src/machine.rs | 4 ++-- crates/prover/src/programs/config.rs | 8 ++++---- crates/prover/src/programs/counter.rs | 4 ++-- crates/prover/src/programs/depth.rs | 4 ++-- crates/prover/src/programs/meter.rs | 4 ++-- crates/prover/src/programs/mod.rs | 8 ++++---- crates/sp1/program/Cargo.toml | 2 +- crates/sp1/stylus-compiler-program/Cargo.toml | 2 +- 9 files changed, 18 insertions(+), 21 deletions(-) diff --git a/crates/prover/Cargo.toml b/crates/prover/Cargo.toml index 0bfbb1423ee..0831d46bdba 100644 --- a/crates/prover/Cargo.toml +++ b/crates/prover/Cargo.toml @@ -68,6 +68,3 @@ native = ["dep:wasmer", "dep:wasmer-compiler-singlepass", "brotli/wasmer_traits" singlepass_rayon = ["wasmer-compiler-singlepass?/rayon"] rayon = ["dep:rayon"] cc_brotli = ["brotli/cc_brotli"] -# Activated by crates/sp1/program and crates/sp1/stylus-compiler-program -# to gate SP1-specific code paths (middleware, depth checking, metering). -sp1 = [] diff --git a/crates/prover/src/machine.rs b/crates/prover/src/machine.rs index 548c977ed70..e9a0195918a 100644 --- a/crates/prover/src/machine.rs +++ b/crates/prover/src/machine.rs @@ -3,7 +3,7 @@ #[cfg(feature = "kzg")] use crate::kzg::prove_kzg_preimage; -#[cfg(all(feature = "native", not(feature = "sp1")))] +#[cfg(feature = "native")] use crate::programs::meter::MeteredMachine; use crate::{ binary::{ @@ -1850,7 +1850,7 @@ impl Machine { self.get_final_result() } - #[cfg(all(feature = "native", not(feature = "sp1")))] + #[cfg(feature = "native")] pub fn call_user_func( &mut self, func: &str, diff --git a/crates/prover/src/programs/config.rs b/crates/prover/src/programs/config.rs index 394dc9f03e4..eb62e0631a7 100644 --- a/crates/prover/src/programs/config.rs +++ b/crates/prover/src/programs/config.rs @@ -11,7 +11,7 @@ use std::fmt::Debug; use wasmer_types::{Pages, SignatureIndex, WASM_PAGE_SIZE}; use wasmparser::Operator; -#[cfg(all(feature = "native", not(feature = "sp1")))] +#[cfg(feature = "native")] use { super::{ counter::Counter, depth::DepthChecker, dynamic::DynamicMeter, heap::HeapBound, @@ -181,7 +181,7 @@ impl CompileConfig { config } - #[cfg(all(feature = "native", not(feature = "sp1")))] + #[cfg(feature = "native")] fn engine_type(&self, target: Target, cranelift: bool) -> Engine { use wasmer::sys::EngineBuilder; @@ -220,13 +220,13 @@ impl CompileConfig { .into() } - #[cfg(all(feature = "native", not(feature = "sp1")))] + #[cfg(feature = "native")] // cranelift only matters for compilation and not usually needed pub fn engine(&self, target: Target) -> Engine { self.engine_type(target, true) } - #[cfg(all(feature = "native", not(feature = "sp1")))] + #[cfg(feature = "native")] pub fn store(&self, target: Target, cranelift: bool) -> Store { Store::new(self.engine_type(target, cranelift)) } diff --git a/crates/prover/src/programs/counter.rs b/crates/prover/src/programs/counter.rs index 7acda29e88f..dc431ff1ae6 100644 --- a/crates/prover/src/programs/counter.rs +++ b/crates/prover/src/programs/counter.rs @@ -2,7 +2,7 @@ // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md use super::{FuncMiddleware, Middleware, ModuleMod}; -#[cfg(not(feature = "sp1"))] +#[cfg(feature = "native")] use crate::Machine; use arbutil::operator::{OperatorCode, OperatorInfo}; @@ -140,7 +140,7 @@ pub trait CountingMachine { fn operator_counts(&mut self) -> Result>; } -#[cfg(not(feature = "sp1"))] +#[cfg(feature = "native")] impl CountingMachine for Machine { fn operator_counts(&mut self) -> Result> { let mut counts = BTreeMap::new(); diff --git a/crates/prover/src/programs/depth.rs b/crates/prover/src/programs/depth.rs index d4d56c7279d..385584385a0 100644 --- a/crates/prover/src/programs/depth.rs +++ b/crates/prover/src/programs/depth.rs @@ -5,7 +5,7 @@ use super::{ config::{CompileMemoryParams, SigMap}, FuncMiddleware, Middleware, ModuleMod, }; -#[cfg(not(feature = "sp1"))] +#[cfg(feature = "native")] use crate::Machine; use crate::internal_func::InternalFunc; @@ -538,7 +538,7 @@ pub trait DepthCheckedMachine { fn set_stack(&mut self, size: u32); } -#[cfg(not(feature = "sp1"))] +#[cfg(feature = "native")] impl DepthCheckedMachine for Machine { fn stack_left(&mut self) -> u32 { let global = self.get_global(STYLUS_STACK_LEFT).unwrap(); diff --git a/crates/prover/src/programs/meter.rs b/crates/prover/src/programs/meter.rs index f3e5ef452e4..51923db8547 100644 --- a/crates/prover/src/programs/meter.rs +++ b/crates/prover/src/programs/meter.rs @@ -2,7 +2,7 @@ // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md #![allow(clippy::needless_lifetimes)] -#[cfg(not(feature = "sp1"))] +#[cfg(feature = "native")] use crate::Machine; use crate::{ programs::{ @@ -334,7 +334,7 @@ pub trait GasMeteredMachine: MeteredMachine { } } -#[cfg(not(feature = "sp1"))] +#[cfg(feature = "native")] impl MeteredMachine for Machine { fn ink_left(&self) -> MachineMeter { macro_rules! convert { diff --git a/crates/prover/src/programs/mod.rs b/crates/prover/src/programs/mod.rs index c021da0c50d..095e633b5ee 100644 --- a/crates/prover/src/programs/mod.rs +++ b/crates/prover/src/programs/mod.rs @@ -1,11 +1,11 @@ // Copyright 2022-2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md -#[cfg(not(feature = "sp1"))] +#[cfg(feature = "native")] use crate::{machine::Module, programs::config::CompileConfig}; -#[cfg(not(feature = "sp1"))] +#[cfg(feature = "native")] use arbutil::{evm::ARBOS_VERSION_STYLUS_CHARGING_FIXES, math::SaturatingSum, Bytes32}; -#[cfg(not(feature = "sp1"))] +#[cfg(feature = "native")] use eyre::WrapErr; use crate::{ @@ -417,7 +417,7 @@ impl StylusData { } } -#[cfg(not(feature = "sp1"))] +#[cfg(feature = "native")] impl Module { pub fn activate( wasm: &[u8], diff --git a/crates/sp1/program/Cargo.toml b/crates/sp1/program/Cargo.toml index 1c9495aeb46..7731068e640 100644 --- a/crates/sp1/program/Cargo.toml +++ b/crates/sp1/program/Cargo.toml @@ -7,7 +7,7 @@ edition = "2024" [dependencies] arbutil = { workspace = true } caller-env = { workspace = true, features = ["brotli"] } -prover = { workspace = true, features = ["sp1", "native"] } +prover = { workspace = true, features = ["native"] } sp1-zkvm = { workspace = true } validation = { workspace = true, features = ["rkyv"] } wasmer = { workspace = true, features = ["sys", "compiler", "singlepass", "wasmparser"] } diff --git a/crates/sp1/stylus-compiler-program/Cargo.toml b/crates/sp1/stylus-compiler-program/Cargo.toml index 7f37fe1c91b..ece4cc16705 100644 --- a/crates/sp1/stylus-compiler-program/Cargo.toml +++ b/crates/sp1/stylus-compiler-program/Cargo.toml @@ -7,4 +7,4 @@ edition = "2024" [dependencies] sp1-zkvm = { workspace = true } wasmer = { workspace = true, features = ["sys", "compiler", "singlepass"] } -prover = { workspace = true, features = ["sp1", "native"] } +prover = { workspace = true, features = ["native"] } From e261713905f23b9f5d2a1fa3811a708126a365d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 27 Mar 2026 11:12:31 +0100 Subject: [PATCH 154/189] prover is no longer staticlib --- crates/prover/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/prover/Cargo.toml b/crates/prover/Cargo.toml index 0831d46bdba..282c9c88507 100644 --- a/crates/prover/Cargo.toml +++ b/crates/prover/Cargo.toml @@ -57,7 +57,7 @@ harness = false [lib] name = "prover" -crate-type = ["staticlib", "lib"] +crate-type = ["lib"] [features] default = ["native", "rayon", "singlepass_rayon", "kzg", "dep:structopt"] From fbf6b39842d7169d4272cf91d83d6ba3d2723fce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 27 Mar 2026 11:18:41 +0100 Subject: [PATCH 155/189] move other ffi stuff --- crates/prover-ffi/src/lib.rs | 71 ++++++++++++++++++++++++++++++- crates/prover-ffi/src/machine.rs | 3 +- crates/prover-ffi/src/preimage.rs | 3 +- crates/prover/src/lib.rs | 67 ----------------------------- crates/stylus/src/evm_api.rs | 2 +- crates/stylus/src/lib.rs | 6 +-- 6 files changed, 77 insertions(+), 75 deletions(-) diff --git a/crates/prover-ffi/src/lib.rs b/crates/prover-ffi/src/lib.rs index 6fcfac860ab..9cc97862b0e 100644 --- a/crates/prover-ffi/src/lib.rs +++ b/crates/prover-ffi/src/lib.rs @@ -1,12 +1,81 @@ +// Copyright 2021-2026, Offchain Labs, Inc. +// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md + #![allow(clippy::missing_safety_doc, clippy::too_many_arguments)] -use prover::RustBytes; use std::sync::atomic; use std::sync::atomic::AtomicU8; +use std::{marker::PhantomData, ptr}; + pub mod c_strings; pub mod machine; pub mod preimage; +#[repr(C)] +#[derive(Clone, Copy)] +pub struct CByteArray { + pub ptr: *const u8, + pub len: usize, +} + +#[repr(C)] +pub struct RustSlice<'a> { + pub ptr: *const u8, + pub len: usize, + pub phantom: PhantomData<&'a [u8]>, +} + +impl<'a> RustSlice<'a> { + pub fn new(slice: &'a [u8]) -> Self { + if slice.is_empty() { + return Self { + ptr: ptr::null(), + len: 0, + phantom: PhantomData, + }; + } + Self { + ptr: slice.as_ptr(), + len: slice.len(), + phantom: PhantomData, + } + } +} + +#[repr(C)] +pub struct RustBytes { + pub ptr: *mut u8, + pub len: usize, + pub cap: usize, +} + +impl RustBytes { + pub unsafe fn into_vec(self) -> Vec { + Vec::from_raw_parts(self.ptr, self.len, self.cap) + } + + pub unsafe fn write(&mut self, mut vec: Vec) { + if vec.capacity() == 0 { + *self = RustBytes { + ptr: ptr::null_mut(), + len: 0, + cap: 0, + }; + return; + } + self.ptr = vec.as_mut_ptr(); + self.len = vec.len(); + self.cap = vec.capacity(); + std::mem::forget(vec); + } +} + +#[repr(C)] +pub struct ResolvedPreimage { + pub ptr: *mut u8, + pub len: isize, // negative if not found +} + /// Frees the vector. Does nothing when the vector is null. /// /// # Safety diff --git a/crates/prover-ffi/src/machine.rs b/crates/prover-ffi/src/machine.rs index 4d6c70439ed..04c50fb397b 100644 --- a/crates/prover-ffi/src/machine.rs +++ b/crates/prover-ffi/src/machine.rs @@ -7,7 +7,8 @@ use eyre::Report; use prover::machine::{ argument_data_to_inbox, get_empty_preimage_resolver, GlobalState, MachineStatus, }; -use prover::{CByteArray, Machine, RustBytes}; +use crate::{CByteArray, RustBytes}; +use prover::Machine; use static_assertions::const_assert_eq; use std::ffi::CStr; use std::os::raw::{c_char, c_int}; diff --git a/crates/prover-ffi/src/preimage.rs b/crates/prover-ffi/src/preimage.rs index 90f8f742373..cdac701e1c4 100644 --- a/crates/prover-ffi/src/preimage.rs +++ b/crates/prover-ffi/src/preimage.rs @@ -6,7 +6,8 @@ use lru::LruCache; use once_cell::sync::OnceCell; use prover::machine::PreimageResolver; use prover::utils::{self, CBytes}; -use prover::{Machine, ResolvedPreimage}; +use crate::ResolvedPreimage; +use prover::Machine; use std::num::NonZeroUsize; use std::sync::Arc; use std::sync::Mutex; diff --git a/crates/prover/src/lib.rs b/crates/prover/src/lib.rs index 77b0189cb19..4d9254696e9 100644 --- a/crates/prover/src/lib.rs +++ b/crates/prover/src/lib.rs @@ -26,70 +26,3 @@ pub mod wavm; mod test; pub use machine::Machine; - -use std::{marker::PhantomData, ptr}; - -#[repr(C)] -#[derive(Clone, Copy)] -pub struct CByteArray { - pub ptr: *const u8, - pub len: usize, -} - -#[repr(C)] -pub struct RustSlice<'a> { - pub ptr: *const u8, - pub len: usize, - pub phantom: PhantomData<&'a [u8]>, -} - -impl<'a> RustSlice<'a> { - pub fn new(slice: &'a [u8]) -> Self { - if slice.is_empty() { - return Self { - ptr: ptr::null(), - len: 0, - phantom: PhantomData, - }; - } - Self { - ptr: slice.as_ptr(), - len: slice.len(), - phantom: PhantomData, - } - } -} - -#[repr(C)] -pub struct RustBytes { - pub ptr: *mut u8, - pub len: usize, - pub cap: usize, -} - -impl RustBytes { - pub unsafe fn into_vec(self) -> Vec { - Vec::from_raw_parts(self.ptr, self.len, self.cap) - } - - pub unsafe fn write(&mut self, mut vec: Vec) { - if vec.capacity() == 0 { - *self = RustBytes { - ptr: ptr::null_mut(), - len: 0, - cap: 0, - }; - return; - } - self.ptr = vec.as_mut_ptr(); - self.len = vec.len(); - self.cap = vec.capacity(); - std::mem::forget(vec); - } -} - -#[repr(C)] -pub struct ResolvedPreimage { - pub ptr: *mut u8, - pub len: isize, // negative if not found -} diff --git a/crates/stylus/src/evm_api.rs b/crates/stylus/src/evm_api.rs index 46f0656e5e3..0888039edd8 100644 --- a/crates/stylus/src/evm_api.rs +++ b/crates/stylus/src/evm_api.rs @@ -6,7 +6,7 @@ use arbutil::evm::{ api::{EvmApiMethod, Gas, EVM_API_METHOD_REQ_OFFSET}, req::RequestHandler, }; -use prover::RustSlice; +use prover_ffi::RustSlice; #[repr(C)] pub struct NativeRequestHandler { diff --git a/crates/stylus/src/lib.rs b/crates/stylus/src/lib.rs index 3f9fc708592..3e86900af25 100644 --- a/crates/stylus/src/lib.rs +++ b/crates/stylus/src/lib.rs @@ -15,10 +15,8 @@ use cache::{deserialize_module, CacheMetrics, InitCache}; use evm_api::NativeRequestHandler; use eyre::ErrReport; use native::NativeInstance; -use prover::{ - programs::{prelude::*, StylusData}, - RustBytes, -}; +use prover::programs::{prelude::*, StylusData}; +use prover_ffi::RustBytes; use run::RunProgram; use std::ptr; use target_cache::{target_cache_get, target_cache_set}; From 993499bc0ce06676b9c01cbb1cc7ca91baad1502 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 27 Mar 2026 11:20:48 +0100 Subject: [PATCH 156/189] separate module --- crates/prover-ffi/src/lib.rs | 67 +-------------------------------- crates/prover-ffi/src/types.rs | 69 ++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 65 deletions(-) create mode 100644 crates/prover-ffi/src/types.rs diff --git a/crates/prover-ffi/src/lib.rs b/crates/prover-ffi/src/lib.rs index 9cc97862b0e..a9730559ae0 100644 --- a/crates/prover-ffi/src/lib.rs +++ b/crates/prover-ffi/src/lib.rs @@ -5,76 +5,13 @@ use std::sync::atomic; use std::sync::atomic::AtomicU8; -use std::{marker::PhantomData, ptr}; pub mod c_strings; pub mod machine; pub mod preimage; +pub mod types; -#[repr(C)] -#[derive(Clone, Copy)] -pub struct CByteArray { - pub ptr: *const u8, - pub len: usize, -} - -#[repr(C)] -pub struct RustSlice<'a> { - pub ptr: *const u8, - pub len: usize, - pub phantom: PhantomData<&'a [u8]>, -} - -impl<'a> RustSlice<'a> { - pub fn new(slice: &'a [u8]) -> Self { - if slice.is_empty() { - return Self { - ptr: ptr::null(), - len: 0, - phantom: PhantomData, - }; - } - Self { - ptr: slice.as_ptr(), - len: slice.len(), - phantom: PhantomData, - } - } -} - -#[repr(C)] -pub struct RustBytes { - pub ptr: *mut u8, - pub len: usize, - pub cap: usize, -} - -impl RustBytes { - pub unsafe fn into_vec(self) -> Vec { - Vec::from_raw_parts(self.ptr, self.len, self.cap) - } - - pub unsafe fn write(&mut self, mut vec: Vec) { - if vec.capacity() == 0 { - *self = RustBytes { - ptr: ptr::null_mut(), - len: 0, - cap: 0, - }; - return; - } - self.ptr = vec.as_mut_ptr(); - self.len = vec.len(); - self.cap = vec.capacity(); - std::mem::forget(vec); - } -} - -#[repr(C)] -pub struct ResolvedPreimage { - pub ptr: *mut u8, - pub len: isize, // negative if not found -} +pub use types::{CByteArray, ResolvedPreimage, RustBytes, RustSlice}; /// Frees the vector. Does nothing when the vector is null. /// diff --git a/crates/prover-ffi/src/types.rs b/crates/prover-ffi/src/types.rs new file mode 100644 index 00000000000..7304ec8c10c --- /dev/null +++ b/crates/prover-ffi/src/types.rs @@ -0,0 +1,69 @@ +// Copyright 2021-2026, Offchain Labs, Inc. +// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md + +use std::{marker::PhantomData, ptr}; + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct CByteArray { + pub ptr: *const u8, + pub len: usize, +} + +#[repr(C)] +pub struct RustSlice<'a> { + pub ptr: *const u8, + pub len: usize, + pub phantom: PhantomData<&'a [u8]>, +} + +impl<'a> RustSlice<'a> { + pub fn new(slice: &'a [u8]) -> Self { + if slice.is_empty() { + return Self { + ptr: ptr::null(), + len: 0, + phantom: PhantomData, + }; + } + Self { + ptr: slice.as_ptr(), + len: slice.len(), + phantom: PhantomData, + } + } +} + +#[repr(C)] +pub struct RustBytes { + pub ptr: *mut u8, + pub len: usize, + pub cap: usize, +} + +impl RustBytes { + pub unsafe fn into_vec(self) -> Vec { + Vec::from_raw_parts(self.ptr, self.len, self.cap) + } + + pub unsafe fn write(&mut self, mut vec: Vec) { + if vec.capacity() == 0 { + *self = RustBytes { + ptr: ptr::null_mut(), + len: 0, + cap: 0, + }; + return; + } + self.ptr = vec.as_mut_ptr(); + self.len = vec.len(); + self.cap = vec.capacity(); + std::mem::forget(vec); + } +} + +#[repr(C)] +pub struct ResolvedPreimage { + pub ptr: *mut u8, + pub len: isize, // negative if not found +} From 8dc056e74d8cafd008dd9cc705f28860de529655 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 27 Mar 2026 11:24:39 +0100 Subject: [PATCH 157/189] fmt --- crates/prover-ffi/src/machine.rs | 2 +- crates/prover-ffi/src/preimage.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/prover-ffi/src/machine.rs b/crates/prover-ffi/src/machine.rs index 04c50fb397b..ab99dda1d75 100644 --- a/crates/prover-ffi/src/machine.rs +++ b/crates/prover-ffi/src/machine.rs @@ -2,12 +2,12 @@ // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md use crate::c_strings::{c_string_to_string, err_to_c_string}; +use crate::{CByteArray, RustBytes}; use arbutil::Bytes32; use eyre::Report; use prover::machine::{ argument_data_to_inbox, get_empty_preimage_resolver, GlobalState, MachineStatus, }; -use crate::{CByteArray, RustBytes}; use prover::Machine; use static_assertions::const_assert_eq; use std::ffi::CStr; diff --git a/crates/prover-ffi/src/preimage.rs b/crates/prover-ffi/src/preimage.rs index cdac701e1c4..2ff018be4a0 100644 --- a/crates/prover-ffi/src/preimage.rs +++ b/crates/prover-ffi/src/preimage.rs @@ -1,12 +1,12 @@ // Copyright 2021-2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md +use crate::ResolvedPreimage; use arbutil::{Bytes32, PreimageType}; use lru::LruCache; use once_cell::sync::OnceCell; use prover::machine::PreimageResolver; use prover::utils::{self, CBytes}; -use crate::ResolvedPreimage; use prover::Machine; use std::num::NonZeroUsize; use std::sync::Arc; From 0298c043d3745c1562e63df8939fe4b8eea2f5ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 27 Mar 2026 11:31:57 +0100 Subject: [PATCH 158/189] unnecessary gating --- crates/prover/src/programs/mod.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/crates/prover/src/programs/mod.rs b/crates/prover/src/programs/mod.rs index 095e633b5ee..7df3ae666a4 100644 --- a/crates/prover/src/programs/mod.rs +++ b/crates/prover/src/programs/mod.rs @@ -1,11 +1,8 @@ // Copyright 2022-2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md -#[cfg(feature = "native")] use crate::{machine::Module, programs::config::CompileConfig}; -#[cfg(feature = "native")] use arbutil::{evm::ARBOS_VERSION_STYLUS_CHARGING_FIXES, math::SaturatingSum, Bytes32}; -#[cfg(feature = "native")] use eyre::WrapErr; use crate::{ @@ -417,7 +414,6 @@ impl StylusData { } } -#[cfg(feature = "native")] impl Module { pub fn activate( wasm: &[u8], From 7f423256119c304f9502af8f223f51dc26b8c39a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 27 Mar 2026 11:55:52 +0100 Subject: [PATCH 159/189] include prover-ffi in cbindgen --- crates/stylus/cbindgen.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/stylus/cbindgen.toml b/crates/stylus/cbindgen.toml index 95adfd462bd..33a9630b235 100644 --- a/crates/stylus/cbindgen.toml +++ b/crates/stylus/cbindgen.toml @@ -3,8 +3,8 @@ include_guard = "arbitrator_bindings" [parse] parse_deps = true -include = ["arbutil", "prover", "brotli"] -extra_bindings = ["arbutil", "prover", "brotli"] +include = ["arbutil", "prover", "prover-ffi", "brotli"] +extra_bindings = ["arbutil", "prover", "prover-ffi", "brotli"] [enum] prefix_with_name = true From fd3257fb5d8237128b37ef518d20d5f0ff302a17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 27 Mar 2026 11:56:07 +0100 Subject: [PATCH 160/189] include kzg in prover-ffi --- crates/prover-ffi/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/prover-ffi/Cargo.toml b/crates/prover-ffi/Cargo.toml index 43e3a5bb895..7ea275874b3 100644 --- a/crates/prover-ffi/Cargo.toml +++ b/crates/prover-ffi/Cargo.toml @@ -20,5 +20,5 @@ lazy_static = { workspace = true } libc = { workspace = true } lru = { workspace = true } once_cell = { workspace = true } -prover = { workspace = true, features = ["native", "libc"] } +prover = { workspace = true, features = ["native", "libc", "kzg"] } static_assertions = { workspace = true } From f4387951676d45d9548b9f1ee1ce82a0aeb51727 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 27 Mar 2026 11:58:35 +0100 Subject: [PATCH 161/189] minor fixes --- crates/prover-ffi/src/c_strings.rs | 7 +++++-- crates/prover-ffi/src/machine.rs | 16 +++++++++++----- crates/prover-ffi/src/preimage.rs | 12 ++++++++++-- crates/prover-ffi/src/types.rs | 14 +++++++++++++- crates/prover/src/cbytes.rs | 5 ++++- crates/stylus/src/lib.rs | 1 + 6 files changed, 44 insertions(+), 11 deletions(-) diff --git a/crates/prover-ffi/src/c_strings.rs b/crates/prover-ffi/src/c_strings.rs index edfdb1ad3aa..288a324148c 100644 --- a/crates/prover-ffi/src/c_strings.rs +++ b/crates/prover-ffi/src/c_strings.rs @@ -4,8 +4,11 @@ use eyre::Report; use std::{ffi::CStr, os::raw::c_char, ptr}; -pub unsafe fn c_string_to_string(c_str: *const c_char) -> String { - CStr::from_ptr(c_str).to_string_lossy().into_owned() +pub unsafe fn c_string_to_string(c_str: *const c_char) -> eyre::Result { + CStr::from_ptr(c_str) + .to_str() + .map(str::to_owned) + .map_err(Report::from) } /// Copies the str-data into a libc free-able C string. diff --git a/crates/prover-ffi/src/machine.rs b/crates/prover-ffi/src/machine.rs index ab99dda1d75..7fefd8f5230 100644 --- a/crates/prover-ffi/src/machine.rs +++ b/crates/prover-ffi/src/machine.rs @@ -61,12 +61,12 @@ unsafe fn arbitrator_load_machine_impl( library_paths_size: isize, debug_chain: bool, ) -> eyre::Result<*mut Machine> { - let binary_path = c_string_to_string(binary_path); + let binary_path = c_string_to_string(binary_path)?; let binary_path = Path::new(&binary_path); let mut libraries = vec![]; for i in 0..library_paths_size { - let path = c_string_to_string(*(library_paths.offset(i))); + let path = c_string_to_string(*(library_paths.offset(i)))?; libraries.push(Path::new(&path).to_owned()); } @@ -86,7 +86,13 @@ unsafe fn arbitrator_load_machine_impl( #[no_mangle] pub unsafe extern "C" fn arbitrator_load_wavm_binary(binary_path: *const c_char) -> *mut Machine { - let binary_path = c_string_to_string(binary_path); + let binary_path = match c_string_to_string(binary_path) { + Ok(s) => s, + Err(err) => { + eprintln!("Error decoding binary path: {err}"); + return ptr::null_mut(); + } + }; let binary_path = Path::new(&binary_path); match Machine::new_from_wavm(binary_path) { Ok(mach) => Box::into_raw(Box::new(mach)), @@ -147,11 +153,11 @@ pub unsafe extern "C" fn arbitrator_add_inbox_message( ) -> c_int { let mach = &mut *mach; if let Some(identifier) = argument_data_to_inbox(inbox_identifier) { - let slice = slice::from_raw_parts(data.ptr, data.len); - let data = slice.to_vec(); + let data = data.as_slice().to_vec(); mach.add_inbox_msg(identifier, index, data); 0 } else { + eprintln!("Unknown inbox identifier: {inbox_identifier}"); 1 } } diff --git a/crates/prover-ffi/src/preimage.rs b/crates/prover-ffi/src/preimage.rs index 2ff018be4a0..97515ba41e7 100644 --- a/crates/prover-ffi/src/preimage.rs +++ b/crates/prover-ffi/src/preimage.rs @@ -25,12 +25,20 @@ pub unsafe extern "C" fn arbitrator_set_preimage_resolver( move |context: u64, ty: PreimageType, hash: Bytes32| -> Option { if ty == PreimageType::EthVersionedHash { let cache: Arc> = { - let mut locked = BLOBHASH_PREIMAGE_CACHE.lock().unwrap(); + let mut locked = BLOBHASH_PREIMAGE_CACHE + .lock() + .unwrap_or_else(|e| e.into_inner()); locked.get_or_insert(hash, Default::default).clone() }; return cache .get_or_try_init(|| { - handle_preimage_resolution(context, ty, hash, resolver).ok_or(()) + match handle_preimage_resolution(context, ty, hash, resolver) { + Some(data) => Ok(data), + None => { + eprintln!("Blob preimage resolution failed for hash {hash}"); + Err(()) + } + } }) .ok() .cloned(); diff --git a/crates/prover-ffi/src/types.rs b/crates/prover-ffi/src/types.rs index 7304ec8c10c..09c56f57e9c 100644 --- a/crates/prover-ffi/src/types.rs +++ b/crates/prover-ffi/src/types.rs @@ -10,11 +10,20 @@ pub struct CByteArray { pub len: usize, } +impl CByteArray { + pub unsafe fn as_slice(&self) -> &[u8] { + if self.ptr.is_null() { + return &[]; + } + std::slice::from_raw_parts(self.ptr, self.len) + } +} + #[repr(C)] pub struct RustSlice<'a> { pub ptr: *const u8, pub len: usize, - pub phantom: PhantomData<&'a [u8]>, + phantom: PhantomData<&'a [u8]>, } impl<'a> RustSlice<'a> { @@ -43,6 +52,9 @@ pub struct RustBytes { impl RustBytes { pub unsafe fn into_vec(self) -> Vec { + if self.ptr.is_null() { + return Vec::new(); + } Vec::from_raw_parts(self.ptr, self.len, self.cap) } diff --git a/crates/prover/src/cbytes.rs b/crates/prover/src/cbytes.rs index 2a64c6ecda9..f9e0edba65e 100644 --- a/crates/prover/src/cbytes.rs +++ b/crates/prover/src/cbytes.rs @@ -25,6 +25,9 @@ mod libc_cbytes { } pub fn as_slice(&self) -> &[u8] { + if self.ptr.is_null() { + return &[]; + } unsafe { std::slice::from_raw_parts(self.ptr, self.len) } } @@ -78,7 +81,7 @@ mod libc_cbytes { impl Drop for CBytes { fn drop(&mut self) { - if !self.ptr.is_null() && self.len > 0 { + if !self.ptr.is_null() { unsafe { libc::free(self.ptr as *mut _); } diff --git a/crates/stylus/src/lib.rs b/crates/stylus/src/lib.rs index 3e86900af25..141f00074fa 100644 --- a/crates/stylus/src/lib.rs +++ b/crates/stylus/src/lib.rs @@ -23,6 +23,7 @@ use target_cache::{target_cache_get, target_cache_set}; pub use brotli; pub use prover; +// This re-export is required to pull prover_ffi's #[no_mangle] FFI symbols into the staticlib output. pub use prover_ffi; pub mod env; From da0f95758743bc5537c83e506ac30e29c4226271 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 27 Mar 2026 14:25:48 +0100 Subject: [PATCH 162/189] catch nil pointer --- crates/prover-ffi/src/c_strings.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crates/prover-ffi/src/c_strings.rs b/crates/prover-ffi/src/c_strings.rs index 288a324148c..9f6a9ec4029 100644 --- a/crates/prover-ffi/src/c_strings.rs +++ b/crates/prover-ffi/src/c_strings.rs @@ -5,6 +5,9 @@ use eyre::Report; use std::{ffi::CStr, os::raw::c_char, ptr}; pub unsafe fn c_string_to_string(c_str: *const c_char) -> eyre::Result { + if c_str.is_null() { + eyre::bail!("unexpected null string pointer"); + } CStr::from_ptr(c_str) .to_str() .map(str::to_owned) From 8627f6b5c574526595c200e27a1d16ebe3d2a03e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 27 Mar 2026 14:44:58 +0100 Subject: [PATCH 163/189] Inherit workspace properties --- crates/sp1/stylus-compiler-program/Cargo.toml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/crates/sp1/stylus-compiler-program/Cargo.toml b/crates/sp1/stylus-compiler-program/Cargo.toml index 7f37fe1c91b..5dd3f8a5caf 100644 --- a/crates/sp1/stylus-compiler-program/Cargo.toml +++ b/crates/sp1/stylus-compiler-program/Cargo.toml @@ -3,6 +3,12 @@ name = "stylus-compiler-program" description = "SP1 program wrapping wasmer singlepass compiler for provable compilation" version = "0.1.0" edition = "2024" +authors.workspace = true +homepage.workspace = true +license.workspace = true +publish.workspace = true +repository.workspace = true +rust-version.workspace = true [dependencies] sp1-zkvm = { workspace = true } From b0809de32bf62346d79fd20679ce283c42651967 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 27 Mar 2026 14:49:12 +0100 Subject: [PATCH 164/189] Split the code to lib and bin --- crates/sp1/stylus-compiler-program/src/lib.rs | 42 +++++++++++++++++++ .../sp1/stylus-compiler-program/src/main.rs | 39 +---------------- 2 files changed, 44 insertions(+), 37 deletions(-) create mode 100644 crates/sp1/stylus-compiler-program/src/lib.rs diff --git a/crates/sp1/stylus-compiler-program/src/lib.rs b/crates/sp1/stylus-compiler-program/src/lib.rs new file mode 100644 index 00000000000..88979191340 --- /dev/null +++ b/crates/sp1/stylus-compiler-program/src/lib.rs @@ -0,0 +1,42 @@ +use prover::programs::{ + MiddlewareWrapper, config::CompileConfig, depth::DepthChecker, dynamic::DynamicMeter, + heap::HeapBound, meter::Meter, start::StartMover, +}; +use std::str::FromStr; +use std::sync::Arc; +use wasmer::{ + Module, Store, + sys::{CompilerConfig, CpuFeature, EngineBuilder, Singlepass, Target, Triple}, +}; + +/// Compiles a Stylus WASM program to a rv64 binary using the wasmer singlepass compiler. +/// +/// Applies the same middleware stack used in the standard Stylus compilation pipeline: +/// `StartMover`, `Meter`, `DynamicMeter`, `DepthChecker`, and `HeapBound`. +pub fn compile(version: u16, debug: bool, wasm: &[u8]) -> Vec { + let compile_config = CompileConfig::version(version, debug); + let mut config = Singlepass::new(); + config.canonicalize_nans(true); + config.enable_verifier(); + + let start = MiddlewareWrapper::new(StartMover::new(compile_config.debug.debug_info)); + let meter = MiddlewareWrapper::new(Meter::new(&compile_config.pricing)); + let dygas = MiddlewareWrapper::new(DynamicMeter::new(&compile_config.pricing)); + let depth = MiddlewareWrapper::new(DepthChecker::new(compile_config.bounds)); + let bound = MiddlewareWrapper::new(HeapBound::new(compile_config.bounds)); + + config.push_middleware(Arc::new(start)); + config.push_middleware(Arc::new(meter)); + config.push_middleware(Arc::new(dygas)); + config.push_middleware(Arc::new(depth)); + config.push_middleware(Arc::new(bound)); + + let triple = Triple::from_str("riscv64").expect("target triple"); + let engine = EngineBuilder::new(config) + .set_target(Some(Target::new(triple, CpuFeature::set()))) + .engine(); + + let store = Store::new(engine); + let module = Module::new(&store, wasm).expect("compilation failed"); + module.serialize().expect("serialize module").to_vec() +} diff --git a/crates/sp1/stylus-compiler-program/src/main.rs b/crates/sp1/stylus-compiler-program/src/main.rs index a47f7d2c26e..3af15892d37 100644 --- a/crates/sp1/stylus-compiler-program/src/main.rs +++ b/crates/sp1/stylus-compiler-program/src/main.rs @@ -3,49 +3,14 @@ #[cfg(target_os = "zkvm")] sp1_zkvm::entrypoint!(main); -use prover::programs::{ - MiddlewareWrapper, config::CompileConfig, depth::DepthChecker, dynamic::DynamicMeter, - heap::HeapBound, meter::Meter, start::StartMover, -}; -use std::str::FromStr; -use std::sync::Arc; -use wasmer::{ - Module, Store, - sys::{CompilerConfig, CpuFeature, EngineBuilder, Singlepass, Target, Triple}, -}; - fn main() { let version = sp1_zkvm::io::read::(); let debug = sp1_zkvm::io::read::(); let wasm = sp1_zkvm::io::read::>(); - let compile_config = CompileConfig::version(version, debug); - let mut config = Singlepass::new(); - config.canonicalize_nans(true); - config.enable_verifier(); - - let start = MiddlewareWrapper::new(StartMover::new(compile_config.debug.debug_info)); - let meter = MiddlewareWrapper::new(Meter::new(&compile_config.pricing)); - let dygas = MiddlewareWrapper::new(DynamicMeter::new(&compile_config.pricing)); - let depth = MiddlewareWrapper::new(DepthChecker::new(compile_config.bounds)); - let bound = MiddlewareWrapper::new(HeapBound::new(compile_config.bounds)); - - config.push_middleware(Arc::new(start)); - config.push_middleware(Arc::new(meter)); - config.push_middleware(Arc::new(dygas)); - config.push_middleware(Arc::new(depth)); - config.push_middleware(Arc::new(bound)); - - let triple = Triple::from_str("riscv64").expect("target triple"); - let engine = EngineBuilder::new(config) - .set_target(Some(Target::new(triple, CpuFeature::set()))) - .engine(); - - let store = Store::new(engine); - let module = Module::new(&store, wasm).expect("compilation failed"); - let rv64_binary = module.serialize().expect("serialize module"); + let rv64_binary = stylus_compiler_program::compile(version, debug, &wasm); - sp1_zkvm::io::commit(&rv64_binary.to_vec()); + sp1_zkvm::io::commit(&rv64_binary); } // Those are referenced by wasmer runtimes, but are never invoked From 3e6b2ce91a2b8a458a805a44ce8e453abf5decd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 27 Mar 2026 14:56:01 +0100 Subject: [PATCH 165/189] Do not unwrap errors in lib --- Cargo.lock | 1 + crates/sp1/stylus-compiler-program/Cargo.toml | 1 + crates/sp1/stylus-compiler-program/src/lib.rs | 11 +++++++---- crates/sp1/stylus-compiler-program/src/main.rs | 3 ++- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3bab50d9239..38679590220 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7825,6 +7825,7 @@ dependencies = [ name = "stylus-compiler-program" version = "0.1.0" dependencies = [ + "anyhow", "prover", "sp1-zkvm", "wasmer", diff --git a/crates/sp1/stylus-compiler-program/Cargo.toml b/crates/sp1/stylus-compiler-program/Cargo.toml index 5dd3f8a5caf..db200dd00ba 100644 --- a/crates/sp1/stylus-compiler-program/Cargo.toml +++ b/crates/sp1/stylus-compiler-program/Cargo.toml @@ -11,6 +11,7 @@ repository.workspace = true rust-version.workspace = true [dependencies] +anyhow = { workspace = true } sp1-zkvm = { workspace = true } wasmer = { workspace = true, features = ["sys", "compiler", "singlepass"] } prover = { workspace = true, features = ["sp1", "native"] } diff --git a/crates/sp1/stylus-compiler-program/src/lib.rs b/crates/sp1/stylus-compiler-program/src/lib.rs index 88979191340..b1105ada8a1 100644 --- a/crates/sp1/stylus-compiler-program/src/lib.rs +++ b/crates/sp1/stylus-compiler-program/src/lib.rs @@ -1,3 +1,4 @@ +use anyhow::{Context, Result}; use prover::programs::{ MiddlewareWrapper, config::CompileConfig, depth::DepthChecker, dynamic::DynamicMeter, heap::HeapBound, meter::Meter, start::StartMover, @@ -13,7 +14,7 @@ use wasmer::{ /// /// Applies the same middleware stack used in the standard Stylus compilation pipeline: /// `StartMover`, `Meter`, `DynamicMeter`, `DepthChecker`, and `HeapBound`. -pub fn compile(version: u16, debug: bool, wasm: &[u8]) -> Vec { +pub fn compile(version: u16, debug: bool, wasm: &[u8]) -> Result> { let compile_config = CompileConfig::version(version, debug); let mut config = Singlepass::new(); config.canonicalize_nans(true); @@ -31,12 +32,14 @@ pub fn compile(version: u16, debug: bool, wasm: &[u8]) -> Vec { config.push_middleware(Arc::new(depth)); config.push_middleware(Arc::new(bound)); - let triple = Triple::from_str("riscv64").expect("target triple"); + let triple = Triple::from_str("riscv64") + .map_err(|e| anyhow::anyhow!("invalid target triple: {e}"))?; let engine = EngineBuilder::new(config) .set_target(Some(Target::new(triple, CpuFeature::set()))) .engine(); let store = Store::new(engine); - let module = Module::new(&store, wasm).expect("compilation failed"); - module.serialize().expect("serialize module").to_vec() + let module = Module::new(&store, wasm).context("wasm compilation failed")?; + let rv64_binary = module.serialize().context("module serialization failed")?; + Ok(rv64_binary.to_vec()) } diff --git a/crates/sp1/stylus-compiler-program/src/main.rs b/crates/sp1/stylus-compiler-program/src/main.rs index 3af15892d37..88701472f06 100644 --- a/crates/sp1/stylus-compiler-program/src/main.rs +++ b/crates/sp1/stylus-compiler-program/src/main.rs @@ -8,7 +8,8 @@ fn main() { let debug = sp1_zkvm::io::read::(); let wasm = sp1_zkvm::io::read::>(); - let rv64_binary = stylus_compiler_program::compile(version, debug, &wasm); + let rv64_binary = stylus_compiler_program::compile(version, debug, &wasm) + .expect("stylus compilation failed"); sp1_zkvm::io::commit(&rv64_binary); } From 20bc6491b3616bcb2895a0c40c1fbfd4de6e1bb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 27 Mar 2026 14:56:29 +0100 Subject: [PATCH 166/189] todo -> unreachable --- crates/sp1/stylus-compiler-program/src/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/sp1/stylus-compiler-program/src/main.rs b/crates/sp1/stylus-compiler-program/src/main.rs index 88701472f06..672da849ed8 100644 --- a/crates/sp1/stylus-compiler-program/src/main.rs +++ b/crates/sp1/stylus-compiler-program/src/main.rs @@ -17,10 +17,10 @@ fn main() { // Those are referenced by wasmer runtimes, but are never invoked #[unsafe(no_mangle)] pub extern "C" fn __negdf2(_x: f64) -> f64 { - todo!() + unreachable!() } #[unsafe(no_mangle)] pub extern "C" fn __negsf2(_x: f32) -> f32 { - todo!() + unreachable!() } From 92e92e4d9671d9dbad403c91d5396b5fc115b9a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 27 Mar 2026 15:19:26 +0100 Subject: [PATCH 167/189] Add new crate --- Cargo.lock | 4 ++++ Cargo.toml | 1 + crates/sp1/stylus-compiler-runner/Cargo.toml | 16 ++++++++++++++++ crates/sp1/stylus-compiler-runner/main.rs | 3 +++ 4 files changed, 24 insertions(+) create mode 100644 crates/sp1/stylus-compiler-runner/Cargo.toml create mode 100644 crates/sp1/stylus-compiler-runner/main.rs diff --git a/Cargo.lock b/Cargo.lock index 38679590220..7fa65b1f267 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7831,6 +7831,10 @@ dependencies = [ "wasmer", ] +[[package]] +name = "stylus-compiler-runner" +version = "0.1.0" + [[package]] name = "subenum" version = "1.1.3" diff --git a/Cargo.toml b/Cargo.toml index 2b1ecdbf80d..6b1b2862427 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,7 @@ members = [ "crates/sp1/program", "crates/sp1/runner", "crates/sp1/stylus-compiler-program", + "crates/sp1/stylus-compiler-runner", ] default-members = [ "crates/jit", diff --git a/crates/sp1/stylus-compiler-runner/Cargo.toml b/crates/sp1/stylus-compiler-runner/Cargo.toml new file mode 100644 index 00000000000..ca02b7f2fbc --- /dev/null +++ b/crates/sp1/stylus-compiler-runner/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "stylus-compiler-runner" +version = "0.1.0" +authors.workspace = true +edition.workspace = true +homepage.workspace = true +license.workspace = true +publish.workspace = true +repository.workspace = true +rust-version.workspace = true + +[[bin]] +name = "stylus-compiler-runner" +path = "main.rs" + +[dependencies] diff --git a/crates/sp1/stylus-compiler-runner/main.rs b/crates/sp1/stylus-compiler-runner/main.rs new file mode 100644 index 00000000000..e7a11a969c0 --- /dev/null +++ b/crates/sp1/stylus-compiler-runner/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} From 81e5a92db3c9216fd1898752de2462d41d12db9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 27 Mar 2026 15:43:56 +0100 Subject: [PATCH 168/189] Add build.rs --- Cargo.lock | 4 ++++ Cargo.toml | 1 + crates/sp1/stylus-compiler-runner/Cargo.toml | 4 ++++ crates/sp1/stylus-compiler-runner/build.rs | 5 +++++ 4 files changed, 14 insertions(+) create mode 100644 crates/sp1/stylus-compiler-runner/build.rs diff --git a/Cargo.lock b/Cargo.lock index 7fa65b1f267..6b7e9dc0427 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7834,6 +7834,10 @@ dependencies = [ [[package]] name = "stylus-compiler-runner" version = "0.1.0" +dependencies = [ + "sp1-build", + "stylus-compiler-program", +] [[package]] name = "subenum" diff --git a/Cargo.toml b/Cargo.toml index 6b1b2862427..001cf748bc3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -114,6 +114,7 @@ forward = { path = "crates/wasm-libraries/forward" } jit = { path = "crates/jit" } prover = { path = "crates/prover", default-features = false } stylus = { path = "crates/stylus", default-features = false } +stylus-compiler-program = { path = "crates/sp1/stylus-compiler-program" } user-host-trait = { path = "crates/wasm-libraries/user-host-trait" } validation = { path = "crates/validation" } diff --git a/crates/sp1/stylus-compiler-runner/Cargo.toml b/crates/sp1/stylus-compiler-runner/Cargo.toml index ca02b7f2fbc..616c7877a9c 100644 --- a/crates/sp1/stylus-compiler-runner/Cargo.toml +++ b/crates/sp1/stylus-compiler-runner/Cargo.toml @@ -14,3 +14,7 @@ name = "stylus-compiler-runner" path = "main.rs" [dependencies] +stylus-compiler-program = { workspace = true } + +[build-dependencies] +sp1-build = { workspace = true } diff --git a/crates/sp1/stylus-compiler-runner/build.rs b/crates/sp1/stylus-compiler-runner/build.rs new file mode 100644 index 00000000000..fe835dd2e63 --- /dev/null +++ b/crates/sp1/stylus-compiler-runner/build.rs @@ -0,0 +1,5 @@ +use sp1_build::build_program_with_args; + +fn main() { + build_program_with_args("../stylus-compiler-program", Default::default()) +} From 1b42a11b08c92ebe9b00f34cde54207eb123d8dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 27 Mar 2026 15:51:35 +0100 Subject: [PATCH 169/189] Add the commands --- Cargo.lock | 1 + crates/sp1/stylus-compiler-runner/Cargo.toml | 1 + crates/sp1/stylus-compiler-runner/main.rs | 46 +++++++++++++++++++- 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 6b7e9dc0427..b05d1751911 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7835,6 +7835,7 @@ dependencies = [ name = "stylus-compiler-runner" version = "0.1.0" dependencies = [ + "clap 4.5.53", "sp1-build", "stylus-compiler-program", ] diff --git a/crates/sp1/stylus-compiler-runner/Cargo.toml b/crates/sp1/stylus-compiler-runner/Cargo.toml index 616c7877a9c..a29cba6bb77 100644 --- a/crates/sp1/stylus-compiler-runner/Cargo.toml +++ b/crates/sp1/stylus-compiler-runner/Cargo.toml @@ -14,6 +14,7 @@ name = "stylus-compiler-runner" path = "main.rs" [dependencies] +clap = { workspace = true, features = ["derive"] } stylus-compiler-program = { workspace = true } [build-dependencies] diff --git a/crates/sp1/stylus-compiler-runner/main.rs b/crates/sp1/stylus-compiler-runner/main.rs index e7a11a969c0..67603596c0d 100644 --- a/crates/sp1/stylus-compiler-runner/main.rs +++ b/crates/sp1/stylus-compiler-runner/main.rs @@ -1,3 +1,47 @@ +use clap::{Parser, Subcommand}; +use std::path::PathBuf; + +#[derive(Parser)] +#[command(version, about = "Run the Stylus WASM compiler in various execution modes")] +struct Cli { + #[command(subcommand)] + command: Command, + + /// Path to the Stylus WASM binary to compile. + wasm: PathBuf, +} + +#[derive(Subcommand)] +enum Command { + /// Compile the WASM natively using the host Stylus compiler. + /// + /// Uses the same wasmer singlepass pipeline as the SP1 program, but runs + /// directly on the host without any zkVM overhead. Useful for quick + /// iteration and as a reference output for comparison. + Native, + + /// Compile the WASM inside SP1 in fast execution mode (no proof). + /// + /// Runs the stylus-compiler-program ELF through SP1's MinimalExecutor. + /// Fast and lightweight — validates that the SP1 program executes correctly + /// without the cost of proof generation. + Execute, + + /// Compile the WASM inside SP1 and generate a validity proof. + /// + /// Runs the stylus-compiler-program ELF through the full SP1 prover, + /// producing a proof that the compilation was executed correctly. + /// Slower than `execute` but provides cryptographic guarantees. + Prove, + + /// Compile natively and via SP1, then assert the outputs match. + /// + /// Runs both `native` and `execute` and compares the resulting rv64 + /// binaries byte-for-byte. Useful for verifying that the SP1 program + /// faithfully reproduces the native compilation result. + Compare, +} + fn main() { - println!("Hello, world!"); + let _cli = Cli::parse(); } From 68ccbaaca5d427075bb66fa1b91d6576c5829ff2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 27 Mar 2026 16:20:43 +0100 Subject: [PATCH 170/189] Add input struct --- Cargo.lock | 3 +++ crates/sp1/stylus-compiler-program/Cargo.toml | 1 + crates/sp1/stylus-compiler-program/src/lib.rs | 15 ++++++++++++--- crates/sp1/stylus-compiler-program/src/main.rs | 8 ++------ 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b05d1751911..b31619d6e1b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7827,6 +7827,7 @@ version = "0.1.0" dependencies = [ "anyhow", "prover", + "serde", "sp1-zkvm", "wasmer", ] @@ -7837,7 +7838,9 @@ version = "0.1.0" dependencies = [ "clap 4.5.53", "sp1-build", + "sp1-sdk", "stylus-compiler-program", + "tracing", ] [[package]] diff --git a/crates/sp1/stylus-compiler-program/Cargo.toml b/crates/sp1/stylus-compiler-program/Cargo.toml index db200dd00ba..3704cc6db86 100644 --- a/crates/sp1/stylus-compiler-program/Cargo.toml +++ b/crates/sp1/stylus-compiler-program/Cargo.toml @@ -12,6 +12,7 @@ rust-version.workspace = true [dependencies] anyhow = { workspace = true } +serde = { workspace = true, features = ["derive"] } sp1-zkvm = { workspace = true } wasmer = { workspace = true, features = ["sys", "compiler", "singlepass"] } prover = { workspace = true, features = ["sp1", "native"] } diff --git a/crates/sp1/stylus-compiler-program/src/lib.rs b/crates/sp1/stylus-compiler-program/src/lib.rs index b1105ada8a1..655bb0d8ed7 100644 --- a/crates/sp1/stylus-compiler-program/src/lib.rs +++ b/crates/sp1/stylus-compiler-program/src/lib.rs @@ -3,6 +3,7 @@ use prover::programs::{ MiddlewareWrapper, config::CompileConfig, depth::DepthChecker, dynamic::DynamicMeter, heap::HeapBound, meter::Meter, start::StartMover, }; +use serde::{Deserialize, Serialize}; use std::str::FromStr; use std::sync::Arc; use wasmer::{ @@ -10,12 +11,20 @@ use wasmer::{ sys::{CompilerConfig, CpuFeature, EngineBuilder, Singlepass, Target, Triple}, }; +/// Input parameters for Stylus WASM compilation. +#[derive(Serialize, Deserialize)] +pub struct CompileInput { + pub version: u16, + pub debug: bool, + pub wasm: Vec, +} + /// Compiles a Stylus WASM program to a rv64 binary using the wasmer singlepass compiler. /// /// Applies the same middleware stack used in the standard Stylus compilation pipeline: /// `StartMover`, `Meter`, `DynamicMeter`, `DepthChecker`, and `HeapBound`. -pub fn compile(version: u16, debug: bool, wasm: &[u8]) -> Result> { - let compile_config = CompileConfig::version(version, debug); +pub fn compile(input: &CompileInput) -> Result> { + let compile_config = CompileConfig::version(input.version, input.debug); let mut config = Singlepass::new(); config.canonicalize_nans(true); config.enable_verifier(); @@ -39,7 +48,7 @@ pub fn compile(version: u16, debug: bool, wasm: &[u8]) -> Result> { .engine(); let store = Store::new(engine); - let module = Module::new(&store, wasm).context("wasm compilation failed")?; + let module = Module::new(&store, &input.wasm).context("wasm compilation failed")?; let rv64_binary = module.serialize().context("module serialization failed")?; Ok(rv64_binary.to_vec()) } diff --git a/crates/sp1/stylus-compiler-program/src/main.rs b/crates/sp1/stylus-compiler-program/src/main.rs index 672da849ed8..21f5db52d6f 100644 --- a/crates/sp1/stylus-compiler-program/src/main.rs +++ b/crates/sp1/stylus-compiler-program/src/main.rs @@ -4,13 +4,9 @@ sp1_zkvm::entrypoint!(main); fn main() { - let version = sp1_zkvm::io::read::(); - let debug = sp1_zkvm::io::read::(); - let wasm = sp1_zkvm::io::read::>(); - - let rv64_binary = stylus_compiler_program::compile(version, debug, &wasm) + let input = sp1_zkvm::io::read::(); + let rv64_binary = stylus_compiler_program::compile(&input) .expect("stylus compilation failed"); - sp1_zkvm::io::commit(&rv64_binary); } From 7fa8ff75486ead66471e997fc7e8d75ab1b9e9a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 27 Mar 2026 16:20:55 +0100 Subject: [PATCH 171/189] Add implementation for the commands --- crates/sp1/stylus-compiler-runner/Cargo.toml | 2 + crates/sp1/stylus-compiler-runner/main.rs | 74 +++++++++++++++++++- 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/crates/sp1/stylus-compiler-runner/Cargo.toml b/crates/sp1/stylus-compiler-runner/Cargo.toml index a29cba6bb77..3111c5674be 100644 --- a/crates/sp1/stylus-compiler-runner/Cargo.toml +++ b/crates/sp1/stylus-compiler-runner/Cargo.toml @@ -15,7 +15,9 @@ path = "main.rs" [dependencies] clap = { workspace = true, features = ["derive"] } +sp1-sdk = { workspace = true, features = ["blocking"] } stylus-compiler-program = { workspace = true } +tracing = { workspace = true } [build-dependencies] sp1-build = { workspace = true } diff --git a/crates/sp1/stylus-compiler-runner/main.rs b/crates/sp1/stylus-compiler-runner/main.rs index 67603596c0d..7ad171eec10 100644 --- a/crates/sp1/stylus-compiler-runner/main.rs +++ b/crates/sp1/stylus-compiler-runner/main.rs @@ -1,5 +1,16 @@ use clap::{Parser, Subcommand}; +use sp1_sdk::{ + blocking::{Prover, ProverClient}, + include_elf, + Elf, + ProvingKey, + SP1Stdin, + blocking::ProveRequest +}; use std::path::PathBuf; +use stylus_compiler_program::{compile, CompileInput}; + +const COMPILER_ELF: Elf = include_elf!("stylus-compiler-program"); #[derive(Parser)] #[command(version, about = "Run the Stylus WASM compiler in various execution modes")] @@ -9,6 +20,14 @@ struct Cli { /// Path to the Stylus WASM binary to compile. wasm: PathBuf, + + /// Arbitrum version passed to the Stylus compiler. + #[arg(long, default_value_t = 2)] + version: u16, + + /// Enable debug compilation mode. + #[arg(long)] + debug: bool, } #[derive(Subcommand)] @@ -43,5 +62,58 @@ enum Command { } fn main() { - let _cli = Cli::parse(); + sp1_sdk::utils::setup_logger(); + + let cli = Cli::parse(); + let wasm = std::fs::read(&cli.wasm).expect("failed to read wasm file"); + let input = CompileInput { version: cli.version, debug: cli.debug, wasm }; + + match cli.command { + Command::Native => { + let binary = compile(&input).expect("native compilation failed"); + tracing::info!("compiled successfully, output size: {} bytes", binary.len()); + } + Command::Execute => { + let binary = sp1_execute(&input); + tracing::info!("SP1 execution completed, output size: {} bytes", binary.len()); + } + Command::Prove => sp1_prove(&input), + Command::Compare => { + let native = compile(&input).expect("native compilation failed"); + let sp1 = sp1_execute(&input); + assert_eq!(native, sp1, "native and SP1 outputs differ"); + tracing::info!("outputs match ({} bytes)", native.len()); + } + } +} + +fn build_stdin(input: &CompileInput) -> SP1Stdin { + let mut stdin = SP1Stdin::new(); + stdin.write(input); + stdin +} + +fn sp1_execute(input: &CompileInput) -> Vec { + let client = ProverClient::from_env(); + let stdin = build_stdin(input); + let (mut output, report) = client + .execute(COMPILER_ELF, stdin) + .run() + .expect("SP1 execution failed"); + tracing::info!("cycles: {}", report.total_instruction_count()); + output.read::>() +} + +fn sp1_prove(input: &CompileInput) { + let client = ProverClient::from_env(); + let stdin = build_stdin(input); + let pk = client.setup(COMPILER_ELF).expect("failed to setup ELF"); + let proof = client + .prove(&pk, stdin) + .run() + .expect("failed to generate proof"); + client + .verify(&proof, pk.verifying_key(), None) + .expect("failed to verify proof"); + tracing::info!("proof generated and verified successfully"); } From f73630083978de3e3575e2083ff61102b85dc380 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 27 Mar 2026 16:25:30 +0100 Subject: [PATCH 172/189] deserialize output --- Cargo.lock | 1 + crates/sp1/stylus-compiler-runner/Cargo.toml | 1 + crates/sp1/stylus-compiler-runner/main.rs | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index b31619d6e1b..cea4f5a354c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7836,6 +7836,7 @@ dependencies = [ name = "stylus-compiler-runner" version = "0.1.0" dependencies = [ + "bincode", "clap 4.5.53", "sp1-build", "sp1-sdk", diff --git a/crates/sp1/stylus-compiler-runner/Cargo.toml b/crates/sp1/stylus-compiler-runner/Cargo.toml index 3111c5674be..73db6d2d6f5 100644 --- a/crates/sp1/stylus-compiler-runner/Cargo.toml +++ b/crates/sp1/stylus-compiler-runner/Cargo.toml @@ -14,6 +14,7 @@ name = "stylus-compiler-runner" path = "main.rs" [dependencies] +bincode = { workspace = true } clap = { workspace = true, features = ["derive"] } sp1-sdk = { workspace = true, features = ["blocking"] } stylus-compiler-program = { workspace = true } diff --git a/crates/sp1/stylus-compiler-runner/main.rs b/crates/sp1/stylus-compiler-runner/main.rs index 7ad171eec10..fc7083fe168 100644 --- a/crates/sp1/stylus-compiler-runner/main.rs +++ b/crates/sp1/stylus-compiler-runner/main.rs @@ -101,7 +101,7 @@ fn sp1_execute(input: &CompileInput) -> Vec { .run() .expect("SP1 execution failed"); tracing::info!("cycles: {}", report.total_instruction_count()); - output.read::>() + bincode::deserialize(output.as_slice()).expect("deserialize output") } fn sp1_prove(input: &CompileInput) { From 383c9ed0d3f5bf8b660d9cc5c51249b457905a8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 27 Mar 2026 16:52:07 +0100 Subject: [PATCH 173/189] Add sample wasm --- .../stylus-compiler-runner/testdata/memory.wasm | Bin 0 -> 219 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 crates/sp1/stylus-compiler-runner/testdata/memory.wasm diff --git a/crates/sp1/stylus-compiler-runner/testdata/memory.wasm b/crates/sp1/stylus-compiler-runner/testdata/memory.wasm new file mode 100644 index 0000000000000000000000000000000000000000..6815d2475a9f21a872a3af78459089d4f4fd4b49 GIT binary patch literal 219 zcmYj}&1wQM7)9^>qWy6y3f+}1;sdyKJCltl(r1VRrqdli|*Rs zHKfy53mT#H`y{`4|0<(X3hKk5)$SN~hZg4U?^-Zea8Ah%V>(QM2_1hSrm|Av({k0T bEKBSsQdp_*Qo?dMMBz|kCU9^Zi$ie*Xg4yJ literal 0 HcmV?d00001 From 4483104186ee2f11af493438ec0d6828594b5bfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 27 Mar 2026 16:52:59 +0100 Subject: [PATCH 174/189] Make it the default --- crates/sp1/stylus-compiler-runner/main.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/sp1/stylus-compiler-runner/main.rs b/crates/sp1/stylus-compiler-runner/main.rs index fc7083fe168..fd1bfd860a2 100644 --- a/crates/sp1/stylus-compiler-runner/main.rs +++ b/crates/sp1/stylus-compiler-runner/main.rs @@ -19,6 +19,7 @@ struct Cli { command: Command, /// Path to the Stylus WASM binary to compile. + #[arg(default_value = "testdata/memory.wasm")] wasm: PathBuf, /// Arbitrum version passed to the Stylus compiler. From 3b2592f9906e69943b2bb26fec8e888bf9dd1302 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 27 Mar 2026 17:07:54 +0100 Subject: [PATCH 175/189] minor fixes --- crates/sp1/stylus-compiler-runner/main.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/sp1/stylus-compiler-runner/main.rs b/crates/sp1/stylus-compiler-runner/main.rs index fd1bfd860a2..a938385ba02 100644 --- a/crates/sp1/stylus-compiler-runner/main.rs +++ b/crates/sp1/stylus-compiler-runner/main.rs @@ -13,13 +13,13 @@ use stylus_compiler_program::{compile, CompileInput}; const COMPILER_ELF: Elf = include_elf!("stylus-compiler-program"); #[derive(Parser)] -#[command(version, about = "Run the Stylus WASM compiler in various execution modes")] +#[command(about = "Run the Stylus WASM compiler in various execution modes")] struct Cli { #[command(subcommand)] command: Command, /// Path to the Stylus WASM binary to compile. - #[arg(default_value = "testdata/memory.wasm")] + #[arg(default_value = "crates/sp1/stylus-compiler-runner/testdata/memory.wasm")] wasm: PathBuf, /// Arbitrum version passed to the Stylus compiler. @@ -97,7 +97,7 @@ fn build_stdin(input: &CompileInput) -> SP1Stdin { fn sp1_execute(input: &CompileInput) -> Vec { let client = ProverClient::from_env(); let stdin = build_stdin(input); - let (mut output, report) = client + let (output, report) = client .execute(COMPILER_ELF, stdin) .run() .expect("SP1 execution failed"); From e4974a8ecdbd5612ba433c93f66b06dde29956f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 27 Mar 2026 17:13:35 +0100 Subject: [PATCH 176/189] CI --- .github/workflows/_rust-tests.yml | 7 ++++++- .github/workflows/zk-proving.yml | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.github/workflows/_rust-tests.yml b/.github/workflows/_rust-tests.yml index d0be3131445..dd85769bd86 100644 --- a/.github/workflows/_rust-tests.yml +++ b/.github/workflows/_rust-tests.yml @@ -56,7 +56,7 @@ jobs: run: make build-replay-env - name: Clippy check (non-SP1) - run: cargo clippy --workspace --exclude program --exclude sp1-builder --exclude sp1-runner --exclude stylus-compiler-program -- -D warnings -A static_mut_refs + run: cargo clippy --workspace --exclude program --exclude sp1-builder --exclude sp1-runner --exclude stylus-compiler-program --exclude stylus-compiler-runner -- -D warnings -A static_mut_refs - name: Run rust tests id: run-rust-tests @@ -78,6 +78,11 @@ jobs: echo "Rust tests failed. Failing the workflow as required." exit 1 + - name: Run stylus-compiler-runner compare + env: + SP1_PROVER: local + run: cargo run -p stylus-compiler-runner --release -- compare + - name: Check stylus_bechmark run: cargo check --manifest-path crates/tools/stylus_benchmark/Cargo.toml diff --git a/.github/workflows/zk-proving.yml b/.github/workflows/zk-proving.yml index c627c4085c4..e6415354fef 100644 --- a/.github/workflows/zk-proving.yml +++ b/.github/workflows/zk-proving.yml @@ -50,7 +50,12 @@ jobs: # Clippy runs after build because sp1-builder uses include_elf!(), # which requires the SP1 ELF to exist at compile time. - name: Clippy check (SP1) - run: cargo clippy -p program -p sp1-builder -p sp1-runner -p stylus-compiler-program -- -D warnings -A static_mut_refs -A clippy::too_many_arguments + run: cargo clippy -p program -p sp1-builder -p sp1-runner -p stylus-compiler-program -p stylus-compiler-runner -- -D warnings -A static_mut_refs -A clippy::too_many_arguments + + - name: Run stylus-compiler-runner compare + env: + SP1_PROVER: local + run: cargo run -p stylus-compiler-runner --release -- compare - name: Run validation run: | From d6cc62a786a2896b56c20e060f566d29a34cc7cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 27 Mar 2026 17:13:44 +0100 Subject: [PATCH 177/189] fmt --- crates/sp1/stylus-compiler-program/src/lib.rs | 4 ++-- crates/sp1/stylus-compiler-program/src/main.rs | 3 +-- crates/sp1/stylus-compiler-runner/main.rs | 18 +++++++++++------- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/crates/sp1/stylus-compiler-program/src/lib.rs b/crates/sp1/stylus-compiler-program/src/lib.rs index 655bb0d8ed7..91f7b4f8f88 100644 --- a/crates/sp1/stylus-compiler-program/src/lib.rs +++ b/crates/sp1/stylus-compiler-program/src/lib.rs @@ -41,8 +41,8 @@ pub fn compile(input: &CompileInput) -> Result> { config.push_middleware(Arc::new(depth)); config.push_middleware(Arc::new(bound)); - let triple = Triple::from_str("riscv64") - .map_err(|e| anyhow::anyhow!("invalid target triple: {e}"))?; + let triple = + Triple::from_str("riscv64").map_err(|e| anyhow::anyhow!("invalid target triple: {e}"))?; let engine = EngineBuilder::new(config) .set_target(Some(Target::new(triple, CpuFeature::set()))) .engine(); diff --git a/crates/sp1/stylus-compiler-program/src/main.rs b/crates/sp1/stylus-compiler-program/src/main.rs index 21f5db52d6f..ac7989ca220 100644 --- a/crates/sp1/stylus-compiler-program/src/main.rs +++ b/crates/sp1/stylus-compiler-program/src/main.rs @@ -5,8 +5,7 @@ sp1_zkvm::entrypoint!(main); fn main() { let input = sp1_zkvm::io::read::(); - let rv64_binary = stylus_compiler_program::compile(&input) - .expect("stylus compilation failed"); + let rv64_binary = stylus_compiler_program::compile(&input).expect("stylus compilation failed"); sp1_zkvm::io::commit(&rv64_binary); } diff --git a/crates/sp1/stylus-compiler-runner/main.rs b/crates/sp1/stylus-compiler-runner/main.rs index a938385ba02..bc7a8443021 100644 --- a/crates/sp1/stylus-compiler-runner/main.rs +++ b/crates/sp1/stylus-compiler-runner/main.rs @@ -1,11 +1,8 @@ use clap::{Parser, Subcommand}; use sp1_sdk::{ + blocking::ProveRequest, blocking::{Prover, ProverClient}, - include_elf, - Elf, - ProvingKey, - SP1Stdin, - blocking::ProveRequest + include_elf, Elf, ProvingKey, SP1Stdin, }; use std::path::PathBuf; use stylus_compiler_program::{compile, CompileInput}; @@ -67,7 +64,11 @@ fn main() { let cli = Cli::parse(); let wasm = std::fs::read(&cli.wasm).expect("failed to read wasm file"); - let input = CompileInput { version: cli.version, debug: cli.debug, wasm }; + let input = CompileInput { + version: cli.version, + debug: cli.debug, + wasm, + }; match cli.command { Command::Native => { @@ -76,7 +77,10 @@ fn main() { } Command::Execute => { let binary = sp1_execute(&input); - tracing::info!("SP1 execution completed, output size: {} bytes", binary.len()); + tracing::info!( + "SP1 execution completed, output size: {} bytes", + binary.len() + ); } Command::Prove => sp1_prove(&input), Command::Compare => { From 049c159ac008209637d8b714982173b8cb3e5743 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 27 Mar 2026 17:15:06 +0100 Subject: [PATCH 178/189] Remove the compare from general rust tests --- .github/workflows/_rust-tests.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/_rust-tests.yml b/.github/workflows/_rust-tests.yml index dd85769bd86..48cfcb479c1 100644 --- a/.github/workflows/_rust-tests.yml +++ b/.github/workflows/_rust-tests.yml @@ -78,11 +78,6 @@ jobs: echo "Rust tests failed. Failing the workflow as required." exit 1 - - name: Run stylus-compiler-runner compare - env: - SP1_PROVER: local - run: cargo run -p stylus-compiler-runner --release -- compare - - name: Check stylus_bechmark run: cargo check --manifest-path crates/tools/stylus_benchmark/Cargo.toml From 81977305ccd76e5dc2f6402d2571c35c45570457 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Fri, 27 Mar 2026 17:51:56 +0100 Subject: [PATCH 179/189] Proper proving env --- .github/workflows/zk-proving.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/zk-proving.yml b/.github/workflows/zk-proving.yml index e6415354fef..ee07ae3e7cc 100644 --- a/.github/workflows/zk-proving.yml +++ b/.github/workflows/zk-proving.yml @@ -54,7 +54,7 @@ jobs: - name: Run stylus-compiler-runner compare env: - SP1_PROVER: local + SP1_PROVER: cpu run: cargo run -p stylus-compiler-runner --release -- compare - name: Run validation From 6c53fb647accbb07d042c6b0c80259b524f5ebad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Mon, 30 Mar 2026 09:39:42 +0200 Subject: [PATCH 180/189] Pass the input struct --- Cargo.lock | 1 + crates/sp1/runner/Cargo.toml | 1 + crates/sp1/runner/src/main.rs | 9 ++++++--- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fa448d54506..544188e9443 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7621,6 +7621,7 @@ dependencies = [ "serde_json", "sp1-core-executor", "sp1-sdk", + "stylus-compiler-program", "tokio", "tracing", "validation", diff --git a/crates/sp1/runner/Cargo.toml b/crates/sp1/runner/Cargo.toml index 739c6c4c3b1..b19e0d55485 100644 --- a/crates/sp1/runner/Cargo.toml +++ b/crates/sp1/runner/Cargo.toml @@ -13,5 +13,6 @@ bincode = { workspace = true } clap = { workspace = true, features = ["cargo", "derive"] } rkyv = { workspace = true, features = ["indexmap-2", "bytes-1"] } serde_json = { workspace = true } +stylus-compiler-program = { workspace = true } tracing = { workspace = true } tokio = { workspace = true } diff --git a/crates/sp1/runner/src/main.rs b/crates/sp1/runner/src/main.rs index d32cb4cf864..561b97726b0 100644 --- a/crates/sp1/runner/src/main.rs +++ b/crates/sp1/runner/src/main.rs @@ -148,9 +148,12 @@ fn build_input(cli: &Cli) -> Vec { fn run_in_sp1(cli: &Cli, wasm: &[u8]) -> Vec { let mut stdin = SP1Stdin::new(); - stdin.write(&cli.version); - stdin.write(&cli.debug); - stdin.write(&wasm); + let compile_input = stylus_compiler_program::CompileInput { + version: cli.version, + debug: cli.debug, + wasm: wasm.to_vec(), + }; + stdin.write(&compile_input); let compiler_elf = std::fs::read(&cli.stylus_compiler_program).expect("read stylus program"); let program = Arc::new(Program::from(&compiler_elf).expect("parse elf")); From 12ec97d79669cc42e75792393ecc4c661d065aa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Mon, 30 Mar 2026 16:39:14 +0200 Subject: [PATCH 181/189] Comment about comparison. Remove default proving mode --- .github/workflows/zk-proving.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/zk-proving.yml b/.github/workflows/zk-proving.yml index ee07ae3e7cc..9c9f91dd5b9 100644 --- a/.github/workflows/zk-proving.yml +++ b/.github/workflows/zk-proving.yml @@ -53,8 +53,7 @@ jobs: run: cargo clippy -p program -p sp1-builder -p sp1-runner -p stylus-compiler-program -p stylus-compiler-runner -- -D warnings -A static_mut_refs -A clippy::too_many_arguments - name: Run stylus-compiler-runner compare - env: - SP1_PROVER: cpu + # Compare compilation consistency between running it natively and in the SP1 execution mode. run: cargo run -p stylus-compiler-runner --release -- compare - name: Run validation From 0c1352b254c532a502573e5d9f0faabe7a7c2bf8 Mon Sep 17 00:00:00 2001 From: Igor Braga <5835477+bragaigor@users.noreply.github.com> Date: Mon, 30 Mar 2026 12:06:06 -0400 Subject: [PATCH 182/189] update wasmer pin to use wasmer v7.1.0 Signed-off-by: Igor Braga <5835477+bragaigor@users.noreply.github.com> --- Cargo.lock | 17 +++++++++-------- crates/tools/wasmer | 2 +- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2aea47cd460..cd6963b2135 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8856,7 +8856,7 @@ dependencies = [ [[package]] name = "wasmer" -version = "7.1.0-rc.2" +version = "7.1.0" dependencies = [ "bindgen 0.72.1", "bytes", @@ -8890,7 +8890,7 @@ dependencies = [ [[package]] name = "wasmer-compiler" -version = "7.1.0-rc.2" +version = "7.1.0" dependencies = [ "backtrace", "bytes", @@ -8924,7 +8924,7 @@ dependencies = [ [[package]] name = "wasmer-compiler-cranelift" -version = "7.1.0-rc.2" +version = "7.1.0" dependencies = [ "cranelift-codegen", "cranelift-entity", @@ -8944,11 +8944,12 @@ dependencies = [ [[package]] name = "wasmer-compiler-llvm" -version = "7.1.0-rc.2" +version = "7.1.0" dependencies = [ "byteorder", "cc", "crossbeam-channel", + "enum-iterator", "enumset", "inkwell", "itertools 0.14.0", @@ -8969,7 +8970,7 @@ dependencies = [ [[package]] name = "wasmer-compiler-singlepass" -version = "7.1.0-rc.2" +version = "7.1.0" dependencies = [ "byteorder", "dynasm 5.0.0", @@ -8988,7 +8989,7 @@ dependencies = [ [[package]] name = "wasmer-derive" -version = "7.1.0-rc.2" +version = "7.1.0" dependencies = [ "proc-macro-error2", "proc-macro2", @@ -8998,7 +8999,7 @@ dependencies = [ [[package]] name = "wasmer-types" -version = "7.1.0-rc.2" +version = "7.1.0" dependencies = [ "bytecheck", "enum-iterator", @@ -9015,7 +9016,7 @@ dependencies = [ [[package]] name = "wasmer-vm" -version = "7.1.0-rc.2" +version = "7.1.0" dependencies = [ "backtrace", "bytesize", diff --git a/crates/tools/wasmer b/crates/tools/wasmer index 82ffc70a5e6..5ec7b321f10 160000 --- a/crates/tools/wasmer +++ b/crates/tools/wasmer @@ -1 +1 @@ -Subproject commit 82ffc70a5e653b93462172aacf15dc280e0a3348 +Subproject commit 5ec7b321f107b916456296fe63886658cdc3351a From 4873b550ebd64c30537220d1e6fd8bde65a2139a Mon Sep 17 00:00:00 2001 From: Igor Braga <5835477+bragaigor@users.noreply.github.com> Date: Mon, 30 Mar 2026 12:26:57 -0400 Subject: [PATCH 183/189] update wasmer pin to proper pin Signed-off-by: Igor Braga <5835477+bragaigor@users.noreply.github.com> --- crates/tools/wasmer | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/tools/wasmer b/crates/tools/wasmer index 5ec7b321f10..537a034c36d 160000 --- a/crates/tools/wasmer +++ b/crates/tools/wasmer @@ -1 +1 @@ -Subproject commit 5ec7b321f107b916456296fe63886658cdc3351a +Subproject commit 537a034c36d71425d07eddb73802de6b7d1a6947 From ba3c95d4cfd4695464d1b06273cf8428dc8c5e05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 31 Mar 2026 10:43:26 +0200 Subject: [PATCH 184/189] Use block_inputs.json from master (generated with the 7.1.0 version) --- .github/workflows/testdata/block_inputs.json | 149 ++++++++++--------- 1 file changed, 75 insertions(+), 74 deletions(-) diff --git a/.github/workflows/testdata/block_inputs.json b/.github/workflows/testdata/block_inputs.json index f171f7821a5..00fc880c6a0 100644 --- a/.github/workflows/testdata/block_inputs.json +++ b/.github/workflows/testdata/block_inputs.json @@ -4,110 +4,111 @@ "DelayedMsgNr": 0, "PreimagesB64": { "0": { - "dKCH1lclUHQPLRpRY51wYiFnYDcp0FxWF0/xz0qO3tI=": "+HGAgICAoM4/vP9TzWd9mEJJli4Ag8G5S4fQyMmslnL3+ypLyNOhoDs+Qn5MbzIeVG47YP1lqDKwKq5tCvJqfwSjUgr5vreboEkpnjpvGqpg77I070nOk8hUJD8icMb7IQGPvrguMmuGgICAgICAgICAgA==", - "z1jSXMeBbaMsv05dG5nGoe9gEmL7CXOXniop4yeE9xg=": "+EOgIMZ1AuPLNtGlYjd6gdpmROdRmPLSFoxJ0cQrKXfrfHehoGdQcmVjb21waWxlcyI6dHJ1ZSwiRGF0YUF2YWlsYWJp", - "zj+8/1PNZ32YQkmWLgCDwblLh9DIyayWcvf7KkvI06E=": "+GmgIJJBgpRGrVcLW5fTilBHgqZSIgTGfV8pthUVJG0EENy4RvhEgICgVugfFxvMVab/g0XmksD4bltI4BuZbK3AAWIvteNjtCGgvMkPLW2tpbGOFVwXocClWSCq6U85hX050NjtB66PIos=", - "m8+ZF5swXx1UGFUItHzGH7D4uATdRJqbYO0Givex1i8=": "4qAgTekhWDdyi/Jw3FkGldWMkaUaungCdxT+3I29E9BhDQE=", - "HiwXyC7al0/jlh5NiPWUerAm+qTUVy1R776Ame9kOVk=": "+EOgILSNuEkwsztx4Ye9wcKUbKKDk/E+bGD7VyYqYvuzjuKhoBh2nAw5ScmwSLwR4u6BfdQhZdjYNBgHhU1FpEaMlS64", - "DK0+UiKOLO1uZMNQtzW1yUi3ZxELDc63oPnEjh51BD0=": "+FGAgICgMfKwovvHT0H+yJcmtJFHYro6pgWPJ5IzE8Ow5+QlJQiAgICg2Ovlqb74o5dtpU1t/AvKk1jrjZwdKEcbAgcbOixaqdGAgICAgICAgIA=", + "Dm5wic2CwG4arAjqkuH9TvlGVILwaD9N5S7J1CbQam8=": "+FGAgICAgICAgICAgICgr9hmbujOTyptLwYi0zNf0llJsmWfGddIvBOGQVSwZr6AoHpqbZPowNwqMpH9GRQ4MUqhGByvNRkUuYvg1f7dK6f3gIA=", "ZeHel60txRVXFxectmJJ9ygan5pTeBQet3X2Dcql3IU=": "+LGAgKDjXYsN2im17qN582iuMXGh0vmk4nR6ecEsKxCzQZlRW6Cbz5kXmzBfHVQYVQi0fMYfsPi4BN1Emptg7QaK97HWL4CAoKpJlYx2F3NUFEJhUBodLan5Od/Ro5qUyuaxVG4GGhqogKCRbCq8Nx/UMXXcs/ts2AWse4NDD3OTKGkq5UTLuFgvfoCAgICAgKAIZZ08XkQigQL7/+XrYy5EI3g1eWwEpBMoVcYyvpkW1YA=", - "kWwqvDcf1DF13LP7bNgFrHuDQw9zkyhpKuVEy7hYL34=": "+EOgIIzOE607Vcvsp238hPhYj8UCpHIyYEvxHVoDEsEscsqhoHsicGVyaW9kIjowLCJlcG9jaCI6MH0sImFyYml0cnVt", - "N45Zbr1Z6kOitU9MtUxI7dQJybgjBkj1dT+z9NHs+B8=": "+HGAgKBVWPo2Pk7uyWpE2f6R/yjxtt9EKv8vl1pRe8e1ii+W4ICAgICAoO7P4k8UsqzXLKUEI+S9Yl2b2RqQmBEqVyChaqPbbJlogICAgICAoOpx0wqneDsPQ9tBPHeazH7lbIxziHiRtZjQeqC68ESIgA==", - "Vl5U3j1vnqZnRhVS+Mj1Ps+4OOo6UX3xagQN8cUbIt8=": "+EOgIFJ4l4RQaLBXVkGB2nTHzk4JkizHgRXzJ99b0oeCilyhoE9TVmVyc2lvbiI6NTEsIkluaXRpYWxDaGFpbk93bmVy", - "3wdXKRG4rKtlA7M79KpSNWxktP/wuR3R2AbXKGA91bE=": "+ImgIAJd2ZjEpvRjvHcAwGhp5mrB+C+TpMowus3QUBG5tpK4ZvhkBqD//////////////////////////////////hAyeNOE7aBW6B8XG8xVpv+DReaSwPhuW0jgG5lsrcABYi+142O0IaDF0kYBhvcjPJJ+fbLcxwPA5QC2U8qCJzt7+tgEXYWkcA==", - "dnxlQJO2EkjcoX9XaMH40KkfYuuFm6mkrpa0+7P6YhM=": "+JGgwH00CNQBguXe7Se0jRqCY0Excou+bqR8kzQuCAeRCSegz1jSXMeBbaMsv05dG5nGoe9gEmL7CXOXniop4yeE9xiAgICAgICAoIKZzi+vMgYfud2BuRneoGgn+6LDXbvv9WOtr387aTh2gICAgKAgaSiyQL3+MLP9vOF3z6IgZZh0495/kJTvkjkZWQU80ICA", - "4h49KPn06pERCAKkgnvs++ZgckM7D00jVf6MHQXkQTQ=": "4qAgEr3YLiIfen37rrBoFjCKfYxwBO4G6+jvvNiRdrtqZjM=", - "emptk+jA3Coykf0ZFDgxSqEYHK81GRS5i+DV/t0rp/c=": "5p8/vCBpa8LarkQ5v//FfL0hCCNs9PjMhF8V6ZZd7roBhYQF9eEA", - "HzT8A831RUOZ5idq3dlMhpSr8iyO6BChfCBklYqEPpE=": "+EOgIDjrKrO5pGKH+YfN6CEIyjSftQkTfruel8zOslPsgSmhoHJHbGFjaWVyQmxvY2siOjAsImJlcmxpbkJsb2NrIjow", - "9Dojmi9cOEMZUWBXSb0AatojroavPfTk+QOxop62rJk=": "+GmgNbaTCFvrIbCHjH5fq3UZzg1hBTVM9nRNv7c+N0XpKeS4RvhEgICgVugfFxvMVab/g0XmksD4bltI4BuZbK3AAWIvteNjtCGgvMkPLW2tpbGOFVwXocClWSCq6U85hX050NjtB66PIos=", - "TERnLZosl6Bsi2OWNSpJUdYpLc21wh54Mi/BFpIoP5c=": "+QERoAytPlIijiztbmTDULc1tclIt2cRCw3Ot6D5xI4edQQ9gKDB0t5TvbBKApAxzeNMS/6kVm+W90pmo/a9JINOztl4/4CAgKCB8Ea0qY59dMPZ1EvqojstfXI0q7vKVV3NL6FcxCFY+4CAoMGbduUDJpfU8oZBC60UWBVkKLzBypg6omSWFWYdISkxoKslRe1mHtHF59VZAezGqVgzD1gEePbGyfY/R2CYMJ6NgICg7NNznF9qIfW28UXGlrtucabxxnsfsb/vvSSnrRFZQd6gDnTASFL4Cx3ZRQ7uFuFL0SEXuRpvNifhKCUaTbL10k6gU2neamdXOzBA0w3986FtVQXIynLZLm+gc+xwW/3wLZyA", - "v7IFW2m1BFkCQmNvS6aURfxPONRxlTSnMi09kEGzeiA=": "+FGAgICAoMbDnGDWkwdvTcdNyG0Wos9ffArV6W13NI8KvwpK0B+rgICAgICAgICgVZ1CQ0C7YF/f3m/fJtrcNYFlvwB2P0YS5GIyYGujsu+AgIA=", - "98qRqNFliss0eIdt4jm8MKeHtqXxsIbLkiNplgroiSU=": "5aAgTkazWt2mC/1m9/LZUGvm/s5rVSWNR3X6DCT6MsGq+oOCAlg=", - "iOdXg+ht6dlv0ss2TIwTLfHB5z1vndkjILNSAuM/r/k=": "5qAgM4vD7zvbUX4p6lwMWtodkp6jw4xn5OF+lCESeKX7HYSDQZtk", - "odw9Pi0X+jiFrUkb2JYqEIVY/7leLGv3Xfu86ZhPg8E=": "56AgT4KR6c9uV1ojjGBJbTOyhJ76SUgjaxvvdMoDHmAX04WEAehIAA==", "D4M7U+s8Sc1FOYZJZJkMsdpONeCLn0SNg1s3RMvzXDo=": "56AgdGg/ujGSuKqKNnYe2zRaOG0AI2pBq8j2Jnbtg1vyW4WEAehIAA==", - "B9SI75e1Xkk4mTyRZmz054KbjMd1VSZPORe6W1jHlzk=": "+QIgoOYJoo8U0sCrL4l186m16ZDeX97rVrhfgfHrshIgOXrBoB3MTejex116q4W1Z7bM1BrTEkUblIp0E/ChQv1A1JNHlKSwAAAAAAAAAAAAc2VxdWVuY2VyoCI/Ep6TPIgWdcKonnaGsHyFN3pqIsIpxXzjqOUnS0BooPpjJgloOxF/67TXp9o1lJ6Mcemcns75BlNuJ7iFj0x1oKNeEyvL4uOFopIF8Q/g0vI1/hEk/sTW2iDb//DI6+W1uQEAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAACAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGhwQAAAAAAACDII4ehGm6xsSgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAAAAAAAAAAAAAAAAAHgAAAAAAAAAzAAAAAAAAAACIAAAAAAAAAAGEBfZWMA==", - "0U8osqi1HYTe97iCTnB/wiNHV8Xjs/3L47+tbWz97ok=": "4Z806dKkpQxPAvfQVhQh4MPknlcmhwjBoL44M7l6DdQaZg==", - "Wwyud1Idx1sGWf8V9ebkgcKnHw0UJC3UMUtWwhcjpGM=": "+NGgWvuROhyCEXBF1xLhfuSr4eRNM3JdZU+8TunTrJ35RneAoIjnV4PobenZb9LLNkyMEy3xwec9b53ZIyCzUgLjP6/5oEO7FY28svix8THG2PINDK0eeSqms+el3rET7a/uHKhsgKB7WDQC5pyjLMIRnt6Smve2r/3+lYSGld/3p0Uk5SXQNKDVH7isE4PNtJknPpTC+ha6RULZInisrYeDOv2/xyf2fYCAgKAfNPwDzfVFQ5nmJ2rd2UyGlKvyLI7oEKF8IGSVioQ+kYCAgICAgA==", + "HzT8A831RUOZ5idq3dlMhpSr8iyO6BChfCBklYqEPpE=": "+EOgIDjrKrO5pGKH+YfN6CEIyjSftQkTfruel8zOslPsgSmhoHJHbGFjaWVyQmxvY2siOjAsImJlcmxpbkJsb2NrIjow", + "VZ1CQ0C7YF/f3m/fJtrcNYFlvwB2P0YS5GIyYGujsu8=": "+G+gIF71pCk5iToI3qHV9i7IXtb8k1c0CvFpMmW8nWSMjXS4TPhKgIbE0DIuWWCgVugfFxvMVab/g0XmksD4bltI4BuZbK3AAWIvteNjtCGgxdJGAYb3IzySfn2y3McDwOUAtlPKgic7e/rYBF2FpHA=", + "PqnnqaKtw4uMbmE8jqOQOw6T9uSOBbOrKPjer54bNxM=": "+EOgIP4+RlG26qvgBENz2PjFXiVeO2nnuQv5mNs24kidDOqhoGxpdHlDb21taXR0ZWUiOmZhbHNlLCJJbml0aWFsQXJi", + "EkoCrIuIiGSc2OfJHqqE9fB/y2jY16jnYiFk4H7b1oM=": "+NGAgICglsZGqMWCVOv4rP2W+yejXFvVh+ldznRCMJ68c/6PqMqguCuvB97/vjXV4qNPcHIrtWT9XnUIDVDOZIhDCZ2mtdSAgKDb6zR1OR1sXdAliYU8cs9VxnA6PMN1JKge5Z0ZnMAnZaCznUANpP6nM8epBPe4jZcandMuDdU5xyaaEGuBJs18dqAeLBfILtqXT+OWHk2I9ZR6sCb6pNRXLVHvvoCZ72Q5WYCg78Voc9FPQ51xcJ66LnCaeLtx9Hvrqc4hh8zZL1/C5IKAgICAgA==", + "gVkzSGrUaExIL1MT637NmXMtIbfcl6qVbtyNWBXcVvk=": "5p8xmDjv4+Vn/ayPYWfvABjQ4KMeDcTieW2Om9T86rBxhYQ6MH19", "vMkPLW2tpbGOFVwXocClWSCq6U85hX050NjtB66PIos=": "/g==", - "eYdoiUAm3AJoYyDw5xMDtmqRE7vXU19yzcEqdS9d/Gw=": "4qAgP5aDEpFEkw2aZbPQqmgsJFYbdVze8qNLVs2+hyhatQI=", - "e1g0AuacoyzCEZ7ekpr3tq/9/pWEhpXf96dFJOUl0DQ=": "+EKgIFagIkaBc0I35yYlQuYE6LhlprkzOaMyunezPw7AK1CgnwIAGaEAAFXwAAID6ACARQsyMgFtAB8AIAACAAAAAAA=", - "vY9PVwhU3EE4tYR6/yr4vruVep3+e2t6r9+T4bjEr4A=": "+FGg3wdXKRG4rKtlA7M79KpSNWxktP/wuR3R2AbXKGA91bGAgICAgICAgICAgKAIctrhU8EXDeD6ngYD9Jt+ArbH89hcsyPShYj6O1iyrICAgIA=", - "c5FdtCCx505h62R2CqXjj26Bipb7q8LLLWmD57XRZC4=": "5qAg++NpBR6i/Mb4jLo5FAqZbK5hsNNJsxTh15/k3mg3SoSD5OHA", - "AVsV5xXdgS+1KDip33nucWFlEUCUMLQi9FIK6Z9HxUc=": "+NGgrc4ZncvofGmMzkVhq5mQxHGjzfoeneNIefIjJI/VX/6AoF+ul2lcDQ+h/IecCy+kLjAZbfdBaWh0yBvyOfw9i4y9gKCvCwG+BcHG0MJ/SU4bY5kcnT3pzoAXG6zM/mV9/sb8x4CAgKAT+VsnbhH7KHicB5jXK2GwFbmxCqc4vZxgybBkoKMj24CAoFAvb8syC872TjYjuzjadgJ71rqP60Kfj2hYhu79zE7EoAHUkUbJNsmrQnUiPGiDSRja2mpt0h89ySfHkYfHwPxfgICAgA==", - "/V8u1sYMAX3//6jj55kA41ne2t0F1LT1lZYbQCnoXBA=": "+QIRoDeOWW69WepDorVPTLVMSO3UCcm4IwZI9XU/s/TR7PgfoGXh3petLcUVVxcXnLZiSfcoGp+aU3gUHrd19g3KpdyFoHZ8ZUCTthJI3KF/V2jB+NCpH2LrhZuppK6WtPuz+mIToBIs8KawfnvDppYMl3L2u3jfb6P0d8ps09wMhiz4u9UooGLjvVKc7eOZxDfTl9gparoCj92qEIE0oCmcHWasH/H1oExEZy2aLJegbItjljUqSVHWKS3NtcIeeDIvwRaSKD+XoLMnZ0KczXB7xSZqHQCGheoTzQT0CtoLgxpd2/QfhdOToEiR8hiXmHYCMyY/1NH9Af0t2ADP2VsiSB4jlQHycXfXoBJKAqyLiIhknNjnyR6qhPXwf8to2Neo52IhZOB+29aDoJ2PWHeeLDZ/CIYYij6vcrSvMCGrT4qtkknwqtCYFq+ooDM7m+zNGGB9OJuFIlj5hWAzUdZO+T5afzb7FnY0iknzoHB8nfXP2wfDHS6+ZKn8NOhUijZWuW5N1GvZs7uC8D5UoMFudePR0Z/HcduH9RH7IfWn5bkjqhhqgs3d0HUp/9KBoEcXf+a6zRV6quf5H9xndgZJ9n1FFuAYMRWmT7ydXynfoEPl2WNt54nRmDaKjYROyCNz7TCMFAXyQSe9qETAQieroFsMrndSHcdbBln/FfXm5IHCpx8NFCQt1DFLVsIXI6RjgA==", - "yew99iybEu0GtKKLPOWA3wYNr69cRdr0F3iR685WYPk=": "+FGAgKB1g/ukkoQBzYVMFb2DHyRddiSH2DS1DazxGRRjkuyNWYCAgICAgICgw1N1/Lnt2e0+pcjr2GQp7xAC1et6kYWj8cNgcOfzcE+AgICAgIA=", "rQwVF3p+pElZ9MZz723mSRelAkHOPpW9tZ1zYdUNZ+8=": "56AgncHVPXKZN0hJBncjkGvDK/yF64ShOgdknaTVBM6gCoWEAcnDgA==", - "YuO9Upzt45nEN9OX2ClqugKP3aoQgTSgKZwdZqwf8fU=": "+NGg8ENh3uYSkCctnIhZ1jygg7EYZRqh9tvWA0PmU26LQYCAgICAoK0MFRd6fqRJWfTGc+9t5kkXpQJBzj6VvbWdc2HVDWfvgKBPo3hSnH4FFvXq0plroOqq6Fn9/irnXLmMTmkrvBXliKC/+dlkiEKJgYnB+8niB30dq7NhLOYvqRSGljT+SZvUj6BTZb/VtVpv7opExhgI9NLdkolq+hyEgNEnmDBnY7M4AoCAoH685mExqvza+zwEQySlgii6li83NUeOJ4kbcq3VZ5L3gICAgA==", + "SQixK1mXqpvWDunRXUCeJxcrMUdTntW7HL825lSBYRk=": "+EGfN8kEik7d181t1bMP3cLgw2l3NgMITDTK7vpyCTRPmqCfAgUHAdUAAQF/SQACQAAAAAAAAAAAAAAAAAAAAAAAAA==", + "Rxd/5rrNFXqq5/kf3Gd2Bkn2fUUW4BgxFaZPvJ1fKd8=": "+NGgr2PbbPJyOj5zAHuy8qKDryfX4CirxS7JDX9G+2Cx0/qge8pKCpBr6Z2zAnMQ7uu9TjW2ldTHHijPhd/PKlY/oz6AgKAPgztT6zxJzUU5hklkmQyx2k414IufRI2DWzdEy/NcOoCAgKAObnCJzYLAbhqsCOqS4f1O+UZUgvBoP03lLsnUJtBqb6BlhZL5tbW7OZdDmdI7AyG3pyDFtz0rNu6mLa/DNFsmW4CAoBzURinu6VnAa+9YocxoOIAvx/VF0xecR9e+j470ZTpCgICAgA==", "412LDdopte6jefNorjFxodL5pOJ0ennBLCsQs0GZUVs=": "5qAgXRF3OXFV2qeWoVTl8tIkTdy6yrJVg9GJgP/N9JhPsoSDNWZk", + "i9UMskMMcLDI9iy9oetTbJFnN+9KUX0HZTkTQoaEu9s=": "+EOgICCGr8Od0MKP3/rqdQ1DzhGllID9/LWL/FXUxAhpiLihoCI6IjB4MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw", + "F7TiEZ4xnGsOwap/PpDdE+QlfNTZpmRYJbskh7dng+s=": "4qAgtobEh4+Cel0m/kRhESVvA1MkdTc3e4HZrGyeD6/x/wI=", + "dnxlQJO2EkjcoX9XaMH40KkfYuuFm6mkrpa0+7P6YhM=": "+JGgwH00CNQBguXe7Se0jRqCY0Excou+bqR8kzQuCAeRCSegz1jSXMeBbaMsv05dG5nGoe9gEmL7CXOXniop4yeE9xiAgICAgICAoIKZzi+vMgYfud2BuRneoGgn+6LDXbvv9WOtr387aTh2gICAgKAgaSiyQL3+MLP9vOF3z6IgZZh0495/kJTvkjkZWQU80ICA", + "5ATJM/gtfbsC44E68Fq1cLO2HsWiW1wFyYTyVM8xHt4=": "+EKfMac3BAKInN3RCqOBIiEYHRLUZfXloOdpZxOv/MBbOaGgeyJjaGFpbklkIjo0MTIzNDYsImhvbWVzdGVhZEJsb2M=", + "z/PY61VoJPuBRP3MatMymzT0TSAQpnO7gy5PuEf+zSY=": "+EKfPj6STOum/lPdVlGhTIjrn2+55sl2M2mmCOMxD+VwmqGgIjp7IkVuYWJsZUFyYk9TIjp0cnVlLCJBbGxvd0RlYnU=", + "rSkvJVYlnwtn31svQMtMbgAh2biUEeptQoTzQv8ZuuY=": "+GmgIGjbBfIcM/iLt85QaH2X4fDh0BbJ+iRX1aoRWDc1fMq4RvhEAYCgVugfFxvMVab/g0XmksD4bltI4BuZbK3AAWIvteNjtCGg2Ptqx7aEuc+eJrQ2aLNqQgnDEjV2MZv8rGAJ4ZFSTZg=", "SJHyGJeYdgIzJj/U0f0B/S3YAM/ZWyJIHiOVAfJxd9c=": "+HGgNwSELilKUzBDAVZGXr6/g8OijOkqP7a+xXh8afskAhKAgICAgICAoPfKkajRZYrLNHiHbeI5vDCnh7al8bCGy5IjaZYK6IklgKA2n0yO11NAokpQuWDnmu1//+TgAAje7s1++SsHVXrRE4CAgICAgA==", + "5zSQIE8PSLSx0cbsfBjTW8jm746ztENb/EbONW2s0tw=": "6aAgCH8Hc6Fx3cpHgPmzKLTjx7Ytlzy5bwjVTunqfXEJ44eGxNAyLllg", + "odw9Pi0X+jiFrUkb2JYqEIVY/7leLGv3Xfu86ZhPg8E=": "56AgT4KR6c9uV1ojjGBJbTOyhJ76SUgjaxvvdMoDHmAX04WEAehIAA==", + "r2PbbPJyOj5zAHuy8qKDryfX4CirxS7JDX9G+2Cx0/o=": "+FGg9MzUylYylsVwjNgcpTCr89rJtbdo2URNar2lt9lcp8aAgICAgICAgKCBWTNIatRoTEgvUxPrfs2Zcy0ht9yXqpVu3I1YFdxW+YCAgICAgIA=", + "ZYWS+bW1uzmXQ5nSOwMht6cgxbc9Kzbupi2vwzRbJls=": "56Ag1INQeIC/JIgdFBIu31SzY4AFeVpxZc+Un4HvmruJEYWE6sE6rQ==", + "3lPUz+7tip+stJLxnH//81Om56/cgvEcbwJRrJ5tdBI=": "5qAgtioVwzR2bB+a0BX80gbybPyeVB5lDExEyHgQcJ7gIISDBkq6", + "wW5149HRn8dx24f1Efsh9afluSOqGGqCzd3QdSn/0oE=": "+HGAgICAgKBLSROEcOHpBnMj/3LFwcPZDteVOgjSvRUamUA9JCtgU4CAgKCL1QyyQwxwsMj2LL2h61NskWc370pRfQdlORNChoS724CAgICAoGipiic72NEG91yujpOzxRuigD7aKHKeqJVdvpcoM4DZgA==", + "aKmKJzvY0Qb3XK6Ok7PFG6KAPtoocp6olV2+lygzgNk=": "+EOgICGQkNXXBiqvbZWpImJ16AyaMDGA4Iv24TtgVMEIJJWhoNAl8ieCBR8Vh59T6mB9i+Fykk0IBfto38Cwe4Vf3Jxy", + "UqFRZqskqDMolhosifrZ9K9PayVhHvr4gfeuaKMYCAg=": "+FGg3wdXKRG4rKtlA7M79KpSNWxktP/wuR3R2AbXKGA91bGAgICAgICAgICAgKD7WLwdcLfUb5oT8s2mHGuwqwUOsOQIf8XimUSTjZXjj4CAgIA=", + "+WniGCsri2LFViSPD2AI60v5EgNhM2k9ug2q/Mcmbwc=": "+EOgIIRPBOJCTGZwtGyApze6fAuimDWGj0//iS2kogBFF6WhoDUwQmxvY2siOjAsImVpcDE1NUJsb2NrIjowLCJlaXAx", + "iOdXg+ht6dlv0ss2TIwTLfHB5z1vndkjILNSAuM/r/k=": "5qAgM4vD7zvbUX4p6lwMWtodkp6jw4xn5OF+lCESeKX7HYSDQZtk", + "aG50DYUbyFlBW4E3Q+zTSvfG4bTdbWvj+STS9fBJC+g=": "+EKgIFagIkaBc0I35yYlQuYE6LhlprkzOaMyunezPw7AK1CgnwIAIoEAAFXwAAID6ACARQsyMgFtAB8AIAACAAAAAAA=", "IGkoskC9/jCz/bzhd8+iIGWYdOPef5CU75I5GVkFPNA=": "5aAg58w5cHd2c3N2vhgF3HQNvGC1fI/1YSvo7EP1K/ztRYOCAiQ=", - "wdLeU72wSgKQMc3jTEv+pFZvlvdKZqP2vSSDTs7ZeP8=": "+EOgIPeKg/Qog9t+mMP6hEiQzW3La3nCUvs6Jbno+cpb7FWhoDAwMDAwMDAwMDAwMDAiLCJHZW5lc2lzQmxvY2tOdW0i", - "gVkzSGrUaExIL1MT637NmXMtIbfcl6qVbtyNWBXcVvk=": "5p8xmDjv4+Vn/ayPYWfvABjQ4KMeDcTieW2Om9T86rBxhYQ6MH19", - "2Ptqx7aEuc+eJrQ2aLNqQgnDEjV2MZv8rGAJ4ZFSTZg=": "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": "+NGgGEZbng8BaVhm+1anw9sttFIAECkf4doy3moDqUidVtKAgICAoDRspog7lwDsL/yTv88sQswPORBzZdT92/mZqjiChMiVoCA9ozIXBmN9nprdSOlbtz1tcOGAAY5fppc4JidWdm3hgICgodw9Pi0X+jiFrUkb2JYqEIVY/7leLGv3Xfu86ZhPg8GAgICgnpH6/jT+huZsR5abhLuIuxC+dRDXQvQA/ddOkscv772AoLX8FwmnovA5ulxIRYDAsNlzwf2HISDFH4j22mhcdw3HgA==", - "vuvtuR5A4MDJs5AmHN+Ce06NNmEPFwuTZ8ZHXBK8GIs=": "+GifMU7InCAcI6pg4jHjmTs5ZrM/8fVdGY7CWYCVerMgZbhG+EQBgKD9Xy7WxgwBff//qOPnmQDjWd7a3QXUtPWVlhtAKehcEKDF0kYBhvcjPJJ+fbLcxwPA5QC2U8qCJzt7+tgEXYWkcA==", + "+6VKSRFzV4EUzu8H2UsLEW/eErzSDipc6Do2cAiY0K0=": "+FGAgICAoK0pLyVWJZ8LZ99bL0DLTG4AIdm4lBHqbUKE80L/GbrmgICAgICAgICAoI8t2Y3yEGoV/6nH7cw0UDJfvOZdrkkoJW3o/+FHDiDBgIA=", + "z1jSXMeBbaMsv05dG5nGoe9gEmL7CXOXniop4yeE9xg=": "+EOgIMZ1AuPLNtGlYjd6gdpmROdRmPLSFoxJ0cQrKXfrfHehoGdQcmVjb21waWxlcyI6dHJ1ZSwiRGF0YUF2YWlsYWJp", + "eo+BP27pw5jBU/hw0hbFaxgPWf/LrnX/sG0de0CDhJs=": "+HGgBAmtFZXpslJN4oEl7BH1BnpKbyTpyH5CMNgnJ1p9KBOgijG0HUCxtKA3HobDKxXL5N+StHEvVw8yDoFdkWELifOAgICAgICAgICAoEkIsStZl6qb1g7p0V1AnicXKzFHU57Vuxy/NuZUgWEZgICAgA==", + "MfKwovvHT0H+yJcmtJFHYro6pgWPJ5IzE8Ow5+QlJQg=": "+EKfNZUsxum0Cp1/KGzPIWCuUQmqvXqp6vNanV64s0dFxaGgb25zdGFudGlub3BsZUJsb2NrIjowLCJwZXRlcnNidXI=", + "m8+ZF5swXx1UGFUItHzGH7D4uATdRJqbYO0Givex1i8=": "4qAgTekhWDdyi/Jw3FkGldWMkaUaungCdxT+3I29E9BhDQE=", "LTglIP01WB8/8arFqf9gzRBLNYZzF9jMCx26rczdRB8=": "+EOgIDiCgRJhbI8QAZAI5U2U/brCatoZSYPb5flPQR/BjxWhoDU4QmxvY2siOjAsImJ5emFudGl1bUJsb2NrIjowLCJj", - "VZ1CQ0C7YF/f3m/fJtrcNYFlvwB2P0YS5GIyYGujsu8=": "+G+gIF71pCk5iToI3qHV9i7IXtb8k1c0CvFpMmW8nWSMjXS4TPhKgIbE0DIuWWCgVugfFxvMVab/g0XmksD4bltI4BuZbK3AAWIvteNjtCGgxdJGAYb3IzySfn2y3McDwOUAtlPKgic7e/rYBF2FpHA=", - "Q+XZY23nidGYNoqNhE7II3PtMIwUBfJBJ72oRMBCJ6s=": "+NGAgICgF7TiEZ4xnGsOwap/PpDdE+QlfNTZpmRYJbskh7dng+uAoNoSx7LHa6TLWAloAKO0JVRfmH6l+wbRwIc8CxwrpHOBgICgVXwF38O/SCYqMDPkAxkbyNt1ahY2dkY+AWkB3CH3XrOgul2Rut+Do5u5AqDitzcN9s1zWR+32JnNcTtMsEXAZGegJmk3TRLT7eM7gvKJjjBLGxD64Gs3iHuFJEgYHtCft+2AoD6p56mircOLjG5hPI6jkDsOk/bkjgWzqyj43q+eGzcTgICAgA==", - "gfBGtKmOfXTD2dRL6qI7LX1yNKu7ylVdzS+hXMQhWPs=": "+EOgIIBzjzlIbl+Sb84y26s+3m8wqB6NWpiKKmdTUmpPqLahoGdCbG9jayI6MCwiaXN0YW5idWxCbG9jayI6MCwibXVp", - "i9UMskMMcLDI9iy9oetTbJFnN+9KUX0HZTkTQoaEu9s=": "+EOgICCGr8Od0MKP3/rqdQ1DzhGllID9/LWL/FXUxAhpiLihoCI6IjB4MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw", + "2hLHssdrpMtYCWgAo7QlVF+YfqX7BtHAhzwLHCukc4E=": "5aAgc0XEU6ISVbaYSQK3G1bq1v3YiStSDAjlvIiUSLAGPoOC1qA=", + "EizwprB+e8OmlgyXcva7eN9vo/R3ymzT3AyGLPi71Sg=": "+NGgGEZbng8BaVhm+1anw9sttFIAECkf4doy3moDqUidVtKAgICAoDRspog7lwDsL/yTv88sQswPORBzZdT92/mZqjiChMiVoCA9ozIXBmN9nprdSOlbtz1tcOGAAY5fppc4JidWdm3hgICgodw9Pi0X+jiFrUkb2JYqEIVY/7leLGv3Xfu86ZhPg8GAgICgnpH6/jT+huZsR5abhLuIuxC+dRDXQvQA/ddOkscv772AoLX8FwmnovA5ulxIRYDAsNlzwf2HISDFH4j22mhcdw3HgA==", + "YuO9Upzt45nEN9OX2ClqugKP3aoQgTSgKZwdZqwf8fU=": "+NGg8ENh3uYSkCctnIhZ1jygg7EYZRqh9tvWA0PmU26LQYCAgICAoK0MFRd6fqRJWfTGc+9t5kkXpQJBzj6VvbWdc2HVDWfvgKBPo3hSnH4FFvXq0plroOqq6Fn9/irnXLmMTmkrvBXliKC/+dlkiEKJgYnB+8niB30dq7NhLOYvqRSGljT+SZvUj6BTZb/VtVpv7opExhgI9NLdkolq+hyEgNEnmDBnY7M4AoCAoH685mExqvza+zwEQySlgii6li83NUeOJ4kbcq3VZ5L3gICAgA==", + "o7a8QpV5KY21SwTaIhqwamEncePw8rkZq9s0JQIf+L4=": "+FGAgICAgICAgICgewt1lpK5fn7UYlg/ed+dhlnGsF5kdw+AMJ+ca6LJGayAgICgKLN98UhCLBUi1/hWfh64J+qrupWdDAkKkQDEFMXRzqWAgIA=", + "eYdoiUAm3AJoYyDw5xMDtmqRE7vXU19yzcEqdS9d/Gw=": "4qAgP5aDEpFEkw2aZbPQqmgsJFYbdVze8qNLVs2+hyhatQI=", "cHyd9c/bB8MdLr5kqfw06FSKNla5bk3Ua9mzu4LwPlQ=": "+LGAoMcFaIQUMo3OwgVGedOxKQqZBS1JCTLN4E51c6fRMWPMoJtQVRbzTLsM6mZa27bEkdyEORxICweh+gYRsMiq1KkMoBEwU/5egnb1Wi4vaKB7U3PL5kL7EHzJmrpKjUaXPOT+gICAgICAoOIePSj59OqREQgCpIJ77PvmYHJDOw9NI1X+jB0F5EE0gICAoHMHRo+5suEKP+x50LwPk+mAnAagAtpxq5PfcqM+5ZP1gIA=", - "Rxd/5rrNFXqq5/kf3Gd2Bkn2fUUW4BgxFaZPvJ1fKd8=": "+NGgr2PbbPJyOj5zAHuy8qKDryfX4CirxS7JDX9G+2Cx0/qge8pKCpBr6Z2zAnMQ7uu9TjW2ldTHHijPhd/PKlY/oz6AgKAPgztT6zxJzUU5hklkmQyx2k414IufRI2DWzdEy/NcOoCAgKAObnCJzYLAbhqsCOqS4f1O+UZUgvBoP03lLsnUJtBqb6BlhZL5tbW7OZdDmdI7AyG3pyDFtz0rNu6mLa/DNFsmW4CAoBzURinu6VnAa+9YocxoOIAvx/VF0xecR9e+j470ZTpCgICAgA==", - "w1N1/Lnt2e0+pcjr2GQp7xAC1et6kYWj8cNgcOfzcE8=": "+EKfICTsYlac8Hf07+EmnYOsWzO3uXmRR5cP61e7a41Q/aGgayI6MCwiZGFvRm9ya1N1cHBvcnQiOnRydWUsImVpcDE=", + "Vl5U3j1vnqZnRhVS+Mj1Ps+4OOo6UX3xagQN8cUbIt8=": "+EOgIFJ4l4RQaLBXVkGB2nTHzk4JkizHgRXzJ99b0oeCilyhoE9TVmVyc2lvbiI6NTEsIkluaXRpYWxDaGFpbk93bmVy", + "98qRqNFliss0eIdt4jm8MKeHtqXxsIbLkiNplgroiSU=": "5aAgTkazWt2mC/1m9/LZUGvm/s5rVSWNR3X6DCT6MsGq+oOCAlg=", "2XSGu1Tewo5FblA9vd6XmiUQjYZ8CgbxPyoCepxvBAY=": "56Ag7YHaAaqqO2S+9FQ0CTRs1QMz4z2gynCUpfTjj2hGu4WEBfbLYA==", - "r2PbbPJyOj5zAHuy8qKDryfX4CirxS7JDX9G+2Cx0/o=": "+FGg9MzUylYylsVwjNgcpTCr89rJtbdo2URNar2lt9lcp8aAgICAgICAgKCBWTNIatRoTEgvUxPrfs2Zcy0ht9yXqpVu3I1YFdxW+YCAgICAgIA=", - "3lPUz+7tip+stJLxnH//81Om56/cgvEcbwJRrJ5tdBI=": "5qAgtioVwzR2bB+a0BX80gbybPyeVB5lDExEyHgQcJ7gIISDBkq6", - "gpnOL68yBh+53YG5Gd6gaCf7osNdu+/1Y62vfztpOHY=": "+FGAgICAgICAgICgz/PY61VoJPuBRP3MatMymzT0TSAQpnO7gy5PuEf+zSaAgKDRTyiyqLUdhN73uIJOcH/CI0dXxeOz/cvjv61tbP3uiYCAgIA=", - "2hLHssdrpMtYCWgAo7QlVF+YfqX7BtHAhzwLHCukc4E=": "5aAgc0XEU6ISVbaYSQK3G1bq1v3YiStSDAjlvIiUSLAGPoOC1qA=", - "lsZGqMWCVOv4rP2W+yejXFvVh+ldznRCMJ68c/6PqMo=": "+FGAgICAgICAgICAgICgZDC5L1lfFW5noXszFBOUBDq4ASEOF2vzBa4e+DNzfmuAoOQEyTP4LX27AuOBOvBatXCzth7FoltcBcmE8lTPMR7egIA=", "zu8fatbAy364+xVnir8R2jzg06fHEGqpAMWTDlVqQ/8=": "M3P//////////////////////////hRgYFdgIDYDYFxXXzVjo7GzHV9SYCBfYARgHGBkWvoVYFxXX1FgAYEDghFgXFeBYgX/0JEDEWBcV2IF/9CQBlRfUmAgX/NbX1/9W181YgX/0GABY6Oxsx1fUmAgX2AEYBxgZFr6FWBcV19RAwZVAA==", - "ZYWS+bW1uzmXQ5nSOwMht6cgxbc9Kzbupi2vwzRbJls=": "56Ag1INQeIC/JIgdFBIu31SzY4AFeVpxZc+Un4HvmruJEYWE6sE6rQ==", - "F7TiEZ4xnGsOwap/PpDdE+QlfNTZpmRYJbskh7dng+s=": "4qAgtobEh4+Cel0m/kRhESVvA1MkdTc3e4HZrGyeD6/x/wI=", + "DK0+UiKOLO1uZMNQtzW1yUi3ZxELDc63oPnEjh51BD0=": "+FGAgICgMfKwovvHT0H+yJcmtJFHYro6pgWPJ5IzE8Ow5+QlJQiAgICg2Ovlqb74o5dtpU1t/AvKk1jrjZwdKEcbAgcbOixaqdGAgICAgICAgIA=", + "0U8osqi1HYTe97iCTnB/wiNHV8Xjs/3L47+tbWz97ok=": "4Z806dKkpQxPAvfQVhQh4MPknlcmhwjBoL44M7l6DdQaZg==", + "c5FdtCCx505h62R2CqXjj26Bipb7q8LLLWmD57XRZC4=": "5qAg++NpBR6i/Mb4jLo5FAqZbK5hsNNJsxTh15/k3mg3SoSD5OHA", + "GoWdBoUM9GDeTwAycHFDzVfL4mqKlx8x0gYn/pbGtXI=": "+NGgWvuROhyCEXBF1xLhfuSr4eRNM3JdZU+8TunTrJ35RneAoIjnV4PobenZb9LLNkyMEy3xwec9b53ZIyCzUgLjP6/5oEO7FY28svix8THG2PINDK0eeSqms+el3rET7a/uHKhsgKBobnQNhRvIWUFbgTdD7NNK98bhtN1ta+P5JNL18EkL6KDVH7isE4PNtJknPpTC+ha6RULZInisrYeDOv2/xyf2fYCAgKAfNPwDzfVFQ5nmJ2rd2UyGlKvyLI7oEKF8IGSVioQ+kYCAgICAgA==", + "dKCH1lclUHQPLRpRY51wYiFnYDcp0FxWF0/xz0qO3tI=": "+HGAgICAoM4/vP9TzWd9mEJJli4Ag8G5S4fQyMmslnL3+ypLyNOhoDs+Qn5MbzIeVG47YP1lqDKwKq5tCvJqfwSjUgr5vreboEkpnjpvGqpg77I070nOk8hUJD8icMb7IQGPvrguMmuGgICAgICAgICAgA==", + "4h49KPn06pERCAKkgnvs++ZgckM7D00jVf6MHQXkQTQ=": "4qAgEr3YLiIfen37rrBoFjCKfYxwBO4G6+jvvNiRdrtqZjM=", + "w1N1/Lnt2e0+pcjr2GQp7xAC1et6kYWj8cNgcOfzcE8=": "+EKfICTsYlac8Hf07+EmnYOsWzO3uXmRR5cP61e7a41Q/aGgayI6MCwiZGFvRm9ya1N1cHBvcnQiOnRydWUsImVpcDE=", + "1tomgX9XHOTZABebCrFZopfofFN0E4WeLW1nFVt8YKQ=": "+QIRoOG8pe5eO3q05ZX3ky53Vwpve3VgXwZHxwVG5DUPGOIcoGXh3petLcUVVxcXnLZiSfcoGp+aU3gUHrd19g3KpdyFoHZ8ZUCTthJI3KF/V2jB+NCpH2LrhZuppK6WtPuz+mIToBIs8KawfnvDppYMl3L2u3jfb6P0d8ps09wMhiz4u9UooGLjvVKc7eOZxDfTl9gparoCj92qEIE0oCmcHWasH/H1oGpk5kGNguJTplTo9KFcNC+GkNuFNqO++EOu3a3GtLqroLMnZ0KczXB7xSZqHQCGheoTzQT0CtoLgxpd2/QfhdOToEiR8hiXmHYCMyY/1NH9Af0t2ADP2VsiSB4jlQHycXfXoBJKAqyLiIhknNjnyR6qhPXwf8to2Neo52IhZOB+29aDoJ2PWHeeLDZ/CIYYij6vcrSvMCGrT4qtkknwqtCYFq+ooDM7m+zNGGB9OJuFIlj5hWAzUdZO+T5afzb7FnY0iknzoHB8nfXP2wfDHS6+ZKn8NOhUijZWuW5N1GvZs7uC8D5UoMFudePR0Z/HcduH9RH7IfWn5bkjqhhqgs3d0HUp/9KBoEcXf+a6zRV6quf5H9xndgZJ9n1FFuAYMRWmT7ydXynfoEPl2WNt54nRmDaKjYROyCNz7TCMFAXyQSe9qETAQieroBqFnQaFDPRg3k8AMnBxQ81Xy+JqipcfMdIGJ/6WxrVygA==", + "nY9Yd54sNn8IhhiKPq9ytK8wIatPiq2SSfCq0JgWr6g=": "+NGAoMawi5vTuskmwfTynYPaT9MtC9ietkxIopRHSpifjQkwoHORXbQgsedOYetkdgql449ugYqW+6vCyy1pg+e10WQuoMkF3YLYhUczq9VoxPxEn/s1NKp2NmK6pxwiF2Led6LIgICAgICgeYdoiUAm3AJoYyDw5xMDtmqRE7vXU19yzcEqdS9d/GyAgKDeU9TP7u2Kn6y0kvGcf//zU6bnr9yC8RxvAlGsnm10EqDZdIa7VN7CjkVuUD293peaJRCNhnwKBvE/KgJ6nG8EBoCAgA==", + "emptk+jA3Coykf0ZFDgxSqEYHK81GRS5i+DV/t0rp/c=": "5p8/vCBpa8LarkQ5v//FfL0hCCNs9PjMhF8V6ZZd7roBhYQF9eEA", + "+1i8HXC31G+aE/LNphxrsKsFDrDkCH/F4plEk42V448=": "+GmgIJ1XvgXdaTccTdLocbzm6fQSQjaCW7YS7hikXlZ1vlG4RvhEAYCgrGb5kxcXdJXOlM/7rmI0drBHMzgisU0NuTfI+b550vigzu8fatbAy364+xVnir8R2jzg06fHEGqpAMWTDlVqQ/8=", + "2Ptqx7aEuc+eJrQ2aLNqQgnDEjV2MZv8rGAJ4ZFSTZg=": "7/AAARtdHVGU6dEogM7D2FjuVGEICrlpNFgfzuvyOl+3HCHJrN9rs6pSq92ySx5riL96gbBmiYJk9yDb114gOATwzBFHdzGn93LS1SJDgIXA9qZC3lS5OlNZIfTDDZhF5zbt8gILw8B0jPnz73WZ5b33/peluwsqwCVQU8hhLtOUlv7T/2fhZLXezFheow4IFuZmKQDQhatMWkMZ6K5s3dapozsZq9A9q3oMV1eLj9p5irEoBMQ3qJ7vMb+C4Wl4XGZWfNoCZCunK8VPInO9KSNu2knVuufqo//TkX1Xol8Ot2WcvThFlY06POL/tssBB7A2H8Co6pvbYJu8E0x3BanNWj/2/O04uH87tA9Etpy1/yIZHGBOjTHWlDLnSpYr0T5TLlnLy/IxlcqmBr3x46eDc9k8e23Pv7JfWFb2MjdLH6K2/nJvd+fgaPX1D1Q+mDkQjUmlc36ORqgU8uQUwOR35tSaAOeUDUljHKLnGqTNBplVVJVRUhWgqugZbtDrt33aMiPCIHLb1YQe7VRN3n4iTcyutCaqWlRU5b+Zez4lUuQxdpx6u1RVBdTFNdFeqBwqtVs+fQ59gV94p+BmdKE1vhMuL9WcrPMKg9WVUbni79OPTmDzW9dbgK7bgD3BeCe1CbXyGytzVmkZoivpOFuo55y7itTnxCvxZJV3VgoIrKuyQ3gn1OhT5cqF0kK2eV1P1QeKTDDbEUg4lRIcvKpWlAOCARScy2BIUtAtsA2aBbZBWYC2EW6N8GqcAmpKKGFbiyT/0Rl0YSwXxb4KXxp7mIsaEJpB8LB9wTJgu1KIyNJifvAUp8sPx8sXIR/skjcGeaETZyJoxwNMS4ymGA0x6mLUxKiKUYFRFlESURRREJEXkRORFZGBSAtJCUkKSQiJC4kJiQqJgGix11R6DReJvi0kMDRx7tkMwjhC1xgKGDWafPx0LeChDZuOWc5U0mOIeWUm8C1uhV7dP9tBGcjPcYRFQOIKfV2A1I1atP3qj+0wFuwu2cXSTv5hFMGTTKcNdUnaY4X3yPHxXtdwo7VF2u7jI7yGG74/nKWHmL3zGr69zzV8e59ruHnHNdz8lSgivBNAh2lNVZxlI8w+CyChDD0zxI/9ExY5EEdZu2hR3f8UP0sI/PJTqefx+HiP8OPdw098CyvQdVfAb4aSoPz/DXwqSkCokigPmxnSeZn3Xxih0GQi72A6UauFDA4EJzByccuDNQFCjaRMAAnhk21kNMf8p54kNJNsFcCvpE7ajqj0l2Hqoi+fgM+gdDjF+e8IqitevKB3jMSYBv22oOeH+RftDS0kzWv/6dBOIbI7YMyyNdInRkhH6TsjZD9fFBj00mFoMYgZD6+vLlP1TJWrL978/K0ukoZlJx+fZgQX1pqAOl3F5Kma3ghqbJ0PfYQERUNZILmw/VMvScC2/C7fbKDlMXPHqVza/ZzQ2Jg3+siZMl2KYzfTIg0XacGddSXiOKIUheQxugcdqfVZ5KMJNNgkt+uUYVyo0JzrCoJtsmSix4LTwDltuwnKNC7xQORywwrEQ0H7rXnGwVFyNybRI8fGNaS1VnAVehqQjFVsYpuIYQaAwJK74JjIuRtJ6xJblLRxSI3S0WSqgkDsmWY2tgUL4xUpIjdpETdtaQmexS9vjd0HM8sjJQhsUrS3M34WJH0mU0SNpMlEMMZvpSwgKmeGwpkGm9eoorbRzfQ2ItnCyhIACPGyfQmMLkpmEUUeMPWzTR3AqeJ35/YGYkHfGSZvhYm22eCaRstuIOxOA2H4rdeqD0um0mgZJXW3tutf2YYqaSUCjpGpZrBDbvmeduUx+I0d9Rwkx9afygem4cuhRXgQQJIg06/GTXPf4v8v/GrBQ4lBK4jlnhyw7BDugWKyYqudGfl52n8MNRET3U2h5Q1uxFyilgr1dP92jgKBCGwnoAyG8Yw+kauq3+J0EL/jp+CroYUQLV2wxNEI8j9EcWBwtN2rnYdiwQiXFpf4hrYf0gpQz1XkA5tmPt+6imLXPMuUmHqGE0Q+Vvb3H9Jkr1BzMxtnvor/i0dySOFgXHVJSXKlo2BOtDyeCsxgvGXG7nE5dGUSlz4V+WNxQu0+Ha6d/x/dq6/o3WbfXDrHRlEfhbEMoc+o0FZNlGLwlT/vjONzO09fEzodKViGPIWAd6aBoSHEXPSuqoGdKQqj9oExln+oeysxSxOP4gBu5WkMw51nHAxkHUEJy0oC3KKZXV4Z+idLNRuelEvI/5H82LzvyCFB7VxH9cgDFZZTAWZ6ihvrCD1h+EQ2CNMR4KdGpb2Kep4qemsh/M710KSmoNDwVaknNkBynmCYIl+M6L7FlR634zYVFebgocAUcSH2rC31PRX3ELUfWpHTByFw9B+8I9vreyM6EeOiBiRYvWAby+wSHDUz11JDxVQ2HfGAPyNBaYNRMtxRp5dW+iqt5kD+pX9ne4kzJycJQqzZNMl1etLfP1j3IG1Xfbxi2129kMoZkO05v7WeQtdj4eCriIEV3e5+F+a6wbWb1pJXKHlprfAG6Frh0lrrXRDI1lCFrkWvZungZDLy/v0ErhzwmLg4OG/1ihi4a5DYq1wI5GS/vWONOcHIdAJV97uYZk35qOU7rNWpdcDiYmIky9/NlZ2EJJeUbO6FpdWrthh7jdwjE79Du1HwGXWQCQdrePyQQdTjDEdYVaBq0KoBG/VAhcbtWHZ76toBCEwmJdGXVcjZptXnJGYxmix2r1k+385oFJaQlKgPWhPIYDSri5xdQZRE7y1tbDDOYJKfLPvTp8MGeKyCwQGOCwavRff78nf05zZC62yZjrQx21ASElTzR6N8JowxPpp4VW/G3x2cDLR8JvrFBQPvnt8z5y440TgifFlPVcez73WNzJ/js4F9OjnjwZHXqOZsST4RP86OD4hbhzZBVOL1PAF+AIYkgusKAjHrqHOxAGLaZwOGOcZ9B4oPdDOhLYsgejdpkk+wgXyzzmLqK5+2ZrrbIwA6oHBrL2DMETy0R0QvMGRKKHDFgD8rNhLAAjL8MKBeaslmDgaxe04YCeMozug9n+IpbmuVMuWdzPdwfITgcvYtfrkyz4ffqHX1O2htWZ2an66s2iwaK1tf+gP4tnF6/QF/pkS4p9kQSan8Fj9dCdNfQoSQJESSERBGQQ6LiAumN/NTcjDt2ZsV1cjgjj63SfG6g9hbDoCwBS9gu8qtX8NSJ9s8AQyJCykb7A1jISJbxekfrCSRDy3TSZrvfsOOn6D6oSEthTD6kJ+8m/tQKHfRxXO6u2EW4oNeqGqN1Wd3mvjRuvuZoHMtULATx+hfDtNbWcJ01PAw750DP51i1lH5P86dQDh9hKlWxM9/OhkspVagngmEc9DmGcYlKx8I", "J5FwDDqTOASPiTfyngRhTP+IwBE9bY16qWusdOrlCB0=": "+HCgM4DHt66BpY65jZx43kof1/2VNfyVPtK+YC2qpBdnMSq4TfhLgIcBKv1U/iGqoFboHxcbzFWm/4NF5pLA+G5bSOAbmWytwAFiL7XjY7QhoMXSRgGG9yM8kn59stzHA8DlALZTyoInO3v62ARdhaRw", - "+6VKSRFzV4EUzu8H2UsLEW/eErzSDipc6Do2cAiY0K0=": "+FGAgICAoK0pLyVWJZ8LZ99bL0DLTG4AIdm4lBHqbUKE80L/GbrmgICAgICAgICAoI8t2Y3yEGoV/6nH7cw0UDJfvOZdrkkoJW3o/+FHDiDBgIA=", - "wW5149HRn8dx24f1Efsh9afluSOqGGqCzd3QdSn/0oE=": "+HGAgICAgKBLSROEcOHpBnMj/3LFwcPZDteVOgjSvRUamUA9JCtgU4CAgKCL1QyyQwxwsMj2LL2h61NskWc370pRfQdlORNChoS724CAgICAoGipiic72NEG91yujpOzxRuigD7aKHKeqJVdvpcoM4DZgA==", - "Dm5wic2CwG4arAjqkuH9TvlGVILwaD9N5S7J1CbQam8=": "+FGAgICAgICAgICAgICgr9hmbujOTyptLwYi0zNf0llJsmWfGddIvBOGQVSwZr6AoHpqbZPowNwqMpH9GRQ4MUqhGByvNRkUuYvg1f7dK6f3gIA=", - "rSkvJVYlnwtn31svQMtMbgAh2biUEeptQoTzQv8ZuuY=": "+GmgIGjbBfIcM/iLt85QaH2X4fDh0BbJ+iRX1aoRWDc1fMq4RvhEAYCgVugfFxvMVab/g0XmksD4bltI4BuZbK3AAWIvteNjtCGg2Ptqx7aEuc+eJrQ2aLNqQgnDEjV2MZv8rGAJ4ZFSTZg=", - "MfKwovvHT0H+yJcmtJFHYro6pgWPJ5IzE8Ow5+QlJQg=": "+EKfNZUsxum0Cp1/KGzPIWCuUQmqvXqp6vNanV64s0dFxaGgb25zdGFudGlub3BsZUJsb2NrIjowLCJwZXRlcnNidXI=", - "ZDC5L1lfFW5noXszFBOUBDq4ASEOF2vzBa4e+DNzfms=": "+EKfMCs0zUhggQyA09yo3M9lblF6lxjOlue1I2hPMlSqYaGgLCJsb25kb25CbG9jayI6MCwiZGVwb3NpdENvbnRyYWM=", - "PqnnqaKtw4uMbmE8jqOQOw6T9uSOBbOrKPjer54bNxM=": "+EOgIP4+RlG26qvgBENz2PjFXiVeO2nnuQv5mNs24kidDOqhoGxpdHlDb21taXR0ZWUiOmZhbHNlLCJJbml0aWFsQXJi", - "5zSQIE8PSLSx0cbsfBjTW8jm746ztENb/EbONW2s0tw=": "6aAgCH8Hc6Fx3cpHgPmzKLTjx7Ytlzy5bwjVTunqfXEJ44eGxNAyLllg", - "Ij8SnpM8iBZ1wqiedoawfIU3emoiwinFfOOo5SdLQGg=": "+QHRoAJ2LN2cz2FwnTqQ6smZZGhM2ggb3GKSaofN3+l/MVvFoBaxyvhNiY32ZSpUj+UkpvNSXHndQSAZo0wPi/LPlDIUoPbyw2wW3enDwnv6XwQmWRaUyZcBI0JLYqrK5rWzUWNvgKBzkWZztrphwRJ5hTcLy06ksUQsxZVyTAqT5XXuD35NvqAnkXAMOpM4BI+JN/KeBGFM/4jAET1tjXqpa6x06uUIHaC9j09XCFTcQTi1hHr/Kvi+u5V6nf57a3qv35PhuMSvgKB/9vrSUXXjLAegyh2E5As2Ra2Rd5gS2ZoDivAknExoaKB8ujMx6GtjTNlrlmCXCSzQZI4TVDc2bluwOnU/5Bn7W6D7pUpJEXNXgRTO7wfZSwsRb94SvNIOKlzoOjZwCJjQrYCgv7IFW2m1BFkCQmNvS6aURfxPONRxlTSnMi09kEGzeiCgdKCH1lclUHQPLRpRY51wYiFnYDcp0FxWF0/xz0qO3tKgOAcGQQJAdWRsdFboQecF+upU/xGQXF4LyrpN1FVhPBmgsthtqf+nnM/9KftHf9sEiXGfGxiSdQCn15r+I1A1t0ig9Dojmi9cOEMZUWBXSb0AatojroavPfTk+QOxop62rJmA", - "xsOcYNaTB29Nx03IbRaiz198CtXpbXc0jwq/CkrQH6s=": "+FGAgICAgICAgICgewt1lpK5fn7UYlg/ed+dhlnGsF5kdw+AMJ+ca6LJGayAgICgvuvtuR5A4MDJs5AmHN+Ce06NNmEPFwuTZ8ZHXBK8GIuAgIA=", - "z/PY61VoJPuBRP3MatMymzT0TSAQpnO7gy5PuEf+zSY=": "+EKfPj6STOum/lPdVlGhTIjrn2+55sl2M2mmCOMxD+VwmqGgIjp7IkVuYWJsZUFyYk9TIjp0cnVlLCJBbGxvd0RlYnU=", - "ETBT/l6CdvVaLi9ooHtTc8vmQvsQfMmaukqNRpc85P4=": "4qAgn7rEah2ic87FZAOEg1Eca65vL1sVk8DQDnkRH8R8ox4=", - "sydnQpzNcHvFJmodAIaF6hPNBPQK2guDGl3b9B+F05M=": "+JGgzhwMzDjPvj8BAJGNO4OxglwgtG5E4SGVmOJLKPyJlt+AgICAoAghGWzm3h+IDorrJwPzLXbgIg3E78NWDvotJ2n2JJnVgICAgICAoC04JSD9NVgfP/Gqxan/YM0QSzWGcxfYzAsduq3M3UQfgICgVl5U3j1vnqZnRhVS+Mj1Ps+4OOo6UX3xagQN8cUbIt+A", + "ID2jMhcGY32emt1I6Vu3PW1w4YABjl+mlzgmJ1Z2beE=": "4qAghcjGmIrHq/rPo2JB9O47LJ/VWmZehrm/i0+gEweZygI=", "Mzub7M0YYH04m4UiWPmFYDNR1k75Plp/NvsWdjSKSfM=": "+JGg+WniGCsri2LFViSPD2AI60v5EgNhM2k9ug2q/McmbweAgICAgICAgICg5zSQIE8PSLSx0cbsfBjTW8jm746ztENb/EbONW2s0tyAoLAza1S2xkkE53f5gJR1egT4iE/DAOtm7UljFaxoqXtaoCP4sZh3Of7PpossL7c/Nj46w05/b5UKB/Oh9EYUK6eigICA", - "+WniGCsri2LFViSPD2AI60v5EgNhM2k9ug2q/Mcmbwc=": "+EOgIIRPBOJCTGZwtGyApze6fAuimDWGj0//iS2kogBFF6WhoDUwQmxvY2siOjAsImVpcDE1NUJsb2NrIjowLCJlaXAx", - "WvuROhyCEXBF1xLhfuSr4eRNM3JdZU+8TunTrJ35Rnc=": "4hugyew99iybEu0GtKKLPOWA3wYNr69cRdr0F3iR685WYPk=", - "DnTASFL4Cx3ZRQ7uFuFL0SEXuRpvNifhKCUaTbL10k4=": "+HGgHgQ7bqaKkOjgcL+YXhQmY8KPaEi2sqvU8TrOjQ941f2gijG0HUCxtKA3HobDKxXL5N+StHEvVw8yDoFdkWELifOAgICAgICAgICAoKBn2PLKcUJPAlPkVQKIvG3Jy+UGRBWUfr6apoE42eJLgICAgA==", + "kWwqvDcf1DF13LP7bNgFrHuDQw9zkyhpKuVEy7hYL34=": "+EOgIIzOE607Vcvsp238hPhYj8UCpHIyYEvxHVoDEsEscsqhoHsicGVyaW9kIjowLCJlcG9jaCI6MH0sImFyYml0cnVt", + "HiwXyC7al0/jlh5NiPWUerAm+qTUVy1R776Ame9kOVk=": "+EOgILSNuEkwsztx4Ye9wcKUbKKDk/E+bGD7VyYqYvuzjuKhoBh2nAw5ScmwSLwR4u6BfdQhZdjYNBgHhU1FpEaMlS64", "zhwMzDjPvj8BAJGNO4OxglwgtG5E4SGVmOJLKPyJlt8=": "+EOgIGGjC1AKR52t7JqtzTEPH5hMnctqby9txb20aZBgjE2hoDAwMDAwMDAwMDAwMDAwMDAwMDAwMCIsImNsaXF1ZSI6", - "nY9Yd54sNn8IhhiKPq9ytK8wIatPiq2SSfCq0JgWr6g=": "+NGAoMawi5vTuskmwfTynYPaT9MtC9ietkxIopRHSpifjQkwoHORXbQgsedOYetkdgql449ugYqW+6vCyy1pg+e10WQuoMkF3YLYhUczq9VoxPxEn/s1NKp2NmK6pxwiF2Led6LIgICAgICgeYdoiUAm3AJoYyDw5xMDtmqRE7vXU19yzcEqdS9d/GyAgKDeU9TP7u2Kn6y0kvGcf//zU6bnr9yC8RxvAlGsnm10EqDZdIa7VN7CjkVuUD293peaJRCNhnwKBvE/KgJ6nG8EBoCAgA==", - "5ATJM/gtfbsC44E68Fq1cLO2HsWiW1wFyYTyVM8xHt4=": "+EKfMac3BAKInN3RCqOBIiEYHRLUZfXloOdpZxOv/MBbOaGgeyJjaGFpbklkIjo0MTIzNDYsImhvbWVzdGVhZEJsb2M=", - "ID2jMhcGY32emt1I6Vu3PW1w4YABjl+mlzgmJ1Z2beE=": "4qAghcjGmIrHq/rPo2JB9O47LJ/VWmZehrm/i0+gEweZygI=", - "EkoCrIuIiGSc2OfJHqqE9fB/y2jY16jnYiFk4H7b1oM=": "+NGAgICglsZGqMWCVOv4rP2W+yejXFvVh+ldznRCMJ68c/6PqMqguCuvB97/vjXV4qNPcHIrtWT9XnUIDVDOZIhDCZ2mtdSAgKDb6zR1OR1sXdAliYU8cs9VxnA6PMN1JKge5Z0ZnMAnZaCznUANpP6nM8epBPe4jZcandMuDdU5xyaaEGuBJs18dqAeLBfILtqXT+OWHk2I9ZR6sCb6pNRXLVHvvoCZ72Q5WYCg78Voc9FPQ51xcJ66LnCaeLtx9Hvrqc4hh8zZL1/C5IKAgICAgA==", + "Q+XZY23nidGYNoqNhE7II3PtMIwUBfJBJ72oRMBCJ6s=": "+NGAgICgF7TiEZ4xnGsOwap/PpDdE+QlfNTZpmRYJbskh7dng+uAoNoSx7LHa6TLWAloAKO0JVRfmH6l+wbRwIc8CxwrpHOBgICgVXwF38O/SCYqMDPkAxkbyNt1ahY2dkY+AWkB3CH3XrOgul2Rut+Do5u5AqDitzcN9s1zWR+32JnNcTtMsEXAZGegJmk3TRLT7eM7gvKJjjBLGxD64Gs3iHuFJEgYHtCft+2AoD6p56mircOLjG5hPI6jkDsOk/bkjgWzqyj43q+eGzcTgICAgA==", + "ETBT/l6CdvVaLi9ooHtTc8vmQvsQfMmaukqNRpc85P4=": "4qAgn7rEah2ic87FZAOEg1Eca65vL1sVk8DQDnkRH8R8ox4=", + "WvuROhyCEXBF1xLhfuSr4eRNM3JdZU+8TunTrJ35Rnc=": "4hugyew99iybEu0GtKKLPOWA3wYNr69cRdr0F3iR685WYPk=", + "yew99iybEu0GtKKLPOWA3wYNr69cRdr0F3iR685WYPk=": "+FGAgKB1g/ukkoQBzYVMFb2DHyRddiSH2DS1DazxGRRjkuyNWYCAgICAgICgw1N1/Lnt2e0+pcjr2GQp7xAC1et6kYWj8cNgcOfzcE+AgICAgIA=", "v/nZZIhCiYGJwfvJ4gd9HauzYSzmL6kUhpY0/kmb1I8=": "+EOgINv2WDSH/niY/t0p9sJ1u51PMGzwjSo0TP1KNFlSWM6hoHRBZGRyZXNzIjoiMHgwMDAwMDAwMDAwMDAwMDAwMDAw", - "oGfY8spxQk8CU+RVAoi8bcnL5QZEFZR+vpqmgTjZ4ks=": "+EGfN8kEik7d181t1bMP3cLgw2l3NgMITDTK7vpyCTRPmqCfAgUHAdUAAQF+cQACQAAAAAAAAAAAAAAAAAAAAAAAAA==", - "CHLa4VPBFw3g+p4GA/SbfgK2x/PYXLMj0oWI+jtYsqw=": "+GmgIJ1XvgXdaTccTdLocbzm6fQSQjaCW7YS7hikXlZ1vlG4RvhEAYCgAVsV5xXdgS+1KDip33nucWFlEUCUMLQi9FIK6Z9HxUegzu8fatbAy364+xVnir8R2jzg06fHEGqpAMWTDlVqQ/8=" + "gpnOL68yBh+53YG5Gd6gaCf7osNdu+/1Y62vfztpOHY=": "+FGAgICAgICAgICgz/PY61VoJPuBRP3MatMymzT0TSAQpnO7gy5PuEf+zSaAgKDRTyiyqLUdhN73uIJOcH/CI0dXxeOz/cvjv61tbP3uiYCAgIA=", + "sydnQpzNcHvFJmodAIaF6hPNBPQK2guDGl3b9B+F05M=": "+JGgzhwMzDjPvj8BAJGNO4OxglwgtG5E4SGVmOJLKPyJlt+AgICAoAghGWzm3h+IDorrJwPzLXbgIg3E78NWDvotJ2n2JJnVgICAgICAoC04JSD9NVgfP/Gqxan/YM0QSzWGcxfYzAsduq3M3UQfgICgVl5U3j1vnqZnRhVS+Mj1Ps+4OOo6UX3xagQN8cUbIt+A", + "zj+8/1PNZ32YQkmWLgCDwblLh9DIyayWcvf7KkvI06E=": "+GmgIJJBgpRGrVcLW5fTilBHgqZSIgTGfV8pthUVJG0EENy4RvhEgICgVugfFxvMVab/g0XmksD4bltI4BuZbK3AAWIvteNjtCGgvMkPLW2tpbGOFVwXocClWSCq6U85hX050NjtB66PIos=", + "amTmQY2C4lOmVOj0oVw0L4aQ24U2o774Q67drca0uqs=": "+QERoAytPlIijiztbmTDULc1tclIt2cRCw3Ot6D5xI4edQQ9gKDB0t5TvbBKApAxzeNMS/6kVm+W90pmo/a9JINOztl4/4CAgKCB8Ea0qY59dMPZ1EvqojstfXI0q7vKVV3NL6FcxCFY+4CAoMGbduUDJpfU8oZBC60UWBVkKLzBypg6omSWFWYdISkxoKslRe1mHtHF59VZAezGqVgzD1gEePbGyfY/R2CYMJ6NgICgeFDgyflenYm1RRuJPmtND0NJtb6mbdUCEvjS8F8TqVCgeo+BP27pw5jBU/hw0hbFaxgPWf/LrnX/sG0de0CDhJugU2neamdXOzBA0w3986FtVQXIynLZLm+gc+xwW/3wLZyA", + "ZDC5L1lfFW5noXszFBOUBDq4ASEOF2vzBa4e+DNzfms=": "+EKfMCs0zUhggQyA09yo3M9lblF6lxjOlue1I2hPMlSqYaGgLCJsb25kb25CbG9jayI6MCwiZGVwb3NpdENvbnRyYWM=", + "lsZGqMWCVOv4rP2W+yejXFvVh+ldznRCMJ68c/6PqMo=": "+FGAgICAgICAgICAgICgZDC5L1lfFW5noXszFBOUBDq4ASEOF2vzBa4e+DNzfmuAoOQEyTP4LX27AuOBOvBatXCzth7FoltcBcmE8lTPMR7egIA=", + "gfBGtKmOfXTD2dRL6qI7LX1yNKu7ylVdzS+hXMQhWPs=": "+EOgIIBzjzlIbl+Sb84y26s+3m8wqB6NWpiKKmdTUmpPqLahoGdCbG9jayI6MCwiaXN0YW5idWxCbG9jayI6MCwibXVp", + "wdLeU72wSgKQMc3jTEv+pFZvlvdKZqP2vSSDTs7ZeP8=": "+EOgIPeKg/Qog9t+mMP6hEiQzW3La3nCUvs6Jbno+cpb7FWhoDAwMDAwMDAwMDAwMDAiLCJHZW5lc2lzQmxvY2tOdW0i", + "rGb5kxcXdJXOlM/7rmI0drBHMzgisU0NuTfI+b550vg=": "+NGgoWOPV8QRc8bL5aTuekGBq6MShXhFvCCWFt/F0uCDhcqAoF+ul2lcDQ+h/IecCy+kLjAZbfdBaWh0yBvyOfw9i4y9gKCp9zYu5JRNU5PkeALSfvg1P+nl6h/eEZwIFzjnIaTn9YCAgKCjR2M2ZyFGKgNhOa2ZSnssi/gf5n4OFjRrrJCIqlpOmICAoMoooo8Dmpbdb39ZEuZtRZtz2NzZlC1v5pLMQiBV3gd2oAVhDckU8kcYtEOuXpdOD2FpiHpvxUiH+e1ZvBIiBBrXgICAgA==", + "9Dojmi9cOEMZUWBXSb0AatojroavPfTk+QOxop62rJk=": "+GmgNbaTCFvrIbCHjH5fq3UZzg1hBTVM9nRNv7c+N0XpKeS4RvhEgICgVugfFxvMVab/g0XmksD4bltI4BuZbK3AAWIvteNjtCGgvMkPLW2tpbGOFVwXocClWSCq6U85hX050NjtB66PIos=", + "upuq9C/jOCFKGZEdj1ujb35hoHFsdX7wHYr7/5lsCrM=": "+FGAgICAoKO2vEKVeSmNtUsE2iIasGphJ3Hj8PK5GavbNCUCH/i+gICAgICAgICgVZ1CQ0C7YF/f3m/fJtrcNYFlvwB2P0YS5GIyYGujsu+AgIA=", + "BSZPysSa96q94ekuFtboty4KMV9TMNDILAVY22fxyVw=": "+QIgoMXZy253ve7MJasEGMq3+1OQod+H/J2cTvhgH2RMEMJOoB3MTejex116q4W1Z7bM1BrTEkUblIp0E/ChQv1A1JNHlKSwAAAAAAAAAAAAc2VxdWVuY2VyoPlUZb8ixcWx4jQbL1rkh6S8hRBFN9VwsBdRUnsYfezxoPpjJgloOxF/67TXp9o1lJ6Mcemcns75BlNuJ7iFj0x1oKNeEyvL4uOFopIF8Q/g0vI1/hEk/sTW2iDb//DI6+W1uQEAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAACAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGhwQAAAAAAACDII4ehGnGqEOgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAAAAAAAAAAAAAAAAAHgAAAAAAAAAzAAAAAAAAAACIAAAAAAAAAAGEBfZWMA==", + "4byl7l47erTllfeTLndXCm97dWBfBkfHBUbkNQ8Y4hw=": "+HGAgKBVWPo2Pk7uyWpE2f6R/yjxtt9EKv8vl1pRe8e1ii+W4ICAgICAoCcW7c2xGr1tRFxYToyKKa2Z8VuUHN+7r+Uza3m5vPqfgICAgICAoOpx0wqneDsPQ9tBPHeazH7lbIxziHiRtZjQeqC68ESIgA==", + "3wdXKRG4rKtlA7M79KpSNWxktP/wuR3R2AbXKGA91bE=": "+ImgIAJd2ZjEpvRjvHcAwGhp5mrB+C+TpMowus3QUBG5tpK4ZvhkBqD//////////////////////////////////hAyeNOE7aBW6B8XG8xVpv+DReaSwPhuW0jgG5lsrcABYi+142O0IaDF0kYBhvcjPJJ+fbLcxwPA5QC2U8qCJzt7+tgEXYWkcA==", + "KLN98UhCLBUi1/hWfh64J+qrupWdDAkKkQDEFMXRzqU=": "+GifMU7InCAcI6pg4jHjmTs5ZrM/8fVdGY7CWYCVerMgZbhG+EQBgKDW2iaBf1cc5NkAF5sKsVmil+h8U3QThZ4tbWcVW3xgpKDF0kYBhvcjPJJ+fbLcxwPA5QC2U8qCJzt7+tgEXYWkcA==", + "+VRlvyLFxbHiNBsvWuSHpLyFEEU31XCwF1FSexh97PE=": "+QHRoAJ2LN2cz2FwnTqQ6smZZGhM2ggb3GKSaofN3+l/MVvFoBaxyvhNiY32ZSpUj+UkpvNSXHndQSAZo0wPi/LPlDIUoPbyw2wW3enDwnv6XwQmWRaUyZcBI0JLYqrK5rWzUWNvgKBzkWZztrphwRJ5hTcLy06ksUQsxZVyTAqT5XXuD35NvqAnkXAMOpM4BI+JN/KeBGFM/4jAET1tjXqpa6x06uUIHaBSoVFmqySoMyiWGiyJ+tn0r09rJWEe+viB965ooxgICKB/9vrSUXXjLAegyh2E5As2Ra2Rd5gS2ZoDivAknExoaKB8ujMx6GtjTNlrlmCXCSzQZI4TVDc2bluwOnU/5Bn7W6D7pUpJEXNXgRTO7wfZSwsRb94SvNIOKlzoOjZwCJjQrYCgupuq9C/jOCFKGZEdj1ujb35hoHFsdX7wHYr7/5lsCrOgdKCH1lclUHQPLRpRY51wYiFnYDcp0FxWF0/xz0qO3tKgOAcGQQJAdWRsdFboQecF+upU/xGQXF4LyrpN1FVhPBmgsthtqf+nnM/9KftHf9sEiXGfGxiSdQCn15r+I1A1t0ig9Dojmi9cOEMZUWBXSb0AatojroavPfTk+QOxop62rJmA" } }, "BatchInfo": [ { "Number": 6, - "DataB64": "AAAAAGm5dWMAAAAAabrU8wAAAAAAAAAAAAAAAAAAAC0AAAAAAAAAAQALYICGA4RpusbEggQeuLUABAL4sIMGSroGhAvrwgCEC+vCAIN6EgCUoCBiqkywhyMVrKPqbb8HfZCy2sGAuEEBW2PtQVqnRJ/TCnjq71QsMDg7Xe5wsEzYjw70SBWRK4gLxg7EpvPoBHtDobBSzIg7rKbCUt6kWhKTLx7LPbOVhsCAoPErgXOt/qsVIKhKrWuQC3OLMl0MJkOx7P3aFtiXVN7DoAd6+TpCXDrFRh4PFezCa/PQSH5+NDO5KgDZF1cr6CmAAw==" + "DataB64": "AAAAAGnFVuMAAAAAaca2cwAAAAAAAAAAAAAAAAAAAC0AAAAAAAAAAQALYICGA4RpxqhDggQfuLUABAL4sIMGSroGhAvrwgCEC+vCAIN6EgCUoCBiqkywhyMVrKPqbb8HfZCy2sGAuEEBaCLaJbqmV64Qqi6+Tz8cvm+hvS7OlZRXPbOfnsxnU4TJyGPim57Zqfrrp4fUK6weRLM0maPK3ldVowloJ10nuMABoIH5ZaDhSWQGIBihmncw7+FPA4Bdr9JtEBpnQSdQTlf5oGZEEhN8J3jzAIHG7QbNqiPKPvQkrOhJtKLrdfKip3w9Aw==" } ], "DelayedMsgB64": "", "StartState": { - "BlockHash": "0x07d488ef97b55e4938993c91666cf4e7829b8cc77555264f3917ba5b58c79739", + "BlockHash": "0x05264fcac49af7aabde1e92e16d6e8b72e0a315f5330d0c82c0558db67f1c95c", "SendRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", "Batch": 6, "PosInBatch": 0 }, "UserWasms": { "amd64": { - "0x18769c0c3949c9b048bc11e2ee817dd42165d8d8341807854d45a4468c952eb8": "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" + "0x18769c0c3949c9b048bc11e2ee817dd42165d8d8341807854d45a4468c952eb8": "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" }, "wavm": { "0x18769c0c3949c9b048bc11e2ee817dd42165d8d8341807854d45a4468c952eb8": "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" From 4c3712e7712470841724e7c5c0a5514451ac7b92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 31 Mar 2026 12:07:38 +0200 Subject: [PATCH 185/189] fix import --- crates/prover/src/machine.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/prover/src/machine.rs b/crates/prover/src/machine.rs index 5d79bb82c53..71ba2cba7fa 100644 --- a/crates/prover/src/machine.rs +++ b/crates/prover/src/machine.rs @@ -18,7 +18,7 @@ use std::{ use arbutil::{crypto, math, Bytes32, Color, DebugColor, PreimageType}; use brotli::Dictionary; -#[cfg(feature = "native")] +#[cfg(feature = "kzg")] use c_kzg::BYTES_PER_BLOB; use digest::Digest; use eyre::{bail, ensure, eyre, Result, WrapErr}; From f2e00a0764d0699c29c6a28234af8ecea7585457 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Thu, 2 Apr 2026 13:15:15 +0200 Subject: [PATCH 186/189] cargo fix --edition --workspace --allow-dirty --- crates/jit/src/machine.rs | 2 +- crates/prover/Cargo.toml | 2 +- crates/prover/src/binary.rs | 8 +++---- crates/prover/src/host.rs | 8 +++---- crates/prover/src/internal_func.rs | 2 +- crates/prover/src/machine.rs | 30 ++++++++++++------------- crates/prover/src/print.rs | 4 ++-- crates/prover/src/programs/depth.rs | 8 +++---- crates/prover/src/programs/dynamic.rs | 4 ++-- crates/prover/src/programs/meter.rs | 2 +- crates/prover/src/programs/mod.rs | 2 +- crates/prover/src/value.rs | 4 ++-- crates/prover/src/wavm.rs | 32 +++++++++++++-------------- 13 files changed, 54 insertions(+), 54 deletions(-) diff --git a/crates/jit/src/machine.rs b/crates/jit/src/machine.rs index 87d38377b18..bb66afcd52b 100644 --- a/crates/jit/src/machine.rs +++ b/crates/jit/src/machine.rs @@ -114,7 +114,7 @@ fn make_llvm_engine() -> Engine { fn imports(store: &mut Store, func_env: &FunctionEnv) -> wasmer::Imports { macro_rules! func { - ($func:expr) => { + ($func:expr_2021) => { Function::new_typed_with_env(store, func_env, $func) }; } diff --git a/crates/prover/Cargo.toml b/crates/prover/Cargo.toml index 282c9c88507..2fde57279b2 100644 --- a/crates/prover/Cargo.toml +++ b/crates/prover/Cargo.toml @@ -46,7 +46,7 @@ wat = { workspace = true } [dev-dependencies] criterion = { workspace = true, features = ["html_reports"] } -rand = { workspace = true } +rand = { workspace = true, features = ["std", "std_rng"] } [build-dependencies] forward = { workspace = true } diff --git a/crates/prover/src/binary.rs b/crates/prover/src/binary.rs index 8a4707f8847..94ac1080b1d 100644 --- a/crates/prover/src/binary.rs +++ b/crates/prover/src/binary.rs @@ -356,7 +356,7 @@ pub fn parse_with_version<'a>( use Payload::*; macro_rules! process { - ($dest:expr, $source:expr) => {{ + ($dest:expr_2021, $source:expr_2021) => {{ for item in $source.into_iter() { $dest.push(item?.into()) } @@ -573,7 +573,7 @@ impl<'a> WasmBinary<'a> { /// this macro exists since middlewares aren't sized (can't use a vec without boxes) macro_rules! apply { - ($middleware:expr) => { + ($middleware:expr_2021) => { let mut mid = Middleware::::instrument(&$middleware, index)?; mid.locals_info(&locals); @@ -687,7 +687,7 @@ impl<'a> WasmBinary<'a> { // not strictly necessary, but anti-DoS limits and extra checks in case of bugs macro_rules! limit { - ($limit:expr, $count:expr, $name:expr) => { + ($limit:expr_2021, $count:expr_2021, $name:expr_2021) => { if $count > $limit { bail!("too many wasm {}: {} > {}", $name, $count, $limit); } @@ -716,7 +716,7 @@ impl<'a> WasmBinary<'a> { let max_len = 512; macro_rules! too_long { - ($name:expr, $len:expr) => { + ($name:expr_2021, $len:expr_2021) => { bail!( "wasm {} too long: {} > {}", $name.red(), diff --git a/crates/prover/src/host.rs b/crates/prover/src/host.rs index 0eff62e4079..ed88e061c37 100644 --- a/crates/prover/src/host.rs +++ b/crates/prover/src/host.rs @@ -123,10 +123,10 @@ impl Hostio { () => { FunctionType::default() }; - ([$($args:expr),*]) => { + ([$($args:expr_2021),*]) => { FunctionType::new(vec![$($args),*], vec![]) }; - ([$($args:expr),*], [$($outs:expr),*]) => { + ([$($args:expr_2021),*], [$($outs:expr_2021),*]) => { FunctionType::new(vec![$($args),*], vec![$($outs),*]) }; } @@ -180,10 +180,10 @@ impl Hostio { let mut body = vec![]; macro_rules! opcode { - ($opcode:expr) => { + ($opcode:expr_2021) => { body.push(Instruction::simple($opcode)) }; - ($opcode:expr, $value:expr) => { + ($opcode:expr_2021, $value:expr_2021) => { body.push(Instruction::with_data($opcode, $value as u64)) }; } diff --git a/crates/prover/src/internal_func.rs b/crates/prover/src/internal_func.rs index ec243664d20..8b07f9b8200 100644 --- a/crates/prover/src/internal_func.rs +++ b/crates/prover/src/internal_func.rs @@ -31,7 +31,7 @@ impl InternalFunc { pub fn ty(&self) -> FunctionType { use InternalFunc::*; macro_rules! func { - ([$($args:expr),*], [$($outs:expr),*]) => { + ([$($args:expr_2021),*], [$($outs:expr_2021),*]) => { FunctionType::new(vec![$($args),*], vec![$($outs),*]) }; } diff --git a/crates/prover/src/machine.rs b/crates/prover/src/machine.rs index 71ba2cba7fa..e6a3019159d 100644 --- a/crates/prover/src/machine.rs +++ b/crates/prover/src/machine.rs @@ -397,7 +397,7 @@ impl Module { Instruction::simple(Opcode::Return), ]; Function::new_from_wavm(wavm, import.ty.clone(), vec![]) - } else if let Ok((hostio, debug)) = host::get_impl(import.module, import_name) { + } else { match host::get_impl(import.module, import_name) { Ok((hostio, debug)) => { ensure!( (debug && debug_funcs) || (!debug && allow_hostapi), "Host func {} in {} not enabled debug_funcs={debug_funcs} hostapi={allow_hostapi} debug={debug}", @@ -405,14 +405,14 @@ impl Module { import.module.red(), ); hostio - } else { + } _ => { bail!( "No such import {} in {} for {}", import_name.red(), import.module.red(), bin_name.red() ) - }; + }}}; ensure!( &func.ty == have_ty, "Import {} for {} has different function signature than export.\nexpected {} in {}\nbut have {}", @@ -1427,13 +1427,13 @@ impl Machine { ($opcode:ident) => { entrypoint.push(Instruction::simple(Opcode::$opcode)); }; - ($opcode:ident, $value:expr) => { + ($opcode:ident, $value:expr_2021) => { entrypoint.push(Instruction::with_data(Opcode::$opcode, $value)); }; - ($opcode:ident ($inside:expr)) => { + ($opcode:ident ($inside:expr_2021)) => { entrypoint.push(Instruction::simple(Opcode::$opcode($inside))); }; - (@cross, $module:expr, $func:expr) => { + (@cross, $module:expr_2021, $func:expr_2021) => { entrypoint.push(Instruction::with_data( Opcode::CrossModuleCall, pack_cross_module_call($module, $func), @@ -1975,7 +1975,7 @@ impl Machine { () => { error!("") }; - ($format:expr $(, $message:expr)*) => {{ + ($format:expr_2021 $(, $message:expr_2021)*) => {{ if self.debug_info { println!("\n{} {}", "error on line".grey(), line!().pink()); println!($format, $($message.pink()),*); @@ -2665,7 +2665,7 @@ impl Machine { name: &str, ) -> Result<()> { macro_rules! pull_arg { - ($offset:expr, $t:ident) => { + ($offset:expr_2021, $t:ident) => { value_stack .get(value_stack.len().wrapping_sub($offset + 1)) .and_then(|v| match v { @@ -2676,7 +2676,7 @@ impl Machine { }; } macro_rules! read_u32_ptr { - ($ptr:expr) => { + ($ptr:expr_2021) => { module .memory .get_u32($ptr.into()) @@ -2684,7 +2684,7 @@ impl Machine { }; } macro_rules! read_bytes_segment { - ($ptr:expr, $size:expr) => { + ($ptr:expr_2021, $size:expr_2021) => { module .memory .get_range($ptr as usize, $size as usize) @@ -2792,7 +2792,7 @@ impl Machine { fn stack_hashes(&self) -> (FrameStackHash, ValueStackHash, InterStackHash) { macro_rules! compute { - ($stack:expr, $prefix:expr) => {{ + ($stack:expr_2021, $prefix:expr_2021) => {{ let frames = $stack.iter().map(|v| v.hash()); hash_stack(frames, concat!($prefix, " stack:")) }}; @@ -2805,7 +2805,7 @@ impl Machine { // + Keccak("cothread:" + 2nd_stack+Keccak("cothread:" + 3drd_stack + ...) // ) macro_rules! compute_multistack { - ($field:expr, $stacks:expr, $prefix:expr, $hasher: expr) => {{ + ($field:expr_2021, $stacks:expr_2021, $prefix:expr_2021, $hasher: expr_2021) => {{ let first_elem = *$stacks.first().unwrap(); let first_hash = hash_stack( first_elem.iter().map(|v| v.hash()), @@ -2897,12 +2897,12 @@ impl Machine { let mut data = vec![self.status as u8]; macro_rules! out { - ($bytes:expr) => { + ($bytes:expr_2021) => { data.extend($bytes); }; } macro_rules! fail { - ($format:expr $(,$message:expr)*) => {{ + ($format:expr_2021 $(,$message:expr_2021)*) => {{ let text = format!($format, $($message.red()),*); panic!("WASM validation failed: {text}"); }}; @@ -3200,7 +3200,7 @@ impl Machine { } PopCoThread => { macro_rules! prove_pop { - ($multistack:expr, $hasher:expr) => { + ($multistack:expr_2021, $hasher:expr_2021) => { let len = $multistack.len(); if (len > 2) { out!($hasher($multistack[len - 2])); diff --git a/crates/prover/src/print.rs b/crates/prover/src/print.rs index 28cf599f170..6ebeb5e68a8 100644 --- a/crates/prover/src/print.rs +++ b/crates/prover/src/print.rs @@ -65,13 +65,13 @@ impl Display for Module { let mut pad = 0; macro_rules! w { - ($($args:expr),*) => {{ + ($($args:expr_2021),*) => {{ let text = format!($($args),*); write!(f, "{:pad$}{text}", "")?; }}; } macro_rules! wln { - ($($args:expr),*) => {{ + ($($args:expr_2021),*) => {{ w!($($args),*); writeln!(f)?; }}; diff --git a/crates/prover/src/programs/depth.rs b/crates/prover/src/programs/depth.rs index 1dca94c4396..41c140c426a 100644 --- a/crates/prover/src/programs/depth.rs +++ b/crates/prover/src/programs/depth.rs @@ -236,7 +236,7 @@ impl FuncDepthChecker<'_> { let mut stack: u32 = 0; macro_rules! push { - ($count:expr) => {{ + ($count:expr_2021) => {{ stack += $count; worst = worst.max(stack); }}; @@ -245,7 +245,7 @@ impl FuncDepthChecker<'_> { }; } macro_rules! pop { - ($count:expr) => {{ + ($count:expr_2021) => {{ stack = stack.saturating_sub($count); }}; () => { @@ -253,7 +253,7 @@ impl FuncDepthChecker<'_> { }; } macro_rules! ins_and_outs { - ($ty:expr) => {{ + ($ty:expr_2021) => {{ let ins = $ty.inputs.len() as u32; let outs = $ty.outputs.len() as u32; push!(outs); @@ -272,7 +272,7 @@ impl FuncDepthChecker<'_> { } #[rustfmt::skip] macro_rules! block_type { - ($ty:expr) => {{ + ($ty:expr_2021) => {{ match $ty { BlockType::Empty => {} BlockType::Type(_) => push!(1), diff --git a/crates/prover/src/programs/dynamic.rs b/crates/prover/src/programs/dynamic.rs index 26abb260b39..22a7e292276 100644 --- a/crates/prover/src/programs/dynamic.rs +++ b/crates/prover/src/programs/dynamic.rs @@ -85,14 +85,14 @@ impl<'a> FuncMiddleware<'a> for FuncDynamicMeter { }; } macro_rules! get { - ($global:expr) => { + ($global:expr_2021) => { GlobalGet { global_index: $global, } }; } macro_rules! set { - ($global:expr) => { + ($global:expr_2021) => { GlobalSet { global_index: $global, } diff --git a/crates/prover/src/programs/meter.rs b/crates/prover/src/programs/meter.rs index b28c032f754..4864ebef9c2 100644 --- a/crates/prover/src/programs/meter.rs +++ b/crates/prover/src/programs/meter.rs @@ -339,7 +339,7 @@ pub trait GasMeteredMachine: MeteredMachine { impl MeteredMachine for Machine { fn ink_left(&self) -> MachineMeter { macro_rules! convert { - ($global:expr) => {{ + ($global:expr_2021) => {{ $global.unwrap().try_into().expect("type mismatch") }}; } diff --git a/crates/prover/src/programs/mod.rs b/crates/prover/src/programs/mod.rs index 60e8cba207d..aa1a01e6a64 100644 --- a/crates/prover/src/programs/mod.rs +++ b/crates/prover/src/programs/mod.rs @@ -448,7 +448,7 @@ impl Module { }; macro_rules! pay { - ($us:expr) => { + ($us:expr_2021) => { let amount = us_to_gas($us); if *gas < amount { *gas = 0; diff --git a/crates/prover/src/value.rs b/crates/prover/src/value.rs index fdd71965469..f655ab3d5e0 100644 --- a/crates/prover/src/value.rs +++ b/crates/prover/src/value.rs @@ -289,12 +289,12 @@ impl Display for Value { let rparem = ")".grey(); macro_rules! single { - ($ty:expr, $value:expr) => {{ + ($ty:expr_2021, $value:expr_2021) => {{ write!(f, "{}{}{}{}", $ty.grey(), lparem, $value, rparem) }}; } macro_rules! pair { - ($ty:expr, $left:expr, $right:expr) => {{ + ($ty:expr_2021, $left:expr_2021, $right:expr_2021) => {{ let eq = "=".grey(); write!( f, diff --git a/crates/prover/src/wavm.rs b/crates/prover/src/wavm.rs index 52619a50122..d4d97ee3b3a 100644 --- a/crates/prover/src/wavm.rs +++ b/crates/prover/src/wavm.rs @@ -483,40 +483,40 @@ pub fn wasm_to_wavm( }; } macro_rules! opcode { - ($opcode:ident ($($inside:expr),*)) => {{ + ($opcode:ident ($($inside:expr_2021),*)) => {{ out.push(Instruction::simple(Opcode::$opcode($($inside,)*))); }}; - ($opcode:ident ($($inside:expr),*), @push $delta:expr) => {{ + ($opcode:ident ($($inside:expr_2021),*), @push $delta:expr_2021) => {{ out.push(Instruction::simple(Opcode::$opcode($($inside,)*))); stack += $delta; }}; - ($opcode:ident ($($inside:expr),*), @pop $delta:expr) => {{ + ($opcode:ident ($($inside:expr_2021),*), @pop $delta:expr_2021) => {{ out.push(Instruction::simple(Opcode::$opcode($($inside,)*))); stack -= $delta; }}; ($opcode:ident) => {{ out.push(Instruction::simple(Opcode::$opcode)); }}; - ($opcode:ident, @push $delta:expr) => {{ + ($opcode:ident, @push $delta:expr_2021) => {{ out.push(Instruction::simple(Opcode::$opcode)); stack += $delta; }}; - ($opcode:ident, @pop $delta:expr) => {{ + ($opcode:ident, @pop $delta:expr_2021) => {{ out.push(Instruction::simple(Opcode::$opcode)); stack -= $delta; }}; - ($opcode:ident, $value:expr) => {{ + ($opcode:ident, $value:expr_2021) => {{ out.push(Instruction::with_data(Opcode::$opcode, $value)); }}; - ($opcode:ident, $value:expr, @push $delta:expr) => {{ + ($opcode:ident, $value:expr_2021, @push $delta:expr_2021) => {{ out.push(Instruction::with_data(Opcode::$opcode, $value)); stack += $delta; }}; - ($opcode:ident, $value:expr, @pop $delta:expr) => {{ + ($opcode:ident, $value:expr_2021, @pop $delta:expr_2021) => {{ out.push(Instruction::with_data(Opcode::$opcode, $value)); stack -= $delta; }}; - (@cross, $module:expr, $func:expr) => { + (@cross, $module:expr_2021, $func:expr_2021) => { out.push(Instruction::with_data( Opcode::CrossModuleCall, pack_cross_module_call($module, $func), @@ -524,7 +524,7 @@ pub fn wasm_to_wavm( }; } macro_rules! load { - ($type:ident, $memory:expr, $bytes:expr, $signed:ident) => {{ + ($type:ident, $memory:expr_2021, $bytes:expr_2021, $signed:ident) => {{ ensure!($memory.memory == 0, "multi-memory proposal not supported"); let op = Opcode::MemoryLoad { ty: ArbValueType::$type, @@ -535,7 +535,7 @@ pub fn wasm_to_wavm( }}; } macro_rules! store { - ($type:ident, $memory:expr, $bytes:expr) => {{ + ($type:ident, $memory:expr_2021, $bytes:expr_2021) => {{ ensure!($memory.memory == 0, "multi-memory proposal not supported"); let op = Opcode::MemoryStore { ty: ArbValueType::$type, @@ -546,7 +546,7 @@ pub fn wasm_to_wavm( }}; } macro_rules! compare { - ($type:ident, $rel:ident, $signed:expr) => {{ + ($type:ident, $rel:ident, $signed:expr_2021) => {{ let op = Opcode::IRelOp(IntegerValType::$type, IRelOpType::$rel, $signed); out.push(Instruction::simple(op)); stack -= 1; @@ -572,7 +572,7 @@ pub fn wasm_to_wavm( }}; } macro_rules! call { - ($func:expr) => {{ + ($func:expr_2021) => {{ let ty = &func_types[($func) as usize]; let delta = ty.outputs.len() as isize - ty.inputs.len() as isize; opcode!(Call, ($func).into(), @push delta) @@ -585,7 +585,7 @@ pub fn wasm_to_wavm( ($func:ident $(,$data:ident)+) => { float!(@impl $func($($data),+)) }; - (@impl $func:expr) => {{ + (@impl $func:expr_2021) => {{ #[allow(unused_imports)] use crate::{ binary::{FloatInstruction::*, FloatType::*, FloatUnOp::*, FloatBinOp::*, FloatRelOp::*}, @@ -660,7 +660,7 @@ pub fn wasm_to_wavm( }; macro_rules! branch { - ($kind:ident, $depth:expr) => {{ + ($kind:ident, $depth:expr_2021) => {{ use Scope::*; let mut dest = 0; let scope = scopes.len() - $depth as usize - 1; @@ -718,7 +718,7 @@ pub fn wasm_to_wavm( }}; } macro_rules! height_after_block { - ($ty:expr) => {{ + ($ty:expr_2021) => {{ let ty = $ty; stack + block_type_results(*ty) as isize - block_type_params(*ty) as isize }}; From 7bb30343ffb78c9f48437772037f59c61dc6fb96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Thu, 2 Apr 2026 13:16:13 +0200 Subject: [PATCH 187/189] cargo +nightly fmt --- crates/prover/src/machine.rs | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/crates/prover/src/machine.rs b/crates/prover/src/machine.rs index e6a3019159d..10e72ce8c77 100644 --- a/crates/prover/src/machine.rs +++ b/crates/prover/src/machine.rs @@ -397,22 +397,27 @@ impl Module { Instruction::simple(Opcode::Return), ]; Function::new_from_wavm(wavm, import.ty.clone(), vec![]) - } else { match host::get_impl(import.module, import_name) { Ok((hostio, debug)) => { - ensure!( + } else { + match host::get_impl(import.module, import_name) { + Ok((hostio, debug)) => { + ensure!( (debug && debug_funcs) || (!debug && allow_hostapi), "Host func {} in {} not enabled debug_funcs={debug_funcs} hostapi={allow_hostapi} debug={debug}", import_name.red(), import.module.red(), ); - hostio - } _ => { - bail!( - "No such import {} in {} for {}", - import_name.red(), - import.module.red(), - bin_name.red() - ) - }}}; + hostio + } + _ => { + bail!( + "No such import {} in {} for {}", + import_name.red(), + import.module.red(), + bin_name.red() + ) + } + } + }; ensure!( &func.ty == have_ty, "Import {} for {} has different function signature than export.\nexpected {} in {}\nbut have {}", From 8a3e23797a1b3a9aa8a035e00b5d01e79ccd452f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Thu, 2 Apr 2026 13:16:42 +0200 Subject: [PATCH 188/189] bump workspace edition && cargo +nightly fmt --- Cargo.toml | 2 +- crates/arbutil/src/evm/api.rs | 6 +- crates/arbutil/src/evm/req.rs | 4 +- crates/arbutil/src/math.rs | 2 +- crates/arbutil/src/pricing.rs | 2 +- crates/brotli/src/cgo.rs | 2 +- crates/brotli/src/dicts/mod.rs | 4 +- crates/caller-env/src/arbcrypto.rs | 2 +- crates/jit/src/caller_env.rs | 2 +- crates/jit/src/machine.rs | 10 +- crates/jit/src/main.rs | 2 +- crates/jit/src/program.rs | 7 +- crates/jit/src/stylus_backend.rs | 8 +- crates/jit/src/test.rs | 2 +- crates/jit/src/wasip1_stub.rs | 2 +- crates/prover-ffi/src/machine.rs | 4 +- crates/prover-ffi/src/preimage.rs | 2 +- crates/prover/benches/merkle_bench.rs | 2 +- crates/prover/src/binary.rs | 10 +- crates/prover/src/host.rs | 6 +- crates/prover/src/kzg.rs | 4 +- crates/prover/src/machine.rs | 98 +++++++++++-------- crates/prover/src/main.rs | 6 +- crates/prover/src/memory.rs | 2 +- crates/prover/src/prepare.rs | 2 +- crates/prover/src/programs/config.rs | 6 +- crates/prover/src/programs/counter.rs | 2 +- crates/prover/src/programs/depth.rs | 6 +- crates/prover/src/programs/dynamic.rs | 4 +- crates/prover/src/programs/heap.rs | 4 +- crates/prover/src/programs/meter.rs | 9 +- crates/prover/src/programs/mod.rs | 58 ++++++----- crates/prover/src/programs/start.rs | 2 +- crates/prover/src/utils.rs | 2 +- crates/prover/src/value.rs | 8 +- crates/prover/src/wavm.rs | 6 +- crates/sp1/stylus-compiler-runner/main.rs | 5 +- crates/stylus/src/benchmarks.rs | 4 +- crates/stylus/src/env.rs | 4 +- crates/stylus/src/evm_api.rs | 2 +- crates/stylus/src/host.rs | 4 +- crates/stylus/src/lib.rs | 8 +- crates/stylus/src/native.rs | 12 +-- crates/stylus/src/run.rs | 4 +- crates/stylus/src/target_cache.rs | 2 +- crates/stylus/src/test/api.rs | 4 +- crates/stylus/src/test/misc.rs | 2 +- crates/stylus/src/test/mod.rs | 9 +- crates/stylus/src/test/native.rs | 17 ++-- crates/stylus/src/test/sdk.rs | 2 +- crates/stylus/src/test/timings.rs | 2 +- crates/stylus/src/test/wavm.rs | 2 +- crates/validation/src/lib.rs | 2 +- crates/validation/src/transfer/receiver.rs | 7 +- crates/validation/src/transfer/sender.rs | 7 +- crates/validation/src/transfer/tests.rs | 2 +- crates/validator/src/config.rs | 12 ++- crates/validator/src/engine/execution.rs | 6 +- crates/validator/src/engine/machine.rs | 17 ++-- .../validator/src/engine/machine_locator.rs | 14 +-- crates/validator/src/jwt.rs | 2 +- crates/validator/src/server.rs | 2 +- crates/validator/src/spawner_endpoints.rs | 8 +- crates/wasm-libraries/arbcompress/lib.rs | 3 +- crates/wasm-libraries/arbcrypto/lib.rs | 3 +- crates/wasm-libraries/host-io/lib.rs | 2 +- crates/wasm-libraries/user-host-trait/lib.rs | 9 +- crates/wasm-libraries/user-host/src/link.rs | 7 +- .../wasm-libraries/user-host/src/program.rs | 12 +-- crates/wasm-libraries/user-test/src/ink.rs | 2 +- crates/wasm-libraries/user-test/src/lib.rs | 2 +- .../wasm-libraries/user-test/src/program.rs | 8 +- crates/wasm-libraries/wasi-stub/lib.rs | 3 +- 73 files changed, 269 insertions(+), 244 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3ed985afc51..724c678a20e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,7 +39,7 @@ resolver = "2" [workspace.package] authors = ["Offchain Labs"] -edition = "2021" +edition = "2024" homepage = "https://arbitrum.io" license = "BSL" publish = false diff --git a/crates/arbutil/src/evm/api.rs b/crates/arbutil/src/evm/api.rs index 77b5047f888..f5c1ad945a6 100644 --- a/crates/arbutil/src/evm/api.rs +++ b/crates/arbutil/src/evm/api.rs @@ -3,10 +3,10 @@ use std::sync::Arc; -use eyre::{eyre, Result}; +use eyre::{Result, eyre}; use num_enum::IntoPrimitive; -use crate::{evm::user::UserOutcomeKind, Bytes20, Bytes32}; +use crate::{Bytes20, Bytes32, evm::user::UserOutcomeKind}; #[derive(Clone, Copy, Debug, PartialEq, Eq, IntoPrimitive)] #[repr(u8)] @@ -184,7 +184,7 @@ pub trait EvmApi: Send + 'static { /// Persists any dirty values in the storage cache to the EVM state trie, dropping the cache /// entirely if requested. Analogous to repeated invocations of `vm.SSTORE`. fn flush_storage_cache(&mut self, clear: bool, gas_left: Gas) - -> Result<(Gas, UserOutcomeKind)>; + -> Result<(Gas, UserOutcomeKind)>; /// Reads the 32-byte value in the EVM's transient state trie at offset `key`. /// Analogous to `vm.TLOAD`. diff --git a/crates/arbutil/src/evm/req.rs b/crates/arbutil/src/evm/req.rs index 80599d0be37..4a9be8ed5f9 100644 --- a/crates/arbutil/src/evm/req.rs +++ b/crates/arbutil/src/evm/req.rs @@ -3,16 +3,16 @@ use std::collections::hash_map::Entry; -use eyre::{bail, eyre, Result}; +use eyre::{Result, bail, eyre}; use super::api::{Gas, Ink}; use crate::{ + Bytes20, Bytes32, evm::{ api::{CreateRespone, DataReader, EvmApi, EvmApiMethod, EvmApiStatus}, storage::{StorageCache, StorageWord}, user::UserOutcomeKind, }, - Bytes20, Bytes32, }; pub trait RequestHandler: Send + 'static { diff --git a/crates/arbutil/src/math.rs b/crates/arbutil/src/math.rs index 0d1dc299e23..2f727217aa6 100644 --- a/crates/arbutil/src/math.rs +++ b/crates/arbutil/src/math.rs @@ -3,7 +3,7 @@ use std::ops::{BitAnd, Sub}; -use num_traits::{ops::saturating::SaturatingAdd, Zero}; +use num_traits::{Zero, ops::saturating::SaturatingAdd}; /// Checks if a number is a power of 2. pub fn is_power_of_2(value: T) -> bool diff --git a/crates/arbutil/src/pricing.rs b/crates/arbutil/src/pricing.rs index e5b954aa079..a9ac036d3fe 100644 --- a/crates/arbutil/src/pricing.rs +++ b/crates/arbutil/src/pricing.rs @@ -2,8 +2,8 @@ // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md use crate::{ - evm::{self, api::Ink}, Bytes32, + evm::{self, api::Ink}, }; /// For hostios that may return something. diff --git a/crates/brotli/src/cgo.rs b/crates/brotli/src/cgo.rs index 33f72fc865a..49f1de86f97 100644 --- a/crates/brotli/src/cgo.rs +++ b/crates/brotli/src/cgo.rs @@ -3,7 +3,7 @@ use core::{mem::MaybeUninit, slice}; -use crate::{BrotliStatus, Dictionary, DEFAULT_WINDOW_SIZE}; +use crate::{BrotliStatus, DEFAULT_WINDOW_SIZE, Dictionary}; /// Mechanism for passing data between Go and Rust where Rust can specify the initialized length. #[derive(Clone, Copy)] diff --git a/crates/brotli/src/dicts/mod.rs b/crates/brotli/src/dicts/mod.rs index d816ba2acd1..7a34ace7572 100644 --- a/crates/brotli/src/dicts/mod.rs +++ b/crates/brotli/src/dicts/mod.rs @@ -7,8 +7,8 @@ use lazy_static::lazy_static; use num_enum::{IntoPrimitive, TryFromPrimitive}; use crate::{ - types::BrotliSharedDictionaryType, BrotliStatus, CustomAllocator, EncoderPreparedDictionary, - HeapItem, + BrotliStatus, CustomAllocator, EncoderPreparedDictionary, HeapItem, + types::BrotliSharedDictionaryType, }; extern "C" { diff --git a/crates/caller-env/src/arbcrypto.rs b/crates/caller-env/src/arbcrypto.rs index 4345329a42c..bf999766211 100644 --- a/crates/caller-env/src/arbcrypto.rs +++ b/crates/caller-env/src/arbcrypto.rs @@ -5,7 +5,7 @@ use core::mem::MaybeUninit; use k256::ecdsa::{RecoveryId, Signature, VerifyingKey}; use tiny_keccak::{Hasher, Keccak}; -use crate::{arbcrypto::ECRecoveryStatus::*, ExecEnv, GuestPtr, MemAccess}; +use crate::{ExecEnv, GuestPtr, MemAccess, arbcrypto::ECRecoveryStatus::*}; #[repr(u32)] enum ECRecoveryStatus { diff --git a/crates/jit/src/caller_env.rs b/crates/jit/src/caller_env.rs index 83a935caf32..da22eaa26c5 100644 --- a/crates/jit/src/caller_env.rs +++ b/crates/jit/src/caller_env.rs @@ -4,7 +4,7 @@ use std::mem::{self, MaybeUninit}; use arbutil::{Bytes20, Bytes32}; -use caller_env::{wavmio::WavmIo, ExecEnv, GuestPtr, MemAccess}; +use caller_env::{ExecEnv, GuestPtr, MemAccess, wavmio::WavmIo}; use rand::RngCore; use wasmer::{Memory, MemoryView, StoreMut, WasmPtr}; diff --git a/crates/jit/src/machine.rs b/crates/jit/src/machine.rs index bb66afcd52b..b5cab607a8f 100644 --- a/crates/jit/src/machine.rs +++ b/crates/jit/src/machine.rs @@ -12,19 +12,19 @@ use std::{ use arbutil::{Bytes32, PreimageType}; use caller_env::GoRuntimeState; -use eyre::{bail, ErrReport, Report, Result}; +use eyre::{ErrReport, Report, Result, bail}; use sha3::{Digest, Keccak256}; use thiserror::Error; use validation::local_target; use wasmer::{ - imports, sys::CompilerConfig, Engine, Function, FunctionEnv, FunctionEnvMut, Instance, Memory, - Module, RuntimeError, Store, + Engine, Function, FunctionEnv, FunctionEnvMut, Instance, Memory, Module, RuntimeError, Store, + imports, sys::CompilerConfig, }; use wasmer_compiler_cranelift::Cranelift; use crate::{ - arbcompress, arbcrypto, program, stylus_backend::CothreadHandler, wasip1_stub, wavmio, - InputMode, LocalInput, Opts, ValidatorOpts, + InputMode, LocalInput, Opts, ValidatorOpts, arbcompress, arbcrypto, program, + stylus_backend::CothreadHandler, wasip1_stub, wavmio, }; /// A pre-compiled WASM module bundled with the Engine that produced it. diff --git a/crates/jit/src/main.rs b/crates/jit/src/main.rs index 72948970111..ef35a78762e 100644 --- a/crates/jit/src/main.rs +++ b/crates/jit/src/main.rs @@ -4,7 +4,7 @@ use arbutil::Color; use clap::Parser; use eyre::Result; -use jit::{machine::Escape, run, Opts}; +use jit::{Opts, machine::Escape, run}; use validation::transfer::{send_failure_response, send_successful_response}; use wasmer::FrameInfo; diff --git a/crates/jit/src/program.rs b/crates/jit/src/program.rs index 1594b442b5d..0b17c250a69 100644 --- a/crates/jit/src/program.rs +++ b/crates/jit/src/program.rs @@ -6,9 +6,10 @@ use std::sync::Arc; use arbutil::{ - evm::{api::Gas, EvmData}, + Bytes32, + evm::{EvmData, api::Gas}, format::DebugBytes, - heapify, Bytes32, + heapify, }; use caller_env::{GuestPtr, MemAccess}; use eyre::eyre; @@ -23,7 +24,7 @@ use prover::{ use crate::{ caller_env::JitEnv, machine::{Escape, MaybeEscape, WasmEnv, WasmEnvMut}, - stylus_backend::{exec_wasm, MessageFromCothread}, + stylus_backend::{MessageFromCothread, exec_wasm}, }; const DEFAULT_STYLUS_ARBOS_VERSION: u64 = 31; diff --git a/crates/jit/src/stylus_backend.rs b/crates/jit/src/stylus_backend.rs index a85c1f0d943..ff995c143fb 100644 --- a/crates/jit/src/stylus_backend.rs +++ b/crates/jit/src/stylus_backend.rs @@ -5,8 +5,8 @@ use std::{ sync::{ - mpsc::{self, Receiver, SyncSender}, Arc, + mpsc::{self, Receiver, SyncSender}, }, thread, thread::JoinHandle, @@ -16,13 +16,13 @@ use std::{ use arbutil::{ benchmark::Benchmark, evm::{ - api::{EvmApiMethod, Gas, Ink, VecReader, EVM_API_METHOD_REQ_OFFSET}, + EvmData, + api::{EVM_API_METHOD_REQ_OFFSET, EvmApiMethod, Gas, Ink, VecReader}, req::{EvmApiRequestor, RequestHandler}, user::UserOutcome, - EvmData, }, }; -use eyre::{eyre, Result}; +use eyre::{Result, eyre}; use prover::programs::prelude::*; use stylus::{native::NativeInstance, run::RunProgram}; diff --git a/crates/jit/src/test.rs b/crates/jit/src/test.rs index f0a823ba72c..8754b1a2a64 100644 --- a/crates/jit/src/test.rs +++ b/crates/jit/src/test.rs @@ -4,7 +4,7 @@ #![cfg(test)] use eyre::Result; -use wasmer::{imports, Instance, Module, Store, Value}; +use wasmer::{Instance, Module, Store, Value, imports}; #[test] fn test_crate() -> Result<()> { diff --git a/crates/jit/src/wasip1_stub.rs b/crates/jit/src/wasip1_stub.rs index 16aaef4bbad..e2d10bf231f 100644 --- a/crates/jit/src/wasip1_stub.rs +++ b/crates/jit/src/wasip1_stub.rs @@ -3,7 +3,7 @@ #![allow(clippy::too_many_arguments)] -use caller_env::{self, wasip1_stub::Errno, GuestPtr}; +use caller_env::{self, GuestPtr, wasip1_stub::Errno}; use crate::{ caller_env::{JitEnv, JitExecEnv}, diff --git a/crates/prover-ffi/src/machine.rs b/crates/prover-ffi/src/machine.rs index 582ee7e1eed..6656fdfe8e1 100644 --- a/crates/prover-ffi/src/machine.rs +++ b/crates/prover-ffi/src/machine.rs @@ -12,14 +12,14 @@ use std::{ use arbutil::Bytes32; use eyre::Report; use prover::{ - machine::{argument_data_to_inbox, get_empty_preimage_resolver, GlobalState, MachineStatus}, Machine, + machine::{GlobalState, MachineStatus, argument_data_to_inbox, get_empty_preimage_resolver}, }; use static_assertions::const_assert_eq; use crate::{ - c_strings::{c_string_to_string, err_to_c_string}, CByteArray, RustBytes, + c_strings::{c_string_to_string, err_to_c_string}, }; pub const ARBITRATOR_MACHINE_STATUS_RUNNING: u8 = 0; diff --git a/crates/prover-ffi/src/preimage.rs b/crates/prover-ffi/src/preimage.rs index 1c4429e2e6b..4e37a4fc4c3 100644 --- a/crates/prover-ffi/src/preimage.rs +++ b/crates/prover-ffi/src/preimage.rs @@ -10,9 +10,9 @@ use arbutil::{Bytes32, PreimageType}; use lru::LruCache; use once_cell::sync::OnceCell; use prover::{ + Machine, machine::PreimageResolver, utils::{self, CBytes}, - Machine, }; use crate::ResolvedPreimage; diff --git a/crates/prover/benches/merkle_bench.rs b/crates/prover/benches/merkle_bench.rs index 52098f3cd8a..7ef92dc1787 100644 --- a/crates/prover/benches/merkle_bench.rs +++ b/crates/prover/benches/merkle_bench.rs @@ -1,7 +1,7 @@ // Copyright 2024-2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md use arbutil::Bytes32; -use criterion::{criterion_group, criterion_main, Criterion}; +use criterion::{Criterion, criterion_group, criterion_main}; use prover::merkle::{Merkle, MerkleType}; use rand::Rng; diff --git a/crates/prover/src/binary.rs b/crates/prover/src/binary.rs index 94ac1080b1d..85719c3f124 100644 --- a/crates/prover/src/binary.rs +++ b/crates/prover/src/binary.rs @@ -4,11 +4,11 @@ use std::{convert::TryInto, fmt::Debug, hash::Hash, mem, path::Path, str::FromStr}; use arbutil::{ + Bytes32, Color, DebugColor, evm::{ARBOS_VERSION_STYLUS_CHARGING_FIXES, ARBOS_VERSION_STYLUS_NO_MULTI_VALUE}, math::SaturatingSum, - Bytes32, Color, DebugColor, }; -use eyre::{bail, ensure, eyre, Result, WrapErr}; +use eyre::{Result, WrapErr, bail, ensure, eyre}; use fnv::{FnvHashMap as HashMap, FnvHashSet as HashSet}; use nom::{ branch::alt, @@ -17,7 +17,7 @@ use nom::{ sequence::{preceded, tuple}, }; use serde::{Deserialize, Serialize}; -use wasmer_types::{entity::EntityRef, ExportIndex, FunctionIndex, LocalFunctionIndex}; +use wasmer_types::{ExportIndex, FunctionIndex, LocalFunctionIndex, entity::EntityRef}; use wasmparser::{ BinaryReader, Data, Element, ExternalKind, Imports, MemoryType, Name, NameSectionReader, Naming, Operator, Parser, Payload, TableType, TypeRef, ValType, Validator, WasmFeatures, @@ -25,9 +25,9 @@ use wasmparser::{ use crate::{ programs::{ + FuncMiddleware, Middleware, ModuleMod, STYLUS_ENTRY_POINT, StylusData, config::CompileConfig, counter::Counter, depth::DepthChecker, dynamic::DynamicMeter, - heap::HeapBound, meter::Meter, start::StartMover, FuncMiddleware, Middleware, ModuleMod, - StylusData, STYLUS_ENTRY_POINT, + heap::HeapBound, meter::Meter, start::StartMover, }, value::{ArbValueType, FunctionType, IntegerValType, Value}, }; diff --git a/crates/prover/src/host.rs b/crates/prover/src/host.rs index ed88e061c37..f5c7022153d 100644 --- a/crates/prover/src/host.rs +++ b/crates/prover/src/host.rs @@ -5,8 +5,8 @@ use std::{collections::HashMap, path::Path, str::FromStr}; -use arbutil::{evm::user::UserOutcomeKind, Color, PreimageType}; -use eyre::{bail, ErrReport, Result}; +use arbutil::{Color, PreimageType, evm::user::UserOutcomeKind}; +use eyre::{ErrReport, Result, bail}; use lazy_static::lazy_static; use crate::{ @@ -16,7 +16,7 @@ use crate::{ programs::StylusData, utils, value::{ArbValueType, FunctionType}, - wavm::{wasm_to_wavm, Instruction, Opcode}, + wavm::{Instruction, Opcode, wasm_to_wavm}, }; /// Represents the internal hostio functions a module may have. diff --git a/crates/prover/src/kzg.rs b/crates/prover/src/kzg.rs index 3d27921450c..06449d96b98 100644 --- a/crates/prover/src/kzg.rs +++ b/crates/prover/src/kzg.rs @@ -4,8 +4,8 @@ use std::{convert::TryFrom, io::Write}; use arbutil::Bytes32; -use c_kzg::{KzgSettings, BYTES_PER_BLOB, FIELD_ELEMENTS_PER_BLOB}; -use eyre::{ensure, Result, WrapErr}; +use c_kzg::{BYTES_PER_BLOB, FIELD_ELEMENTS_PER_BLOB, KzgSettings}; +use eyre::{Result, WrapErr, ensure}; use num::BigUint; use sha2::{Digest, Sha256}; diff --git a/crates/prover/src/machine.rs b/crates/prover/src/machine.rs index 10e72ce8c77..7b0b6ad90d8 100644 --- a/crates/prover/src/machine.rs +++ b/crates/prover/src/machine.rs @@ -16,15 +16,15 @@ use std::{ sync::Arc, }; -use arbutil::{crypto, math, Bytes32, Color, DebugColor, PreimageType}; +use arbutil::{Bytes32, Color, DebugColor, PreimageType, crypto, math}; use brotli::Dictionary; #[cfg(feature = "kzg")] use c_kzg::BYTES_PER_BLOB; use digest::Digest; -use eyre::{bail, ensure, eyre, Result, WrapErr}; +use eyre::{Result, WrapErr, bail, ensure, eyre}; use fnv::FnvHashMap as HashMap; use lazy_static::lazy_static; -use num::{traits::PrimInt, Zero}; +use num::{Zero, traits::PrimInt}; #[cfg(feature = "rayon")] use rayon::prelude::*; use serde::{Deserialize, Serialize}; @@ -40,18 +40,18 @@ use crate::kzg::prove_kzg_preimage; use crate::programs::meter::MeteredMachine; use crate::{ binary::{ - self, parse, ExportKind, ExportMap, FloatInstruction, Local, NameCustomSection, WasmBinary, + self, ExportKind, ExportMap, FloatInstruction, Local, NameCustomSection, WasmBinary, parse, }, host, memory::Memory, merkle::{Merkle, MerkleType}, - programs::{config::CompileConfig, ModuleMod, StylusData}, + programs::{ModuleMod, StylusData, config::CompileConfig}, reinterpret::{ReinterpretAsSigned, ReinterpretAsUnsigned}, - utils::{file_bytes, CBytes, RemoteTableType}, + utils::{CBytes, RemoteTableType, file_bytes}, value::{ArbValueType, FunctionType, IntegerValType, ProgramCounter, Value}, wavm::{ - self, pack_cross_module_call, unpack_cross_module_call, wasm_to_wavm, FloatingPointImpls, - IBinOpType, IRelOpType, IUnOpType, Instruction, Opcode, + self, FloatingPointImpls, IBinOpType, IRelOpType, IUnOpType, Instruction, Opcode, + pack_cross_module_call, unpack_cross_module_call, wasm_to_wavm, }, }; @@ -401,11 +401,11 @@ impl Module { match host::get_impl(import.module, import_name) { Ok((hostio, debug)) => { ensure!( - (debug && debug_funcs) || (!debug && allow_hostapi), - "Host func {} in {} not enabled debug_funcs={debug_funcs} hostapi={allow_hostapi} debug={debug}", - import_name.red(), - import.module.red(), - ); + (debug && debug_funcs) || (!debug && allow_hostapi), + "Host func {} in {} not enabled debug_funcs={debug_funcs} hostapi={allow_hostapi} debug={debug}", + import_name.red(), + import.module.red(), + ); hostio } _ => { @@ -421,7 +421,11 @@ impl Module { ensure!( &func.ty == have_ty, "Import {} for {} has different function signature than export.\nexpected {} in {}\nbut have {}", - import_name.red(), bin_name.red(), func.ty.red(), module.red(), have_ty.red(), + import_name.red(), + bin_name.red(), + func.ty.red(), + module.red(), + have_ty.red(), ); func_type_idxs.push(import.offset); @@ -1717,7 +1721,8 @@ impl Machine { if self.initial_hash != new_state.initial_hash { bail!( "attempted to load deserialize machine with initial hash {} into machine with initial hash {}", - new_state.initial_hash, self.initial_hash, + new_state.initial_hash, + self.initial_hash, ); } assert_eq!(self.modules.len(), new_state.modules.len()); @@ -2968,9 +2973,11 @@ impl Machine { // Prove module is in modules merkle tree - out!(mod_merkle - .prove(self.pc.module()) - .expect("Failed to prove module")); + out!( + mod_merkle + .prove(self.pc.module()) + .expect("Failed to prove module") + ); if self.is_halted() { return data; @@ -2980,14 +2987,17 @@ impl Machine { let func = &module.funcs[self.pc.func()]; out!(func.serialize_body_for_proof(self.pc)); - out!(func - .code_merkle - .prove(self.pc.inst() / Function::CHUNK_SIZE) - .expect("Failed to prove against code merkle")); - out!(module - .funcs_merkle - .prove(self.pc.func()) - .expect("Failed to prove against function merkle")); + out!( + func.code_merkle + .prove(self.pc.inst() / Function::CHUNK_SIZE) + .expect("Failed to prove against code merkle") + ); + out!( + module + .funcs_merkle + .prove(self.pc.func()) + .expect("Failed to prove against function merkle") + ); // End next instruction proof, begin instruction specific serialization @@ -3074,30 +3084,38 @@ impl Machine { out!(ty.hash()); let table_usize = usize::try_from(table).unwrap(); let table = &module.tables[table_usize]; - out!(table - .serialize_for_proof() - .expect("failed to serialize table")); - out!(module - .tables_merkle - .prove(table_usize) - .expect("Failed to prove tables merkle")); + out!( + table + .serialize_for_proof() + .expect("failed to serialize table") + ); + out!( + module + .tables_merkle + .prove(table_usize) + .expect("Failed to prove tables merkle") + ); let idx_usize = usize::try_from(idx).unwrap(); if let Some(elem) = table.elems.get(idx_usize) { out!(elem.func_ty.hash()); out!(elem.val.serialize_for_proof()); - out!(table - .elems_merkle - .prove(idx_usize) - .expect("Failed to prove elements merkle")); + out!( + table + .elems_merkle + .prove(idx_usize) + .expect("Failed to prove elements merkle") + ); } } CrossModuleInternalCall => { let module_idx = value_stack.last().unwrap().assume_u32() as usize; let called_module = &self.modules[module_idx]; out!(called_module.serialize_for_proof(&called_module.memory.merkelize())); - out!(mod_merkle - .prove(module_idx) - .expect("Failed to prove module for CrossModuleInternalCall")); + out!( + mod_merkle + .prove(module_idx) + .expect("Failed to prove module for CrossModuleInternalCall") + ); } GetGlobalStateBytes32 | SetGlobalStateBytes32 => { out!(self.global_state.serialize()); diff --git a/crates/prover/src/main.rs b/crates/prover/src/main.rs index cd9271d0933..506f2764d00 100644 --- a/crates/prover/src/main.rs +++ b/crates/prover/src/main.rs @@ -11,13 +11,13 @@ use std::{ sync::Arc, }; -use arbutil::{format, Bytes32, Color, DebugColor, PreimageType}; -use eyre::{eyre, Context, Result}; +use arbutil::{Bytes32, Color, DebugColor, PreimageType, format}; +use eyre::{Context, Result, eyre}; use fnv::{FnvHashMap as HashMap, FnvHashSet as HashSet}; use prover::{ machine::{GlobalState, InboxIdentifier, Machine, MachineStatus, PreimageResolver, ProofInfo}, prepare::prepare_machine, - utils::{file_bytes, hash_preimage, CBytes}, + utils::{CBytes, file_bytes, hash_preimage}, wavm::Opcode, }; use structopt::StructOpt; diff --git a/crates/prover/src/memory.rs b/crates/prover/src/memory.rs index 5b288458690..9ff85fabcbe 100644 --- a/crates/prover/src/memory.rs +++ b/crates/prover/src/memory.rs @@ -7,7 +7,7 @@ use std::{borrow::Cow, collections::HashSet}; use arbutil::Bytes32; use digest::Digest; -use eyre::{bail, Result}; +use eyre::{Result, bail}; use parking_lot::Mutex; #[cfg(feature = "rayon")] use rayon::prelude::*; diff --git a/crates/prover/src/prepare.rs b/crates/prover/src/prepare.rs index ba0ef2f1d32..81f8fee9078 100644 --- a/crates/prover/src/prepare.rs +++ b/crates/prover/src/prepare.rs @@ -12,7 +12,7 @@ use arbutil::{Bytes32, PreimageType}; use validation::ValidationRequest; use crate::{ - machine::{argument_data_to_inbox, GlobalState, Machine}, + machine::{GlobalState, Machine, argument_data_to_inbox}, utils::CBytes, }; diff --git a/crates/prover/src/programs/config.rs b/crates/prover/src/programs/config.rs index 5053fa488a4..4700700eb7f 100644 --- a/crates/prover/src/programs/config.rs +++ b/crates/prover/src/programs/config.rs @@ -13,13 +13,13 @@ use wasmparser::Operator; #[cfg(feature = "native")] use { super::{ - counter::Counter, depth::DepthChecker, dynamic::DynamicMeter, heap::HeapBound, - meter::Meter, start::StartMover, MiddlewareWrapper, + MiddlewareWrapper, counter::Counter, depth::DepthChecker, dynamic::DynamicMeter, + heap::HeapBound, meter::Meter, start::StartMover, }, std::sync::Arc, wasmer::{ - sys::{Cranelift, CraneliftOptLevel, Target}, Engine, Store, + sys::{Cranelift, CraneliftOptLevel, Target}, }, wasmer_compiler_singlepass::Singlepass, }; diff --git a/crates/prover/src/programs/counter.rs b/crates/prover/src/programs/counter.rs index 2f2c84dc112..1933d7dc2b4 100644 --- a/crates/prover/src/programs/counter.rs +++ b/crates/prover/src/programs/counter.rs @@ -4,7 +4,7 @@ use std::{clone::Clone, collections::BTreeMap, fmt::Debug, sync::Arc}; use arbutil::operator::{OperatorCode, OperatorInfo}; -use eyre::{eyre, Result}; +use eyre::{Result, eyre}; use fnv::FnvHashMap as HashMap; use lazy_static::lazy_static; use parking_lot::Mutex; diff --git a/crates/prover/src/programs/depth.rs b/crates/prover/src/programs/depth.rs index 41c140c426a..c3500e581ef 100644 --- a/crates/prover/src/programs/depth.rs +++ b/crates/prover/src/programs/depth.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use arbutil::Color; -use eyre::{bail, Result}; +use eyre::{Result, bail}; use fnv::FnvHashMap as HashMap; use parking_lot::RwLock; use wasmer_types::{ @@ -13,10 +13,10 @@ use wasmer_types::{ use wasmparser::{BlockType, Operator, ValType}; use super::{ - config::{CompileMemoryParams, SigMap}, FuncMiddleware, Middleware, ModuleMod, + config::{CompileMemoryParams, SigMap}, }; -use crate::{internal_func::InternalFunc, value::FunctionType, Machine}; +use crate::{Machine, internal_func::InternalFunc, value::FunctionType}; pub const STYLUS_STACK_LEFT: &str = "stylus_stack_left"; diff --git a/crates/prover/src/programs/dynamic.rs b/crates/prover/src/programs/dynamic.rs index 22a7e292276..3723bc5694a 100644 --- a/crates/prover/src/programs/dynamic.rs +++ b/crates/prover/src/programs/dynamic.rs @@ -1,15 +1,15 @@ // Copyright 2023-2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md -use eyre::{bail, Result}; +use eyre::{Result, bail}; use parking_lot::RwLock; use wasmer_types::{GlobalIndex, GlobalInit, LocalFunctionIndex, Type}; use wasmparser::{BlockType, Operator}; use super::{ + FuncMiddleware, Middleware, ModuleMod, config::CompilePricingParams, meter::{STYLUS_INK_LEFT, STYLUS_INK_STATUS}, - FuncMiddleware, Middleware, ModuleMod, }; pub const SCRATCH_GLOBAL: &str = "stylus_scratch_global"; diff --git a/crates/prover/src/programs/heap.rs b/crates/prover/src/programs/heap.rs index 5456d0453b2..a452357dd1b 100644 --- a/crates/prover/src/programs/heap.rs +++ b/crates/prover/src/programs/heap.rs @@ -2,13 +2,13 @@ // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md use arbutil::Color; -use eyre::{bail, Result}; +use eyre::{Result, bail}; use parking_lot::RwLock; use wasmer_types::{FunctionIndex, GlobalIndex, ImportIndex, LocalFunctionIndex, Pages}; use wasmparser::Operator; use super::{ - config::CompileMemoryParams, dynamic::SCRATCH_GLOBAL, FuncMiddleware, Middleware, ModuleMod, + FuncMiddleware, Middleware, ModuleMod, config::CompileMemoryParams, dynamic::SCRATCH_GLOBAL, }; use crate::value::{ArbValueType, FunctionType}; diff --git a/crates/prover/src/programs/meter.rs b/crates/prover/src/programs/meter.rs index 4864ebef9c2..d4c564a40ae 100644 --- a/crates/prover/src/programs/meter.rs +++ b/crates/prover/src/programs/meter.rs @@ -8,12 +8,13 @@ use std::{ }; use arbutil::{ + Bytes32, evm::{ self, api::{Gas, Ink}, }, operator::OperatorInfo, - pricing, Bytes32, + pricing, }; use derivative::Derivative; use eyre::Result; @@ -27,8 +28,8 @@ use super::config::OpCosts; use crate::Machine; use crate::{ programs::{ - config::{CompilePricingParams, PricingParams, SigMap}, FuncMiddleware, Middleware, ModuleMod, + config::{CompilePricingParams, PricingParams, SigMap}, }, value::FunctionType, }; @@ -339,9 +340,7 @@ pub trait GasMeteredMachine: MeteredMachine { impl MeteredMachine for Machine { fn ink_left(&self) -> MachineMeter { macro_rules! convert { - ($global:expr_2021) => {{ - $global.unwrap().try_into().expect("type mismatch") - }}; + ($global:expr_2021) => {{ $global.unwrap().try_into().expect("type mismatch") }}; } let ink = || Ink(convert!(self.get_global(STYLUS_INK_LEFT))); diff --git a/crates/prover/src/programs/mod.rs b/crates/prover/src/programs/mod.rs index aa1a01e6a64..c0e3dc928e8 100644 --- a/crates/prover/src/programs/mod.rs +++ b/crates/prover/src/programs/mod.rs @@ -3,12 +3,12 @@ use std::fmt::Debug; -use arbutil::{evm::ARBOS_VERSION_STYLUS_CHARGING_FIXES, math::SaturatingSum, Bytes32, Color}; -use eyre::{bail, eyre, Report, Result, WrapErr}; +use arbutil::{Bytes32, Color, evm::ARBOS_VERSION_STYLUS_CHARGING_FIXES, math::SaturatingSum}; +use eyre::{Report, Result, WrapErr, bail, eyre}; use fnv::FnvHashMap as HashMap; use wasmer_types::{ - entity::EntityRef, FunctionIndex, GlobalIndex, GlobalInit, ImportIndex, LocalFunctionIndex, - SignatureIndex, Type, + FunctionIndex, GlobalIndex, GlobalInit, ImportIndex, LocalFunctionIndex, SignatureIndex, Type, + entity::EntityRef, }; use wasmparser::{Operator, ValType}; #[cfg(feature = "native")] @@ -510,66 +510,75 @@ mod test { #[test] fn test_no_multi_value() { // Single-value wasm is accepted at and above the threshold. - assert!(parse_at_threshold( - r#"(module + assert!( + parse_at_threshold( + r#"(module (func (param i32) (result i32) local.get 0 ) )"#, - ) - .is_ok()); + ) + .is_ok() + ); } #[test] fn test_reject_multi_value_function() { // Function type with two return values. - assert!(parse_at_threshold( - r#"(module + assert!( + parse_at_threshold( + r#"(module (func (result i32 i32) i32.const 1 i32.const 2 ) )"#, - ) - .is_err()); + ) + .is_err() + ); } #[test] fn test_reject_multi_value_block() { // (block (param i32) (result i32)) — BlockType::FuncType, rejected even with 1 result. // Single-value equivalent: (block (result i32) local.get 0) - assert!(parse_at_threshold( - r#"(module + assert!( + parse_at_threshold( + r#"(module (func (param i32) (result i32) local.get 0 (block (param i32) (result i32)) ) )"#, - ) - .is_err()); + ) + .is_err() + ); } #[test] fn test_reject_multi_value_loop() { // (loop (param i32) (result i32)) — BlockType::FuncType, rejected even with 1 result. // Single-value equivalent: (loop local.get 0 ...) with value produced inside. - assert!(parse_at_threshold( - r#"(module + assert!( + parse_at_threshold( + r#"(module (func (param i32) (result i32) local.get 0 (loop (param i32) (result i32)) ) )"#, - ) - .is_err()); + ) + .is_err() + ); } #[test] fn test_reject_multi_value_if() { // (if (param i32) (result i32)) — BlockType::FuncType, rejected even with 1 result. // Single-value equivalent: (if (result i32) (then local.get 0) (else i32.const 0)) - assert!(parse_at_threshold( - r#"(module + assert!( + parse_at_threshold( + r#"(module (func (param i32 i32) (result i32) local.get 0 local.get 1 @@ -579,8 +588,9 @@ mod test { ) ) )"#, - ) - .is_err()); + ) + .is_err() + ); } // A minimal valid Stylus wasm that contains a multi-value function type. diff --git a/crates/prover/src/programs/start.rs b/crates/prover/src/programs/start.rs index 9dee33b5696..79bf17a553c 100644 --- a/crates/prover/src/programs/start.rs +++ b/crates/prover/src/programs/start.rs @@ -1,7 +1,7 @@ // Copyright 2022-2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md -use eyre::{bail, Result}; +use eyre::{Result, bail}; use fnv::FnvHashMap as HashMap; use lazy_static::lazy_static; #[cfg(feature = "native")] diff --git a/crates/prover/src/utils.rs b/crates/prover/src/utils.rs index cb12a8f461d..b362a7d5f65 100644 --- a/crates/prover/src/utils.rs +++ b/crates/prover/src/utils.rs @@ -7,7 +7,7 @@ use arbutil::PreimageType; #[cfg(feature = "kzg")] use c_kzg::Blob; use digest::Digest; -use eyre::{eyre, Result}; +use eyre::{Result, eyre}; use serde::{Deserialize, Serialize}; use sha2::Sha256; use sha3::Keccak256; diff --git a/crates/prover/src/value.rs b/crates/prover/src/value.rs index f655ab3d5e0..9a55a76b824 100644 --- a/crates/prover/src/value.rs +++ b/crates/prover/src/value.rs @@ -9,9 +9,9 @@ use std::{ use arbutil::{Bytes32, Color}; use digest::Digest; -use eyre::{bail, ErrReport, Result}; +use eyre::{ErrReport, Result, bail}; use serde::{Deserialize, Serialize}; -use serde_with::{serde_as, TryFromInto}; +use serde_with::{TryFromInto, serde_as}; use sha3::Keccak256; use wasmparser::{FuncType, RefType, ValType}; @@ -289,9 +289,7 @@ impl Display for Value { let rparem = ")".grey(); macro_rules! single { - ($ty:expr_2021, $value:expr_2021) => {{ - write!(f, "{}{}{}{}", $ty.grey(), lparem, $value, rparem) - }}; + ($ty:expr_2021, $value:expr_2021) => {{ write!(f, "{}{}{}{}", $ty.grey(), lparem, $value, rparem) }}; } macro_rules! pair { ($ty:expr_2021, $left:expr_2021, $right:expr_2021) => {{ diff --git a/crates/prover/src/wavm.rs b/crates/prover/src/wavm.rs index d4d97ee3b3a..dfeb09e0f8e 100644 --- a/crates/prover/src/wavm.rs +++ b/crates/prover/src/wavm.rs @@ -5,7 +5,7 @@ use std::ops::{Add, AddAssign, Sub, SubAssign}; use arbutil::{Bytes32, Color, DebugColor}; use digest::Digest; -use eyre::{bail, ensure, Result}; +use eyre::{Result, bail, ensure}; use fnv::FnvHashMap as HashMap; use serde::{Deserialize, Serialize}; use sha3::Keccak256; @@ -224,9 +224,7 @@ impl Opcode { (ArbValueType::I64, 1) => 0x3C, (ArbValueType::I64, 2) => 0x3D, (ArbValueType::I64, 4) => 0x3E, - _ => panic!( - "Unsupported memory store of type {ty:?} to {bytes} bytes", - ), + _ => panic!("Unsupported memory store of type {ty:?} to {bytes} bytes",), }, Opcode::MemorySize => 0x3F, Opcode::MemoryGrow => 0x40, diff --git a/crates/sp1/stylus-compiler-runner/main.rs b/crates/sp1/stylus-compiler-runner/main.rs index beb535bdeac..25167fa544e 100644 --- a/crates/sp1/stylus-compiler-runner/main.rs +++ b/crates/sp1/stylus-compiler-runner/main.rs @@ -2,10 +2,11 @@ use std::path::PathBuf; use clap::{Parser, Subcommand}; use sp1_sdk::{ + Elf, ProvingKey, SP1Stdin, blocking::{ProveRequest, Prover, ProverClient}, - include_elf, Elf, ProvingKey, SP1Stdin, + include_elf, }; -use stylus_compiler_program::{compile, CompileInput}; +use stylus_compiler_program::{CompileInput, compile}; const COMPILER_ELF: Elf = include_elf!("stylus-compiler-program"); diff --git a/crates/stylus/src/benchmarks.rs b/crates/stylus/src/benchmarks.rs index dc907626c07..7c82bd1c582 100644 --- a/crates/stylus/src/benchmarks.rs +++ b/crates/stylus/src/benchmarks.rs @@ -5,11 +5,11 @@ use std::time::{Duration, Instant}; use arbutil::{crypto, format}; use eyre::Result; -use prover::programs::{config::StylusConfig, STYLUS_ENTRY_POINT}; +use prover::programs::{STYLUS_ENTRY_POINT, config::StylusConfig}; use wasmer::{CompilerConfig, Imports, Instance, Module, Store}; use wasmer_compiler_cranelift::{Cranelift, CraneliftOptLevel}; #[cfg(feature = "llvm")] -use wasmer_compiler_llvm::{LLVMOptLevel, LLVM}; +use wasmer_compiler_llvm::{LLVM, LLVMOptLevel}; use wasmer_compiler_singlepass::Singlepass; use crate::{env::WasmEnv, native::NativeInstance}; diff --git a/crates/stylus/src/env.rs b/crates/stylus/src/env.rs index d70fff28335..e3abe235211 100644 --- a/crates/stylus/src/env.rs +++ b/crates/stylus/src/env.rs @@ -13,14 +13,14 @@ use std::{ use arbutil::{ benchmark::Benchmark, evm::{ - api::{DataReader, EvmApi, Ink}, EvmData, + api::{DataReader, EvmApi, Ink}, }, pricing, }; use caller_env::GuestPtr; use derivative::Derivative; -use eyre::{eyre, ErrReport}; +use eyre::{ErrReport, eyre}; use prover::programs::{config::PricingParams, meter::OutOfInkError, prelude::*}; use thiserror::Error; use wasmer::{FunctionEnvMut, Memory, MemoryAccessError, MemoryView, Pages, StoreMut}; diff --git a/crates/stylus/src/evm_api.rs b/crates/stylus/src/evm_api.rs index f5342488c0f..cc9c0fd1c64 100644 --- a/crates/stylus/src/evm_api.rs +++ b/crates/stylus/src/evm_api.rs @@ -2,7 +2,7 @@ // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md use arbutil::evm::{ - api::{EvmApiMethod, Gas, EVM_API_METHOD_REQ_OFFSET}, + api::{EVM_API_METHOD_REQ_OFFSET, EvmApiMethod, Gas}, req::RequestHandler, }; use prover_ffi::RustSlice; diff --git a/crates/stylus/src/host.rs b/crates/stylus/src/host.rs index 5782e3ddecd..dfc0b481ad6 100644 --- a/crates/stylus/src/host.rs +++ b/crates/stylus/src/host.rs @@ -10,12 +10,12 @@ use std::{ }; use arbutil::{ + Color, benchmark::Benchmark, evm::{ - api::{DataReader, EvmApi, Gas, Ink}, EvmData, + api::{DataReader, EvmApi, Gas, Ink}, }, - Color, }; use caller_env::GuestPtr; use eyre::Result; diff --git a/crates/stylus/src/lib.rs b/crates/stylus/src/lib.rs index 1e641928564..2d723a18199 100644 --- a/crates/stylus/src/lib.rs +++ b/crates/stylus/src/lib.rs @@ -4,22 +4,22 @@ use std::ptr; use arbutil::{ + Bytes32, evm::{ + EvmData, api::{DataReader, Gas, Ink}, req::EvmApiRequestor, user::{UserOutcome, UserOutcomeKind}, - EvmData, }, format::DebugBytes, - Bytes32, }; pub use brotli; -use cache::{deserialize_module, CacheMetrics, InitCache}; +use cache::{CacheMetrics, InitCache, deserialize_module}; use evm_api::NativeRequestHandler; use eyre::ErrReport; use native::NativeInstance; pub use prover; -use prover::programs::{prelude::*, StylusData}; +use prover::programs::{StylusData, prelude::*}; // This re-export is required to pull prover_ffi's #[no_mangle] FFI symbols into the staticlib // output. pub use prover_ffi; diff --git a/crates/stylus/src/native.rs b/crates/stylus/src/native.rs index 7dd8e3e1fee..246b8d53ec0 100644 --- a/crates/stylus/src/native.rs +++ b/crates/stylus/src/native.rs @@ -8,29 +8,29 @@ use std::{ }; use arbutil::{ + Bytes32, Color, evm::{ - api::{DataReader, EvmApi, Ink}, EvmData, + api::{DataReader, EvmApi, Ink}, }, operator::OperatorCode, - Bytes32, Color, }; -use eyre::{bail, eyre, ErrReport, Result}; +use eyre::{ErrReport, Result, bail, eyre}; use prover::{ machine::Module as ProverModule, programs::{ + StylusData, config::PricingParams, counter::{Counter, CountingMachine, OP_OFFSETS}, depth::STYLUS_STACK_LEFT, meter::{STYLUS_INK_LEFT, STYLUS_INK_STATUS}, prelude::*, start::StartMover, - StylusData, }, }; use wasmer::{ - imports, sys::Target, AsStoreMut, Function, FunctionEnv, Instance, Memory, Module, Pages, - Store, TypedFunction, Value, WasmTypeList, + AsStoreMut, Function, FunctionEnv, Instance, Memory, Module, Pages, Store, TypedFunction, + Value, WasmTypeList, imports, sys::Target, }; use wasmer_vm::VMExtern; diff --git a/crates/stylus/src/run.rs b/crates/stylus/src/run.rs index 7f6e9d79c9a..3001f2723bf 100644 --- a/crates/stylus/src/run.rs +++ b/crates/stylus/src/run.rs @@ -7,10 +7,10 @@ use arbutil::evm::{ api::{DataReader, EvmApi, Ink}, user::UserOutcome, }; -use eyre::{eyre, Result}; +use eyre::{Result, eyre}; use prover::{ machine::Machine, - programs::{prelude::*, STYLUS_ENTRY_POINT}, + programs::{STYLUS_ENTRY_POINT, prelude::*}, }; use crate::{env::Escape, native::NativeInstance}; diff --git a/crates/stylus/src/target_cache.rs b/crates/stylus/src/target_cache.rs index 2cdaa5a2ddd..1a76a763432 100644 --- a/crates/stylus/src/target_cache.rs +++ b/crates/stylus/src/target_cache.rs @@ -3,7 +3,7 @@ use std::{collections::HashMap, str::FromStr}; -use eyre::{eyre, OptionExt, Result}; +use eyre::{OptionExt, Result, eyre}; use lazy_static::lazy_static; use parking_lot::RwLock; use wasmer::sys::{CpuFeature, Target, Triple}; diff --git a/crates/stylus/src/test/api.rs b/crates/stylus/src/test/api.rs index 98be404f9e0..fff2c9f92e4 100644 --- a/crates/stylus/src/test/api.rs +++ b/crates/stylus/src/test/api.rs @@ -4,12 +4,12 @@ use std::{collections::HashMap, sync::Arc}; use arbutil::{ + Bytes20, Bytes32, evm::{ + EvmData, api::{CreateRespone, EvmApi, Gas, Ink, VecReader}, user::UserOutcomeKind, - EvmData, }, - Bytes20, Bytes32, }; use eyre::Result; use parking_lot::Mutex; diff --git a/crates/stylus/src/test/misc.rs b/crates/stylus/src/test/misc.rs index e3fc15fa7ae..8bc790d5c56 100644 --- a/crates/stylus/src/test/misc.rs +++ b/crates/stylus/src/test/misc.rs @@ -3,7 +3,7 @@ use eyre::Result; use prover::programs::{prelude::*, start::StartMover}; -use wasmer::{imports, sys::Target, Function}; +use wasmer::{Function, imports, sys::Target}; use super::test_configs; use crate::{ diff --git a/crates/stylus/src/test/mod.rs b/crates/stylus/src/test/mod.rs index c984e0aa664..3fd21ef0097 100644 --- a/crates/stylus/src/test/mod.rs +++ b/crates/stylus/src/test/mod.rs @@ -4,24 +4,23 @@ use std::{collections::HashMap, path::Path, sync::Arc}; use arbutil::{ + Bytes20, Bytes32, Color, evm::{ api::{Ink, VecReader}, user::UserOutcome, }, - Bytes20, Bytes32, Color, }; -use eyre::{bail, Result}; +use eyre::{Result, bail}; use prover::{ + Machine, machine::GlobalState, programs::{config::SigMap, prelude::*}, - Machine, }; use rand::prelude::*; use wasmer::{ - imports, + Function, FunctionEnv, Imports, Instance, Module, Store, imports, sys::{CompilerConfig, EngineBuilder, Target}, wasmparser::Operator, - Function, FunctionEnv, Imports, Instance, Module, Store, }; use wasmer_compiler_singlepass::Singlepass; diff --git a/crates/stylus/src/test/native.rs b/crates/stylus/src/test/native.rs index 838a5eb95bb..70aa78bc404 100644 --- a/crates/stylus/src/test/native.rs +++ b/crates/stylus/src/test/native.rs @@ -9,36 +9,35 @@ use std::{collections::HashMap, path::Path, sync::Arc, time::Instant}; use arbutil::{ - crypto, + Bytes20, Bytes32, Color, crypto, evm::{ api::{EvmApi, Gas, Ink}, user::{UserOutcome, UserOutcomeKind}, }, - format, Bytes20, Bytes32, Color, + format, }; -use eyre::{bail, ensure, Result}; +use eyre::{Result, bail, ensure}; use prover::{ - binary, + Machine, binary, programs::{ + MiddlewareWrapper, ModuleMod, counter::{Counter, CountingMachine}, prelude::*, start::StartMover, - MiddlewareWrapper, ModuleMod, }, - Machine, }; use wasmer::{ + ExportIndex, Imports, Pages, Store, sys::{CompilerConfig, EngineBuilder}, wasmparser::Operator, - ExportIndex, Imports, Pages, Store, }; use wasmer_compiler_singlepass::Singlepass; use crate::{ run::RunProgram, test::{ - check_instrumentation, random_bytes20, random_bytes32, random_ink, run_machine, run_native, - test_compile_config, test_configs, TestInstance, + TestInstance, check_instrumentation, random_bytes20, random_bytes32, random_ink, + run_machine, run_native, test_compile_config, test_configs, }, }; diff --git a/crates/stylus/src/test/sdk.rs b/crates/stylus/src/test/sdk.rs index 8d83898326a..d87c19521a8 100644 --- a/crates/stylus/src/test/sdk.rs +++ b/crates/stylus/src/test/sdk.rs @@ -6,7 +6,7 @@ use eyre::Result; use num_bigint::BigUint; -use crate::test::{random_bytes20, random_bytes32, run_native, test_configs, TestInstance}; +use crate::test::{TestInstance, random_bytes20, random_bytes32, run_native, test_configs}; #[test] #[ignore = "needs to update erc20 to use new SDK"] diff --git a/crates/stylus/src/test/timings.rs b/crates/stylus/src/test/timings.rs index d6b06696ad5..5620fb4ad77 100644 --- a/crates/stylus/src/test/timings.rs +++ b/crates/stylus/src/test/timings.rs @@ -6,7 +6,7 @@ use std::time::Instant; use arbutil::{color::Color, format}; use eyre::Result; -use crate::test::{run_native, test_configs, TestInstance}; +use crate::test::{TestInstance, run_native, test_configs}; #[test] fn test_timings() -> Result<()> { diff --git a/crates/stylus/src/test/wavm.rs b/crates/stylus/src/test/wavm.rs index 496dd1e691e..204cf93b343 100644 --- a/crates/stylus/src/test/wavm.rs +++ b/crates/stylus/src/test/wavm.rs @@ -3,7 +3,7 @@ use arbutil::evm::api::Ink; use eyre::Result; -use prover::{programs::prelude::*, Machine}; +use prover::{Machine, programs::prelude::*}; use crate::test::{new_test_machine, test_compile_config}; diff --git a/crates/validation/src/lib.rs b/crates/validation/src/lib.rs index 5c526abf529..c2562e0e60b 100644 --- a/crates/validation/src/lib.rs +++ b/crates/validation/src/lib.rs @@ -7,7 +7,7 @@ use std::{ use arbutil::{Bytes32, PreimageType}; use serde::{Deserialize, Serialize}; -use serde_with::{base64::Base64, As, DisplayFromStr}; +use serde_with::{As, DisplayFromStr, base64::Base64}; pub mod transfer; diff --git a/crates/validation/src/transfer/receiver.rs b/crates/validation/src/transfer/receiver.rs index 64ee001d646..809faf1601b 100644 --- a/crates/validation/src/transfer/receiver.rs +++ b/crates/validation/src/transfer/receiver.rs @@ -9,12 +9,11 @@ use std::{ use io::Error; use crate::{ + GoGlobalState, Inbox, Preimages, ValidationInput, transfer::{ - markers, - primitives::{read_bytes, read_u32, read_u64, read_u8}, - IOResult, + IOResult, markers, + primitives::{read_bytes, read_u8, read_u32, read_u64}, }, - GoGlobalState, Inbox, Preimages, ValidationInput, }; pub fn receive_validation_input(reader: &mut impl Read) -> IOResult { diff --git a/crates/validation/src/transfer/sender.rs b/crates/validation/src/transfer/sender.rs index da6b2d51b07..76a9f78fad1 100644 --- a/crates/validation/src/transfer/sender.rs +++ b/crates/validation/src/transfer/sender.rs @@ -3,12 +3,11 @@ use std::{collections::BTreeMap, io::Write}; use crate::{ + GoGlobalState, Inbox, Preimages, ValidationInput, transfer::{ - markers, - primitives::{write_bytes, write_u32, write_u64, write_u8}, - IOResult, + IOResult, markers, + primitives::{write_bytes, write_u8, write_u32, write_u64}, }, - GoGlobalState, Inbox, Preimages, ValidationInput, }; pub fn send_validation_input(writer: &mut impl Write, input: &ValidationInput) -> IOResult<()> { diff --git a/crates/validation/src/transfer/tests.rs b/crates/validation/src/transfer/tests.rs index 9ae2cfedf43..642be84ae8c 100644 --- a/crates/validation/src/transfer/tests.rs +++ b/crates/validation/src/transfer/tests.rs @@ -5,11 +5,11 @@ use std::{collections::BTreeMap, io::pipe}; use arbutil::Bytes32; use crate::{ + GoGlobalState, ValidationInput, transfer::{ receive_response, receive_validation_input, send_failure_response, send_successful_response, send_validation_input, }, - GoGlobalState, ValidationInput, }; #[test] diff --git a/crates/validator/src/config.rs b/crates/validator/src/config.rs index 215c447b817..326629ad6b5 100644 --- a/crates/validator/src/config.rs +++ b/crates/validator/src/config.rs @@ -15,14 +15,14 @@ use std::{ }; use alloy_rpc_types_engine::JwtSecret; -use anyhow::{anyhow, Context as _, Result}; +use anyhow::{Context as _, Result, anyhow}; use clap::{Parser, ValueEnum}; use tracing::info; use crate::{ engine::{ - machine::JitProcessManager, machine_locator::MachineLocator, replay_binary, ModuleRoot, - DEFAULT_JIT_CRANELIFT, + DEFAULT_JIT_CRANELIFT, ModuleRoot, machine::JitProcessManager, + machine_locator::MachineLocator, replay_binary, }, jwt, }; @@ -166,7 +166,9 @@ impl ServerConfig { let workers = match std::thread::available_parallelism() { Ok(count) => count.get(), Err(e) if e.kind() == std::io::ErrorKind::NotFound => { - warn!("Could not determine machine's available parallelism. Defaulting to {DEFAULT_NUM_WORKERS}."); + warn!( + "Could not determine machine's available parallelism. Defaulting to {DEFAULT_NUM_WORKERS}." + ); DEFAULT_NUM_WORKERS } Err(e) => return Err(e.into()), @@ -223,7 +225,7 @@ pub fn get_jit_path() -> Result { mod tests { use clap::Parser; - use crate::config::{get_jit_path, ServerConfig}; + use crate::config::{ServerConfig, get_jit_path}; #[test] fn verify_cli() { diff --git a/crates/validator/src/engine/execution.rs b/crates/validator/src/engine/execution.rs index a8937e3a259..f686db74696 100644 --- a/crates/validator/src/engine/execution.rs +++ b/crates/validator/src/engine/execution.rs @@ -18,11 +18,11 @@ use std::collections::HashMap; use axum::Json; use jit::CompiledModule; use tracing::info; -use validation::{local_target, GoGlobalState, ValidationInput, ValidationRequest}; +use validation::{GoGlobalState, ValidationInput, ValidationRequest, local_target}; use crate::engine::{ - machine::JitProcessManager, machine_locator::MachineLocator, replay_binary, ModuleRoot, - DEFAULT_JIT_CRANELIFT, + DEFAULT_JIT_CRANELIFT, ModuleRoot, machine::JitProcessManager, machine_locator::MachineLocator, + replay_binary, }; pub async fn validate_native( diff --git a/crates/validator/src/engine/machine.rs b/crates/validator/src/engine/machine.rs index 53ef3089f8c..77add9daccf 100644 --- a/crates/validator/src/engine/machine.rs +++ b/crates/validator/src/engine/machine.rs @@ -25,14 +25,14 @@ use std::{ path::PathBuf, process::Stdio, sync::{ - atomic::{AtomicBool, Ordering}, Arc, + atomic::{AtomicBool, Ordering}, }, thread::sleep, time::Duration, }; -use anyhow::{anyhow, Context, Result}; +use anyhow::{Context, Result, anyhow}; use tokio::{ io::AsyncWriteExt, process::{Child, ChildStdin, Command}, @@ -40,16 +40,15 @@ use tokio::{ }; use tracing::{debug, error, info, warn}; use validation::{ - local_target, + GoGlobalState, ValidationInput, ValidationRequest, local_target, transfer::{receive_response, send_validation_input}, - GoGlobalState, ValidationInput, ValidationRequest, }; use crate::{ config::get_jit_path, engine::{ - machine_locator::MachineLocator, replay_binary, ModuleRoot, DEFAULT_JIT_CRANELIFT, - DEFAULT_WASM_MEMORY_USAGE_LIMIT, + DEFAULT_JIT_CRANELIFT, DEFAULT_WASM_MEMORY_USAGE_LIMIT, ModuleRoot, + machine_locator::MachineLocator, replay_binary, }, }; @@ -180,7 +179,11 @@ impl JitProcessManager { // Clone the Arc while holding the read lock, then drop the lock immediately. // This allows other threads to access the HashMap while we perform I/O operations. Some(machine) => machine.clone(), - None => return Err(anyhow!("Trying to feed machine when no machine for module root {module_root} is available/running")) + None => { + return Err(anyhow!( + "Trying to feed machine when no machine for module root {module_root} is available/running" + )); + } } }; diff --git a/crates/validator/src/engine/machine_locator.rs b/crates/validator/src/engine/machine_locator.rs index 3f0dc8130cd..d6cfd265404 100644 --- a/crates/validator/src/engine/machine_locator.rs +++ b/crates/validator/src/engine/machine_locator.rs @@ -172,13 +172,13 @@ mod tests { str::FromStr, }; - use anyhow::{anyhow, Result}; + use anyhow::{Result, anyhow}; use arbutil::Bytes32; use rand::RngCore; use crate::engine::{ - machine_locator::{MachineLocator, ModuleRootMeta}, ModuleRoot, + machine_locator::{MachineLocator, ModuleRootMeta}, }; fn get_temp_machines_dir() -> Result { @@ -293,10 +293,12 @@ mod tests { // let root_meta_wrapper = file_manager.root_metas.first().unwrap(); let mod_root = root_meta_wrapper.module_root; let module_root = machine_locator.get_machine_path(mod_root).unwrap(); - assert!(module_root - .to_str() - .unwrap() - .contains(&mod_root.to_string())); + assert!( + module_root + .to_str() + .unwrap() + .contains(&mod_root.to_string()) + ); }); Ok(()) diff --git a/crates/validator/src/jwt.rs b/crates/validator/src/jwt.rs index f5593fb6ad6..42b40cdc4a7 100644 --- a/crates/validator/src/jwt.rs +++ b/crates/validator/src/jwt.rs @@ -12,8 +12,8 @@ use axum::{ response::Response, }; use axum_extra::{ - headers::{authorization::Bearer, Authorization}, TypedHeader, + headers::{Authorization, authorization::Bearer}, }; use crate::config::ServerState; diff --git a/crates/validator/src/server.rs b/crates/validator/src/server.rs index 2eb36ed6a74..ff8023571c3 100644 --- a/crates/validator/src/server.rs +++ b/crates/validator/src/server.rs @@ -3,7 +3,7 @@ use std::{future::Future, sync::Arc}; use anyhow::Result; -use axum::{routing::post, Router}; +use axum::{Router, routing::post}; use tokio::{net::TcpListener, signal}; use tower_http::trace::TraceLayer; use tracing::info; diff --git a/crates/validator/src/spawner_endpoints.rs b/crates/validator/src/spawner_endpoints.rs index 8904b801c6c..38591ac1689 100644 --- a/crates/validator/src/spawner_endpoints.rs +++ b/crates/validator/src/spawner_endpoints.rs @@ -9,18 +9,18 @@ use std::sync::Arc; -use axum::{extract::State, Json}; +use axum::{Json, extract::State}; use serde::{Deserialize, Serialize}; -use serde_json::{json, Value}; +use serde_json::{Value, json}; use validation::ValidationRequest; use crate::{ + ServerState, config::ExecutionMode, engine::{ - execution::{validate_continuous, validate_native}, ModuleRoot, + execution::{validate_continuous, validate_native}, }, - ServerState, }; /// JSON-RPC 2.0 response envelope. diff --git a/crates/wasm-libraries/arbcompress/lib.rs b/crates/wasm-libraries/arbcompress/lib.rs index c52d71d165a..6e69f07e8be 100644 --- a/crates/wasm-libraries/arbcompress/lib.rs +++ b/crates/wasm-libraries/arbcompress/lib.rs @@ -5,9 +5,8 @@ use brotli::{BrotliStatus, Dictionary}; use caller_env::{ - self, + self, GuestPtr, static_caller::{StaticExecEnv, StaticMem}, - GuestPtr, }; use paste::paste; diff --git a/crates/wasm-libraries/arbcrypto/lib.rs b/crates/wasm-libraries/arbcrypto/lib.rs index 64dc301cc7a..ac6ff677a5f 100644 --- a/crates/wasm-libraries/arbcrypto/lib.rs +++ b/crates/wasm-libraries/arbcrypto/lib.rs @@ -4,9 +4,8 @@ #![allow(clippy::missing_safety_doc)] use caller_env::{ - self, + self, GuestPtr, static_caller::{StaticExecEnv, StaticMem}, - GuestPtr, }; #[no_mangle] diff --git a/crates/wasm-libraries/host-io/lib.rs b/crates/wasm-libraries/host-io/lib.rs index ba95912cf59..b81f773a83b 100644 --- a/crates/wasm-libraries/host-io/lib.rs +++ b/crates/wasm-libraries/host-io/lib.rs @@ -9,7 +9,7 @@ use core::{ }; use arbutil::PreimageType; -use caller_env::{static_caller::StaticMem, GuestPtr, MemAccess}; +use caller_env::{GuestPtr, MemAccess, static_caller::StaticMem}; extern "C" { pub fn wavm_get_globalstate_bytes32(idx: u32, ptr: *mut u8); diff --git a/crates/wasm-libraries/user-host-trait/lib.rs b/crates/wasm-libraries/user-host-trait/lib.rs index 472dfb3b960..86ff87d314d 100644 --- a/crates/wasm-libraries/user-host-trait/lib.rs +++ b/crates/wasm-libraries/user-host-trait/lib.rs @@ -4,20 +4,19 @@ use std::{borrow::Cow, fmt::Display, time::Instant}; use arbutil::{ + Bytes20, Bytes32, benchmark::Benchmark, crypto, evm::{ - self, + self, ARBOS_VERSION_STYLUS_CHARGING_FIXES, EvmData, api::{CreateRespone, DataReader, EvmApi, Gas, Ink}, storage::StorageCache, user::UserOutcomeKind, - EvmData, ARBOS_VERSION_STYLUS_CHARGING_FIXES, }, - pricing::{hostio, EVM_API_INK}, - Bytes20, Bytes32, + pricing::{EVM_API_INK, hostio}, }; pub use caller_env::GuestPtr; -use eyre::{eyre, Result}; +use eyre::{Result, eyre}; use prover::{ programs::{meter::OutOfInkError, prelude::*}, value::Value, diff --git a/crates/wasm-libraries/user-host/src/link.rs b/crates/wasm-libraries/user-host/src/link.rs index ccddc14ca46..9a1e5697175 100644 --- a/crates/wasm-libraries/user-host/src/link.rs +++ b/crates/wasm-libraries/user-host/src/link.rs @@ -2,15 +2,16 @@ // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md use arbutil::{ + Bytes20, Bytes32, evm::{ + EvmData, api::{Gas, Ink}, user::UserOutcomeKind, - EvmData, }, format::DebugBytes, - heapify, Bytes20, Bytes32, + heapify, }; -use caller_env::{static_caller::StaticMem, GuestPtr, MemAccess}; +use caller_env::{GuestPtr, MemAccess, static_caller::StaticMem}; use prover::{machine::Module, programs::config::StylusConfig}; use crate::program::Program; diff --git a/crates/wasm-libraries/user-host/src/program.rs b/crates/wasm-libraries/user-host/src/program.rs index 06244c7c108..79b5421f66c 100644 --- a/crates/wasm-libraries/user-host/src/program.rs +++ b/crates/wasm-libraries/user-host/src/program.rs @@ -1,21 +1,21 @@ // Copyright 2022-2026, Offchain Labs, Inc. // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md -use core::sync::atomic::{compiler_fence, Ordering}; +use core::sync::atomic::{Ordering, compiler_fence}; use std::{borrow::Cow, cell::UnsafeCell, fmt::Display}; use arbutil::{ + Color, benchmark::Benchmark, evm::{ - api::{EvmApiMethod, Gas, Ink, VecReader, EVM_API_METHOD_REQ_OFFSET}, + EvmData, + api::{EVM_API_METHOD_REQ_OFFSET, EvmApiMethod, Gas, Ink, VecReader}, req::{EvmApiRequestor, RequestHandler}, user::UserOutcomeKind, - EvmData, }, - Color, }; -use caller_env::{static_caller::StaticMem, GuestPtr, MemAccess}; -use eyre::{eyre, Result}; +use caller_env::{GuestPtr, MemAccess, static_caller::StaticMem}; +use eyre::{Result, eyre}; use prover::programs::prelude::*; use user_host_trait::UserHost; use wasmer_types::{Pages, WASM_PAGE_SIZE}; diff --git a/crates/wasm-libraries/user-test/src/ink.rs b/crates/wasm-libraries/user-test/src/ink.rs index fabf87fb10b..a3384548f19 100644 --- a/crates/wasm-libraries/user-test/src/ink.rs +++ b/crates/wasm-libraries/user-test/src/ink.rs @@ -7,7 +7,7 @@ use prover::programs::{ prelude::{GasMeteredMachine, MachineMeter, MeteredMachine}, }; -use crate::{program::Program, GLOBAL_STATE}; +use crate::{GLOBAL_STATE, program::Program}; #[link(wasm_import_module = "hostio")] extern "C" { diff --git a/crates/wasm-libraries/user-test/src/lib.rs b/crates/wasm-libraries/user-test/src/lib.rs index bc2e2643d19..fed24bbd6a6 100644 --- a/crates/wasm-libraries/user-test/src/lib.rs +++ b/crates/wasm-libraries/user-test/src/lib.rs @@ -3,7 +3,7 @@ #![allow(clippy::missing_safety_doc)] -use arbutil::{evm::EvmData, Bytes32}; +use arbutil::{Bytes32, evm::EvmData}; use fnv::FnvHashMap as HashMap; use lazy_static::lazy_static; use parking_lot::Mutex; diff --git a/crates/wasm-libraries/user-test/src/program.rs b/crates/wasm-libraries/user-test/src/program.rs index 51c4ac6a242..3125d444442 100644 --- a/crates/wasm-libraries/user-test/src/program.rs +++ b/crates/wasm-libraries/user-test/src/program.rs @@ -4,16 +4,16 @@ use std::{borrow::Cow, fmt::Display}; use arbutil::{ + Bytes20, Bytes32, Color, benchmark::Benchmark, evm::{ + EvmData, api::{CreateRespone, EvmApi, Gas, Ink, VecReader}, user::UserOutcomeKind, - EvmData, }, - Bytes20, Bytes32, Color, }; -use caller_env::{static_caller::StaticMem, GuestPtr, MemAccess}; -use eyre::{eyre, Result}; +use caller_env::{GuestPtr, MemAccess, static_caller::StaticMem}; +use eyre::{Result, eyre}; use prover::programs::memory::MemoryModel; use user_host_trait::UserHost; diff --git a/crates/wasm-libraries/wasi-stub/lib.rs b/crates/wasm-libraries/wasi-stub/lib.rs index 70a0121ad21..8999136c282 100644 --- a/crates/wasm-libraries/wasi-stub/lib.rs +++ b/crates/wasm-libraries/wasi-stub/lib.rs @@ -5,10 +5,9 @@ #![no_std] use caller_env::{ - self, + self, GuestPtr, static_caller::{StaticExecEnv, StaticMem}, wasip1_stub::Errno, - GuestPtr, }; use paste::paste; use wee_alloc::WeeAlloc; From 6272464b18dc14fb5841fecd160139767bc69436 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Thu, 2 Apr 2026 13:24:12 +0200 Subject: [PATCH 189/189] fmt, clippy --- Cargo.lock | 2 +- crates/prover-ffi/src/machine.rs | 2 -- crates/prover/src/merkle.rs | 5 ++--- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e4cc461ae8a..2bd2c862b4b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5324,7 +5324,7 @@ dependencies = [ "eyre", "lazy_static", "libc", - "lru", + "lru 0.16.3", "once_cell", "prover", "static_assertions", diff --git a/crates/prover-ffi/src/machine.rs b/crates/prover-ffi/src/machine.rs index b118864425d..40ec9a8c1a1 100644 --- a/crates/prover-ffi/src/machine.rs +++ b/crates/prover-ffi/src/machine.rs @@ -2,7 +2,6 @@ // For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md use std::{ - ffi::CStr, os::raw::{c_char, c_int}, path::Path, ptr, slice, @@ -10,7 +9,6 @@ use std::{ }; use arbutil::Bytes32; -use eyre::Report; use prover::{ Machine, machine::{GlobalState, MachineStatus, argument_data_to_inbox, get_empty_preimage_resolver}, diff --git a/crates/prover/src/merkle.rs b/crates/prover/src/merkle.rs index 361ba3a0448..9ecdaa3322a 100644 --- a/crates/prover/src/merkle.rs +++ b/crates/prover/src/merkle.rs @@ -167,11 +167,10 @@ fn new_layer(ty: MerkleType, layer: &[Bytes32], empty_hash: &'static Bytes32) -> #[inline] #[cfg(not(feature = "rayon"))] fn new_layer(ty: MerkleType, layer: &[Bytes32], empty_hash: &'static Bytes32) -> Vec { - let new_layer = layer + layer .chunks(2) .map(|chunk| hash_node(ty, chunk[0], chunk.get(1).unwrap_or(empty_hash))) - .collect(); - new_layer + .collect() } impl Clone for Merkle {