From dd507f775b5c43b17d56d7039a1db71a92ab3475 Mon Sep 17 00:00:00 2001 From: Ratan Kaliani Date: Wed, 28 Aug 2024 16:22:52 -0700 Subject: [PATCH] feat: Cost Estimator + Optimizations (#68) * wip * fix * wip * add cost estimator * chore: add working cli tests, writes to execution report * fix * fix * feat: write in parallel (#71) * write in parallel * write in parallel * wip, wtf * add * feat: cost estimator --------- Co-authored-by: Ubuntu * edits * fix: docs among other things * fix * fix * fix * update span batch server * add * fix * fix * refactor * fix * fix * fix * chore: precompiles, add native host runner * build * keccak * keccak * updates * fix * cleanup * add * add * fix: build * add --------- Co-authored-by: Ubuntu --- .gitignore | 6 + Cargo.lock | 854 ++++++++++++------ Cargo.toml | 26 +- README.md | 6 + client-programs/fault-proof/src/main.rs | 3 +- client-programs/range/src/main.rs | 115 ++- crates/client-utils/Cargo.toml | 1 + crates/client-utils/src/driver.rs | 51 +- crates/client-utils/src/lib.rs | 2 + crates/client-utils/src/oracle/mod.rs | 6 +- crates/client-utils/src/pipes.rs | 18 + crates/client-utils/src/precompiles/mod.rs | 15 +- crates/host-utils/Cargo.toml | 3 + crates/host-utils/src/fetcher.rs | 7 +- crates/host-utils/src/lib.rs | 2 +- crates/host-utils/src/precompile.rs | 42 - crates/host-utils/src/stats.rs | 236 +++++ elf/aggregation-elf | Bin 562208 -> 564000 bytes elf/fault-proof-elf | Bin 5999060 -> 6914156 bytes elf/range-elf | Bin 6035932 -> 7001036 bytes native-host/Cargo.toml | 6 + .../bin/native_host_runner.rs | 11 +- op-proposer-go/cmd/main.go | 1 - op-succinct-proposer/COST_ESTIMATOR.md | 23 + op-succinct-proposer/Cargo.toml | 20 +- op-succinct-proposer/Dockerfile.op_proposer | 3 +- .../Dockerfile.span_batch_server | 39 + op-succinct-proposer/README.md | 4 + op-succinct-proposer/bin/cost_estimator.rs | 307 +++++++ op-succinct-proposer/build.rs | 77 ++ op-succinct-proposer/src/lib.rs | 46 +- zkvm-host/Cargo.toml | 7 +- zkvm-host/bin/multi.rs | 71 +- zkvm-host/build.rs | 4 +- zkvm-host/src/lib.rs | 2 - zkvm-host/src/stats.rs | 79 -- 36 files changed, 1518 insertions(+), 575 deletions(-) create mode 100644 crates/client-utils/src/pipes.rs delete mode 100644 crates/host-utils/src/precompile.rs create mode 100644 crates/host-utils/src/stats.rs rename {op-succinct-proposer => native-host}/bin/native_host_runner.rs (62%) create mode 100644 op-succinct-proposer/COST_ESTIMATOR.md create mode 100644 op-succinct-proposer/Dockerfile.span_batch_server create mode 100644 op-succinct-proposer/bin/cost_estimator.rs create mode 100644 op-succinct-proposer/build.rs delete mode 100644 zkvm-host/src/lib.rs delete mode 100644 zkvm-host/src/stats.rs diff --git a/.gitignore b/.gitignore index 480bcb31..00dcbfc3 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,9 @@ data # DB data db/ + +# Reports +execution-reports/ + +# Rollup Config +**/rollup-config.json diff --git a/Cargo.lock b/Cargo.lock index 4ea90e3d..7cf03f42 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -38,6 +38,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + [[package]] name = "aes" version = "0.8.4" @@ -58,7 +64,7 @@ dependencies = [ "client-utils", "serde_cbor", "sha2", - "sp1-lib 1.1.1", + "sp1-lib 1.2.0-rc1", "sp1-zkvm", ] @@ -131,9 +137,9 @@ dependencies = [ [[package]] name = "alloy-chains" -version = "0.1.27" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b515e82c8468ddb6ff8db21c78a5997442f113fd8471fd5b2261b2602dd0c67" +checksum = "bb07629a5d0645d29f68d2fb6f4d0cf15c89ec0965be915f303967180929743f" dependencies = [ "num_enum 0.7.3", "strum", @@ -292,8 +298,7 @@ dependencies = [ [[package]] name = "alloy-primitives" version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccb3ead547f4532bc8af961649942f0b9c16ee9226e26caa3f38420651cc0bf4" +source = "git+https://github.com/sp1-patches/alloy-core?branch=patch-v0.7.7#7d03e2576454bba809abcf45e2f44c313eaa33d0" dependencies = [ "alloy-rlp", "bytes", @@ -308,6 +313,7 @@ dependencies = [ "rand", "ruint", "serde", + "sha3", "tiny-keccak", ] @@ -339,7 +345,7 @@ dependencies = [ "futures-utils-wasm", "lru", "pin-project", - "reqwest 0.12.5", + "reqwest 0.12.7", "serde", "serde_json", "tokio", @@ -385,7 +391,7 @@ checksum = "4d0f2d905ebd295e7effec65e5f6868d153936130ae718352771de3e7d03c75c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.76", ] [[package]] @@ -403,7 +409,7 @@ dependencies = [ "alloy-transport-ws", "futures", "pin-project", - "reqwest 0.12.5", + "reqwest 0.12.7", "serde", "serde_json", "tokio", @@ -514,7 +520,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.76", ] [[package]] @@ -531,7 +537,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.76", "syn-solidity", "tiny-keccak", ] @@ -549,7 +555,7 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.74", + "syn 2.0.76", "syn-solidity", ] @@ -603,7 +609,7 @@ checksum = "2437d145d80ea1aecde8574d2058cceb8b3c9cba05f6aea8e67907c660d46698" dependencies = [ "alloy-json-rpc", "alloy-transport", - "reqwest 0.12.5", + "reqwest 0.12.7", "serde_json", "tower", "tracing", @@ -873,9 +879,9 @@ checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a" [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "async-stream" @@ -896,7 +902,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.76", ] [[package]] @@ -907,7 +913,7 @@ checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.76", ] [[package]] @@ -945,7 +951,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.76", ] [[package]] @@ -1019,7 +1025,7 @@ dependencies = [ "cc", "cfg-if", "libc", - "miniz_oxide", + "miniz_oxide 0.7.4", "object", "rustc-demangle", "serde", @@ -1095,7 +1101,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.74", + "syn 2.0.76", "which", ] @@ -1125,9 +1131,6 @@ name = "bitflags" version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" -dependencies = [ - "serde", -] [[package]] name = "bitvec" @@ -1137,7 +1140,6 @@ checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" dependencies = [ "funty", "radium", - "serde", "tap", "wyz", ] @@ -1164,9 +1166,9 @@ dependencies = [ [[package]] name = "blake3" -version = "1.5.3" +version = "1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9ec96fe9a81b5e365f9db71fe00edc4fe4ca2cc7dcb7861f0603012a7caa210" +checksum = "d82033247fd8e890df8f740e407ad4d038debb9eb1f40533fffb32e7d17dc6f7" dependencies = [ "arrayref", "arrayvec", @@ -1288,9 +1290,9 @@ dependencies = [ [[package]] name = "bytemuck" -version = "1.17.0" +version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fd4c6dcc3b0aea2f5c0b4b82c2b15fe39ddbc76041a310848f4706edf76bb31" +checksum = "773d90827bc3feecfb67fab12e24de0749aad83c74b9504ecde46237b5cd24e2" [[package]] name = "byteorder" @@ -1309,23 +1311,24 @@ dependencies = [ [[package]] name = "c-kzg" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdf100c4cea8f207e883ff91ca886d621d8a166cb04971dfaa9bb8fd99ed95df" +checksum = "f0307f72feab3300336fb803a57134159f6e20139af1357f36c54cb90d8e8928" dependencies = [ "blst", "cc", "glob", "hex", "libc", + "once_cell", "serde", ] [[package]] name = "camino" -version = "1.1.8" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3054fea8a20d8ff3968d5b22cc27501d2b08dc4decdb31b184323f00c5ef23bb" +checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" dependencies = [ "serde", ] @@ -1355,9 +1358,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.13" +version = "1.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72db2f7947ecee9b03b510377e8bb9077afa27176fdbff55c51027e976fdcc48" +checksum = "57b6a275aa2903740dc87da01c62040406b8812552e97129a63ea8850a17c6e6" dependencies = [ "jobserver", "libc", @@ -1379,6 +1382,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[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.38" @@ -1444,7 +1453,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.76", ] [[package]] @@ -1466,6 +1475,7 @@ dependencies = [ "async-trait", "itertools 0.13.0", "kona-client", + "kona-common", "kona-derive", "kona-executor", "kona-mpt", @@ -1550,7 +1560,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7bb11bd1378bf3731b182997b40cefe00aba6a6cc74042c8318c1b271d3badf7" dependencies = [ - "nix", + "nix 0.27.1", "thiserror", "tokio", ] @@ -1589,9 +1599,9 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "constant_time_eq" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" [[package]] name = "convert_case" @@ -1677,6 +1687,27 @@ dependencies = [ "typenum", ] +[[package]] +name = "csv" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe" +dependencies = [ + "csv-core", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70" +dependencies = [ + "memchr", +] + [[package]] name = "ctr" version = "0.9.2" @@ -1686,6 +1717,16 @@ dependencies = [ "cipher", ] +[[package]] +name = "ctrlc" +version = "3.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90eeab0aa92f3f9b4e87f258c72b139c207d251f9cbc1080a0086b86a8870dd3" +dependencies = [ + "nix 0.29.0", + "windows-sys 0.59.0", +] + [[package]] name = "curve25519-dalek" version = "4.1.3" @@ -1709,7 +1750,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.76", ] [[package]] @@ -1733,7 +1774,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.74", + "syn 2.0.76", ] [[package]] @@ -1744,7 +1785,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.74", + "syn 2.0.76", ] [[package]] @@ -1760,6 +1801,84 @@ dependencies = [ "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 = "data-encoding" version = "2.6.0" @@ -1807,7 +1926,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version 0.4.0", - "syn 2.0.74", + "syn 2.0.76", ] [[package]] @@ -1885,14 +2004,17 @@ checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" [[package]] name = "ecdsa" version = "0.16.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" +source = "git+https://github.com/sp1-patches/signatures?branch=patch-ecdsa-v0.16.8#f518b4a79d427fa9f42086480ea0cf360c11f022" dependencies = [ + "anyhow", + "cfg-if", "der", "digest 0.10.7", "elliptic-curve", + "hex-literal", "rfc6979", "signature", + "sp1-lib 1.2.0-rc1", "spki", ] @@ -1933,6 +2055,12 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + [[package]] name = "encode_unicode" version = "0.3.6" @@ -1974,7 +2102,7 @@ checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.76", ] [[package]] @@ -2125,7 +2253,7 @@ dependencies = [ "regex", "serde", "serde_json", - "syn 2.0.74", + "syn 2.0.76", "toml", "walkdir", ] @@ -2143,7 +2271,7 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.74", + "syn 2.0.76", ] [[package]] @@ -2169,7 +2297,7 @@ dependencies = [ "serde", "serde_json", "strum", - "syn 2.0.74", + "syn 2.0.76", "tempfile", "thiserror", "tiny-keccak", @@ -2269,9 +2397,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "fastrlp" @@ -2457,7 +2585,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.76", ] [[package]] @@ -2636,9 +2764,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" +checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" dependencies = [ "atomic-waker", "bytes", @@ -2770,9 +2898,12 @@ dependencies = [ "dotenv", "futures", "kona-host", + "num-format", "revm", "rkyv", + "serde", "serde_cbor", + "sp1-build", "sp1-sdk", "tokio", ] @@ -2878,7 +3009,7 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "h2 0.4.5", + "h2 0.4.6", "http 1.1.0", "http-body 1.0.1", "httparse", @@ -3237,7 +3368,7 @@ dependencies = [ [[package]] name = "kona-client" version = "0.1.0" -source = "git+https://github.com/ethereum-optimism/kona?branch=main#e4a032c1325687221d01674f0de0fd757e516e65" +source = "git+https://github.com/ethereum-optimism/kona?branch=main#f4a8e6a35b26667956e9d4c3a1110302b036d9a6" dependencies = [ "alloy-consensus", "alloy-eips", @@ -3256,6 +3387,8 @@ dependencies = [ "lru", "op-alloy-consensus", "revm", + "serde", + "serde_json", "spin 0.9.8", "tracing", ] @@ -3263,7 +3396,7 @@ dependencies = [ [[package]] name = "kona-common" version = "0.0.2" -source = "git+https://github.com/ethereum-optimism/kona?branch=main#e4a032c1325687221d01674f0de0fd757e516e65" +source = "git+https://github.com/ethereum-optimism/kona?branch=main#f4a8e6a35b26667956e9d4c3a1110302b036d9a6" dependencies = [ "anyhow", "cfg-if", @@ -3273,20 +3406,20 @@ dependencies = [ [[package]] name = "kona-common-proc" version = "0.0.2" -source = "git+https://github.com/ethereum-optimism/kona?branch=main#e4a032c1325687221d01674f0de0fd757e516e65" +source = "git+https://github.com/ethereum-optimism/kona?branch=main#f4a8e6a35b26667956e9d4c3a1110302b036d9a6" dependencies = [ "anyhow", "cfg-if", "kona-common", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.76", ] [[package]] name = "kona-derive" version = "0.0.2" -source = "git+https://github.com/ethereum-optimism/kona?branch=main#e4a032c1325687221d01674f0de0fd757e516e65" +source = "git+https://github.com/ethereum-optimism/kona?branch=main#f4a8e6a35b26667956e9d4c3a1110302b036d9a6" dependencies = [ "alloc-no-stdlib", "alloy-consensus", @@ -3294,26 +3427,17 @@ dependencies = [ "alloy-primitives", "alloy-provider", "alloy-rlp", - "alloy-rpc-client", - "alloy-rpc-types", - "alloy-sol-types", "alloy-transport", - "alloy-transport-http", "anyhow", "async-trait", "brotli", - "c-kzg", "hashbrown 0.14.5", "kona-primitives", "lru", - "miniz_oxide", + "miniz_oxide 0.8.0", "op-alloy-consensus", - "reqwest 0.12.5", - "revm", + "reqwest 0.12.7", "serde", - "serde_json", - "sha2", - "spin 0.9.8", "tracing", "unsigned-varint", ] @@ -3321,15 +3445,14 @@ dependencies = [ [[package]] name = "kona-executor" version = "0.0.1" -source = "git+https://github.com/ethereum-optimism/kona?branch=main#e4a032c1325687221d01674f0de0fd757e516e65" +source = "git+https://github.com/ethereum-optimism/kona?branch=main#f4a8e6a35b26667956e9d4c3a1110302b036d9a6" dependencies = [ "alloy-consensus", "alloy-eips", "alloy-primitives", - "alloy-rlp", "anyhow", - "kona-derive", "kona-mpt", + "kona-primitives", "op-alloy-consensus", "revm", "tracing", @@ -3338,7 +3461,7 @@ dependencies = [ [[package]] name = "kona-host" version = "0.1.0" -source = "git+https://github.com/ethereum-optimism/kona?branch=main#e4a032c1325687221d01674f0de0fd757e516e65" +source = "git+https://github.com/ethereum-optimism/kona?branch=main#f4a8e6a35b26667956e9d4c3a1110302b036d9a6" dependencies = [ "alloy-consensus", "alloy-eips", @@ -3358,10 +3481,12 @@ dependencies = [ "kona-derive", "kona-mpt", "kona-preimage", + "kona-primitives", "os_pipe", - "reqwest 0.12.5", + "reqwest 0.12.7", "revm", "serde", + "serde_json", "tokio", "tracing", "tracing-subscriber", @@ -3370,7 +3495,7 @@ dependencies = [ [[package]] name = "kona-mpt" version = "0.0.2" -source = "git+https://github.com/ethereum-optimism/kona?branch=main#e4a032c1325687221d01674f0de0fd757e516e65" +source = "git+https://github.com/ethereum-optimism/kona?branch=main#f4a8e6a35b26667956e9d4c3a1110302b036d9a6" dependencies = [ "alloy-consensus", "alloy-primitives", @@ -3384,12 +3509,11 @@ dependencies = [ [[package]] name = "kona-preimage" version = "0.0.2" -source = "git+https://github.com/ethereum-optimism/kona?branch=main#e4a032c1325687221d01674f0de0fd757e516e65" +source = "git+https://github.com/ethereum-optimism/kona?branch=main#f4a8e6a35b26667956e9d4c3a1110302b036d9a6" dependencies = [ "alloy-primitives", "anyhow", "async-trait", - "cfg-if", "kona-common", "rkyv", "tracing", @@ -3398,17 +3522,22 @@ dependencies = [ [[package]] name = "kona-primitives" version = "0.0.1" -source = "git+https://github.com/ethereum-optimism/kona?branch=main#e4a032c1325687221d01674f0de0fd757e516e65" +source = "git+https://github.com/ethereum-optimism/kona?branch=main#f4a8e6a35b26667956e9d4c3a1110302b036d9a6" dependencies = [ "alloy-consensus", "alloy-eips", "alloy-primitives", "alloy-rlp", - "alloy-sol-types", "anyhow", + "c-kzg", + "hashbrown 0.14.5", "op-alloy-consensus", + "revm", "serde", + "sha2", + "spin 0.9.8", "superchain-primitives", + "tracing", ] [[package]] @@ -3421,9 +3550,6 @@ dependencies = [ "glob", "hex", "once_cell", - "serde", - "serde_derive", - "serde_yaml", ] [[package]] @@ -3456,9 +3582,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.156" +version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5f43f184355eefb8d17fc948dbecf6c13be3c141f20d834ae842193a448c72a" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" [[package]] name = "libgit2-sys" @@ -3500,9 +3626,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.19" +version = "1.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc53a7799a7496ebc9fd29f31f7df80e83c9bda5299768af5f9e59eeea74647" +checksum = "d2d16453e800a8cf6dd2fc3eb4bc99b786a9b90c663b8559a5b1a041bf89e472" dependencies = [ "cc", "libc", @@ -3598,6 +3724,15 @@ dependencies = [ "adler", ] +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + [[package]] name = "mio" version = "1.0.2" @@ -3614,8 +3749,10 @@ dependencies = [ name = "native-host" version = "0.1.0" dependencies = [ + "anyhow", "clap", "kona-host", + "log", "tokio", ] @@ -3647,6 +3784,18 @@ dependencies = [ "libc", ] +[[package]] +name = "nix" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" +dependencies = [ + "bitflags 2.6.0", + "cfg-if", + "cfg_aliases", + "libc", +] + [[package]] name = "nohash-hasher" version = "0.2.0" @@ -3762,6 +3911,21 @@ 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" @@ -3829,10 +3993,10 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ - "proc-macro-crate 3.1.0", + "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.76", ] [[package]] @@ -3909,16 +4073,24 @@ dependencies = [ "cargo_metadata", "clap", "client-utils", + "csv", "dotenv", + "futures", "host-utils", + "itertools 0.13.0", "kona-host", + "kona-primitives", + "lazy_static", "log", + "rayon", + "reqwest 0.12.7", "revm", "serde", - "sp1-helper", + "sp1-build", "sp1-sdk", "tokio", "tower-http", + "uuid 1.10.0", ] [[package]] @@ -3969,7 +4141,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.76", ] [[package]] @@ -4333,7 +4505,7 @@ version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" dependencies = [ - "proc-macro-crate 3.1.0", + "proc-macro-crate 3.2.0", "proc-macro2", "quote", "syn 1.0.109", @@ -4480,7 +4652,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.76", ] [[package]] @@ -4519,12 +4691,13 @@ checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265" [[package]] name = "postcard" -version = "1.0.8" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a55c51ee6c0db07e68448e336cf8ea4131a620edefebf9893e759b2d793420f8" +checksum = "5f7f0a8d620d71c457dd1d47df76bb18960378da56af4527aaa10f515eee732e" dependencies = [ "cobs", - "embedded-io", + "embedded-io 0.4.0", + "embedded-io 0.6.1", "serde", ] @@ -4545,12 +4718,12 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.20" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" +checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba" dependencies = [ "proc-macro2", - "syn 2.0.74", + "syn 2.0.76", ] [[package]] @@ -4588,11 +4761,11 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" dependencies = [ - "toml_edit 0.21.1", + "toml_edit 0.22.20", ] [[package]] @@ -4668,7 +4841,16 @@ dependencies = [ "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.76", +] + +[[package]] +name = "prost-types" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9091c90b0a32608e984ff2fa4091273cbdd755d54935c51d520887f4a1dbd5b0" +dependencies = [ + "prost", ] [[package]] @@ -4756,9 +4938,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -4870,9 +5052,9 @@ dependencies = [ [[package]] name = "redox_users" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom", "libredox", @@ -4958,28 +5140,28 @@ dependencies = [ "serde_json", "serde_urlencoded", "sync_wrapper 0.1.2", - "system-configuration", + "system-configuration 0.5.1", "tokio", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "winreg 0.50.0", + "winreg", ] [[package]] name = "reqwest" -version = "0.12.5" +version = "0.12.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7d6d2a27d57148378eb5e111173f4276ad26340ecc5c49a4a2152167a2d6a37" +checksum = "f8f4955649ef5c38cc7f9e8aa41761d48fb9677197daea9984dc54f56aad5e63" dependencies = [ "base64 0.22.1", "bytes", "encoding_rs", "futures-core", "futures-util", - "h2 0.4.5", + "h2 0.4.6", "http 1.1.0", "http-body 1.0.1", "http-body-util", @@ -5003,7 +5185,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "sync_wrapper 1.0.1", - "system-configuration", + "system-configuration 0.6.1", "tokio", "tokio-native-tls", "tokio-rustls", @@ -5015,7 +5197,7 @@ dependencies = [ "wasm-streams", "web-sys", "webpki-roots", - "winreg 0.52.0", + "windows-registry", ] [[package]] @@ -5027,7 +5209,7 @@ dependencies = [ "anyhow", "async-trait", "http 1.1.0", - "reqwest 0.12.5", + "reqwest 0.12.7", "serde", "thiserror", "tower-service", @@ -5036,7 +5218,8 @@ dependencies = [ [[package]] name = "revm" version = "13.0.0" -source = "git+https://github.com/bluealloy/revm#1ad860469755e3cf71383f45d71c3faaf61d3029" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b2f635bbbf4002b1b5c0219f841ec1a317723883ed7662c0d138617539a6087" dependencies = [ "auto_impl", "cfg-if", @@ -5050,7 +5233,8 @@ dependencies = [ [[package]] name = "revm-interpreter" version = "9.0.0" -source = "git+https://github.com/bluealloy/revm#1ad860469755e3cf71383f45d71c3faaf61d3029" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2ad04c7d87dc3421a5ccca76e56dbd0b29a358c03bb41fe9e80976e9d3f397d" dependencies = [ "revm-primitives", "serde", @@ -5059,13 +5243,15 @@ dependencies = [ [[package]] name = "revm-precompile" version = "10.0.0" -source = "git+https://github.com/bluealloy/revm#1ad860469755e3cf71383f45d71c3faaf61d3029" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3526a4ba5ec400e7bbe71affbc10fe2e67c1cd1fb782bab988873d09a102e271" dependencies = [ "aurora-engine-modexp", "blst", "c-kzg", "cfg-if", "k256", + "kzg-rs 0.1.0", "once_cell", "p256", "revm-primitives", @@ -5078,7 +5264,8 @@ dependencies = [ [[package]] name = "revm-primitives" version = "8.0.0" -source = "git+https://github.com/bluealloy/revm#1ad860469755e3cf71383f45d71c3faaf61d3029" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4093d98a26601f0a793871c5bc7928410592f76b1f03fc89fde77180c554643c" dependencies = [ "alloy-eips", "alloy-primitives", @@ -5100,8 +5287,7 @@ dependencies = [ [[package]] name = "rfc6979" version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +source = "git+https://github.com/sp1-patches/signatures?branch=patch-ecdsa-v0.16.8#f518b4a79d427fa9f42086480ea0cf360c11f022" dependencies = [ "hmac", "subtle", @@ -5148,9 +5334,9 @@ dependencies = [ [[package]] name = "rkyv" -version = "0.7.44" +version = "0.7.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cba464629b3394fc4dbc6f940ff8f5b4ff5c7aef40f29166fd4ad12acbc99c0" +checksum = "9008cd6385b9e161d8229e1f6549dd23c3d022f132a2ea37ac3a10ac4935779b" dependencies = [ "bitvec", "bytecheck", @@ -5166,9 +5352,9 @@ dependencies = [ [[package]] name = "rkyv_derive" -version = "0.7.44" +version = "0.7.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7dddfff8de25e6f62b9d64e6e432bf1c6736c57d20323e15ee10435fbda7c65" +checksum = "503d1d27590a2b0a3a4ca4c94755aa2875657196ecbf401a42eff41d7de532c0" dependencies = [ "proc-macro2", "quote", @@ -5282,9 +5468,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "a85d50532239da68e9addb745ba38ff4612a242c1c7ceea689c4bc7c2f43c36f" dependencies = [ "bitflags 2.6.0", "errno", @@ -5325,9 +5511,9 @@ checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" [[package]] name = "rustls-webpki" -version = "0.102.6" +version = "0.102.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e" +checksum = "84678086bd54edf2b415183ed7a94d0efb049f1b646a33e22a36f3794be6ae56" dependencies = [ "ring 0.17.8", "rustls-pki-types", @@ -5394,7 +5580,7 @@ version = "2.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d35494501194174bda522a32605929eefc9ecf7e0a326c26db1fdd85881eb62" dependencies = [ - "proc-macro-crate 3.1.0", + "proc-macro-crate 3.2.0", "proc-macro2", "quote", "syn 1.0.109", @@ -5545,9 +5731,9 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.208" +version = "1.0.209" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2" +checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" dependencies = [ "serde_derive", ] @@ -5564,20 +5750,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.208" +version = "1.0.209" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf" +checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.76", ] [[package]] name = "serde_json" -version = "1.0.125" +version = "1.0.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c8e735a073ccf5be70aa8066aa984eaf2fa000db6c8d0100ae605b366d31ed" +checksum = "8043c06d9f82bd7271361ed64f415fe5e12a77fdb52e573e7f06a516dea329ad" dependencies = [ "indexmap 2.4.0", "itoa", @@ -5604,7 +5790,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.76", ] [[package]] @@ -5655,20 +5841,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.74", -] - -[[package]] -name = "serde_yaml" -version = "0.9.34+deprecated" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" -dependencies = [ - "indexmap 2.4.0", - "itoa", - "ryu", - "serde", - "unsafe-libyaml", + "syn 2.0.76", ] [[package]] @@ -5693,7 +5866,7 @@ checksum = "82fe9db325bcef1fbcde82e078a5cc4efdf787e96b3b9cf45b50b529f2083d67" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.76", ] [[package]] @@ -5710,7 +5883,7 @@ dependencies = [ [[package]] name = "sha2" version = "0.10.8" -source = "git+https://github.com/sp1-patches/RustCrypto-hashes?branch=patch-v0.10.8#1f224388fdede7cef649bce0d63876d1a9e3f515" +source = "git+https://github.com/sp1-patches/RustCrypto-hashes?branch=patch-sha2-v0.10.8#1f224388fdede7cef649bce0d63876d1a9e3f515" dependencies = [ "cfg-if", "cpufeatures", @@ -5720,8 +5893,7 @@ dependencies = [ [[package]] name = "sha3" version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +source = "git+https://github.com/sp1-patches/RustCrypto-hashes?branch=patch-sha3-v0.10.8#8f6d303c0861ba7e5adcc36207c0f41fe5edaabc" dependencies = [ "digest 0.10.7", "keccak", @@ -5832,19 +6004,58 @@ dependencies = [ [[package]] name = "sp1-build" -version = "1.1.1" -source = "git+https://github.com/succinctlabs/sp1.git?branch=experimental#cb6465650ebed0e1d7e9a7d425810ad772217096" +version = "1.2.0-rc1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16a18bb0916d1b4ee6f56bad0d79f0f844b2e7eb8dc6f4abce3dc440541ddf99" dependencies = [ "anyhow", "cargo_metadata", + "chrono", "clap", "dirs", ] [[package]] -name = "sp1-core" -version = "1.1.1" -source = "git+https://github.com/succinctlabs/sp1.git?branch=experimental#cb6465650ebed0e1d7e9a7d425810ad772217096" +name = "sp1-core-executor" +version = "1.2.0-rc1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a627bb8b04c2b537d4eb2a845f01a87357af37b079403d5ded060af445e4ee3" +dependencies = [ + "bincode", + "bytemuck", + "elf", + "eyre", + "generic-array 1.1.0", + "hashbrown 0.14.5", + "hex", + "itertools 0.13.0", + "log", + "nohash-hasher", + "num", + "p3-field", + "p3-keccak-air", + "p3-maybe-rayon", + "rand", + "rrs-succinct", + "serde", + "serde_with", + "sp1-curves", + "sp1-derive", + "sp1-primitives", + "sp1-stark", + "strum", + "strum_macros", + "thiserror", + "tiny-keccak", + "tracing", + "typenum", +] + +[[package]] +name = "sp1-core-machine" +version = "1.2.0-rc1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c8e59ebb97faeae1da856b10108dd3b0d4e37edf83a64c8092c2fb41f2372e4" dependencies = [ "anyhow", "arrayref", @@ -5889,8 +6100,11 @@ dependencies = [ "serde_with", "size", "snowbridge-amcl", + "sp1-core-executor", + "sp1-curves", "sp1-derive", "sp1-primitives", + "sp1-stark", "static_assertions", "strum", "strum_macros", @@ -5904,29 +6118,62 @@ dependencies = [ ] [[package]] -name = "sp1-derive" -version = "1.1.1" -source = "git+https://github.com/succinctlabs/sp1.git?branch=experimental#cb6465650ebed0e1d7e9a7d425810ad772217096" +name = "sp1-cuda" +version = "1.2.0-rc1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e817efa8ac773c56a0522115cb0f44704c1ba358f9db504d63770385be52918f" dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", + "bincode", + "ctrlc", + "prost", + "prost-types", + "serde", + "serde_json", + "sp1-core-machine", + "sp1-prover", + "sp1-stark", + "tokio", + "tracing", + "tracing-subscriber", + "twirp-rs", ] [[package]] -name = "sp1-helper" -version = "1.1.1" -source = "git+https://github.com/succinctlabs/sp1.git?branch=experimental#cb6465650ebed0e1d7e9a7d425810ad772217096" +name = "sp1-curves" +version = "1.2.0-rc1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bcfa6b9b6291ab3b13bcd24ea9414705cdcaea6a25d0cb014e6f6acedd72509" dependencies = [ - "cargo_metadata", - "chrono", - "sp1-build", + "curve25519-dalek", + "dashu", + "elliptic-curve", + "generic-array 1.1.0", + "itertools 0.13.0", + "k256", + "num", + "p3-field", + "serde", + "snowbridge-amcl", + "sp1-primitives", + "sp1-stark", + "typenum", +] + +[[package]] +name = "sp1-derive" +version = "1.2.0-rc1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddb6f5a85805239ba886cd36f371712080e668a1281d953b93df0561fc085a0a" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] name = "sp1-lib" version = "1.1.1" -source = "git+https://github.com/succinctlabs/sp1.git?branch=experimental#cb6465650ebed0e1d7e9a7d425810ad772217096" +source = "git+https://github.com/succinctlabs/sp1.git?branch=experimental#232d0fb2913f86e31383c8116379c51798ef7d78" dependencies = [ "anyhow", "bincode", @@ -5952,8 +6199,9 @@ dependencies = [ [[package]] name = "sp1-primitives" -version = "1.1.1" -source = "git+https://github.com/succinctlabs/sp1.git?branch=experimental#cb6465650ebed0e1d7e9a7d425810ad772217096" +version = "1.2.0-rc1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ca81d652375947f93636e0acfa89ffff7ad74531974d9b0c5c77ee6b74d3ec" dependencies = [ "itertools 0.13.0", "lazy_static", @@ -5965,8 +6213,9 @@ dependencies = [ [[package]] name = "sp1-prover" -version = "1.1.1" -source = "git+https://github.com/succinctlabs/sp1.git?branch=experimental#cb6465650ebed0e1d7e9a7d425810ad772217096" +version = "1.2.0-rc1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c583b70271b8e9b29a2d8cc81237c9150e5668f3ea30f6e1b3b64f043d190632" dependencies = [ "anyhow", "bincode", @@ -5986,13 +6235,15 @@ dependencies = [ "serde", "serde_json", "serial_test", - "sp1-core", + "sp1-core-executor", + "sp1-core-machine", "sp1-primitives", "sp1-recursion-circuit", "sp1-recursion-compiler", "sp1-recursion-core", "sp1-recursion-gnark-ffi", "sp1-recursion-program", + "sp1-stark", "subtle-encoding", "tempfile", "thiserror", @@ -6002,8 +6253,9 @@ dependencies = [ [[package]] name = "sp1-recursion-circuit" -version = "1.1.1" -source = "git+https://github.com/succinctlabs/sp1.git?branch=experimental#cb6465650ebed0e1d7e9a7d425810ad772217096" +version = "1.2.0-rc1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76d52b699642e3f56099fe7b731cc55f269c44150c95d9ce772b9bbbe14e7320" dependencies = [ "bincode", "itertools 0.13.0", @@ -6016,17 +6268,19 @@ dependencies = [ "p3-matrix", "p3-util", "serde", - "sp1-core", + "sp1-core-machine", "sp1-recursion-compiler", "sp1-recursion-core", "sp1-recursion-derive", "sp1-recursion-program", + "sp1-stark", ] [[package]] name = "sp1-recursion-compiler" -version = "1.1.1" -source = "git+https://github.com/succinctlabs/sp1.git?branch=experimental#cb6465650ebed0e1d7e9a7d425810ad772217096" +version = "1.2.0-rc1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6996298c6a55ba2742e20937b44c2eca49c698ef23735f24e310da85b264e22a" dependencies = [ "backtrace", "itertools 0.13.0", @@ -6040,19 +6294,23 @@ dependencies = [ "p3-poseidon2", "p3-symmetric", "p3-util", + "rayon", "serde", - "sp1-core", + "sp1-core-machine", "sp1-primitives", "sp1-recursion-core", "sp1-recursion-core-v2", "sp1-recursion-derive", + "sp1-stark", "tracing", + "vec_map", ] [[package]] name = "sp1-recursion-core" -version = "1.1.1" -source = "git+https://github.com/succinctlabs/sp1.git?branch=experimental#cb6465650ebed0e1d7e9a7d425810ad772217096" +version = "1.2.0-rc1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e426a4215dfc57398b4ec0a1de244d84ffa627443da5aa044420beb4a8ebde6c" dependencies = [ "arrayref", "backtrace", @@ -6076,9 +6334,11 @@ dependencies = [ "p3-util", "serde", "serde_with", - "sp1-core", + "sp1-core-executor", + "sp1-core-machine", "sp1-derive", "sp1-primitives", + "sp1-stark", "static_assertions", "tracing", "zkhash", @@ -6086,8 +6346,9 @@ dependencies = [ [[package]] name = "sp1-recursion-core-v2" -version = "1.1.1" -source = "git+https://github.com/succinctlabs/sp1.git?branch=experimental#cb6465650ebed0e1d7e9a7d425810ad772217096" +version = "1.2.0-rc1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3597f842c4b16778fca5b2ab972b308bcce0c6ca50633e88d2804a5a6bb936c" dependencies = [ "arrayref", "backtrace", @@ -6111,20 +6372,24 @@ dependencies = [ "p3-util", "serde", "serde_with", - "sp1-core", + "sp1-core-executor", + "sp1-core-machine", "sp1-derive", "sp1-primitives", "sp1-recursion-core", + "sp1-stark", "static_assertions", "thiserror", "tracing", + "vec_map", "zkhash", ] [[package]] name = "sp1-recursion-derive" -version = "1.1.1" -source = "git+https://github.com/succinctlabs/sp1.git?branch=experimental#cb6465650ebed0e1d7e9a7d425810ad772217096" +version = "1.2.0-rc1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ad893a3082bc0142fbc4c51965af25e6c6214dcd37bf285cb481c9ceed7bce2" dependencies = [ "proc-macro2", "quote", @@ -6133,8 +6398,9 @@ dependencies = [ [[package]] name = "sp1-recursion-gnark-ffi" -version = "1.1.1" -source = "git+https://github.com/succinctlabs/sp1.git?branch=experimental#cb6465650ebed0e1d7e9a7d425810ad772217096" +version = "1.2.0-rc1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3307cb27b8fab5d8b769bfaa4eaaa2c1e62224cbed0eb0426327635ca1db6a81" dependencies = [ "anyhow", "bincode", @@ -6151,15 +6417,17 @@ dependencies = [ "serde", "serde_json", "sha2", - "sp1-core", + "sp1-core-machine", "sp1-recursion-compiler", + "sp1-stark", "tempfile", ] [[package]] name = "sp1-recursion-program" -version = "1.1.1" -source = "git+https://github.com/succinctlabs/sp1.git?branch=experimental#cb6465650ebed0e1d7e9a7d425810ad772217096" +version = "1.2.0-rc1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8675f1f3f0ecd18748215a8c1ea47974523d3289ae1f64117cd259b5d85d7a8" dependencies = [ "itertools 0.13.0", "p3-air", @@ -6177,18 +6445,21 @@ dependencies = [ "p3-util", "rand", "serde", - "sp1-core", + "sp1-core-executor", + "sp1-core-machine", "sp1-primitives", "sp1-recursion-compiler", "sp1-recursion-core", + "sp1-stark", "stacker", "tracing", ] [[package]] name = "sp1-sdk" -version = "1.1.1" -source = "git+https://github.com/succinctlabs/sp1.git?branch=experimental#cb6465650ebed0e1d7e9a7d425810ad772217096" +version = "1.2.0-rc1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10be778e6b4030feabe5ecda6c8b617cae8d6c4a77db9c2e836f2c1e78f75a1c" dependencies = [ "alloy-sol-types", "anyhow", @@ -6210,13 +6481,16 @@ dependencies = [ "p3-fri", "p3-matrix", "prost", - "reqwest 0.12.5", + "reqwest 0.12.7", "reqwest-middleware", "serde", "serde_json", "sha2", - "sp1-core", + "sp1-core-executor", + "sp1-core-machine", + "sp1-cuda", "sp1-prover", + "sp1-stark", "strum", "strum_macros", "sysinfo", @@ -6228,10 +6502,41 @@ dependencies = [ "vergen", ] +[[package]] +name = "sp1-stark" +version = "1.2.0-rc1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d15e06e3cb60d88c3c4fc66d17713d69cfd8c1338c67519466322e0d15f10168" +dependencies = [ + "arrayref", + "hashbrown 0.14.5", + "itertools 0.13.0", + "p3-air", + "p3-baby-bear", + "p3-challenger", + "p3-commit", + "p3-dft", + "p3-field", + "p3-fri", + "p3-matrix", + "p3-maybe-rayon", + "p3-merkle-tree", + "p3-poseidon2", + "p3-symmetric", + "p3-uni-stark", + "p3-util", + "rayon-scan", + "serde", + "sp1-derive", + "sp1-primitives", + "tracing", +] + [[package]] name = "sp1-zkvm" -version = "1.1.1" -source = "git+https://github.com/succinctlabs/sp1.git?branch=experimental#cb6465650ebed0e1d7e9a7d425810ad772217096" +version = "1.2.0-rc1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "080e2045ac8427c677bd1285b1d9eeccc29a54ee952bb38eff83151894376097" dependencies = [ "bincode", "cfg-if", @@ -6244,7 +6549,7 @@ dependencies = [ "rand", "serde", "sha2", - "sp1-lib 1.1.1", + "sp1-lib 1.2.0-rc1", "sp1-primitives", ] @@ -6299,15 +6604,15 @@ dependencies = [ [[package]] name = "stacker" -version = "0.1.15" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c886bd4480155fd3ef527d45e9ac8dd7118a898a46530b7b94c3e21866259fce" +checksum = "799c883d55abdb5e98af1a7b3f23b9b6de8ecada0ecac058672d7635eb48ca7b" dependencies = [ "cc", "cfg-if", "libc", "psm", - "winapi", + "windows-sys 0.59.0", ] [[package]] @@ -6341,7 +6646,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.74", + "syn 2.0.76", ] [[package]] @@ -6376,9 +6681,9 @@ dependencies = [ [[package]] name = "superchain-primitives" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e35d3e5f7fc00a05e56c9bede517d19c8d91f8686169a585100c1e201183e3c7" +checksum = "f92c0bb828219b159e625b816e9248adafb028eabb86917b0dfbca9c658c0990" dependencies = [ "alloy-consensus", "alloy-eips", @@ -6403,9 +6708,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.74" +version = "2.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fceb41e3d546d0bd83421d3409b1460cc7444cd389341a4c880fe7a042cb3d7" +checksum = "578e081a14e0cefc3279b0472138c513f37b41a08d5a3cca9b6e4e8ceb6cd525" dependencies = [ "proc-macro2", "quote", @@ -6421,7 +6726,7 @@ dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.76", ] [[package]] @@ -6435,6 +6740,9 @@ name = "sync_wrapper" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +dependencies = [ + "futures-core", +] [[package]] name = "sysinfo" @@ -6459,7 +6767,18 @@ checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ "bitflags 1.3.2", "core-foundation", - "system-configuration-sys", + "system-configuration-sys 0.5.0", +] + +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags 2.6.0", + "core-foundation", + "system-configuration-sys 0.6.0", ] [[package]] @@ -6472,6 +6791,16 @@ dependencies = [ "libc", ] +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "tap" version = "1.0.1" @@ -6508,7 +6837,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.76", ] [[package]] @@ -6589,9 +6918,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.39.2" +version = "1.39.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1" +checksum = "9babc99b9923bfa4804bd74722ff02c0381021eafa4db9949217e3be8e84fff5" dependencies = [ "backtrace", "bytes", @@ -6613,7 +6942,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.76", ] [[package]] @@ -6710,17 +7039,6 @@ dependencies = [ "winnow 0.5.40", ] -[[package]] -name = "toml_edit" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" -dependencies = [ - "indexmap 2.4.0", - "toml_datetime", - "winnow 0.5.40", -] - [[package]] name = "toml_edit" version = "0.22.20" @@ -6798,7 +7116,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.76", ] [[package]] @@ -6903,7 +7221,7 @@ dependencies = [ "http-body-util", "hyper 1.4.1", "prost", - "reqwest 0.12.5", + "reqwest 0.12.7", "serde", "serde_json", "thiserror", @@ -6971,15 +7289,9 @@ checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" [[package]] name = "unicode-xid" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" - -[[package]] -name = "unsafe-libyaml" -version = "0.2.11" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" +checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a" [[package]] name = "unsigned-varint" @@ -7050,6 +7362,12 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + [[package]] name = "vergen" version = "8.3.2" @@ -7125,7 +7443,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.76", "wasm-bindgen-shared", ] @@ -7159,7 +7477,7 @@ checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.76", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -7280,6 +7598,36 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-registry" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" +dependencies = [ + "windows-result", + "windows-strings", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -7456,16 +7804,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "winreg" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - [[package]] name = "ws_stream_wasm" version = "0.7.4" @@ -7512,7 +7850,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.76", ] [[package]] @@ -7532,7 +7870,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.76", ] [[package]] @@ -7570,18 +7908,14 @@ dependencies = [ "cargo_metadata", "clap", "client-utils", + "csv", "dotenv", "host-utils", "kona-host", "log", "num-format", "revm", - "sp1-helper", + "sp1-build", "sp1-sdk", "tokio", ] - -[[patch.unused]] -name = "ecdsa" -version = "0.16.9" -source = "git+https://github.com/sp1-patches/signatures?branch=patch-ecdsa-v0.16.9#1caae137b2b2c458b8a542b1c4e9fb40293c67a3" diff --git a/Cargo.toml b/Cargo.toml index e47071b4..bf870d7b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ repository = "" [workspace.dependencies] # kona +# TODO: Change to stable tag when released. kona-common = { git = "https://github.com/ethereum-optimism/kona", branch = "main" } kona-common-proc = { git = "https://github.com/ethereum-optimism/kona", branch = "main" } kona-preimage = { git = "https://github.com/ethereum-optimism/kona", branch = "main", features = [ @@ -46,6 +47,8 @@ futures = "0.3.30" serde_cbor = "0.11.2" log = "0.4.22" itertools = "0.13.0" +reqwest = { version = "0.12", features = ["json"] } +csv = "1.3.0" # serialization @@ -65,7 +68,7 @@ alloy = { version = "0.2", default-features = false, features = ["full"] } alloy-primitives = { version = "0.7.6", default-features = false } alloy-rlp = { version = "0.3.5", default-features = false } alloy-eips = { version = "0.2", default-features = false } -revm = { git = "https://github.com/bluealloy/revm", version = "13.0", default-features = false } +revm = { version = "13.0", default-features = false, features = ["kzg-rs"] } bincode = "1.3.3" base64 = "0.22.1" tower-http = { version = "0.5.2", features = ["limit"] } @@ -74,14 +77,10 @@ alloy-sol-types = { version = "0.7.6" } op-alloy-consensus = { version = "0.1.4", default-features = false } # sp1 -sp1-lib = { git = "https://github.com/succinctlabs/sp1.git", branch = "experimental", features = [ - "verify", -] } -sp1-zkvm = { git = "https://github.com/succinctlabs/sp1.git", branch = "experimental", features = [ - "verify", -] } -sp1-sdk = { git = "https://github.com/succinctlabs/sp1.git", branch = "experimental" } -sp1-helper = { git = "https://github.com/succinctlabs/sp1.git", branch = "experimental" } +sp1-lib = { version = "1.2.0-rc1", features = ["verify"] } +sp1-zkvm = { version = "1.2.0-rc1", features = ["verify"] } +sp1-sdk = { version = "1.2.0-rc1" } +sp1-build = { version = "1.2.0-rc1" } # kzg kzg-rs = { version = "0.2.1" } @@ -95,6 +94,9 @@ lto = "fat" [patch.crates-io] tiny-keccak = { git = "https://github.com/sp1-patches/tiny-keccak", branch = "patch-v2.0.2" } -sha2 = { git = "https://github.com/sp1-patches/RustCrypto-hashes", branch = "patch-v0.10.8", package = "sha2" } -ecdsa-core = { git = "https://github.com/sp1-patches/signatures", package = "ecdsa", branch = "patch-ecdsa-v0.16.9" } -bn = { git = "https://github.com/0xWOLAND/bn.git", package = "substrate-bn", default-features = false } +sha2 = { git = "https://github.com/sp1-patches/RustCrypto-hashes", package = "sha2", branch = "patch-sha2-v0.10.8" } +ecdsa = { git = "https://github.com/sp1-patches/signatures", branch = "patch-ecdsa-v0.16.8" } +bn = { git = "https://github.com/0xWOLAND/bn.git", package = "substrate-bn" } +# Note: Patch alloy-primitives to use sha3 instead of tiny-keccak. Reduces cycle count for Keccak by 50%. +sha3 = { git = "https://github.com/sp1-patches/RustCrypto-hashes", package = "sha3", branch = "patch-sha3-v0.10.8" } +alloy-primitives = { git = "https://github.com/sp1-patches/alloy-core", branch = "patch-v0.7.7" } diff --git a/README.md b/README.md index 55f4ef58..07c9cf19 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,12 @@ Standalone repo to use Kona & SP1 to verify OP Stack blocks. + +## ⚠️ Work in Progress + +**Warning**: This repository is currently a work in progress. The code and documentation are actively being developed and may be subject to significant changes. Use with caution and expect frequent updates. + + ## Overview **`crates`** diff --git a/client-programs/fault-proof/src/main.rs b/client-programs/fault-proof/src/main.rs index 3bce4424..50cbad6d 100644 --- a/client-programs/fault-proof/src/main.rs +++ b/client-programs/fault-proof/src/main.rs @@ -25,6 +25,7 @@ cfg_if! { use alloc::vec::Vec; } else { use kona_client::CachingOracle; + use client_utils::pipes::{ORACLE_READER, HINT_WRITER}; } } @@ -58,7 +59,7 @@ fn main() { // If we are compiling for online mode, create a caching oracle that speaks to the // fetcher via hints, and gather boot info from this oracle. } else { - let oracle = Arc::new(CachingOracle::new(1024)); + let oracle = Arc::new(CachingOracle::new(1024, ORACLE_READER, HINT_WRITER)); let boot = Arc::new(BootInfo::load(oracle.as_ref()).await.unwrap()); let precompile_overrides = NoPrecompileOverride; } diff --git a/client-programs/range/src/main.rs b/client-programs/range/src/main.rs index 3d6557eb..b9844fe2 100644 --- a/client-programs/range/src/main.rs +++ b/client-programs/range/src/main.rs @@ -1,11 +1,12 @@ //! A program to verify a Optimism L2 block STF in the zkVM. #![cfg_attr(target_os = "zkvm", no_main)] +use client_utils::precompiles::ZKVMPrecompileOverride; use kona_client::{ l1::{OracleBlobProvider, OracleL1ChainProvider}, BootInfo, }; -use kona_executor::{NoPrecompileOverride, StatelessL2BlockExecutor}; +use kona_executor::StatelessL2BlockExecutor; use alloy_eips::eip2718::Decodable2718; use kona_primitives::{L2ExecutionPayloadEnvelope, OpBlock}; @@ -36,6 +37,7 @@ cfg_if! { use alloc::vec::Vec; } else { use kona_client::CachingOracle; + use client_utils::pipes::{ORACLE_READER, HINT_WRITER}; } } @@ -46,9 +48,9 @@ fn main() { //////////////////////////////////////////////////////////////// cfg_if! { - // If we are compiling for the zkVM, read inputs from SP1 to generate boot info - // and in memory oracle. if #[cfg(target_os = "zkvm")] { + // If we are compiling for the zkVM, read inputs from SP1 to generate boot info + // and in memory oracle. println!("cycle-tracker-start: boot-load"); let boot = sp1_zkvm::io::read::(); sp1_zkvm::io::commit_slice(&boot.abi_encode()); @@ -60,21 +62,19 @@ fn main() { let oracle = Arc::new(InMemoryOracle::from_raw_bytes(kv_store_bytes)); println!("cycle-tracker-end: oracle-load"); - println!("cycle-tracker-start: oracle-verify"); + println!("cycle-tracker-report-start: oracle-verify"); oracle.verify().expect("key value verification failed"); - println!("cycle-tracker-end: oracle-verify"); - - let precompile_overrides = NoPrecompileOverride; - - // If we are compiling for online mode, create a caching oracle that speaks to the - // fetcher via hints, and gather boot info from this oracle. + println!("cycle-tracker-report-end: oracle-verify"); } else { - let oracle = Arc::new(CachingOracle::new(1024)); + // If we are compiling for online mode, create a caching oracle that speaks to the + // fetcher via hints, and gather boot info from this oracle. + let oracle = Arc::new(CachingOracle::new(1024, ORACLE_READER, HINT_WRITER)); let boot = Arc::new(BootInfo::load(oracle.as_ref()).await.unwrap()); - - let precompile_overrides = NoPrecompileOverride; } } + // Note: On some blocks, key not found in cache errors occur due to the precompiles. For + // recent blocks this isn't an issue, but we should look into this more in the future. + let precompile_overrides = ZKVMPrecompileOverride::default(); let l1_provider = OracleL1ChainProvider::new(boot.clone(), oracle.clone()); let mut l2_provider = MultiblockOracleL2ChainProvider::new(boot.clone(), oracle.clone()); @@ -96,8 +96,10 @@ fn main() { .unwrap(); println!("cycle-tracker-end: derivation-instantiation"); - let mut l2_block_info = driver.l2_safe_head; - let mut new_block_header = &driver.l2_safe_head_header.inner().clone(); + // The initial payload requires block derivation. + println!("cycle-tracker-report-start: payload-derivation"); + let mut payload = driver.produce_payloads().await.unwrap(); + println!("cycle-tracker-report-end: payload-derivation"); println!("cycle-tracker-start: execution-instantiation"); let mut executor = StatelessL2BlockExecutor::builder(&boot.rollup_config) @@ -109,52 +111,47 @@ fn main() { .unwrap(); println!("cycle-tracker-end: execution-instantiation"); + let mut l2_block_info; + let mut new_block_header; 'step: loop { - let l2_attrs_with_parents = driver.produce_payloads().await.unwrap(); - if l2_attrs_with_parents.is_empty() { - continue; + // Execute the payload to generate a new block header. + info!( + "Executing Payload for L2 Block: {}", + payload.parent.block_info.number + 1 + ); + println!("cycle-tracker-report-start: block-execution"); + new_block_header = executor + .execute_payload(payload.attributes.clone()) + .unwrap(); + println!("cycle-tracker-report-end: block-execution"); + let new_block_number = new_block_header.number; + assert_eq!(new_block_number, payload.parent.block_info.number + 1); + + // Generate the Payload Envelope, which can be used to derive cached data. + let l2_payload_envelope: L2ExecutionPayloadEnvelope = OpBlock { + header: new_block_header.clone(), + body: payload + .attributes + .transactions + .iter() + .map(|raw_tx| OpTxEnvelope::decode_2718(&mut raw_tx.as_ref()).unwrap()) + .collect::>(), + withdrawals: boot + .rollup_config + .is_canyon_active(new_block_header.timestamp) + .then(Vec::new), + ..Default::default() } + .into(); + + // Add all data from this block's execution to the cache. + l2_block_info = l2_provider + .update_cache(new_block_header, l2_payload_envelope, &boot.rollup_config) + .unwrap(); - for payload in l2_attrs_with_parents { - // Execute the payload to generate a new block header. - info!( - "Executing Payload for L2 Block: {}", - payload.parent.block_info.number + 1 - ); - println!("cycle-tracker-report-start: block-execution"); - new_block_header = executor - .execute_payload(payload.attributes.clone()) - .unwrap(); - println!("cycle-tracker-report-end: block-execution"); - let new_block_number = new_block_header.number; - assert_eq!(new_block_number, payload.parent.block_info.number + 1); - - // Generate the Payload Envelope, which can be used to derive cached data. - let l2_payload_envelope: L2ExecutionPayloadEnvelope = OpBlock { - header: new_block_header.clone(), - body: payload - .attributes - .transactions - .iter() - .map(|raw_tx| OpTxEnvelope::decode_2718(&mut raw_tx.as_ref()).unwrap()) - .collect::>(), - withdrawals: boot - .rollup_config - .is_canyon_active(new_block_header.timestamp) - .then(Vec::new), - ..Default::default() - } - .into(); - - // Add all data from this block's execution to the cache. - l2_block_info = l2_provider - .update_cache(new_block_header, l2_payload_envelope, &boot.rollup_config) - .unwrap(); - - // Increment last_block_num and check if we have reached the claim block. - if new_block_number == boot.l2_claim_block { - break 'step; - } + // Increment last_block_num and check if we have reached the claim block. + if new_block_number == boot.l2_claim_block { + break 'step; } // Update data for the next iteration. @@ -162,6 +159,8 @@ fn main() { l2_block_info, Sealed::new_unchecked(new_block_header.clone(), new_block_header.hash_slow()), ); + + payload = driver.produce_payloads().await.unwrap(); } println!("cycle-tracker-start: output-root"); diff --git a/crates/client-utils/Cargo.toml b/crates/client-utils/Cargo.toml index 18779cfd..72d0c9ff 100644 --- a/crates/client-utils/Cargo.toml +++ b/crates/client-utils/Cargo.toml @@ -25,6 +25,7 @@ kona-client.workspace = true kona-preimage.workspace = true kona-mpt.workspace = true kona-derive.workspace = true +kona-common.workspace = true # general serde.workspace = true diff --git a/crates/client-utils/src/driver.rs b/crates/client-utils/src/driver.rs index baf9465e..9408ec01 100644 --- a/crates/client-utils/src/driver.rs +++ b/crates/client-utils/src/driver.rs @@ -20,7 +20,6 @@ use kona_derive::{ L1Traversal, StatefulAttributesBuilder, }, traits::{ChainProvider, L2ChainProvider}, - types::StageError, }; use kona_mpt::TrieDBFetcher; use kona_preimage::{CommsClient, PreimageKey, PreimageKeyType}; @@ -143,41 +142,31 @@ impl MultiBlockDerivationDriver { /// Produces the disputed [Vec] payloads, starting with the one after /// the L2 output root, for all the payloads derived in a given span batch. - pub async fn produce_payloads(&mut self) -> Result> { - debug!( - "Stepping on Pipeline for L2 Block: {}", - self.l2_safe_head.block_info.number - ); - match self.pipeline.step(self.l2_safe_head).await { - StepResult::PreparedAttributes => { - debug!("Found Attributes"); - let mut payloads = Vec::new(); - for attr in self.pipeline.by_ref() { - let parent_block_nb = attr.parent.block_info.number; - payloads.push(attr); - if parent_block_nb + 1 == self.l2_claim_block { - break; - } + pub async fn produce_payloads(&mut self) -> Result { + // As we start the safe head at the disputed block's parent, we step the pipeline until the + // first attributes are produced. All batches at and before the safe head will be + // dropped, so the first payload will always be the disputed one. + let mut attributes = None; + while attributes.is_none() { + match self.pipeline.step(self.l2_safe_head).await { + StepResult::PreparedAttributes => { + debug!(target: "client_derivation_driver", "Stepped derivation pipeline") } - return Ok(payloads); - } - StepResult::AdvancedOrigin => { - debug!("Advanced Origin"); - } - StepResult::OriginAdvanceErr(e) => { - error!("Origin Advance Error: {:?}", e); - } - StepResult::StepFailed(e) => match e { - StageError::NotEnoughData => { - debug!("Failed: Not Enough Data"); + StepResult::AdvancedOrigin => { + debug!(target: "client_derivation_driver", "Advanced origin") } - _ => { - error!("Failed: {:?}", e); + StepResult::OriginAdvanceErr(e) => { + error!(target: "client_derivation_driver", "Failed to advance origin: {:?}", e) } - }, + StepResult::StepFailed(e) => { + error!(target: "client_derivation_driver", "Failed to step derivation pipeline: {:?}", e) + } + } + + attributes = self.pipeline.next(); } - Ok(Vec::new()) + Ok(attributes.expect("Must be some")) } /// Finds the startup information for the derivation pipeline. diff --git a/crates/client-utils/src/lib.rs b/crates/client-utils/src/lib.rs index 8d908d83..8b2ada7c 100644 --- a/crates/client-utils/src/lib.rs +++ b/crates/client-utils/src/lib.rs @@ -14,6 +14,8 @@ pub mod precompiles; pub mod types; +pub mod pipes; + extern crate alloc; pub mod driver; diff --git a/crates/client-utils/src/oracle/mod.rs b/crates/client-utils/src/oracle/mod.rs index 8308b1bd..964d5234 100644 --- a/crates/client-utils/src/oracle/mod.rs +++ b/crates/client-utils/src/oracle/mod.rs @@ -1,7 +1,5 @@ //! Contains the host <-> client communication utilities. -use std::collections::HashMap; - use crate::BytesHasherBuilder; use alloy_primitives::{hex, keccak256, FixedBytes}; use anyhow::{anyhow, Result}; @@ -13,6 +11,7 @@ use kzg_rs::Blob as KzgRsBlob; use kzg_rs::Bytes48; use rkyv::{Archive, Deserialize, Infallible, Serialize}; use sha2::{Digest, Sha256}; +use std::collections::HashMap; /// An in-memory HashMap that will serve as the oracle for the zkVM. /// Rather than relying on a trusted host for data, the data in this oracle @@ -74,8 +73,7 @@ impl HintWriterClient for InMemoryOracle { /// and verify it once, rather than verifying each of the 4096 elements separately. #[derive(Default)] struct Blob { - // TODO: This commitment is currently unused. - commitment: FixedBytes<48>, + _commitment: FixedBytes<48>, // 4096 Field elements, each 32 bytes. data: FixedBytes<131072>, kzg_proof: FixedBytes<48>, diff --git a/crates/client-utils/src/pipes.rs b/crates/client-utils/src/pipes.rs new file mode 100644 index 00000000..479d0929 --- /dev/null +++ b/crates/client-utils/src/pipes.rs @@ -0,0 +1,18 @@ +//! Contains FPVM-specific constructs for the `kona-client` program. + +use kona_common::FileDescriptor; +use kona_preimage::{HintWriter, OracleReader, PipeHandle}; + +/// The global preimage oracle reader pipe. +static ORACLE_READER_PIPE: PipeHandle = + PipeHandle::new(FileDescriptor::PreimageRead, FileDescriptor::PreimageWrite); + +/// The global hint writer pipe. +static HINT_WRITER_PIPE: PipeHandle = + PipeHandle::new(FileDescriptor::HintRead, FileDescriptor::HintWrite); + +/// The global preimage oracle reader. +pub static ORACLE_READER: OracleReader = OracleReader::new(ORACLE_READER_PIPE); + +/// The global hint writer. +pub static HINT_WRITER: HintWriter = HintWriter::new(HINT_WRITER_PIPE); diff --git a/crates/client-utils/src/precompiles/mod.rs b/crates/client-utils/src/precompiles/mod.rs index b9d722ca..d420a991 100644 --- a/crates/client-utils/src/precompiles/mod.rs +++ b/crates/client-utils/src/precompiles/mod.rs @@ -3,11 +3,14 @@ use alloc::sync::Arc; use kona_executor::PrecompileOverride; use kona_mpt::{TrieDB, TrieDBFetcher, TrieDBHinter}; +use revm::db::states::state::State; use revm::{ handler::register::EvmHandler, - precompile::{bn128, Precompile, PrecompileResult, PrecompileSpecId, PrecompileWithAddress}, + precompile::{ + bn128, secp256k1, Precompile, PrecompileResult, PrecompileSpecId, PrecompileWithAddress, + }, primitives::Bytes, - ContextPrecompiles, State, + ContextPrecompiles, }; pub const PRECOMPILE_HOOK_FD: u32 = 115; @@ -39,6 +42,12 @@ pub(crate) const ANNOTATED_BN_MUL: PrecompileWithAddress = create_annotated_precompile!(bn128::mul::ISTANBUL, "bn-mul"); pub(crate) const ANNOTATED_BN_PAIR: PrecompileWithAddress = create_annotated_precompile!(bn128::pair::ISTANBUL, "bn-pair"); +pub(crate) const ANNOTATED_KZG_EVAL: PrecompileWithAddress = create_annotated_precompile!( + revm::precompile::kzg_point_evaluation::POINT_EVALUATION, + "kzg-eval" +); +pub(crate) const ANNOTATED_EC_RECOVER: PrecompileWithAddress = + create_annotated_precompile!(secp256k1::ECRECOVER, "ec-recover"); /// The [PrecompileOverride] implementation for the FPVM-accelerated precompiles. #[derive(Debug)] @@ -79,6 +88,8 @@ where ANNOTATED_BN_ADD, ANNOTATED_BN_MUL, ANNOTATED_BN_PAIR, + ANNOTATED_KZG_EVAL, + ANNOTATED_EC_RECOVER, ]; ctx_precompiles.extend(override_precompiles); diff --git a/crates/host-utils/Cargo.toml b/crates/host-utils/Cargo.toml index 90031a5b..16686484 100644 --- a/crates/host-utils/Cargo.toml +++ b/crates/host-utils/Cargo.toml @@ -20,3 +20,6 @@ revm.workspace = true dotenv.workspace = true tokio.workspace = true futures.workspace = true +num-format.workspace = true +serde.workspace = true +sp1-build.workspace = true diff --git a/crates/host-utils/src/fetcher.rs b/crates/host-utils/src/fetcher.rs index adc5b8ad..9a32dcdd 100644 --- a/crates/host-utils/src/fetcher.rs +++ b/crates/host-utils/src/fetcher.rs @@ -25,6 +25,7 @@ pub struct SP1KonaDataFetcher { pub l1_provider: Arc>>, pub l1_beacon_rpc: String, pub l2_rpc: String, + pub l2_node_rpc: String, pub l2_provider: Arc>>, } @@ -57,6 +58,8 @@ impl SP1KonaDataFetcher { let l1_beacon_rpc = env::var("L1_BEACON_RPC").unwrap_or_else(|_| "http://localhost:5052".to_string()); let l2_rpc = env::var("L2_RPC").unwrap_or_else(|_| "http://localhost:9545".to_string()); + let l2_node_rpc = + env::var("L2_NODE_RPC").unwrap_or_else(|_| "http://localhost:5058".to_string()); let l2_provider = Arc::new(ProviderBuilder::default().on_http(Url::from_str(&l2_rpc).unwrap())); SP1KonaDataFetcher { @@ -64,6 +67,7 @@ impl SP1KonaDataFetcher { l1_provider, l1_beacon_rpc, l2_rpc, + l2_node_rpc, l2_provider, } } @@ -343,7 +347,7 @@ impl SP1KonaDataFetcher { // The native programs are built with profile release-client-lto in build.rs let exec_directory = match multi_block { ProgramType::Single => { - format!("{}/target/release-client-lto/fault_proof", workspace_root) + format!("{}/target/release-client-lto/fault-proof", workspace_root) } ProgramType::Multi => format!("{}/target/release-client-lto/range", workspace_root), }; @@ -367,6 +371,7 @@ impl SP1KonaDataFetcher { data_dir: Some(data_directory.into()), exec: Some(exec_directory), server: false, + rollup_config_path: None, v: 0, }) } diff --git a/crates/host-utils/src/lib.rs b/crates/host-utils/src/lib.rs index 129ab2c2..026830e2 100644 --- a/crates/host-utils/src/lib.rs +++ b/crates/host-utils/src/lib.rs @@ -1,6 +1,6 @@ pub mod fetcher; pub mod helpers; -pub mod precompile; +pub mod stats; use alloy_consensus::Header; use alloy_primitives::B256; diff --git a/crates/host-utils/src/precompile.rs b/crates/host-utils/src/precompile.rs deleted file mode 100644 index bc0f57e7..00000000 --- a/crates/host-utils/src/precompile.rs +++ /dev/null @@ -1,42 +0,0 @@ -use revm::precompile::{Bytes, Precompile, Precompiles}; -use revm::primitives::Address; - -/// This precompile hook substitutes the precompile with a custom one that can stub out the logic -/// for specific operations that we don't have precompiles for. Used in `create_hook_precompile`. -pub fn precompile_hook(_env: sp1_sdk::HookEnv, buf: &[u8]) -> Vec> { - let addr: Address = buf[0..20].try_into().unwrap(); - let gas_limit = u64::from_le_bytes(buf[20..28].try_into().unwrap()); - let input: Bytes = buf[28..].to_vec().into(); - println!("[HOOK] Precompile addr {} called.", addr); - - // Note: Fetch the latest precompiles because the gas costs are different from older versions. - // Otherwise, the hooked precompiles will fail. - let precompiles = Precompiles::latest(); - - let precompile = precompiles.inner().get(&addr).unwrap(); - let result = match precompile { - Precompile::Standard(precompile) => precompile(&input, gas_limit), - _ => panic!("Annotated precompile must be a standard precompile."), - }; - - let mut serialized_vec = vec![]; - match result { - Ok(result) => { - serialized_vec.push(0); - serialized_vec.extend_from_slice(&result.gas_used.to_le_bytes()); - serialized_vec.extend_from_slice(&result.bytes); - } - Err(err) => { - serialized_vec.push(1); - match err { - revm::precompile::PrecompileErrors::Error(_) => { - serialized_vec.push(0); - } - revm::precompile::PrecompileErrors::Fatal { .. } => { - serialized_vec.push(1); - } - } - } - } - vec![serialized_vec] -} diff --git a/crates/host-utils/src/stats.rs b/crates/host-utils/src/stats.rs new file mode 100644 index 00000000..051a60b2 --- /dev/null +++ b/crates/host-utils/src/stats.rs @@ -0,0 +1,236 @@ +use std::{fmt, time::Duration}; + +use crate::fetcher::{ChainMode, SP1KonaDataFetcher}; +use num_format::{Locale, ToFormattedString}; +use serde::{Deserialize, Serialize}; +use sp1_sdk::{CostEstimator, ExecutionReport}; + +/// Statistics for the multi-block execution. +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct ExecutionStats { + pub batch_start: u64, + pub batch_end: u64, + pub execution_duration_sec: u64, + pub total_instruction_count: u64, + pub oracle_verify_instruction_count: u64, + pub derivation_instruction_count: u64, + pub block_execution_instruction_count: u64, + pub blob_verification_instruction_count: u64, + pub total_sp1_gas: u64, + pub nb_blocks: u64, + pub nb_transactions: u64, + pub eth_gas_used: u64, + pub cycles_per_block: u64, + pub cycles_per_transaction: u64, + pub transactions_per_block: u64, + pub gas_used_per_block: u64, + pub gas_used_per_transaction: u64, + pub bn_pair_cycles: u64, + pub bn_add_cycles: u64, + pub bn_mul_cycles: u64, + pub kzg_eval_cycles: u64, + pub ec_recover_cycles: u64, +} + +/// Write a statistic to the formatter. +fn write_stat(f: &mut fmt::Formatter<'_>, label: &str, value: u64) -> fmt::Result { + writeln!( + f, + "| {:<30} | {:>25} |", + label, + value.to_formatted_string(&Locale::en) + ) +} + +impl fmt::Display for ExecutionStats { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + writeln!( + f, + "+--------------------------------+---------------------------+" + )?; + writeln!(f, "| {:<30} | {:<25} |", "Metric", "Value")?; + writeln!( + f, + "+--------------------------------+---------------------------+" + )?; + write_stat(f, "Batch Start", self.batch_start)?; + write_stat(f, "Batch End", self.batch_end)?; + write_stat( + f, + "Execution Duration (seconds)", + self.execution_duration_sec, + )?; + write_stat(f, "Total Instruction Count", self.total_instruction_count)?; + write_stat( + f, + "Oracle Verify Cycles", + self.oracle_verify_instruction_count, + )?; + write_stat(f, "Derivation Cycles", self.derivation_instruction_count)?; + write_stat( + f, + "Block Execution Cycles", + self.block_execution_instruction_count, + )?; + write_stat( + f, + "Blob Verification Cycles", + self.blob_verification_instruction_count, + )?; + write_stat(f, "Total SP1 Gas", self.total_sp1_gas)?; + write_stat(f, "Number of Blocks", self.nb_blocks)?; + write_stat(f, "Number of Transactions", self.nb_transactions)?; + write_stat(f, "Ethereum Gas Used", self.eth_gas_used)?; + write_stat(f, "Cycles per Block", self.cycles_per_block)?; + write_stat(f, "Cycles per Transaction", self.cycles_per_transaction)?; + write_stat(f, "Transactions per Block", self.transactions_per_block)?; + write_stat(f, "Gas Used per Block", self.gas_used_per_block)?; + write_stat(f, "Gas Used per Transaction", self.gas_used_per_transaction)?; + write_stat(f, "BN Pair Cycles", self.bn_pair_cycles)?; + write_stat(f, "BN Add Cycles", self.bn_add_cycles)?; + write_stat(f, "BN Mul Cycles", self.bn_mul_cycles)?; + write_stat(f, "KZG Eval Cycles", self.kzg_eval_cycles)?; + write_stat(f, "EC Recover Cycles", self.ec_recover_cycles)?; + writeln!( + f, + "+--------------------------------+---------------------------+" + ) + } +} + +/// Get the execution stats for a given report. +pub async fn get_execution_stats( + data_fetcher: &SP1KonaDataFetcher, + start: u64, + end: u64, + report: &ExecutionReport, + execution_duration: Duration, +) -> ExecutionStats { + // Get the total instruction count for execution across all blocks. + let block_execution_instruction_count: u64 = + *report.cycle_tracker.get("block-execution").unwrap_or(&0); + let oracle_verify_instruction_count: u64 = + *report.cycle_tracker.get("oracle-verify").unwrap_or(&0); + let derivation_instruction_count: u64 = + *report.cycle_tracker.get("payload-derivation").unwrap_or(&0); + let blob_verification_instruction_count: u64 = + *report.cycle_tracker.get("blob-verification").unwrap_or(&0); + + let nb_blocks = end - start + 1; + + // Fetch the number of transactions in the blocks from the L2 RPC. + let block_data_range = data_fetcher + .get_block_data_range(ChainMode::L2, start, end) + .await + .expect("Failed to fetch block data range."); + + let nb_transactions = block_data_range.iter().map(|b| b.transaction_count).sum(); + let total_gas_used = block_data_range.iter().map(|b| b.gas_used).sum(); + + let bn_add_cycles: u64 = *report.cycle_tracker.get("precompile-bn-add").unwrap_or(&0); + let bn_mul_cycles: u64 = *report.cycle_tracker.get("precompile-bn-mul").unwrap_or(&0); + let bn_pair_cycles: u64 = *report.cycle_tracker.get("precompile-bn-pair").unwrap_or(&0); + let kzg_eval_cycles: u64 = *report + .cycle_tracker + .get("precompile-kzg-eval") + .unwrap_or(&0); + let ec_recover_cycles: u64 = *report + .cycle_tracker + .get("precompile-ec-recover") + .unwrap_or(&0); + + let cycles_per_block = block_execution_instruction_count / nb_blocks; + let cycles_per_transaction = block_execution_instruction_count / nb_transactions; + let transactions_per_block = nb_transactions / nb_blocks; + let gas_used_per_block = total_gas_used / nb_blocks; + let gas_used_per_transaction = total_gas_used / nb_transactions; + + ExecutionStats { + batch_start: start, + batch_end: end, + execution_duration_sec: execution_duration.as_secs(), + total_instruction_count: report.total_instruction_count(), + derivation_instruction_count, + oracle_verify_instruction_count, + block_execution_instruction_count, + blob_verification_instruction_count, + total_sp1_gas: report.estimate_gas(), + nb_blocks, + nb_transactions, + eth_gas_used: total_gas_used, + cycles_per_block, + cycles_per_transaction, + transactions_per_block, + gas_used_per_block, + gas_used_per_transaction, + bn_add_cycles, + bn_mul_cycles, + bn_pair_cycles, + kzg_eval_cycles, + ec_recover_cycles, + } +} + +#[derive(Debug, Clone)] +pub struct SpanBatchStats { + pub span_start: u64, + pub span_end: u64, + pub total_blocks: u64, + pub total_transactions: u64, + pub total_gas_used: u64, + pub total_cycles: u64, + pub total_sp1_gas: u64, + pub cycles_per_block: u64, + pub cycles_per_transaction: u64, + pub gas_used_per_block: u64, + pub gas_used_per_transaction: u64, + pub total_derivation_cycles: u64, + pub total_execution_cycles: u64, + pub total_blob_verification_cycles: u64, + pub bn_add_cycles: u64, + pub bn_mul_cycles: u64, + pub bn_pair_cycles: u64, + pub kzg_eval_cycles: u64, + pub ec_recover_cycles: u64, +} + +impl fmt::Display for SpanBatchStats { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + writeln!( + f, + "+-------------------------------+---------------------------+" + )?; + writeln!(f, "| {:<30} | {:<25} |", "Metric", "Value")?; + writeln!( + f, + "+-------------------------------+---------------------------+" + )?; + write_stat(f, "Span Start", self.span_start)?; + write_stat(f, "Span End", self.span_end)?; + write_stat(f, "Total Blocks", self.total_blocks)?; + write_stat(f, "Total Transactions", self.total_transactions)?; + write_stat(f, "Total Gas Used", self.total_gas_used)?; + write_stat(f, "Total Cycles", self.total_cycles)?; + write_stat(f, "Total SP1 Gas", self.total_sp1_gas)?; + write_stat(f, "Cycles per Block", self.cycles_per_block)?; + write_stat(f, "Cycles per Transaction", self.cycles_per_transaction)?; + write_stat(f, "Gas Used per Block", self.gas_used_per_block)?; + write_stat(f, "Gas Used per Transaction", self.gas_used_per_transaction)?; + write_stat(f, "Total Derivation Cycles", self.total_derivation_cycles)?; + write_stat(f, "Total Execution Cycles", self.total_execution_cycles)?; + write_stat( + f, + "Total Blob Verification Cycles", + self.total_blob_verification_cycles, + )?; + write_stat(f, "BN Add Cycles", self.bn_add_cycles)?; + write_stat(f, "BN Mul Cycles", self.bn_mul_cycles)?; + write_stat(f, "BN Pair Cycles", self.bn_pair_cycles)?; + write_stat(f, "KZG Eval Cycles", self.kzg_eval_cycles)?; + write_stat(f, "EC Recover Cycles", self.ec_recover_cycles)?; + writeln!( + f, + "+-------------------------------+---------------------------+" + ) + } +} diff --git a/elf/aggregation-elf b/elf/aggregation-elf index 76e9483e3eb96afd0f33f417c63c199b6d5a541a..d7de62f03b89091cde2a60f1ee3bac32076d068c 100755 GIT binary patch delta 190042 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

|uUthK8f%5Av{?+HKUJ=r~XF%9&aZmw*G}+l&sf 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 delta 188716 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

jf|Zo0w`*r$cHE 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

x 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