diff --git a/.gitignore b/.gitignore index 8fd34cc2d5..24c0cf6e2e 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,5 @@ target zkvm-prover/*.json .work/ rollup/tests.test +local-secrets.md +tmp/ diff --git a/AGENTS.md b/AGENTS.md index 449aecbdc8..4fc61b2d4e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -20,6 +20,45 @@ Follow the structured testing guide in [`docs/testing/openvm-upgrade-testing-gui 4. End-to-end proving 5. Docker image builds +## Shadow Coordinator + Prover Testing (Production Task Replay) + +For testing proof generation against **real mainnet production tasks** without interfering with the live system, use the **Shadow Coordinator** approach. This is significantly faster than a full shadow fork: + +- **Architecture**: Local coordinator (`:8390`) + local prover (GPU), fed by imported production task data. +- **Docs**: [`tests/shadow-testing/docs/GUIDE.md`](tests/shadow-testing/docs/GUIDE.md) — full setup guide, troubleshooting, config reference. +- **Quick Start**: [`tests/shadow-testing/README.md`](tests/shadow-testing/README.md) +- **Automation**: [`tests/shadow-testing/Makefile`](tests/shadow-testing/Makefile) — Makefile targets for Docker and bare-metal shadow fork testing. + +Key hard-won rules: +- **L2 RPC for coordinator task generation** (must support `debug_executionWitness`): + - ✅ **Primary**: `https://l2geth-rpc-proxy.mainnet.aws.scroll.io/` (internal/debug-enabled, supports `debug_executionWitness`) + - ⚠️ **Fallback**: `https://mainnet-rpc.scroll.io` (public RPC, may not support `debug_executionWitness` for chunk task generation) + - ❌ **Avoid**: `https://rpc.scroll.io` (does not work) +- **Alchemy API for Anvil fork** (must use Alchemy, others hit rate limits): + - ✅ **Primary**: `https://eth-mainnet.g.alchemy.com/v2/YOUR_ALCHEMY_API_KEY` + - 📋 **Credential source**: Check `local-secrets.md`, `.env`, or `.pgpass` first. If not found, **ask a human** — do not guess or invent keys. +- **S3 circuit URLs**: v0.9.0 uses `releases/v0.9.0/` prefix. (v0.8.0 historically used `v0.8.0/` without `/releases/`.) +- **l2_block table**: Coordinator needs this for block hash lookups. Must be populated and linked via `chunk_hash`. +- **Blocks**: Must be post-fork (GalileoV2 / codec V10 = blocks ≥ 33,750,000 on mainnet). +- **L1 messages**: If chunks contain L1 messages, prover needs `scroll_getL1MessagesInBlock` RPC support. Most chunks at current mainnet height do NOT contain L1 messages, so this is usually non-blocking. +- **Anvil MUST fork Ethereum L1, NOT Scroll L2**: The ScrollChain proxy address `0xa13BAF47339d63B743e7Da8741db5456DAc1E556` is on **Ethereum mainnet** (chainId=1), not Scroll mainnet (chainId=534352). If you accidentally point Anvil at a Scroll L2 RPC (e.g., `scroll-mainnet.g.alchemy.com`), the proxy address will have no code or wrong code, and all contract interactions will fail. Always verify `eth_chainId` returns `1` after forking. + +### Sepolia Shadow Fork — Additional Rules + +| Dimension | Mainnet | Sepolia | Trap | +|-----------|---------|---------|------| +| **DB port** | `localhost:5433` (shadow) / `15432` (RDS tunnel) | `localhost:25432` (RDS tunnel) | Wrong port = connecting to mainnet data | +| **L2 RPC** | `l2geth-rpc-proxy.mainnet.aws.scroll.io` | `l2geth-rpc-proxy.sepolia.aws.scroll.io` | Public Sepolia RPC (`sepolia-rpc.scroll.io`) rejects `debug_executionWitness` | +| **Verifier** | Mainnet has `latestVerifier[10] = 0x0dE1...` (can `anvil_setCode`) | Production proofs + production MVRV may already match | Re-using old proofs → check MVRV first. Testing **new guest** → MUST deploy fresh verifier | +| **`committedBatches`** | Sparse, but fork block usually covers target batches | Sparse; **every bundle end batch must exist** | Missing entry → `ErrorIncorrectBatchHash(0x2a1c1442)` | +| **`L1MessageQueueV2`** | Reset `nextUnfinalizedQueueIndex = 0` sufficient | Set to `MIN(total_l1_messages_popped_before)` of first target batch; **slot 104** (verify with `forge inspect`) | Wrong slot/value → `ErrorFinalizedIndexTooLarge(0x16465978)` | +| **Anvil gas estimation** | Same as mainnet | `eth_estimateGas` fails with fee caps present (`Gas=0`) | Patch `estimategas.go` or use `--min-codec-version` workaround | +| **Sender balance** | Persisted across restarts | **Resets to 0** after Anvil restart | Must re-fund EOAs before each relayer start | +| **Relayer flags** | Standard | Requires `--config ` AND `--min-codec-version 10` | Missing flags = wrong config or immediate exit | +| **DB scope** | Imported limited range | Full production snapshot (batches 128080+) | Relayer batch committer floods logs with commit retries | +| **Blob version** | Usually V0 | Anvil 1.0.0 cannot decode BlobSidecar V1 | Set `fusaka_timestamp: 2000000000` in relayer config | +| **Proofs in DB** | May already be v0.9.0 | Old proofs are v0.7.3 | Must reset `proving_status = 1` to regenerate with v0.9.0 | + ## Useful Commands ```bash @@ -64,6 +103,28 @@ make coordinator_setup | `zkvm-prover/` | Build scripts and runtime config for the prover binary | | `build/dockerfiles/` | Dockerfiles for production images | +## Troubleshooting: Verifier Wrapper Deployment on Shadow Forks + +### `anvil_setCode` Does NOT Reset Immutables +- **Problem**: Copying a mainnet verifier wrapper (e.g., `ZkEvmVerifierPostFeynman`) to Anvil via `anvil_setCode` preserves the **original immutables** (`verifierDigest1`, `verifierDigest2`, `protocolVersion`). These digests are bound to the mainnet plonk verifier VK and will **never** match locally-generated proofs. +- **Symptom**: `VerificationFailed` (selector `0x439cc0cd`) even when the plonk verifier binary, public input hash, and proof are all individually correct. +- **Root cause**: The wrapper assembles its own `instances` array from immutables + `keccak256(protocolVersion || publicInput)`. Wrong immutables = wrong instances = plonk verifier rejects the proof. +- **Solution**: **Always recompile and redeploy** the wrapper with immutables extracted from the *local* proof's `instances` array (bytes 384–416 and 416–448 for digest1/digest2). + +### Do Not "Fix" Production Solidity Without Evidence +- **Problem**: When `VerificationFailed` appears, it's tempting to blame the assembly loop in the wrapper (`sub(0x5a0, i)` vs `add(0x1c0, i)`). +- **Reality**: The production wrapper (`ZkEvmVerifierPostFeynman.sol`) has used `sub(0x5a0, i)` since deployment and has finalized thousands of bundles on mainnet. The loop direction maps hash bytes in **reverse order** to instance words, which matches the verifier circuit's expectation. +- **Symptom of wrong patch**: Changing the loop to `add(0x1c0, i)` inverts the hash-word layout, producing a different set of instances that also fail verification. +- **Correct diagnosis flow**: + 1. Verify the plonk verifier binary matches the deployed contract runtime code. + 2. Verify `keccak256(abi.encodePacked(protocolVersion, publicInput))` matches the proof metadata `bundle_pi_hash`. + 3. Verify the wrapper's immutables match the local proof's digest words. + 4. Only after (1–3) pass should you look at Solidity logic — and even then, production code is almost certainly correct. + +### Access Control on `finalizeBundlePostEuclidV2` +- `ScrollChain.finalizeBundlePostEuclidV2` has `OnlyProver` modifier. +- On shadow fork, impersonate the registered prover EOA before sending the transaction: `cast rpc anvil_impersonateAccount `. + ## Troubleshooting Common E2E Test Issues ### Port Conflicts (Shared Servers) @@ -97,18 +158,42 @@ make coordinator_setup ### S3 Asset URLs - The prover config `base_url` must match the actual S3 object path. Verify with `curl -sI` before running. -- The coordinator downloads **verifier** assets from `v0.X.X/verifier/`; the prover downloads **circuit** assets from `///`. -- If you see HTTP 403 from S3, check whether the URL contains a `releases/` segment that shouldn't be there. +- For v0.9.0, both coordinator **verifier** assets and prover **circuit** assets are under `scroll-zkvm/releases/v0.9.0/`. Earlier v0.8.0 assets used `scroll-zkvm/v0.X.X/` for verifier assets and `scroll-zkvm/galileov2/` for prover circuits. +- If you see HTTP 403 from S3, check whether the URL uses the correct `releases/` prefix for the target version. ### Multiple Coordinator Instances - Running `make coordinator_setup` rebuilds the binary but does not stop running instances. If the old instance holds port 8390, the new one fails with `bind: address already in use`. - Always check with `ss -tlnp | grep 8390` before launching. +## Agent Discipline: Research Before Experimentation + +> **Rule**: When encountering a problem that is **non-trivial**, **time-consuming**, or **has failed more than once**, the agent **must** search existing documentation before attempting new fixes. +> +> 1. Read all relevant markdown files in the task directory (e.g., `tests/shadow-testing/docs/*.md`). +> 2. Search for similar error messages, selectors, or symptoms in the codebase and docs. +> 3. Only after confirming the issue is **not documented** should you design a new experiment. +> +> **Why**: This repository has extensive documentation of past pitfalls. Blind experimentation wastes time and repeats mistakes that are already solved in writing. + ## Coordination with Humans - **Code / logic issues**: agents should reason independently and propose fixes. - **Environment / secrets issues** (database passwords, RPC endpoints, cloud credentials, sudo access): ask the human and wait for a response. Do not time out and make unilateral decisions. +## Secrets & Credentials Reference + +**All sensitive endpoints, keys, and passwords for local development are documented in [`local-secrets.md`](local-secrets.md)** (git-ignored). + +| Category | What's Inside | Why It Matters | +|----------|---------------|----------------| +| **RPC Endpoints** | ETH L1 (Alchemy mainnet/sepolia), Scroll L2 (public/internal) | Anvil must fork **ETH L1**, not Scroll L2. Coordinator needs debug-enabled L2 RPC. | +| **Database DSNs** | Local shadow DB (port 5433), Sepolia shadow DB (port 5442), Mainnet RDS (port 15432 via tunnel) | Wrong DSN = wrong chain data = wasted proving hours. | +| **Contract Addresses** | ScrollChain proxy, L1MessageQueueV2, RollupVerifier, MockVerifier | These change per network (mainnet vs sepolia). Hard-coding without checking = `ErrorIncorrectBatchHash`. | +| **Sender Keys** | Commit/finalize EOA private keys for shadow fork | Anvil-funded accounts; never use production keys in shadow tests. | +| **S3 URLs** | Circuit asset base URLs | v0.9.0 uses the `releases/v0.9.0/` prefix. Wrong URL = 403. | + +> **Agent Rule**: Before starting any shadow fork or E2E test, always cross-reference `local-secrets.md`. If a required secret is missing, ask the human — do not invent URLs or credentials. + ## Documentation Index | Document | What It Covers | @@ -116,4 +201,9 @@ make coordinator_setup | [`docs/prover-coordinator-overview.md`](docs/prover-coordinator-overview.md) | Architecture, data flow, component relationships, common operations | | [`docs/testing/openvm-upgrade-testing-guide.md`](docs/testing/openvm-upgrade-testing-guide.md) | Step-by-step testing checklist after OpenVM / zkvm-prover upgrades | | [`docs/testing/docker-compose-e2e-guide.md`](docs/testing/docker-compose-e2e-guide.md) | Production-like E2E testing with Docker Compose + Coordinator Proxy | +| [`tests/shadow-testing/docs/GUIDE.md`](tests/shadow-testing/docs/GUIDE.md) | Shadow coordinator + local prover setup for production task replay | +| [`tests/shadow-testing/docs/TROUBLESHOOTING.md`](tests/shadow-testing/docs/TROUBLESHOOTING.md) | Structured pitfalls and agent checklists for shadow testing | +| [`tests/shadow-testing/docs/TROUBLESHOOTING.md`](tests/shadow-testing/docs/TROUBLESHOOTING.md) | Structured pitfalls and agent checklists for shadow testing | +| [`tests/shadow-testing/README.md`](tests/shadow-testing/README.md) | Quick reference for common shadow testing commands | | [`docs/testing_reports/openvm-v1.6.0-guest-v0.8.0-May19.md`](docs/testing_reports/openvm-v1.6.0-guest-v0.8.0-May19.md) | Test report for PR #1783 (OpenVM 1.6.0, guest v0.8.0) | +| [`docs/testing/single-chunk-reproving.md`](docs/testing/single-chunk-reproving.md) | Re-proving one specific mainnet chunk using shadow DB + local coordinator/prover | diff --git a/Cargo.lock b/Cargo.lock index a397bc5f7d..393a9935d5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -135,7 +135,7 @@ checksum = "9f5bedd6a59a2bd3a2f1cb7ff488549a2004302edca4df4d578bf0a814888615" dependencies = [ "alloy-consensus", "alloy-core", - "alloy-eips 1.8.3", + "alloy-eips", "alloy-json-rpc", "alloy-network", "alloy-provider", @@ -163,10 +163,10 @@ version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9b151e38e42f1586a01369ec52a6934702731d07e8509a7307331b09f6c46dc" dependencies = [ - "alloy-eips 1.8.3", + "alloy-eips", "alloy-primitives", "alloy-rlp", - "alloy-serde 1.8.3", + "alloy-serde", "alloy-trie 0.9.5", "alloy-tx-macros", "auto_impl", @@ -190,10 +190,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e2d5e8668ef6215efdb7dcca6f22277b4e483a5650e05f5de22b2350971f4b8" dependencies = [ "alloy-consensus", - "alloy-eips 1.8.3", + "alloy-eips", "alloy-primitives", "alloy-rlp", - "alloy-serde 1.8.3", + "alloy-serde", "serde", ] @@ -260,26 +260,6 @@ dependencies = [ "thiserror 2.0.18", ] -[[package]] -name = "alloy-eips" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "609515c1955b33af3d78d26357540f68c5551a90ef58fd53def04f2aa074ec43" -dependencies = [ - "alloy-eip2124", - "alloy-eip2930", - "alloy-eip7702", - "alloy-primitives", - "alloy-rlp", - "alloy-serde 0.14.0", - "auto_impl", - "c-kzg", - "derive_more 2.1.1", - "either", - "serde", - "sha2 0.10.9", -] - [[package]] name = "alloy-eips" version = "1.8.3" @@ -292,7 +272,7 @@ dependencies = [ "alloy-eip7928", "alloy-primitives", "alloy-rlp", - "alloy-serde 1.8.3", + "alloy-serde", "auto_impl", "borsh", "c-kzg", @@ -312,7 +292,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08e9e656d58027542447c1ca5aa4ca96293f09e6920c4651953b7451a7c35e4e" dependencies = [ "alloy-consensus", - "alloy-eips 1.8.3", + "alloy-eips", "alloy-hardforks", "alloy-primitives", "alloy-rpc-types-engine", @@ -333,9 +313,9 @@ version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbf9480307b09d22876efb67d30cadd9013134c21f3a17ec9f93fd7536d38024" dependencies = [ - "alloy-eips 1.8.3", + "alloy-eips", "alloy-primitives", - "alloy-serde 1.8.3", + "alloy-serde", "alloy-trie 0.9.5", "borsh", "serde", @@ -391,13 +371,13 @@ checksum = "8eaf2ae05219e73e0979cb2cf55612aafbab191d130f203079805eaf881cca58" dependencies = [ "alloy-consensus", "alloy-consensus-any", - "alloy-eips 1.8.3", + "alloy-eips", "alloy-json-rpc", "alloy-network-primitives", "alloy-primitives", "alloy-rpc-types-any", "alloy-rpc-types-eth", - "alloy-serde 1.8.3", + "alloy-serde", "alloy-signer", "alloy-sol-types", "async-trait", @@ -416,9 +396,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e58f4f345cef483eab7374f2b6056973c7419ffe8ad35e994b7a7f5d8e0c7ba4" dependencies = [ "alloy-consensus", - "alloy-eips 1.8.3", + "alloy-eips", "alloy-primitives", - "alloy-serde 1.8.3", + "alloy-serde", "serde", ] @@ -445,7 +425,7 @@ dependencies = [ "rapidhash", "rkyv", "ruint", - "rustc-hash 2.1.2", + "rustc-hash 2.1.3", "serde", "sha3", "tiny-keccak", @@ -459,7 +439,7 @@ checksum = "de2597751539b1cc8fe4204e5325f9a9ed83fcacfb212018dfcfa7877e76de21" dependencies = [ "alloy-chains", "alloy-consensus", - "alloy-eips 1.8.3", + "alloy-eips", "alloy-json-rpc", "alloy-network", "alloy-network-primitives", @@ -492,9 +472,9 @@ dependencies = [ [[package]] name = "alloy-rlp" -version = "0.3.15" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc90b1e703d3c03f4ff7f48e82dd0bc1c8211ab7d079cd836a06fcfeb06651cb" +checksum = "24671b1f62edcf0f9b62994c7bf72cd621a04a4b99f5020ece1a647b40e2f103" dependencies = [ "alloy-rlp-derive", "arrayvec", @@ -503,13 +483,13 @@ dependencies = [ [[package]] name = "alloy-rlp-derive" -version = "0.3.15" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36834a5c0a2fa56e171bf256c34d70fca07d0c0031583edea1c4946b7889c9e" +checksum = "9d4311c03125e8a18296504560b9de3d75ecbd0dcda7f71e6cf2a196d57e6fba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -543,7 +523,7 @@ checksum = "fbde0801a32d21c5f111f037bee7e22874836fba7add34ed4a6919932dd7cf23" dependencies = [ "alloy-consensus-any", "alloy-rpc-types-eth", - "alloy-serde 1.8.3", + "alloy-serde", ] [[package]] @@ -565,10 +545,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "605ec375d91073851f566a3082548af69a28dca831b27a8be7c1b4c49f5c6ca2" dependencies = [ "alloy-consensus", - "alloy-eips 1.8.3", + "alloy-eips", "alloy-primitives", "alloy-rlp", - "alloy-serde 1.8.3", + "alloy-serde", "derive_more 2.1.1", "ethereum_ssz", "ethereum_ssz_derive", @@ -584,11 +564,11 @@ checksum = "361cd87ead4ba7659bda8127902eda92d17fa7ceb18aba1676f7be10f7222487" dependencies = [ "alloy-consensus", "alloy-consensus-any", - "alloy-eips 1.8.3", + "alloy-eips", "alloy-network-primitives", "alloy-primitives", "alloy-rlp", - "alloy-serde 1.8.3", + "alloy-serde", "alloy-sol-types", "itertools 0.14.0", "serde", @@ -597,17 +577,6 @@ dependencies = [ "thiserror 2.0.18", ] -[[package]] -name = "alloy-serde" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4dba6ff08916bc0a9cbba121ce21f67c0b554c39cf174bc7b9df6c651bd3c3b" -dependencies = [ - "alloy-primitives", - "serde", - "serde_json", -] - [[package]] name = "alloy-serde" version = "1.8.3" @@ -645,7 +614,7 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -662,7 +631,7 @@ dependencies = [ "proc-macro2", "quote", "sha3", - "syn 2.0.117", + "syn 2.0.118", "syn-solidity", ] @@ -678,7 +647,7 @@ dependencies = [ "macro-string", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", "syn-solidity", ] @@ -784,7 +753,7 @@ dependencies = [ "darling 0.21.3", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -857,15 +826,15 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.102" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" +checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3" [[package]] name = "ar_archive_writer" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb93bbb63b9c227414f6eb3a0adfddca591a8ce1e9b60661bb08969b87e340b" +checksum = "4087686b4b0a3427190bae57a1d9a478dbb2d40c5dc1bd6e2b6d797913bdd348" dependencies = [ "object", ] @@ -973,6 +942,23 @@ dependencies = [ "zeroize", ] +[[package]] +name = "ark-ff" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7a806ac6c8307b929df4645776290a50ee2aac754ad09d8bdf73391309e43af" +dependencies = [ + "ark-ff-asm 0.6.0", + "ark-ff-macros 0.6.0", + "ark-serialize 0.6.0", + "ark-std 0.6.0", + "digest 0.10.7", + "educe", + "num-bigint", + "num-traits", + "zeroize", +] + [[package]] name = "ark-ff-asm" version = "0.3.0" @@ -1000,7 +986,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60" dependencies = [ "quote", - "syn 2.0.117", + "syn 2.0.118", +] + +[[package]] +name = "ark-ff-asm" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1479009684adc073dff49a1025d3a7065b317a9ead25aaaca38cdc70058ba8a2" +dependencies = [ + "quote", + "syn 2.0.118", ] [[package]] @@ -1038,7 +1034,20 @@ dependencies = [ "num-traits", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", +] + +[[package]] +name = "ark-ff-macros" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a0691ed21ef00ef89c1e9bda832eba493dda3ec2f8d892fb25b705f73f06bb8" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 2.0.118", ] [[package]] @@ -1112,13 +1121,26 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f4d068aaf107ebcd7dfb52bc748f8030e0fc930ac8e360146ca54c1203088f7" dependencies = [ - "ark-serialize-derive", + "ark-serialize-derive 0.5.0", "ark-std 0.5.0", "arrayvec", "digest 0.10.7", "num-bigint", ] +[[package]] +name = "ark-serialize" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a74dd304fd536fb95d0a328e72be759209cc496a9da094c5bc56e5fea4f9e86b" +dependencies = [ + "ark-serialize-derive 0.6.0", + "ark-std 0.6.0", + "digest 0.10.7", + "num-bigint", + "serde_with", +] + [[package]] name = "ark-serialize-derive" version = "0.5.0" @@ -1127,7 +1149,18 @@ checksum = "213888f660fddcca0d257e88e54ac05bca01885f258ccdf695bafd77031bb69d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f153690697a2b91e5e1251ff98411ee5371500a111a0fd317a70e588eb300f9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", ] [[package]] @@ -1161,6 +1194,16 @@ dependencies = [ "rand 0.8.6", ] +[[package]] +name = "ark-std" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "367c9c827ed431bff6868b7aa926e05b16eb46603cc8b6e768e4a5553fa1d155" +dependencies = [ + "num-traits", + "rand 0.8.6", +] + [[package]] name = "arrayref" version = "0.3.9" @@ -1169,9 +1212,9 @@ checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" [[package]] name = "arrayvec" -version = "0.7.6" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56" dependencies = [ "serde", ] @@ -1219,7 +1262,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -1230,7 +1273,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -1257,14 +1300,14 @@ checksum = "ffdcb70bdbc4d478427380519163274ac86e52916e10f0a8889adf0f96d3fee7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] name = "autocfg" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "axum" @@ -1387,16 +1430,16 @@ version = "0.72.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "cexpr", "clang-sys", "itertools 0.13.0", "proc-macro2", "quote", "regex", - "rustc-hash 2.1.2", - "shlex", - "syn 2.0.117", + "rustc-hash 2.1.3", + "shlex 1.3.0", + "syn 2.0.118", ] [[package]] @@ -1420,38 +1463,45 @@ version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a6ed1b54d8dc333e7be604d00fa9262f4635485ffea923647b6521a5fff045d" dependencies = [ - "arrayvec", - "bitcode_derive", "bytemuck", - "glam", "serde", ] [[package]] -name = "bitcode_derive" -version = "0.6.9" +name = "bitcoin-consensus-encoding" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "238b90427dfad9da4a9abd60f3ec1cdee6b80454bde49ed37f1781dd8e9dc7f9" +checksum = "b2d6094e2a1ba3c93b5a596fe5a10d1a10c3c6e06785cde89f693a044c01aa40" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", + "bitcoin-internals", +] + +[[package]] +name = "bitcoin-internals" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a30a22d1f112dde8e16be7b45c63645dc165cef254f835b3e1e9553e485cfa64" +dependencies = [ + "hex-conservative 0.3.2", ] [[package]] name = "bitcoin-io" -version = "0.1.4" +version = "0.1.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dee39a0ee5b4095224a0cfc6bf4cc1baf0f9624b96b367e53b66d974e51d953" +checksum = "bb5de036369d1ac59d3c1819ebc4d850f89466f5401c571a285b6ed564a4cb78" +dependencies = [ + "bitcoin-consensus-encoding", +] [[package]] name = "bitcoin_hashes" -version = "0.14.1" +version = "0.14.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26ec84b80c482df901772e931a9a681e26a1b9ee2302edeff23cb30328745c8b" +checksum = "bca4c7abb40c8817d77403c880988cfd484f23ab2365726afb2f798363e2c4a2" dependencies = [ "bitcoin-io", - "hex-conservative", + "hex-conservative 0.2.2", ] [[package]] @@ -1462,9 +1512,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.11.1" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" +checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" dependencies = [ "serde_core", ] @@ -1477,9 +1527,9 @@ checksum = "6099cdc01846bc367c4e7dd630dc5966dccf36b652fae7a74e17b640411a91b2" [[package]] name = "bitvec" -version = "1.0.1" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +checksum = "ddcec3d12c579d40898fe0a9a358a803c23e9c52ca3c425707f81c9436211837" dependencies = [ "funty", "radium", @@ -1508,20 +1558,6 @@ dependencies = [ "constant_time_eq", ] -[[package]] -name = "blake3" -version = "1.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0aa83c34e62843d924f905e0f5c866eb1dd6545fc4d719e803d9ba6030371fce" -dependencies = [ - "arrayref", - "arrayvec", - "cc", - "cfg-if", - "constant_time_eq", - "cpufeatures 0.3.0", -] - [[package]] name = "block-buffer" version = "0.9.0" @@ -1592,9 +1628,9 @@ dependencies = [ [[package]] name = "bon" -version = "3.9.1" +version = "3.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f47dbe92550676ee653353c310dfb9cf6ba17ee70396e1f7cf0a2020ad49b2fe" +checksum = "a602c73c7b0148ec6d12af6fd5cc7a46e2eacc8878271a999abac56eed12f561" dependencies = [ "bon-macros", "rustversion", @@ -1602,9 +1638,9 @@ dependencies = [ [[package]] name = "bon-macros" -version = "3.9.1" +version = "3.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "519bd3116aeeb42d5372c29d982d16d0170d3d4a5ed85fc7dd91642ffff3c67c" +checksum = "6dee98b0db6a962de883bf5d20362dee4d7ca0d12fe39a7c6c73c844e1cd7c1f" dependencies = [ "darling 0.23.0", "ident_case", @@ -1612,14 +1648,14 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] name = "borsh" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfd1e3f8955a5d7de9fab72fc8373fade9fb8a703968cb200ae3dc6cf08e185a" +checksum = "2f3f6da4992df95bbcd9af42a6c7dcb994498fc9048230405f3b36ff7cd3f145" dependencies = [ "borsh-derive", "bytes", @@ -1628,15 +1664,15 @@ dependencies = [ [[package]] name = "borsh-derive" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfcfdc083699101d5a7965e49925975f2f55060f94f9a05e7187be95d530ca59" +checksum = "3ae8fb4fb5740e4b2c4884ff95f5f32f5e8479db1e8fd8eb49ddbe09eb09bb7c" dependencies = [ "once_cell", "proc-macro-crate 3.5.0", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -1650,9 +1686,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.20.2" +version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "byte-slice-cast" @@ -1680,14 +1716,14 @@ checksum = "89385e82b5d1821d2219e0b095efa2cc1f246cbf99080f3be46a1a85c0d392d9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] name = "bytemuck" -version = "1.25.0" +version = "1.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" +checksum = "d6aedf8ae72766347502cf3cb4f41cf5e9cc37d28bee90f1fdaaae15f9cf9424" [[package]] name = "byteorder" @@ -1697,18 +1733,18 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.11.1" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" +checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" dependencies = [ "serde", ] [[package]] name = "bytesize" -version = "2.3.1" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bd91ee7b2422bcb158d90ef4d14f75ef67f340943fc4149891dcce8f8b972a3" +checksum = "3d7c8918969267b2932ffd5655509bbbea0833823058c378876953217f5fc50e" [[package]] name = "bzip2-sys" @@ -1722,9 +1758,9 @@ dependencies = [ [[package]] name = "c-kzg" -version = "2.1.7" +version = "2.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6648ed1e4ea8e8a1a4a2c78e1cda29a3fd500bc622899c340d8525ea9a76b24a" +checksum = "38d04308254695569fdb9bfe3bacc1c91837a670d0806605eb82d63748fbd3a6" dependencies = [ "blst", "cc", @@ -1737,9 +1773,9 @@ dependencies = [ [[package]] name = "camino" -version = "1.2.2" +version = "1.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e629a66d692cb9ff1a1c664e41771b3dcaf961985a9774c0eb0bd1b51cf60a48" +checksum = "5f2d30e4173c4026932d51d31d6b0613b1fd3014bf3f9f8943d4ba139c437ba0" dependencies = [ "serde_core", ] @@ -1769,14 +1805,14 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.62" +version = "1.2.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98" +checksum = "e17dd265a7d0f31ef544e1b20e03add05d3b45b491b633b10d67145d2acc1a38" dependencies = [ "find-msvc-tools", "jobserver", "libc", - "shlex", + "shlex 2.0.1", ] [[package]] @@ -1800,11 +1836,22 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +[[package]] +name = "chacha20" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "rand_core 0.10.1", +] + [[package]] name = "chrono" -version = "0.4.44" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" dependencies = [ "iana-time-zone", "num-traits", @@ -1865,7 +1912,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -1874,6 +1921,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" +[[package]] +name = "cobs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" +dependencies = [ + "thiserror 2.0.18", +] + [[package]] name = "color-eyre" version = "0.6.5" @@ -1936,9 +1992,9 @@ checksum = "cc14f565cf027a105f7a44ccf9e5b424348421a1d8952a8fc9d499d313107789" [[package]] name = "const-hex" -version = "1.19.0" +version = "1.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20d9a563d167a9cce0f94153382b33cb6eded6dfabff03c69ad65a28ea1514e0" +checksum = "33e2a781ebdf4467d1428dc4593067825fb646f6871475098d8577421af73558" dependencies = [ "cfg-if", "cpufeatures 0.2.17", @@ -2101,18 +2157,18 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.15" +version = "0.5.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +checksum = "d85363c37faeca707aef026efa9f3b34d077bce547e48f770770625c6013679e" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +checksum = "5181e0de7b61eb03a81e347d6dd8797bae9da5146707b51077e2d71a54ec0ceb" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -2120,27 +2176,27 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.18" +version = "0.9.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +checksum = "2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-queue" -version = "0.3.12" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" +checksum = "803d13fb3b09d88be9f4dbc29062c66b19bf7170867ceb746d2a8689bf6c7a26" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.21" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" [[package]] name = "crunchy" @@ -2187,7 +2243,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" dependencies = [ "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -2215,24 +2271,6 @@ dependencies = [ "cipher", ] -[[package]] -name = "cuda-config" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ee74643f7430213a1a78320f88649de309b20b80818325575e393f848f79f5d" -dependencies = [ - "glob", -] - -[[package]] -name = "cuda-runtime-sys" -version = "0.3.0-alpha.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d070b301187fee3c611e75a425cf12247b7c75c09729dbdef95cb9cb64e8c39" -dependencies = [ - "cuda-config", -] - [[package]] name = "cudarc" version = "0.9.15" @@ -2280,7 +2318,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -2295,7 +2333,7 @@ dependencies = [ "quote", "serde", "strsim", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -2308,7 +2346,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -2319,7 +2357,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core 0.20.11", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -2330,7 +2368,7 @@ checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ "darling_core 0.21.3", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -2341,7 +2379,7 @@ checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" dependencies = [ "darling_core 0.23.0", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -2375,7 +2413,6 @@ version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" dependencies = [ - "powerfmt", "serde_core", ] @@ -2398,7 +2435,7 @@ checksum = "d150dea618e920167e5973d70ae6ece4385b7164e0d799fe7c122dd0a5d912ad" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -2409,7 +2446,7 @@ checksum = "2cdc8d50f426189eef89dac62fabfa0abb27d5cc008f25bf4156a0203325becc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -2420,7 +2457,7 @@ checksum = "d08b3a0bcc0d079199cd476b2cae8435016ec11d1c0986c6901c5ac223041534" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -2449,7 +2486,7 @@ checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", "unicode-xid", ] @@ -2463,7 +2500,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version 0.4.1", - "syn 2.0.117", + "syn 2.0.118", "unicode-xid", ] @@ -2490,13 +2527,13 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -2575,14 +2612,14 @@ dependencies = [ "enum-ordinalize", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] name = "either" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" dependencies = [ "serde", ] @@ -2613,6 +2650,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "embedded-io" +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 = "encoder-standard" version = "0.1.0" @@ -2638,34 +2687,22 @@ checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" [[package]] name = "enum-ordinalize" -version = "4.3.2" +version = "4.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a1091a7bb1f8f2c4b28f1fe2cef4980ca2d410a3d727d67ecc3178c9b0800f0" +checksum = "07f808d588c10e464ea6f7d3eaed500049eff30aaac103460f61828c2d65b3eb" dependencies = [ "enum-ordinalize-derive", ] [[package]] name = "enum-ordinalize-derive" -version = "4.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ca9601fb2d62598ee17836250842873a413586e5d7ed88b356e38ddbb0ec631" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] - -[[package]] -name = "enum_dispatch" -version = "0.3.13" +version = "4.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa18ce2bc66555b3218614519ac839ddb759a7d6720732f979ef8d13be147ecd" +checksum = "42e528e2d34ba8a67a1a650b86beae8ef69fc5fdb638016f386b973226590432" dependencies = [ - "once_cell", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -2676,7 +2713,7 @@ checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -2745,9 +2782,9 @@ dependencies = [ [[package]] name = "ethereum_serde_utils" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dc1355dbb41fbbd34ec28d4fb2a57d9a70c67ac3c19f6a5ca4d4a176b9e997a" +checksum = "38df44a7a271ab43835678f9215b53cc2523e4714a215da6643d83dc110245da" dependencies = [ "alloy-primitives", "hex", @@ -2780,7 +2817,7 @@ dependencies = [ "darling 0.20.11", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -3011,7 +3048,7 @@ checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -3098,36 +3135,34 @@ 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" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi 6.0.0", - "wasip2", - "wasip3", + "rand_core 0.10.1", + "wasm-bindgen", ] [[package]] name = "getset" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf0fc11e47561d47397154977bc219f4cf809b2974facc3ccb3b89e2436f912" +checksum = "6cf442baaabe4213ce7d1239afc26c039180b6456da2cededa316ae2c8a77a77" dependencies = [ - "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -3162,15 +3197,9 @@ checksum = "53010ccb100b96a67bc32c0175f0ed1426b31b655d562898e57325f81c023ac0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] -[[package]] -name = "glam" -version = "0.32.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f70749695b063ecbf6b62949ccccde2e733ec3ecbbd71d467dca4e5c6c97cca0" - [[package]] name = "glob" version = "0.3.3" @@ -3214,9 +3243,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "171fefbc92fe4a4de27e0698d6a5b392d6a0e333506bc49133760b3bcf948733" +checksum = "6cb093c84e8bd9b188d4c4a8cb6579fc016968d14c99882163cd3ff402a4f155" dependencies = [ "atomic-waker", "bytes", @@ -3242,9 +3271,8 @@ dependencies = [ [[package]] name = "halo2-axiom" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0aee3f8178b78275038e5ea0e2577140056d2c4c87fccaf6777dc0a8eebe455a" +version = "0.5.2" +source = "git+https://github.com/axiom-crypto/halo2.git?tag=v0.5.2#1eed471495b64ec1edf22f0661bbc65d0e4381d5" dependencies = [ "blake2b_simd", "crossbeam", @@ -3264,9 +3292,8 @@ dependencies = [ [[package]] name = "halo2-base" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678cf3adc0a39d7b4d9b82315a655201aa24a430dd1902b162c508047f56ac69" +version = "0.5.4" +source = "git+https://github.com/axiom-crypto/halo2-lib.git?tag=v0.5.4#a69fdee77f41bdd48ad658b69673dea5a0815db4" dependencies = [ "getset", "halo2-axiom", @@ -3285,9 +3312,8 @@ dependencies = [ [[package]] name = "halo2-ecc" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c00681fdd1febaf552d8814e9f5a6a142d81a1514102190da07039588b366" +version = "0.5.4" +source = "git+https://github.com/axiom-crypto/halo2-lib.git?tag=v0.5.4#a69fdee77f41bdd48ad658b69673dea5a0815db4" dependencies = [ "halo2-base", "itertools 0.11.0", @@ -3451,12 +3477,27 @@ dependencies = [ "arrayvec", ] +[[package]] +name = "hex-conservative" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830e599c2904b08f0834ee6337d8fe8f0ed4a63b5d9e7a7f49c0ffa06d08d360" +dependencies = [ + "arrayvec", +] + [[package]] name = "hex-literal" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" +[[package]] +name = "hex-literal" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e712f64ec3850b98572bffac52e2c6f282b29fe6c5fa6d42334b30be438d95c1" + [[package]] name = "hkdf" version = "0.12.4" @@ -3477,9 +3518,9 @@ dependencies = [ [[package]] name = "http" -version = "1.4.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425" dependencies = [ "bytes", "itoa", @@ -3522,18 +3563,18 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hybrid-array" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9155a582abd142abc056962c29e3ce5ff2ad5469f4246b537ed42c5deba857da" +checksum = "818356c5132c1fede50f837ca96afbe78ff42413047f4abb886217845e1b6c8c" dependencies = [ "typenum", ] [[package]] name = "hyper" -version = "1.9.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" +checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498" dependencies = [ "atomic-waker", "bytes", @@ -3714,12 +3755,6 @@ 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" @@ -3782,7 +3817,7 @@ checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -3891,23 +3926,22 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jobserver" -version = "0.1.34" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" dependencies = [ - "getrandom 0.3.4", + "getrandom 0.4.3", "libc", ] [[package]] name = "js-sys" -version = "0.3.98" +version = "0.3.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67df7112613f8bfd9150013a0314e196f4800d3201ae742489d999db2f979f08" +checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" dependencies = [ "cfg-if", "futures-util", - "once_cell", "wasm-bindgen", ] @@ -3943,12 +3977,12 @@ dependencies = [ [[package]] name = "k256" version = "0.13.4" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "ecdsa", "elliptic-curve", "ff 0.13.1", - "hex-literal", + "hex-literal 1.1.0", "num-bigint", "once_cell", "openvm", @@ -3970,9 +4004,9 @@ dependencies = [ [[package]] name = "keccak-asm" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1766b89733097006f3a1388a02849865d6bc98c89273cb622e29fdd209922183" +checksum = "dd5dc2c0d691cbf7595cde551ced329cca99c2387c2cbc97754c5d0cd045d3ee" dependencies = [ "digest 0.10.7", "sha3-asm", @@ -4028,12 +4062,6 @@ dependencies = [ "spin 0.9.8", ] -[[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.186" @@ -4129,9 +4157,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.28" +version = "1.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc3a226e576f50782b3305c5ccf458698f92798987f551c6a02efe8276721e22" +checksum = "85bc9657773828b90eeb625adff10eeac83cc21bbfd8e23a03eaa8a33c9e28d9" dependencies = [ "cc", "pkg-config", @@ -4148,6 +4176,8 @@ dependencies = [ "c-kzg", "eyre", "git-version", + "openvm-sdk", + "openvm-stark-sdk", "regex", "sbv-core", "sbv-primitives", @@ -4199,9 +4229,9 @@ checksum = "9374ef4228402d4b7e403e5838cb880d9ee663314b0a900d5a6aabf0c213552e" [[package]] name = "log" -version = "0.4.29" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" [[package]] name = "lru" @@ -4245,7 +4275,7 @@ checksum = "59a9dbbfc75d2688ed057456ce8a3ee3f48d12eec09229f560f3643b9f275653" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -4263,6 +4293,16 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" +[[package]] +name = "matrixmultiply" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06de3016e9fae57a36fd14dba131fccf49f74b40b7fbdb472f96e361ec71a08" +dependencies = [ + "autocfg", + "rawpointer", +] + [[package]] name = "maybe-rayon" version = "0.1.1" @@ -4275,15 +4315,15 @@ dependencies = [ [[package]] name = "memchr" -version = "2.8.0" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" [[package]] name = "memmap2" -version = "0.9.10" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714098028fe011992e1c3962653c96b2d578c4b4bce9036e15ff220319b1e0e3" +checksum = "d1219ed1b7f229ee7104d281dd01d6802fe28bb6e95d292942c4daacdeb798c0" dependencies = [ "libc", ] @@ -4364,9 +4404,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" +checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" dependencies = [ "libc", "wasi", @@ -4411,7 +4451,7 @@ checksum = "4568f25ccbd45ab5d5603dc34318c1ec56b117531781260002151b8530a9f931" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -4431,6 +4471,21 @@ dependencies = [ "tempfile", ] +[[package]] +name = "ndarray" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "882ed72dce9365842bf196bdeedf5055305f11fc8c03dee7bb0194a6cad34841" +dependencies = [ + "matrixmultiply", + "num-complex", + "num-integer", + "num-traits", + "portable-atomic", + "portable-atomic-util", + "rawpointer", +] + [[package]] name = "nibble_vec" version = "0.1.0" @@ -4475,9 +4530,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367" dependencies = [ "num-integer", "num-traits", @@ -4511,11 +4566,10 @@ dependencies = [ [[package]] name = "num-iter" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +checksum = "c92800bd69a1eac91786bcfe9da64a897eb72911b8dc3095decbd07429e8048b" dependencies = [ - "autocfg", "num-integer", "num-traits", ] @@ -4606,7 +4660,7 @@ dependencies = [ "proc-macro-crate 1.3.1", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -4618,12 +4672,21 @@ dependencies = [ "proc-macro-crate 3.5.0", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] -name = "nybbles" -version = "0.3.4" +name = "nvtx" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad2e855e8019f99e4b94ac33670eb4e4f570a2e044f3749a0b2c7f83b841e52c" +dependencies = [ + "cc", +] + +[[package]] +name = "nybbles" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8983bb634df7248924ee0c4c3a749609b5abcb082c28fffe3254b3eb3602b307" dependencies = [ @@ -4680,10 +4743,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a501241474c3118833d6195312ae7eb7cc90bbb0d5f524cbb0b06619e49ff67" dependencies = [ "alloy-consensus", - "alloy-eips 1.8.3", + "alloy-eips", "alloy-primitives", "alloy-rlp", - "alloy-serde 1.8.3", + "alloy-serde", "derive_more 2.1.1", "serde", "serde_with", @@ -4697,7 +4760,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "726da827358a547be9f1e37c2a756b9e3729cb0350f43408164794b370cad8ae" dependencies = [ "alloy-consensus", - "alloy-eips 1.8.3", + "alloy-eips", "alloy-primitives", "alloy-rlp", "derive_more 2.1.1", @@ -4711,7 +4774,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8f24b8cb66e4b33e6c9e508bf46b8ecafc92eadd0b93fedd306c0accb477657" dependencies = [ "alloy-consensus", - "alloy-eips 1.8.3", + "alloy-eips", "alloy-primitives", "alloy-rlp", "alloy-rpc-types-engine", @@ -4767,11 +4830,11 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.80" +version = "0.10.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a45fa2aa886c42762255da344f0a0d313e254066c46aad76f300c3d3da62d967" +checksum = "77823a27f0babb03091cb9ed9ef80af3b39dbc82f97e8fa530374b7dafd87a45" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "cfg-if", "foreign-types", "libc", @@ -4787,7 +4850,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -4798,9 +4861,9 @@ checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" [[package]] name = "openssl-sys" -version = "0.9.116" +version = "0.9.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28a22dc7140cda5f096e5e7724a6962ca81a7f8bfd2979f9b18c11af56318c4" +checksum = "b47e7e6bb2c38cd930d25a23b40fa52e068c10e85f3e03a7f5ba5aaca5713695" dependencies = [ "cc", "libc", @@ -4810,8 +4873,8 @@ dependencies = [ [[package]] name = "openvm" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "bytemuck", "getrandom 0.2.17", @@ -4825,8 +4888,8 @@ dependencies = [ [[package]] name = "openvm-algebra-circuit" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "blstrs", "cfg-if", @@ -4836,13 +4899,14 @@ dependencies = [ "halo2curves-axiom 0.7.2 (git+https://github.com/axiom-crypto/halo2curves.git?tag=v0.7.2)", "num-bigint", "num-traits", + "once_cell", "openvm-algebra-transpiler", "openvm-circuit", "openvm-circuit-derive", "openvm-circuit-primitives", "openvm-circuit-primitives-derive", + "openvm-cpu-backend", "openvm-cuda-backend", - "openvm-cuda-builder", "openvm-cuda-common", "openvm-instructions", "openvm-mod-circuit-builder", @@ -4858,18 +4922,18 @@ dependencies = [ [[package]] name = "openvm-algebra-complex-macros" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "openvm-macros-common", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] name = "openvm-algebra-guest" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "halo2curves-axiom 0.7.2 (git+https://github.com/axiom-crypto/halo2curves.git?tag=v0.7.2)", "num-bigint", @@ -4884,20 +4948,20 @@ dependencies = [ [[package]] name = "openvm-algebra-moduli-macros" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "num-bigint", "num-prime", "openvm-macros-common", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] name = "openvm-algebra-transpiler" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "openvm-algebra-guest", "openvm-instructions", @@ -4910,8 +4974,8 @@ dependencies = [ [[package]] name = "openvm-bigint-circuit" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "cfg-if", "derive-new 0.6.0", @@ -4921,6 +4985,7 @@ dependencies = [ "openvm-circuit-derive", "openvm-circuit-primitives", "openvm-circuit-primitives-derive", + "openvm-cpu-backend", "openvm-cuda-backend", "openvm-cuda-builder", "openvm-cuda-common", @@ -4936,8 +5001,8 @@ dependencies = [ [[package]] name = "openvm-bigint-guest" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "openvm-platform", "strum_macros 0.26.4", @@ -4945,8 +5010,8 @@ dependencies = [ [[package]] name = "openvm-bigint-transpiler" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "openvm-bigint-guest", "openvm-instructions", @@ -4960,8 +5025,8 @@ dependencies = [ [[package]] name = "openvm-build" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "cargo_metadata", "eyre", @@ -4972,17 +5037,16 @@ dependencies = [ [[package]] name = "openvm-circuit" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "abi_stable", "backtrace", + "bytesize", "cfg-if", "dashmap", - "derivative", "derive-new 0.6.0", "derive_more 1.0.0", - "enum_dispatch", "eyre", "getset", "itertools 0.14.0", @@ -4991,6 +5055,7 @@ dependencies = [ "openvm-circuit-derive", "openvm-circuit-primitives", "openvm-circuit-primitives-derive", + "openvm-cpu-backend", "openvm-cuda-backend", "openvm-cuda-builder", "openvm-cuda-common", @@ -5001,7 +5066,7 @@ dependencies = [ "p3-baby-bear", "p3-field", "rand 0.9.4", - "rustc-hash 2.1.2", + "rustc-hash 2.1.3", "serde", "serde-big-array", "static_assertions", @@ -5011,95 +5076,144 @@ dependencies = [ [[package]] name = "openvm-circuit-derive" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] name = "openvm-circuit-primitives" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "derive-new 0.6.0", "itertools 0.14.0", "num-bigint", "num-traits", "openvm-circuit-primitives-derive", + "openvm-cpu-backend", "openvm-cuda-backend", "openvm-cuda-builder", "openvm-cuda-common", "openvm-stark-backend", "rand 0.9.4", + "struct-reflection", "tracing", ] [[package]] name = "openvm-circuit-primitives-derive" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "itertools 0.14.0", + "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", +] + +[[package]] +name = "openvm-codec-derive" +version = "2.0.0" +source = "git+https://github.com/openvm-org/stark-backend.git?tag=v2.0.0#16d60de724c21dcadfde7d8315a1db507e5832d7" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 2.0.118", ] [[package]] name = "openvm-continuations" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ + "cfg-if", "derivative", + "derive-new 0.6.0", + "eyre", + "hex", + "itertools 0.14.0", + "num-bigint", "openvm-circuit", - "openvm-native-compiler", - "openvm-native-recursion", + "openvm-circuit-primitives", + "openvm-cpu-backend", + "openvm-cuda-backend", + "openvm-cuda-common", + "openvm-poseidon2-air", + "openvm-recursion-circuit", + "openvm-recursion-circuit-derive", "openvm-stark-backend", "openvm-stark-sdk", + "openvm-verify-stark-host", + "p3-air", "p3-bn254", + "p3-field", + "p3-matrix", "serde", - "static_assertions", + "tracing", +] + +[[package]] +name = "openvm-cpu-backend" +version = "2.0.0" +source = "git+https://github.com/openvm-org/stark-backend.git?tag=v2.0.0#16d60de724c21dcadfde7d8315a1db507e5832d7" +dependencies = [ + "cfg-if", + "derive-new 0.7.0", + "getset", + "itertools 0.14.0", + "openvm-stark-backend", + "p3-air", + "p3-baby-bear", + "p3-dft", + "p3-field", + "p3-interpolation", + "p3-matrix", + "p3-maybe-rayon", + "p3-util", + "rayon", + "rustc-hash 2.1.3", + "serde", + "thiserror 1.0.69", + "tracing", ] [[package]] name = "openvm-cuda-backend" -version = "1.4.0" -source = "git+https://github.com/openvm-org/stark-backend.git?tag=v1.4.0#2d4c6da0c84f43b15fcdac84ce13fd2325148c66" +version = "2.0.0" +source = "git+https://github.com/openvm-org/stark-backend.git?tag=v2.0.0#16d60de724c21dcadfde7d8315a1db507e5832d7" dependencies = [ - "bincode 2.0.1", - "bincode_derive", - "derivative", "derive-new 0.7.0", + "getset", + "glob", "itertools 0.14.0", - "lazy_static", - "metrics", "openvm-cuda-builder", "openvm-cuda-common", "openvm-stark-backend", "openvm-stark-sdk", "p3-baby-bear", - "p3-commit", + "p3-bn254", "p3-dft", "p3-field", - "p3-fri", - "p3-matrix", - "p3-merkle-tree", "p3-symmetric", "p3-util", - "rustc-hash 2.1.2", + "rand 0.9.4", + "rustc-hash 2.1.3", "serde", - "serde_json", "thiserror 1.0.69", "tracing", + "zkhash-axiom", ] [[package]] name = "openvm-cuda-builder" -version = "1.4.0" -source = "git+https://github.com/openvm-org/stark-backend.git?tag=v1.4.0#2d4c6da0c84f43b15fcdac84ce13fd2325148c66" +version = "2.0.0" +source = "git+https://github.com/openvm-org/stark-backend.git?tag=v2.0.0#16d60de724c21dcadfde7d8315a1db507e5832d7" dependencies = [ "cc", "glob", @@ -5107,8 +5221,8 @@ dependencies = [ [[package]] name = "openvm-cuda-common" -version = "1.4.0" -source = "git+https://github.com/openvm-org/stark-backend.git?tag=v1.4.0#2d4c6da0c84f43b15fcdac84ce13fd2325148c66" +version = "2.0.0" +source = "git+https://github.com/openvm-org/stark-backend.git?tag=v2.0.0#16d60de724c21dcadfde7d8315a1db507e5832d7" dependencies = [ "bytesize", "ctor 0.5.0", @@ -5122,24 +5236,79 @@ dependencies = [ [[package]] name = "openvm-custom-insn" version = "0.1.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", +] + +[[package]] +name = "openvm-deferral-circuit" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" +dependencies = [ + "cfg-if", + "dashmap", + "derive-new 0.6.0", + "derive_more 1.0.0", + "itertools 0.14.0", + "openvm-circuit", + "openvm-circuit-derive", + "openvm-circuit-primitives", + "openvm-circuit-primitives-derive", + "openvm-cpu-backend", + "openvm-cuda-backend", + "openvm-cuda-builder", + "openvm-cuda-common", + "openvm-deferral-transpiler", + "openvm-instructions", + "openvm-poseidon2-air", + "openvm-rv32im-circuit", + "openvm-stark-backend", + "openvm-stark-sdk", + "p3-field", + "rand 0.9.4", + "rustc-hash 2.1.3", + "serde", +] + +[[package]] +name = "openvm-deferral-guest" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" +dependencies = [ + "openvm-custom-insn", + "strum_macros 0.26.4", +] + +[[package]] +name = "openvm-deferral-transpiler" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" +dependencies = [ + "eyre", + "openvm-deferral-guest", + "openvm-instructions", + "openvm-instructions-derive", + "openvm-transpiler", + "p3-field", + "rrs-lib", + "serde", + "strum 0.26.3", ] [[package]] name = "openvm-ecc-circuit" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "blstrs", "cfg-if", "derive-new 0.6.0", "derive_more 1.0.0", "halo2curves-axiom 0.7.2 (git+https://github.com/axiom-crypto/halo2curves.git?tag=v0.7.2)", - "hex-literal", + "hex-literal 1.1.0", "lazy_static", "num-bigint", "num-traits", @@ -5148,6 +5317,7 @@ dependencies = [ "openvm-circuit", "openvm-circuit-derive", "openvm-circuit-primitives", + "openvm-cpu-backend", "openvm-cuda-backend", "openvm-cuda-common", "openvm-ecc-transpiler", @@ -5164,8 +5334,8 @@ dependencies = [ [[package]] name = "openvm-ecc-guest" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "ecdsa", "elliptic-curve", @@ -5183,18 +5353,18 @@ dependencies = [ [[package]] name = "openvm-ecc-sw-macros" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "openvm-macros-common", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] name = "openvm-ecc-transpiler" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "openvm-ecc-guest", "openvm-instructions", @@ -5207,8 +5377,8 @@ dependencies = [ [[package]] name = "openvm-instructions" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "backtrace", "derive-new 0.6.0", @@ -5224,19 +5394,18 @@ dependencies = [ [[package]] name = "openvm-instructions-derive" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] name = "openvm-keccak256-circuit" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ - "cfg-if", "derive-new 0.6.0", "derive_more 1.0.0", "itertools 0.14.0", @@ -5244,6 +5413,7 @@ dependencies = [ "openvm-circuit-derive", "openvm-circuit-primitives", "openvm-circuit-primitives-derive", + "openvm-cpu-backend", "openvm-cuda-backend", "openvm-cuda-builder", "openvm-cuda-common", @@ -5261,16 +5431,16 @@ dependencies = [ [[package]] name = "openvm-keccak256-guest" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "openvm-platform", ] [[package]] name = "openvm-keccak256-transpiler" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "openvm-instructions", "openvm-instructions-derive", @@ -5283,143 +5453,38 @@ dependencies = [ [[package]] name = "openvm-macros-common" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ - "syn 2.0.117", + "syn 2.0.118", ] [[package]] name = "openvm-mod-circuit-builder" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ - "cuda-runtime-sys", "itertools 0.14.0", "num-bigint", "num-traits", "openvm-circuit", "openvm-circuit-primitives", - "openvm-cuda-backend", - "openvm-cuda-builder", - "openvm-cuda-common", - "openvm-instructions", - "openvm-stark-backend", - "openvm-stark-sdk", - "rand 0.8.6", - "rand 0.9.4", - "tracing", -] - -[[package]] -name = "openvm-native-circuit" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" -dependencies = [ - "cfg-if", - "derive-new 0.6.0", - "derive_more 1.0.0", - "eyre", - "itertools 0.14.0", - "openvm-circuit", - "openvm-circuit-derive", - "openvm-circuit-primitives", - "openvm-circuit-primitives-derive", - "openvm-cuda-backend", - "openvm-cuda-builder", - "openvm-cuda-common", "openvm-instructions", - "openvm-native-compiler", - "openvm-poseidon2-air", - "openvm-rv32im-circuit", - "openvm-rv32im-transpiler", - "openvm-stark-backend", - "openvm-stark-sdk", - "p3-field", - "rand 0.9.4", - "serde", - "static_assertions", - "strum 0.26.3", -] - -[[package]] -name = "openvm-native-compiler" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" -dependencies = [ - "backtrace", - "itertools 0.14.0", - "num-bigint", - "num-integer", - "openvm-circuit", - "openvm-instructions", - "openvm-instructions-derive", - "openvm-native-compiler-derive", - "openvm-rv32im-transpiler", - "openvm-stark-backend", - "openvm-stark-sdk", - "serde", - "snark-verifier-sdk", - "strum 0.26.3", - "strum_macros 0.26.4", - "zkhash", -] - -[[package]] -name = "openvm-native-compiler-derive" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" -dependencies = [ - "quote", - "syn 2.0.117", -] - -[[package]] -name = "openvm-native-recursion" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" -dependencies = [ - "cfg-if", - "itertools 0.14.0", - "lazy_static", - "once_cell", - "openvm-circuit", - "openvm-native-circuit", - "openvm-native-compiler", - "openvm-native-compiler-derive", "openvm-stark-backend", "openvm-stark-sdk", - "p3-dft", - "p3-fri", - "p3-merkle-tree", - "p3-symmetric", "rand 0.8.6", "rand 0.9.4", - "serde", - "serde_json", - "serde_with", - "snark-verifier-sdk", "tracing", ] -[[package]] -name = "openvm-native-transpiler" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" -dependencies = [ - "openvm-instructions", - "openvm-transpiler", - "p3-field", -] - [[package]] name = "openvm-pairing" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "group 0.13.0", "halo2curves-axiom 0.7.2 (git+https://github.com/axiom-crypto/halo2curves.git?tag=v0.7.2)", - "hex-literal", + "hex-literal 1.1.0", "itertools 0.14.0", "num-bigint", "num-traits", @@ -5438,8 +5503,8 @@ dependencies = [ [[package]] name = "openvm-pairing-circuit" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "cfg-if", "derive-new 0.6.0", @@ -5452,6 +5517,7 @@ dependencies = [ "openvm-circuit", "openvm-circuit-derive", "openvm-circuit-primitives", + "openvm-cpu-backend", "openvm-cuda-backend", "openvm-ecc-circuit", "openvm-ecc-guest", @@ -5469,12 +5535,12 @@ dependencies = [ [[package]] name = "openvm-pairing-guest" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "blstrs", "halo2curves-axiom 0.7.2 (git+https://github.com/axiom-crypto/halo2curves.git?tag=v0.7.2)", - "hex-literal", + "hex-literal 1.1.0", "itertools 0.14.0", "lazy_static", "num-bigint", @@ -5490,8 +5556,8 @@ dependencies = [ [[package]] name = "openvm-pairing-transpiler" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "openvm-instructions", "openvm-pairing-guest", @@ -5503,8 +5569,8 @@ dependencies = [ [[package]] name = "openvm-platform" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "libm", "openvm-custom-insn", @@ -5513,11 +5579,12 @@ dependencies = [ [[package]] name = "openvm-poseidon2-air" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "derivative", "lazy_static", + "openvm-circuit-primitives", "openvm-cuda-builder", "openvm-stark-backend", "openvm-stark-sdk", @@ -5525,13 +5592,50 @@ dependencies = [ "p3-poseidon2-air", "p3-symmetric", "rand 0.9.4", - "zkhash", + "zkhash-axiom", +] + +[[package]] +name = "openvm-recursion-circuit" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" +dependencies = [ + "derive-new 0.6.0", + "itertools 0.14.0", + "openvm-circuit", + "openvm-circuit-primitives", + "openvm-cpu-backend", + "openvm-cuda-backend", + "openvm-cuda-builder", + "openvm-cuda-common", + "openvm-poseidon2-air", + "openvm-recursion-circuit-derive", + "openvm-stark-backend", + "openvm-stark-sdk", + "p3-air", + "p3-baby-bear", + "p3-field", + "p3-matrix", + "p3-maybe-rayon", + "p3-symmetric", + "strum 0.26.3", + "strum_macros 0.26.4", + "tracing", +] + +[[package]] +name = "openvm-recursion-circuit-derive" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" +dependencies = [ + "quote", + "syn 2.0.118", ] [[package]] name = "openvm-rv32-adapters" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "derive-new 0.6.0", "itertools 0.14.0", @@ -5547,8 +5651,8 @@ dependencies = [ [[package]] name = "openvm-rv32im-circuit" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "cfg-if", "derive-new 0.6.0", @@ -5560,6 +5664,7 @@ dependencies = [ "openvm-circuit-derive", "openvm-circuit-primitives", "openvm-circuit-primitives-derive", + "openvm-cpu-backend", "openvm-cuda-backend", "openvm-cuda-builder", "openvm-cuda-common", @@ -5570,22 +5675,22 @@ dependencies = [ "rand 0.9.4", "serde", "strum 0.26.3", + "tracing", ] [[package]] name = "openvm-rv32im-guest" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "openvm-custom-insn", - "p3-field", "strum_macros 0.26.4", ] [[package]] name = "openvm-rv32im-transpiler" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "openvm-instructions", "openvm-instructions-derive", @@ -5600,124 +5705,147 @@ dependencies = [ [[package]] name = "openvm-sdk" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ + "alloy-sol-types", "bitcode", - "bon", "cfg-if", "clap", "derivative", + "derive-new 0.6.0", "derive_more 1.0.0", "eyre", "getset", + "halo2-base", "hex", "itertools 0.14.0", - "metrics", - "num-bigint", "openvm", + "openvm-build", + "openvm-circuit", + "openvm-continuations", + "openvm-cuda-backend", + "openvm-deferral-circuit", + "openvm-recursion-circuit", + "openvm-sdk-config", + "openvm-stark-backend", + "openvm-stark-sdk", + "openvm-static-verifier", + "openvm-transpiler", + "openvm-verify-stark-circuit", + "openvm-verify-stark-host", + "serde", + "serde_json", + "serde_with", + "tempfile", + "thiserror 1.0.69", + "tracing", +] + +[[package]] +name = "openvm-sdk-config" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" +dependencies = [ + "bon", + "cfg-if", + "derive_more 1.0.0", "openvm-algebra-circuit", "openvm-algebra-transpiler", "openvm-bigint-circuit", "openvm-bigint-transpiler", - "openvm-build", "openvm-circuit", "openvm-continuations", + "openvm-cpu-backend", "openvm-cuda-backend", + "openvm-deferral-circuit", + "openvm-deferral-transpiler", "openvm-ecc-circuit", "openvm-ecc-transpiler", "openvm-keccak256-circuit", "openvm-keccak256-transpiler", - "openvm-native-circuit", - "openvm-native-compiler", - "openvm-native-recursion", - "openvm-native-transpiler", "openvm-pairing-circuit", "openvm-pairing-transpiler", "openvm-rv32im-circuit", "openvm-rv32im-transpiler", - "openvm-sha256-circuit", - "openvm-sha256-transpiler", + "openvm-sha2-circuit", + "openvm-sha2-transpiler", "openvm-stark-backend", "openvm-stark-sdk", "openvm-transpiler", - "p3-bn254", - "p3-fri", - "rand 0.9.4", - "rrs-lib", + "openvm-verify-stark-circuit", "serde", - "serde_json", - "serde_with", - "snark-verifier", - "snark-verifier-sdk", - "tempfile", - "thiserror 1.0.69", "toml", - "tracing", ] [[package]] name = "openvm-sha2" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ - "openvm-sha256-guest", + "openvm-sha2-guest", "sha2 0.10.9", ] [[package]] -name = "openvm-sha256-air" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +name = "openvm-sha2-air" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ + "ndarray", + "num_enum 0.7.6", "openvm-circuit-primitives", + "openvm-circuit-primitives-derive", "openvm-stark-backend", "rand 0.9.4", "sha2 0.10.9", ] [[package]] -name = "openvm-sha256-circuit" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +name = "openvm-sha2-circuit" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "cfg-if", "derive-new 0.6.0", "derive_more 1.0.0", + "itertools 0.14.0", + "ndarray", "openvm-circuit", "openvm-circuit-derive", "openvm-circuit-primitives", + "openvm-circuit-primitives-derive", + "openvm-cpu-backend", "openvm-cuda-backend", "openvm-cuda-builder", "openvm-cuda-common", "openvm-instructions", "openvm-rv32im-circuit", - "openvm-sha256-air", - "openvm-sha256-transpiler", + "openvm-sha2-air", + "openvm-sha2-transpiler", "openvm-stark-backend", "openvm-stark-sdk", "rand 0.9.4", "serde", "sha2 0.10.9", - "strum 0.26.3", ] [[package]] -name = "openvm-sha256-guest" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +name = "openvm-sha2-guest" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "openvm-platform", ] [[package]] -name = "openvm-sha256-transpiler" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +name = "openvm-sha2-transpiler" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "openvm-instructions", "openvm-instructions-derive", - "openvm-sha256-guest", + "openvm-sha2-guest", "openvm-stark-backend", "openvm-transpiler", "rrs-lib", @@ -5726,72 +5854,97 @@ dependencies = [ [[package]] name = "openvm-stark-backend" -version = "1.4.0" -source = "git+https://github.com/openvm-org/stark-backend.git?tag=v1.4.0#2d4c6da0c84f43b15fcdac84ce13fd2325148c66" +version = "2.0.0" +source = "git+https://github.com/openvm-org/stark-backend.git?tag=v2.0.0#16d60de724c21dcadfde7d8315a1db507e5832d7" dependencies = [ - "bitcode", "cfg-if", "derivative", "derive-new 0.7.0", "eyre", + "getset", + "hex-literal 1.1.0", "itertools 0.14.0", + "metrics", + "num-bigint", + "openvm-codec-derive", "p3-air", "p3-challenger", - "p3-commit", + "p3-dft", "p3-field", + "p3-interpolation", "p3-matrix", "p3-maybe-rayon", + "p3-symmetric", "p3-util", + "postcard", "rayon", - "rustc-hash 2.1.2", + "rustc-hash 2.1.3", "serde", "serde_json", "thiserror 1.0.69", + "tikv-jemallocator", "tracing", ] [[package]] name = "openvm-stark-sdk" -version = "1.4.0" -source = "git+https://github.com/openvm-org/stark-backend.git?tag=v1.4.0#2d4c6da0c84f43b15fcdac84ce13fd2325148c66" +version = "2.0.0" +source = "git+https://github.com/openvm-org/stark-backend.git?tag=v2.0.0#16d60de724c21dcadfde7d8315a1db507e5832d7" dependencies = [ "dashmap", - "derivative", - "derive_more 1.0.0", - "ff 0.13.1", + "derive-new 0.7.0", + "eyre", + "hex-literal 1.1.0", "itertools 0.14.0", "metrics", "metrics-tracing-context", "metrics-util", "num-bigint", + "nvtx", + "openvm-cpu-backend", "openvm-stark-backend", "p3-baby-bear", - "p3-blake3", "p3-bn254", - "p3-dft", - "p3-fri", - "p3-goldilocks", - "p3-keccak", - "p3-koala-bear", - "p3-merkle-tree", - "p3-poseidon", + "p3-field", "p3-poseidon2", - "p3-symmetric", "rand 0.9.4", "serde", "serde_json", "static_assertions", - "toml", "tracing", "tracing-forest", "tracing-subscriber 0.3.23", - "zkhash", + "zkhash-axiom", +] + +[[package]] +name = "openvm-static-verifier" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" +dependencies = [ + "halo2-base", + "itertools 0.14.0", + "num-bigint", + "num-integer", + "once_cell", + "openvm-continuations", + "openvm-cpu-backend", + "openvm-cuda-backend", + "openvm-recursion-circuit", + "openvm-stark-sdk", + "openvm-verify-stark-host", + "rand_chacha 0.3.1", + "serde", + "serde_json", + "serde_with", + "snark-verifier-sdk", + "tracing", ] [[package]] name = "openvm-transpiler" -version = "1.6.0" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "elf", "eyre", @@ -5802,6 +5955,54 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "openvm-verify-stark-circuit" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" +dependencies = [ + "bitcode", + "cfg-if", + "derive-new 0.6.0", + "eyre", + "itertools 0.14.0", + "openvm-circuit", + "openvm-circuit-primitives", + "openvm-continuations", + "openvm-cpu-backend", + "openvm-cuda-backend", + "openvm-cuda-common", + "openvm-deferral-circuit", + "openvm-poseidon2-air", + "openvm-recursion-circuit", + "openvm-recursion-circuit-derive", + "openvm-stark-backend", + "openvm-stark-sdk", + "openvm-verify-stark-host", + "p3-air", + "p3-field", + "p3-matrix", + "serde", + "tracing", +] + +[[package]] +name = "openvm-verify-stark-host" +version = "2.0.0" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" +dependencies = [ + "bitcode", + "eyre", + "openvm-circuit", + "openvm-circuit-primitives", + "openvm-recursion-circuit-derive", + "openvm-stark-backend", + "openvm-stark-sdk", + "p3-field", + "serde", + "thiserror 1.0.69", + "zstd", +] + [[package]] name = "ordered-float" version = "4.6.0" @@ -5832,12 +6033,12 @@ dependencies = [ [[package]] name = "p256" version = "0.13.2" -source = "git+https://github.com/openvm-org/openvm.git?tag=v1.6.0#eda5bf031a6bd0960adb1dcf59b9a0a951eacb20" +source = "git+https://github.com/openvm-org/openvm.git?tag=v2.0.0#15a7ab6baed03d75050dbef2bbad4b4e98fb8dba" dependencies = [ "ecdsa", "elliptic-curve", "ff 0.13.1", - "hex-literal", + "hex-literal 1.1.0", "num-bigint", "openvm", "openvm-algebra-guest", @@ -5872,17 +6073,6 @@ dependencies = [ "rand 0.9.4", ] -[[package]] -name = "p3-blake3" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a8f97fd783752532861bf29bac344b7c226a0d1e2151148834c43c651a5d401" -dependencies = [ - "blake3", - "p3-symmetric", - "p3-util", -] - [[package]] name = "p3-bn254" version = "0.4.3" @@ -5913,21 +6103,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "p3-commit" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf6d7dcb58a8f21f0e1325dc7f7699ad749878ccbe7e286e61f9d46bde2bfa88" -dependencies = [ - "itertools 0.14.0", - "p3-challenger", - "p3-dft", - "p3-field", - "p3-matrix", - "p3-util", - "serde", -] - [[package]] name = "p3-dft" version = "0.4.3" @@ -5959,46 +6134,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "p3-fri" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13ca6a795cfc4180425fbf16dfdb4c9c2bfa85971dd55b5930d97b513e0835df" -dependencies = [ - "itertools 0.14.0", - "p3-challenger", - "p3-commit", - "p3-dft", - "p3-field", - "p3-interpolation", - "p3-matrix", - "p3-maybe-rayon", - "p3-util", - "rand 0.9.4", - "serde", - "thiserror 2.0.18", - "tracing", -] - -[[package]] -name = "p3-goldilocks" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c47d5c650bbeb25941b9a1fa9bfaf59b3cd202a438ea2c20892489af001399" -dependencies = [ - "num-bigint", - "p3-challenger", - "p3-dft", - "p3-field", - "p3-mds", - "p3-poseidon2", - "p3-symmetric", - "p3-util", - "paste", - "rand 0.9.4", - "serde", -] - [[package]] name = "p3-interpolation" version = "0.4.3" @@ -6011,18 +6146,6 @@ dependencies = [ "p3-util", ] -[[package]] -name = "p3-keccak" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a61b090fb42152d1fcb2f82227b8619b1b022f9cd4a123123dccc9c2ab75d5de" -dependencies = [ - "p3-field", - "p3-symmetric", - "p3-util", - "tiny-keccak", -] - [[package]] name = "p3-keccak-air" version = "0.4.3" @@ -6038,20 +6161,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "p3-koala-bear" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfb02789fca0950e246123d652bd78e75a76e3b90a651fd88dbb215cd3e81f5a" -dependencies = [ - "p3-challenger", - "p3-field", - "p3-monty-31", - "p3-poseidon2", - "p3-symmetric", - "rand 0.9.4", -] - [[package]] name = "p3-matrix" version = "0.4.3" @@ -6089,25 +6198,6 @@ dependencies = [ "rand 0.9.4", ] -[[package]] -name = "p3-merkle-tree" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60e20f61ea816e94f83ed7b8134a5e98d0cad7bd6dff226bc1da17a5143c63cb" -dependencies = [ - "itertools 0.14.0", - "p3-commit", - "p3-field", - "p3-matrix", - "p3-maybe-rayon", - "p3-symmetric", - "p3-util", - "rand 0.9.4", - "serde", - "thiserror 2.0.18", - "tracing", -] - [[package]] name = "p3-monty-31" version = "0.4.3" @@ -6131,18 +6221,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "p3-poseidon" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "548af7ff569975882bc411f653aba7d89a6d85813ca58ef922fd0b1ecb6b5866" -dependencies = [ - "p3-field", - "p3-mds", - "p3-symmetric", - "rand 0.9.4", -] - [[package]] name = "p3-poseidon2" version = "0.4.3" @@ -6235,7 +6313,7 @@ dependencies = [ "proc-macro-crate 3.5.0", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -6330,9 +6408,9 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pest" -version = "2.8.6" +version = "2.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0848c601009d37dfa3430c4666e147e49cdcf1b92ecd3e63657d8a5f19da662" +checksum = "47627dd7305c6a2d6c8c6bcd24c5a4c17dbbf425f4f9c5313e724b38fc9782e9" dependencies = [ "memchr", "ucd-trie", @@ -6346,6 +6424,7 @@ checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" dependencies = [ "phf_macros 0.11.3", "phf_shared 0.11.3", + "serde", ] [[package]] @@ -6389,7 +6468,7 @@ dependencies = [ "phf_shared 0.11.3", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -6402,7 +6481,7 @@ dependencies = [ "phf_shared 0.13.1", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -6440,7 +6519,7 @@ checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -6488,6 +6567,15 @@ version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" +[[package]] +name = "portable-atomic-util" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618" +dependencies = [ + "portable-atomic", +] + [[package]] name = "poseidon-primitives" version = "0.2.0" @@ -6503,6 +6591,18 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "postcard" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24" +dependencies = [ + "cobs", + "embedded-io 0.4.0", + "embedded-io 0.6.1", + "serde", +] + [[package]] name = "potential_utf" version = "0.1.5" @@ -6534,7 +6634,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -6576,7 +6676,7 @@ version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" dependencies = [ - "toml_edit 0.25.11+spec-1.1.0", + "toml_edit 0.25.12+spec-1.1.0", ] [[package]] @@ -6598,7 +6698,7 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -6618,7 +6718,7 @@ checksum = "4b45fcc2344c680f5025fe57779faef368840d0bd1f42f216291f0dc4ace4744" dependencies = [ "bit-set", "bit-vec", - "bitflags 2.11.1", + "bitflags 2.13.0", "num-traits", "rand 0.9.4", "rand_chacha 0.9.0", @@ -6686,7 +6786,7 @@ checksum = "7347867d0a7e1208d93b46767be83e2b8f978c3dad35f775ac8d8847551d6fe1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -6712,16 +6812,16 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quinn" -version = "0.11.9" +version = "0.11.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +checksum = "0c1a41e437b6bbd489372cd4971de128e85c855f56c57f283d20ff016cf7c0a8" dependencies = [ "bytes", "cfg_aliases", "pin-project-lite", "quinn-proto", "quinn-udp", - "rustc-hash 2.1.2", + "rustc-hash 2.1.3", "rustls", "socket2", "thiserror 2.0.18", @@ -6732,16 +6832,17 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.14" +version = "0.11.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" +checksum = "2f4bfc015262b9df63c8845072ce59068853ff5872180c2ce2f13038b970e560" dependencies = [ "bytes", - "getrandom 0.3.4", + "getrandom 0.4.3", "lru-slab", - "rand 0.9.4", + "rand 0.10.2", + "rand_pcg", "ring", - "rustc-hash 2.1.2", + "rustc-hash 2.1.3", "rustls", "rustls-pki-types", "slab", @@ -6753,23 +6854,23 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.14" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" +checksum = "35a133f956daabe89a61a685c2649f13d82d5aa4bd5d12d1277e1072a21c0694" dependencies = [ "cfg_aliases", "libc", "once_cell", "socket2", "tracing", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] name = "quote" -version = "1.0.45" +version = "1.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" dependencies = [ "proc-macro2", ] @@ -6804,9 +6905,9 @@ dependencies = [ [[package]] name = "rancor" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a063ea72381527c2a0561da9c80000ef822bdd7c3241b1cc1b12100e3df081ee" +checksum = "daff8b7b3ccf5f7ba270b3e7a0a4d4c701c5797e38dec27c7e2c3dbb830fed1c" dependencies = [ "ptr_meta", ] @@ -6834,6 +6935,17 @@ dependencies = [ "serde", ] +[[package]] +name = "rand" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" +dependencies = [ + "chacha20", + "getrandom 0.4.3", + "rand_core 0.10.1", +] + [[package]] name = "rand_chacha" version = "0.3.1" @@ -6873,6 +6985,21 @@ dependencies = [ "serde", ] +[[package]] +name = "rand_core" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" + +[[package]] +name = "rand_pcg" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caa0f4137e1c0a72f4c651489402276c8e8e1cf081f3b0ba156d2cbeef09e86a" +dependencies = [ + "rand_core 0.10.1", +] + [[package]] name = "rand_xorshift" version = "0.3.0" @@ -6893,9 +7020,9 @@ dependencies = [ [[package]] name = "rapidhash" -version = "4.4.1" +version = "4.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e48930979c155e2f33aa36ab3119b5ee81332beb6482199a8ecd6029b80b59" +checksum = "5da7e78a036ce858e8d55b7e7dc8ba3a88b78350fd2155d3591bbd966b58589e" dependencies = [ "rustversion", ] @@ -6906,9 +7033,15 @@ version = "11.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", ] +[[package]] +name = "rawpointer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" + [[package]] name = "rayon" version = "1.12.0" @@ -6944,7 +7077,7 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", ] [[package]] @@ -6964,14 +7097,14 @@ checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] name = "regex" -version = "1.12.3" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +checksum = "2a0e75113e14dc5acb068cd0786884f214f1312650a3d36d269f5c4f3cdee8a2" dependencies = [ "aho-corasick", "memchr", @@ -6981,9 +7114,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +checksum = "1f388202e4b80542a0921078cc23b6333bcf1409c1e3f86404cae4766a6131db" dependencies = [ "aho-corasick", "memchr", @@ -6992,15 +7125,15 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" [[package]] name = "rend" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cadadef317c2f20755a64d7fdc48f9e7178ee6b0e1f7fce33fa60f1d68a276e6" +checksum = "663ba70707f96e871406fe10d68128412e619b06d1d47cb91c3a4c6501176240" dependencies = [ "bytecheck", ] @@ -7105,7 +7238,7 @@ source = "git+https://github.com/scroll-tech/reth?tag=scroll-v91.2#11d0a3f73186d dependencies = [ "alloy-chains", "alloy-consensus", - "alloy-eips 1.8.3", + "alloy-eips", "alloy-evm", "alloy-genesis", "alloy-primitives", @@ -7124,7 +7257,7 @@ version = "1.8.2" source = "git+https://github.com/scroll-tech/reth?tag=scroll-v91.2#11d0a3f73186dee7a1ba0d51ea5416dc8fef3e46" dependencies = [ "alloy-consensus", - "alloy-eips 1.8.3", + "alloy-eips", "alloy-genesis", "alloy-primitives", "alloy-trie 0.9.5", @@ -7143,7 +7276,7 @@ source = "git+https://github.com/scroll-tech/reth?tag=scroll-v91.2#11d0a3f73186d dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -7165,7 +7298,7 @@ version = "1.8.2" source = "git+https://github.com/scroll-tech/reth?tag=scroll-v91.2#11d0a3f73186dee7a1ba0d51ea5416dc8fef3e46" dependencies = [ "alloy-consensus", - "alloy-eips 1.8.3", + "alloy-eips", "reth-chainspec", "reth-consensus", "reth-primitives-traits", @@ -7176,7 +7309,7 @@ name = "reth-db-models" version = "1.8.2" source = "git+https://github.com/scroll-tech/reth?tag=scroll-v91.2#11d0a3f73186dee7a1ba0d51ea5416dc8fef3e46" dependencies = [ - "alloy-eips 1.8.3", + "alloy-eips", "alloy-primitives", "reth-primitives-traits", ] @@ -7198,7 +7331,7 @@ version = "1.8.2" source = "git+https://github.com/scroll-tech/reth?tag=scroll-v91.2#11d0a3f73186dee7a1ba0d51ea5416dc8fef3e46" dependencies = [ "alloy-consensus", - "alloy-eips 1.8.3", + "alloy-eips", "alloy-primitives", "reth-chainspec", "reth-consensus", @@ -7226,11 +7359,11 @@ version = "1.8.2" source = "git+https://github.com/scroll-tech/reth?tag=scroll-v91.2#11d0a3f73186dee7a1ba0d51ea5416dc8fef3e46" dependencies = [ "alloy-consensus", - "alloy-eips 1.8.3", + "alloy-eips", "alloy-primitives", "alloy-rlp", "alloy-rpc-types-eth", - "alloy-serde 1.8.3", + "alloy-serde", "reth-codecs", "reth-primitives-traits", "serde", @@ -7243,7 +7376,7 @@ version = "1.8.2" source = "git+https://github.com/scroll-tech/reth?tag=scroll-v91.2#11d0a3f73186dee7a1ba0d51ea5416dc8fef3e46" dependencies = [ "alloy-consensus", - "alloy-eips 1.8.3", + "alloy-eips", "alloy-evm", "alloy-primitives", "auto_impl", @@ -7265,7 +7398,7 @@ version = "1.8.2" source = "git+https://github.com/scroll-tech/reth?tag=scroll-v91.2#11d0a3f73186dee7a1ba0d51ea5416dc8fef3e46" dependencies = [ "alloy-consensus", - "alloy-eips 1.8.3", + "alloy-eips", "alloy-evm", "alloy-primitives", "alloy-rpc-types-engine", @@ -7298,7 +7431,7 @@ version = "1.8.2" source = "git+https://github.com/scroll-tech/reth?tag=scroll-v91.2#11d0a3f73186dee7a1ba0d51ea5416dc8fef3e46" dependencies = [ "alloy-consensus", - "alloy-eips 1.8.3", + "alloy-eips", "alloy-evm", "alloy-primitives", "derive_more 2.1.1", @@ -7339,7 +7472,7 @@ version = "1.8.2" source = "git+https://github.com/scroll-tech/reth?tag=scroll-v91.2#11d0a3f73186dee7a1ba0d51ea5416dc8fef3e46" dependencies = [ "alloy-consensus", - "alloy-eips 1.8.3", + "alloy-eips", "alloy-genesis", "alloy-primitives", "alloy-rlp", @@ -7390,10 +7523,10 @@ source = "git+https://github.com/scroll-tech/reth?tag=scroll-v91.2#11d0a3f73186d dependencies = [ "alloy-chains", "alloy-consensus", - "alloy-eips 1.8.3", + "alloy-eips", "alloy-genesis", "alloy-primitives", - "alloy-serde 1.8.3", + "alloy-serde", "auto_impl", "derive_more 2.1.1", "once_cell", @@ -7414,7 +7547,7 @@ version = "1.8.2" source = "git+https://github.com/scroll-tech/reth?tag=scroll-v91.2#11d0a3f73186dee7a1ba0d51ea5416dc8fef3e46" dependencies = [ "alloy-consensus", - "alloy-eips 1.8.3", + "alloy-eips", "alloy-evm", "alloy-primitives", "alloy-rpc-types-engine", @@ -7458,7 +7591,7 @@ version = "1.8.2" source = "git+https://github.com/scroll-tech/reth?tag=scroll-v91.2#11d0a3f73186dee7a1ba0d51ea5416dc8fef3e46" dependencies = [ "alloy-consensus", - "alloy-eips 1.8.3", + "alloy-eips", "alloy-primitives", "alloy-rlp", "bytes", @@ -7521,7 +7654,7 @@ version = "1.8.2" source = "git+https://github.com/scroll-tech/reth?tag=scroll-v91.2#11d0a3f73186dee7a1ba0d51ea5416dc8fef3e46" dependencies = [ "alloy-consensus", - "alloy-eips 1.8.3", + "alloy-eips", "alloy-primitives", "alloy-rpc-types-engine", "auto_impl", @@ -7542,7 +7675,7 @@ name = "reth-storage-errors" version = "1.8.2" source = "git+https://github.com/scroll-tech/reth?tag=scroll-v91.2#11d0a3f73186dee7a1ba0d51ea5416dc8fef3e46" dependencies = [ - "alloy-eips 1.8.3", + "alloy-eips", "alloy-primitives", "alloy-rlp", "derive_more 2.1.1", @@ -7559,7 +7692,7 @@ version = "1.8.2" source = "git+https://github.com/scroll-tech/reth?tag=scroll-v91.2#11d0a3f73186dee7a1ba0d51ea5416dc8fef3e46" dependencies = [ "alloy-consensus", - "alloy-eips 1.8.3", + "alloy-eips", "alloy-primitives", "alloy-rlp", "alloy-trie 0.9.5", @@ -7626,21 +7759,21 @@ dependencies = [ [[package]] name = "revm" -version = "22.0.1" +version = "27.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5378e95ffe5c8377002dafeb6f7d370a55517cef7d6d6c16fc552253af3b123" +checksum = "5e6bf82101a1ad8a2b637363a37aef27f88b4efc8a6e24c72bf5f64923dc5532" dependencies = [ - "revm-bytecode 3.0.0", - "revm-context 3.0.1", - "revm-context-interface 3.0.0", - "revm-database 3.0.0", - "revm-database-interface 3.0.0", - "revm-handler 3.0.1", - "revm-inspector 3.0.1", - "revm-interpreter 18.0.0", - "revm-precompile 19.0.0", - "revm-primitives 18.0.0", - "revm-state 3.0.0", + "revm-bytecode 6.2.2", + "revm-context 8.0.4", + "revm-context-interface 9.0.0", + "revm-database 7.0.5", + "revm-database-interface 7.0.5", + "revm-handler 8.1.0", + "revm-inspector 8.1.0", + "revm-interpreter 24.0.0", + "revm-precompile 25.0.0", + "revm-primitives 20.2.1", + "revm-state 7.0.5", ] [[package]] @@ -7682,13 +7815,13 @@ dependencies = [ [[package]] name = "revm-bytecode" -version = "3.0.0" +version = "6.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e63e138d520c5c5bc25ecc82506e9e4e6e85a811809fc5251c594378dccabfc6" +checksum = "66c52031b73cae95d84cd1b07725808b5fd1500da3e5e24574a3b2dc13d9f16d" dependencies = [ "bitvec", "phf 0.11.3", - "revm-primitives 18.0.0", + "revm-primitives 20.2.1", "serde", ] @@ -7717,17 +7850,17 @@ dependencies = [ [[package]] name = "revm-context" -version = "3.0.1" +version = "8.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9765628dfea4f3686aa8f2a72471c52801e6b38b601939ac16965f49bac66580" +checksum = "9cd508416a35a4d8a9feaf5ccd06ac6d6661cd31ee2dc0252f9f7316455d71f9" dependencies = [ "cfg-if", "derive-where", - "revm-bytecode 3.0.0", - "revm-context-interface 3.0.0", - "revm-database-interface 3.0.0", - "revm-primitives 18.0.0", - "revm-state 3.0.0", + "revm-bytecode 6.2.2", + "revm-context-interface 9.0.0", + "revm-database-interface 7.0.5", + "revm-primitives 20.2.1", + "revm-state 7.0.5", "serde", ] @@ -7766,16 +7899,17 @@ dependencies = [ [[package]] name = "revm-context-interface" -version = "3.0.0" +version = "9.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82d74335aa1f14222cc4d3be1f62a029cc7dc03819cc8d080ff17b7e1d76375f" +checksum = "dc90302642d21c8f93e0876e201f3c5f7913c4fcb66fb465b0fd7b707dfe1c79" dependencies = [ "alloy-eip2930", "alloy-eip7702", "auto_impl", - "revm-database-interface 3.0.0", - "revm-primitives 18.0.0", - "revm-state 3.0.0", + "either", + "revm-database-interface 7.0.5", + "revm-primitives 20.2.1", + "revm-state 7.0.5", "serde", ] @@ -7812,15 +7946,15 @@ dependencies = [ [[package]] name = "revm-database" -version = "3.0.0" +version = "7.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e5c80c5a2fd605f2119ee32a63fb3be941fb6a81ced8cdb3397abca28317224" +checksum = "39a276ed142b4718dcf64bc9624f474373ed82ef20611025045c3fb23edbef9c" dependencies = [ - "alloy-eips 0.14.0", - "revm-bytecode 3.0.0", - "revm-database-interface 3.0.0", - "revm-primitives 18.0.0", - "revm-state 3.0.0", + "alloy-eips", + "revm-bytecode 6.2.2", + "revm-database-interface 7.0.5", + "revm-primitives 20.2.1", + "revm-state 7.0.5", "serde", ] @@ -7829,7 +7963,7 @@ name = "revm-database" version = "9.0.1" source = "git+https://github.com/scroll-tech/revm?tag=scroll-v91#10e11b985ed28bd383e624539868bcc3f613d77c" dependencies = [ - "alloy-eips 1.8.3", + "alloy-eips", "revm-bytecode 7.0.1", "revm-database-interface 8.0.2", "revm-primitives 21.0.1", @@ -7843,7 +7977,7 @@ version = "9.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "980d8d6bba78c5dd35b83abbb6585b0b902eb25ea4448ed7bfba6283b0337191" dependencies = [ - "alloy-eips 1.8.3", + "alloy-eips", "revm-bytecode 7.1.1", "revm-database-interface 8.0.5", "revm-primitives 21.0.2", @@ -7853,13 +7987,14 @@ dependencies = [ [[package]] name = "revm-database-interface" -version = "3.0.0" +version = "7.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0e4dfbc734b1ea67b5e8f8b3c7dc4283e2210d978cdaf6c7a45e97be5ea53b3" +checksum = "8c523c77e74eeedbac5d6f7c092e3851dbe9c7fec6f418b85992bd79229db361" dependencies = [ "auto_impl", - "revm-primitives 18.0.0", - "revm-state 3.0.0", + "either", + "revm-primitives 20.2.1", + "revm-state 7.0.5", "serde", ] @@ -7890,19 +8025,20 @@ dependencies = [ [[package]] name = "revm-handler" -version = "3.0.1" +version = "8.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8676379521c7bf179c31b685c5126ce7800eab5844122aef3231b97026d41a10" +checksum = "1529c8050e663be64010e80ec92bf480315d21b1f2dbf65540028653a621b27d" dependencies = [ "auto_impl", - "revm-bytecode 3.0.0", - "revm-context 3.0.1", - "revm-context-interface 3.0.0", - "revm-database-interface 3.0.0", - "revm-interpreter 18.0.0", - "revm-precompile 19.0.0", - "revm-primitives 18.0.0", - "revm-state 3.0.0", + "derive-where", + "revm-bytecode 6.2.2", + "revm-context 8.0.4", + "revm-context-interface 9.0.0", + "revm-database-interface 7.0.5", + "revm-interpreter 24.0.0", + "revm-precompile 25.0.0", + "revm-primitives 20.2.1", + "revm-state 7.0.5", "serde", ] @@ -7945,17 +8081,18 @@ dependencies = [ [[package]] name = "revm-inspector" -version = "3.0.1" +version = "8.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfed4ecf999a3f6ae776ae2d160478c5dca986a8c2d02168e04066b1e34c789e" +checksum = "f78db140e332489094ef314eaeb0bd1849d6d01172c113ab0eb6ea8ab9372926" dependencies = [ "auto_impl", - "revm-context 3.0.1", - "revm-database-interface 3.0.0", - "revm-handler 3.0.1", - "revm-interpreter 18.0.0", - "revm-primitives 18.0.0", - "revm-state 3.0.0", + "either", + "revm-context 8.0.4", + "revm-database-interface 7.0.5", + "revm-handler 8.1.0", + "revm-interpreter 24.0.0", + "revm-primitives 20.2.1", + "revm-state 7.0.5", "serde", "serde_json", ] @@ -7997,13 +8134,13 @@ dependencies = [ [[package]] name = "revm-interpreter" -version = "18.0.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "feb20260342003cfb791536e678ef5bbea1bfd1f8178b170e8885ff821985473" +checksum = "ff9d7d9d71e8a33740b277b602165b6e3d25fff091ba3d7b5a8d373bf55f28a7" dependencies = [ - "revm-bytecode 3.0.0", - "revm-context-interface 3.0.0", - "revm-primitives 18.0.0", + "revm-bytecode 6.2.2", + "revm-context-interface 9.0.0", + "revm-primitives 20.2.1", "serde", ] @@ -8034,15 +8171,16 @@ dependencies = [ [[package]] name = "revm-precompile" -version = "19.0.0" +version = "25.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418e95eba68c9806c74f3e36cd5d2259170b61e90ac608b17ff8c435038ddace" +checksum = "4cee3f336b83621294b4cfe84d817e3eef6f3d0fce00951973364cc7f860424d" dependencies = [ "ark-bls12-381", "ark-bn254", "ark-ec", "ark-ff 0.5.0", "ark-serialize 0.5.0", + "arrayref", "aurora-engine-modexp", "blst", "c-kzg", @@ -8051,9 +8189,10 @@ dependencies = [ "libsecp256k1", "once_cell", "p256 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)", - "revm-primitives 18.0.0", + "revm-primitives 20.2.1", "ripemd", - "secp256k1 0.30.0", + "rug", + "secp256k1 0.31.1", "sha2 0.10.9", ] @@ -8082,12 +8221,13 @@ dependencies = [ [[package]] name = "revm-primitives" -version = "18.0.0" +version = "20.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc2283ff87358ec7501956c5dd8724a6c2be959c619c4861395ae5e0054575f" +checksum = "5aa29d9da06fe03b249b6419b33968ecdf92ad6428e2f012dc57bcd619b5d94e" dependencies = [ "alloy-primitives", - "enumn", + "num_enum 0.7.6", + "once_cell", "serde", ] @@ -8130,13 +8270,13 @@ dependencies = [ [[package]] name = "revm-state" -version = "3.0.0" +version = "7.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09dd121f6e66d75ab111fb51b4712f129511569bc3e41e6067ae760861418bd8" +checksum = "1f64fbacb86008394aaebd3454f9643b7d5a782bd251135e17c5b33da592d84d" dependencies = [ - "bitflags 2.11.1", - "revm-bytecode 3.0.0", - "revm-primitives 18.0.0", + "bitflags 2.13.0", + "revm-bytecode 6.2.2", + "revm-primitives 20.2.1", "serde", ] @@ -8145,7 +8285,7 @@ name = "revm-state" version = "8.0.1" source = "git+https://github.com/scroll-tech/revm?tag=scroll-v91#10e11b985ed28bd383e624539868bcc3f613d77c" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "revm-bytecode 7.0.1", "revm-primitives 21.0.1", "serde", @@ -8157,7 +8297,7 @@ version = "8.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d8be953b7e374dbdea0773cf360debed8df394ea8d82a8b240a6b5da37592fc" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "revm-bytecode 7.1.1", "revm-primitives 21.0.2", "serde", @@ -8213,9 +8353,9 @@ dependencies = [ [[package]] name = "rkyv" -version = "0.8.16" +version = "0.8.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73389e0c99e664f919275ab5b5b0471391fe9a8de61e1dff9b1eaf56a90f16e3" +checksum = "815cc8a37159a463064825246cadb07961e25cd9885908606f6d08a98d8f8874" dependencies = [ "bytecheck", "bytes", @@ -8232,13 +8372,13 @@ dependencies = [ [[package]] name = "rkyv_derive" -version = "0.8.16" +version = "0.8.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d2ed0b54125315fb36bd021e82d314d1c126548f871634b483f46b31d13cac6" +checksum = "c0ed1a78a1b19d184b0daa629dd9a024573173ec7d485b287cb369fb3607cc1c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -8297,14 +8437,15 @@ dependencies = [ [[package]] name = "ruint" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0298da754d1395046b0afdc2f20ee76d29a8ae310cd30ffa84ed42acba9cb12a" +checksum = "45caf26f647c19115bf9c453c70ffe4a4a3a6390dceebd942610584f99b8ddce" dependencies = [ "alloy-rlp", "ark-ff 0.3.0", "ark-ff 0.4.2", "ark-ff 0.5.0", + "ark-ff 0.6.0", "bytes", "fastrlp 0.3.1", "fastrlp 0.4.0", @@ -8332,9 +8473,9 @@ checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" [[package]] name = "rustc-demangle" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d" +checksum = "b74b56ffa8bb2830709a538c2cbcae9aa062db0d2a42563bfb09bdaae44020eb" [[package]] name = "rustc-hash" @@ -8344,9 +8485,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustc-hash" -version = "2.1.2" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" [[package]] name = "rustc-hex" @@ -8378,7 +8519,7 @@ version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "errno", "libc", "linux-raw-sys", @@ -8387,9 +8528,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.40" +version = "0.23.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" +checksum = "6b92b125634d9b795e7beca796cc790df15a7fb38323bf3196fda83292d06b1f" dependencies = [ "once_cell", "ring", @@ -8401,9 +8542,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.14.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" +checksum = "764899a24af3980067ee14bc143654f297b22eaebfe3c7b6b211920a5a59b046" dependencies = [ "web-time", "zeroize", @@ -8422,9 +8563,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" [[package]] name = "rusty-fork" @@ -8474,13 +8615,13 @@ version = "2.0.0" source = "git+https://github.com/scroll-tech/stateless-block-verifier?tag=scroll-v91.2#3a32848c9438432125751eae8837757f6b87562e" dependencies = [ "alloy-consensus", - "alloy-eips 1.8.3", + "alloy-eips", "alloy-evm", "alloy-network", "alloy-primitives", "alloy-rpc-types-debug", "alloy-rpc-types-eth", - "alloy-serde 1.8.3", + "alloy-serde", "reth-chainspec", "reth-ethereum-forks", "reth-evm", @@ -8552,7 +8693,7 @@ dependencies = [ "proc-macro-crate 3.5.0", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -8600,10 +8741,10 @@ version = "1.8.2" source = "git+https://github.com/scroll-tech/reth?tag=scroll-v91.2#11d0a3f73186dee7a1ba0d51ea5416dc8fef3e46" dependencies = [ "alloy-consensus", - "alloy-eips 1.8.3", + "alloy-eips", "alloy-primitives", "alloy-rlp", - "alloy-serde 1.8.3", + "alloy-serde", "derive_more 2.1.1", "reth-codecs", "serde", @@ -8616,7 +8757,7 @@ version = "1.8.2" source = "git+https://github.com/scroll-tech/reth?tag=scroll-v91.2#11d0a3f73186dee7a1ba0d51ea5416dc8fef3e46" dependencies = [ "alloy-consensus", - "alloy-eips 1.8.3", + "alloy-eips", "alloy-evm", "alloy-primitives", "auto_impl", @@ -8659,11 +8800,11 @@ version = "1.8.2" source = "git+https://github.com/scroll-tech/reth?tag=scroll-v91.2#11d0a3f73186dee7a1ba0d51ea5416dc8fef3e46" dependencies = [ "alloy-consensus", - "alloy-eips 1.8.3", + "alloy-eips", "alloy-network-primitives", "alloy-primitives", "alloy-rpc-types-eth", - "alloy-serde 1.8.3", + "alloy-serde", "derive_more 2.1.1", "scroll-alloy-consensus", "serde", @@ -8703,8 +8844,8 @@ dependencies = [ [[package]] name = "scroll-zkvm-prover" -version = "0.8.0" -source = "git+https://github.com/scroll-tech/zkvm-prover?rev=ed3b964#ed3b964c8d0e93856b089d880ad2eda7e08fb7b4" +version = "0.9.0" +source = "git+https://github.com/scroll-tech/zkvm-prover?tag=v0.9.0#bf8494e57828bc449e9582ca6f97b53bd9b6eaf1" dependencies = [ "base64", "bincode 1.3.3", @@ -8713,10 +8854,17 @@ dependencies = [ "git-version", "hex", "openvm-circuit", - "openvm-native-circuit", - "openvm-native-recursion", + "openvm-continuations", + "openvm-cuda-backend", + "openvm-deferral-circuit", + "openvm-recursion-circuit", "openvm-sdk", + "openvm-sdk-config", + "openvm-stark-backend", "openvm-stark-sdk", + "openvm-static-verifier", + "openvm-verify-stark-circuit", + "openvm-verify-stark-host", "scroll-zkvm-types", "scroll-zkvm-verifier", "serde", @@ -8729,8 +8877,8 @@ dependencies = [ [[package]] name = "scroll-zkvm-types" -version = "0.8.0" -source = "git+https://github.com/scroll-tech/zkvm-prover?rev=ed3b964#ed3b964c8d0e93856b089d880ad2eda7e08fb7b4" +version = "0.9.0" +source = "git+https://github.com/scroll-tech/zkvm-prover?tag=v0.9.0#bf8494e57828bc449e9582ca6f97b53bd9b6eaf1" dependencies = [ "alloy-primitives", "base64", @@ -8738,9 +8886,11 @@ dependencies = [ "eyre", "hex", "once_cell", - "openvm-native-recursion", + "openvm-circuit", "openvm-sdk", "openvm-stark-sdk", + "openvm-static-verifier", + "openvm-verify-stark-host", "sbv-primitives", "scroll-zkvm-types-base", "scroll-zkvm-types-batch", @@ -8753,11 +8903,11 @@ dependencies = [ [[package]] name = "scroll-zkvm-types-base" -version = "0.8.0" -source = "git+https://github.com/scroll-tech/zkvm-prover?rev=ed3b964#ed3b964c8d0e93856b089d880ad2eda7e08fb7b4" +version = "0.9.0" +source = "git+https://github.com/scroll-tech/zkvm-prover?tag=v0.9.0#bf8494e57828bc449e9582ca6f97b53bd9b6eaf1" dependencies = [ "alloy-primitives", - "alloy-serde 1.8.3", + "alloy-serde", "serde", "sha2 0.10.9", "sha3", @@ -8765,8 +8915,8 @@ dependencies = [ [[package]] name = "scroll-zkvm-types-batch" -version = "0.8.0" -source = "git+https://github.com/scroll-tech/zkvm-prover?rev=ed3b964#ed3b964c8d0e93856b089d880ad2eda7e08fb7b4" +version = "0.9.0" +source = "git+https://github.com/scroll-tech/zkvm-prover?tag=v0.9.0#bf8494e57828bc449e9582ca6f97b53bd9b6eaf1" dependencies = [ "alloy-primitives", "c-kzg", @@ -8786,8 +8936,8 @@ dependencies = [ [[package]] name = "scroll-zkvm-types-bundle" -version = "0.8.0" -source = "git+https://github.com/scroll-tech/zkvm-prover?rev=ed3b964#ed3b964c8d0e93856b089d880ad2eda7e08fb7b4" +version = "0.9.0" +source = "git+https://github.com/scroll-tech/zkvm-prover?tag=v0.9.0#bf8494e57828bc449e9582ca6f97b53bd9b6eaf1" dependencies = [ "scroll-zkvm-types-base", "serde", @@ -8795,20 +8945,20 @@ dependencies = [ [[package]] name = "scroll-zkvm-types-chunk" -version = "0.8.0" -source = "git+https://github.com/scroll-tech/zkvm-prover?rev=ed3b964#ed3b964c8d0e93856b089d880ad2eda7e08fb7b4" +version = "0.9.0" +source = "git+https://github.com/scroll-tech/zkvm-prover?tag=v0.9.0#bf8494e57828bc449e9582ca6f97b53bd9b6eaf1" dependencies = [ "alloy-consensus", "alloy-primitives", "alloy-sol-types", "ecies", - "hex-literal", + "hex-literal 0.4.1", "itertools 0.14.0", - "k256 0.13.4 (git+https://github.com/openvm-org/openvm.git?tag=v1.6.0)", + "k256 0.13.4 (git+https://github.com/openvm-org/openvm.git?tag=v2.0.0)", "openvm-ecc-guest", "openvm-pairing", "openvm-sha2", - "p256 0.13.2 (git+https://github.com/openvm-org/openvm.git?tag=v1.6.0)", + "p256 0.13.2 (git+https://github.com/openvm-org/openvm.git?tag=v2.0.0)", "sbv-core", "sbv-helpers", "sbv-primitives", @@ -8820,15 +8970,18 @@ dependencies = [ [[package]] name = "scroll-zkvm-verifier" -version = "0.8.0" -source = "git+https://github.com/scroll-tech/zkvm-prover?rev=ed3b964#ed3b964c8d0e93856b089d880ad2eda7e08fb7b4" +version = "0.9.0" +source = "git+https://github.com/scroll-tech/zkvm-prover?tag=v0.9.0#bf8494e57828bc449e9582ca6f97b53bd9b6eaf1" dependencies = [ "bincode 1.3.3", "eyre", "once_cell", + "openvm-circuit", "openvm-continuations", - "openvm-native-recursion", "openvm-sdk", + "openvm-stark-sdk", + "openvm-static-verifier", + "openvm-verify-stark-host", "scroll-zkvm-types", "serde", "serde_json", @@ -8899,7 +9052,7 @@ version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "core-foundation 0.10.1", "core-foundation-sys", "libc", @@ -8999,14 +9152,14 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] name = "serde_json" -version = "1.0.149" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" dependencies = [ "indexmap 2.14.0", "itoa", @@ -9024,7 +9177,7 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -9061,9 +9214,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.20.0" +version = "3.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e72c1c2cb7b223fafb600a619537a871c2818583d619401b785e7c0b746ccde2" +checksum = "76a5c54c7310e7b8b9577c286d7e399ddd876c3e12b3ed917a8aabc4b96e9e8c" dependencies = [ "base64", "bs58", @@ -9081,14 +9234,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.20.0" +version = "3.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b90c488738ecb4fb0262f41f43bc40efc5868d9fb744319ddf5f5317f417bfac" +checksum = "84d57bc0c8b9a17920c178daa6bb924850d54a9c97ab45194bb8c17ad66bb660" dependencies = [ "darling 0.23.0", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -9150,9 +9303,9 @@ dependencies = [ [[package]] name = "sha3-asm" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f3f15d4e239ebe08413eed880e0f9b5af4b40ee0472543320efa91d488e96a7" +checksum = "a6287fd675f713484342a89cbf0a386abef5f15919cfad607e5e1f19e1e15331" dependencies = [ "cc", "cfg-if", @@ -9173,6 +9326,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + [[package]] name = "signature" version = "2.2.0" @@ -9231,9 +9390,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.15.1" +version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" dependencies = [ "serde", ] @@ -9246,9 +9405,8 @@ checksum = "1b6b67fb9a61334225b5b790716f609cd58395f895b3fe8b328786812a40bc3b" [[package]] name = "snark-verifier" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d798d8ce8e29b8820ecc1028ac44cc4fc0f0296728af6fe6a0c4db05782c0a4" +version = "0.2.6" +source = "git+https://github.com/axiom-crypto/snark-verifier.git?tag=v0.2.6#364e82654c746b063aff528d8cb660890908278a" dependencies = [ "halo2-base", "halo2-ecc", @@ -9260,7 +9418,7 @@ dependencies = [ "num-traits", "pairing 0.23.0", "rand 0.8.6", - "revm 22.0.1", + "revm 27.1.0", "ruint", "serde", "sha3", @@ -9268,9 +9426,8 @@ dependencies = [ [[package]] name = "snark-verifier-sdk" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a338d065044702bf751e87cf353daac63e2fc4c53a3e323cbcd98c603ee6e66c" +version = "0.2.6" +source = "git+https://github.com/axiom-crypto/snark-verifier.git?tag=v0.2.6#364e82654c746b063aff528d8cb660890908278a" dependencies = [ "ark-std 0.3.0", "bincode 1.3.3", @@ -9292,9 +9449,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" dependencies = [ "libc", "windows-sys 0.61.2", @@ -9362,6 +9519,26 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "struct-reflection" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "701b671d1ad68e250e05718f95dae3014a17f4e69cbe51842531c30495ff3301" +dependencies = [ + "struct-reflection-derive", +] + +[[package]] +name = "struct-reflection-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ab74230a0592602e361bd63c645413fa8cbe4500d10274e849179e5c72548f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + [[package]] name = "strum" version = "0.24.1" @@ -9418,7 +9595,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -9431,7 +9608,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -9443,7 +9620,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -9465,9 +9642,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.117" +version = "2.0.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" dependencies = [ "proc-macro2", "quote", @@ -9483,7 +9660,7 @@ dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -9503,7 +9680,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -9512,7 +9689,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "core-foundation 0.9.4", "system-configuration-sys", ] @@ -9540,7 +9717,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.4.2", + "getrandom 0.4.3", "once_cell", "rustix", "windows-sys 0.61.2", @@ -9564,7 +9741,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -9575,7 +9752,7 @@ checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", "test-case-core", ] @@ -9605,7 +9782,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -9616,14 +9793,14 @@ checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] name = "thread_local" -version = "1.1.9" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +checksum = "1ad99c4c6d32803332c548b1af0540b357b3f5fc0be8f6c6bfe8b2e6ae784070" dependencies = [ "cfg-if", ] @@ -9637,14 +9814,33 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "tikv-jemalloc-sys" +version = "0.6.1+5.3.0-1-ge13ca993e8ccb9ba9847cc330696e02839f328f7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd8aa5b2ab86a2cefa406d889139c162cbb230092f7d1d7cbc1716405d852a3b" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "tikv-jemallocator" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0359b4327f954e0567e69fb191cf1436617748813819c94b8cd4a431422d053a" +dependencies = [ + "libc", + "tikv-jemalloc-sys", +] + [[package]] name = "time" -version = "0.3.47" +version = "0.3.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" +checksum = "18dfaaeddcb932337b5e7866ee7d0ce9b76d2fd092997146f187ec09b4558a50" dependencies = [ "deranged", - "itoa", "num-conv", "powerfmt", "serde_core", @@ -9654,15 +9850,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" +checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" [[package]] name = "time-macros" -version = "0.2.27" +version = "0.2.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" +checksum = "c431b87111666e491a90baa837f914fb45cd5dc3c268591b0220ff5057f2085f" dependencies = [ "num-conv", "time-core", @@ -9689,9 +9885,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" +checksum = "bb4ebadaa0af04fab11ae01eb5f9fdb5f9c5b875506e210e71c07873528baa7f" dependencies = [ "tinyvec_macros", ] @@ -9725,7 +9921,7 @@ checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -9830,9 +10026,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.25.11+spec-1.1.0" +version = "0.25.12+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b" +checksum = "d2153edc6955a6c354fad8f5efd38b6a8769bdccf9fe50f8e1329f81b0baa5d7" dependencies = [ "indexmap 2.14.0", "toml_datetime 1.1.1+spec-1.1.0", @@ -9877,7 +10073,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" dependencies = [ "async-compression", - "bitflags 2.11.1", + "bitflags 2.13.0", "bytes", "futures-core", "futures-util", @@ -9924,7 +10120,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -10037,9 +10233,9 @@ checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" [[package]] name = "typenum" -version = "1.20.0" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" [[package]] name = "typewit" @@ -10079,9 +10275,9 @@ checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "unicode-segmentation" -version = "1.13.2" +version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" +checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" [[package]] name = "unicode-xid" @@ -10148,9 +10344,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.23.1" +version = "1.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76" +checksum = "bf80a72845275afea99e7f2b434723d3bc7e38470fcd1c7ed39a599c73319a53" dependencies = [ "js-sys", "wasm-bindgen", @@ -10219,27 +10415,18 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.3+wasi-0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" -dependencies = [ - "wit-bindgen 0.57.1", -] - -[[package]] -name = "wasip3" -version = "0.4.0+wasi-0.3.0-rc-2026-01-06" +version = "1.0.4+wasi-0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" dependencies = [ - "wit-bindgen 0.51.0", + "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.121" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49ace1d07c165b0864824eee619580c4689389afa9dc9ed3a4c75040d82e6790" +checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" dependencies = [ "cfg-if", "once_cell", @@ -10250,9 +10437,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.71" +version = "0.4.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96492d0d3ffba25305a7dc88720d250b1401d7edca02cc3bcd50633b424673b8" +checksum = "c62df1340f32221cb9c54d6a27b030e3dba64361d4a95bed55f9aacb44da291d" dependencies = [ "js-sys", "wasm-bindgen", @@ -10260,9 +10447,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.121" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e68e6f4afd367a562002c05637acb8578ff2dea1943df76afb9e83d177c8578" +checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -10270,48 +10457,26 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.121" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d95a9ec35c64b2a7cb35d3fead40c4238d0940c86d107136999567a4703259f2" +checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.121" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4e0100b01e9f0d03189a92b96772a1fb998639d981193d7dbab487302513441" +checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" 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", -] - -[[package]] -name = "wasm-metadata" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" -dependencies = [ - "anyhow", - "indexmap 2.14.0", - "wasm-encoder", - "wasmparser", -] - [[package]] name = "wasm-streams" version = "0.4.2" @@ -10340,18 +10505,6 @@ dependencies = [ "web-sys", ] -[[package]] -name = "wasmparser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" -dependencies = [ - "bitflags 2.11.1", - "hashbrown 0.15.5", - "indexmap 2.14.0", - "semver 1.0.28", -] - [[package]] name = "wasmtimer" version = "0.4.3" @@ -10368,9 +10521,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.98" +version = "0.3.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b572dff8bcf38bad0fa19729c89bb5748b2b9b1d8be70cf90df697e3a8f32aa" +checksum = "8622dcb61c0bcc9fffa6938bed81210af2da9a7e4a1a834b2e37a59b6dfb6141" dependencies = [ "js-sys", "wasm-bindgen", @@ -10388,9 +10541,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52f5ee44c96cf55f1b349600768e3ece3a8f26010c05265ab73f945bb1a2eb9d" +checksum = "bf85cb06032201fa7c6f829d7db5a7e5aa45bcc0655327713065f6f0576731bf" dependencies = [ "rustls-pki-types", ] @@ -10438,7 +10591,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -10449,7 +10602,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -10493,7 +10646,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -10502,16 +10655,7 @@ 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", + "windows-targets", ] [[package]] @@ -10529,31 +10673,14 @@ 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", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] [[package]] @@ -10562,96 +10689,48 @@ 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.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.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.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.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.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.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" @@ -10679,100 +10758,12 @@ dependencies = [ "memchr", ] -[[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" version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" -[[package]] -name = "wit-bindgen-core" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" -dependencies = [ - "anyhow", - "heck 0.5.0", - "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 0.5.0", - "indexmap 2.14.0", - "prettyplease", - "syn 2.0.117", - "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.117", - "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.11.1", - "indexmap 2.14.0", - "log", - "serde", - "serde_derive", - "serde_json", - "wasm-encoder", - "wasm-metadata", - "wasmparser", - "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.14.0", - "log", - "semver 1.0.28", - "serde", - "serde_derive", - "serde_json", - "unicode-xid", - "wasmparser", -] - [[package]] name = "writeable" version = "0.6.3" @@ -10790,9 +10781,9 @@ dependencies = [ [[package]] name = "yoke" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" +checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" dependencies = [ "stable_deref_trait", "yoke-derive", @@ -10807,28 +10798,28 @@ checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", "synstructure", ] [[package]] name = "zerocopy" -version = "0.8.48" +version = "0.8.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" +checksum = "b7cbbc0a705a0fd05cc3676525980d2bf5a9bc4adac6d6475209a7887cf59d19" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.48" +version = "0.8.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" +checksum = "e2e817b7b52d0c7358d3246da9d69935ebb18116b2b102b4230dac079b4862f5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -10848,28 +10839,28 @@ checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", "synstructure", ] [[package]] name = "zeroize" -version = "1.8.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" dependencies = [ "zeroize_derive", ] [[package]] name = "zeroize_derive" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" +checksum = "3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -10902,13 +10893,14 @@ checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] -name = "zkhash" +name = "zkhash-axiom" version = "0.2.0" -source = "git+https://github.com/HorizenLabs/poseidon2.git?rev=bb476b9#bb476b9ca38198cf5092487283c8b8c5d4317c4e" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d038a7895d0e3ab0a352f53e7eb4f1f829f88fce2fb3cff93d665a8a0e01af6" dependencies = [ "ark-ff 0.4.2", "ark-std 0.4.0", diff --git a/Cargo.toml b/Cargo.toml index 3bd50a362a..0775ab855b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,9 +17,9 @@ repository = "https://github.com/scroll-tech/scroll" version = "4.7.12" [workspace.dependencies] -scroll-zkvm-prover = { git = "https://github.com/scroll-tech/zkvm-prover", rev = "ed3b964" } -scroll-zkvm-verifier = { git = "https://github.com/scroll-tech/zkvm-prover", rev = "ed3b964" } -scroll-zkvm-types = { git = "https://github.com/scroll-tech/zkvm-prover", rev = "ed3b964" } +scroll-zkvm-prover = { git = "https://github.com/scroll-tech/zkvm-prover", tag = "v0.9.0" } +scroll-zkvm-verifier = { git = "https://github.com/scroll-tech/zkvm-prover", tag = "v0.9.0" } +scroll-zkvm-types = { git = "https://github.com/scroll-tech/zkvm-prover", tag = "v0.9.0" } sbv-primitives = { git = "https://github.com/scroll-tech/stateless-block-verifier", tag = "scroll-v91.2", features = ["scroll", "rkyv"] } sbv-utils = { git = "https://github.com/scroll-tech/stateless-block-verifier", tag = "scroll-v91.2" } diff --git a/common/types/message/message.go b/common/types/message/message.go index 7b35d362d8..f32f8daa69 100644 --- a/common/types/message/message.go +++ b/common/types/message/message.go @@ -165,8 +165,15 @@ type OpenVMProofStat struct { // Proof for flatten VM proof type OpenVMProof struct { + Proof []byte `json:"proofs"` + PublicValues []byte `json:"public_values"` +} + +// Proof for flatten VM stark proof (v0.9.0+) +type OpenVMStarkProof struct { Proof []byte `json:"proofs"` PublicValues []byte `json:"public_values"` + UserPvsProof []byte `json:"user_pvs_proof"` Stat *OpenVMProofStat `json:"stat,omitempty"` } @@ -183,13 +190,13 @@ type OpenVMChunkProof struct { TotalGasUsed uint64 `json:"chunk_total_gas"` } `json:"metadata"` - VmProof *OpenVMProof `json:"proof"` - Vk []byte `json:"vk,omitempty"` - GitVersion string `json:"git_version,omitempty"` + StarkProof *OpenVMStarkProof `json:"proof"` + Vk []byte `json:"vk,omitempty"` + GitVersion string `json:"git_version,omitempty"` } func (p *OpenVMChunkProof) Proof() []byte { - proofJson, err := json.Marshal(p.VmProof) + proofJson, err := json.Marshal(p.StarkProof) if err != nil { panic(fmt.Sprint("marshaling error", err)) } @@ -217,13 +224,13 @@ type OpenVMBatchProof struct { BatchHash common.Hash `json:"batch_hash"` } `json:"metadata"` - VmProof *OpenVMProof `json:"proof"` - Vk []byte `json:"vk,omitempty"` - GitVersion string `json:"git_version,omitempty"` + StarkProof *OpenVMStarkProof `json:"proof"` + Vk []byte `json:"vk,omitempty"` + GitVersion string `json:"git_version,omitempty"` } func (p *OpenVMBatchProof) Proof() []byte { - proofJson, err := json.Marshal(p.VmProof) + proofJson, err := json.Marshal(p.StarkProof) if err != nil { panic(fmt.Sprint("marshaling error", err)) } @@ -240,13 +247,13 @@ func (ap *OpenVMBatchProof) SanityCheck() error { return errors.New("batch info not ready") } - if ap.VmProof == nil { + if ap.StarkProof == nil { return errors.New("proof not ready") } else { if len(ap.Vk) == 0 { return errors.New("vk not ready") } - pf := ap.VmProof + pf := ap.StarkProof if pf.Proof == nil { return errors.New("proof data not ready") } diff --git a/coordinator/internal/logic/submitproof/proof_receiver.go b/coordinator/internal/logic/submitproof/proof_receiver.go index e9d4c5abe5..5c4b51d03f 100644 --- a/coordinator/internal/logic/submitproof/proof_receiver.go +++ b/coordinator/internal/logic/submitproof/proof_receiver.go @@ -232,7 +232,7 @@ func (m *ProofReceiverLogic) HandleZkProof(ctx *gin.Context, proofParameter coor return unmarshalErr } success, verifyErr = m.verifier.VerifyChunkProof(chunkProof, hardForkName) - if stat := chunkProof.VmProof.Stat; stat != nil { + if stat := chunkProof.StarkProof.Stat; stat != nil { if g, _ := m.proverSpeed.GetMetricWithLabelValues("chunk", "exec"); g != nil && stat.ExecutionTimeMills > 0 { g.Set(float64(stat.TotalCycle) / float64(stat.ExecutionTimeMills*1000)) } @@ -252,7 +252,7 @@ func (m *ProofReceiverLogic) HandleZkProof(ctx *gin.Context, proofParameter coor return unmarshalErr } success, verifyErr = m.verifier.VerifyBatchProof(batchProof, hardForkName) - if stat := batchProof.VmProof.Stat; stat != nil { + if stat := batchProof.StarkProof.Stat; stat != nil { if g, _ := m.proverSpeed.GetMetricWithLabelValues("batch", "exec"); g != nil && stat.ExecutionTimeMills > 0 { g.Set(float64(stat.TotalCycle) / float64(stat.ExecutionTimeMills*1000)) } diff --git a/coordinator/internal/logic/verifier/mock.go b/coordinator/internal/logic/verifier/mock.go index a79ed8d8fc..9e602aa44f 100644 --- a/coordinator/internal/logic/verifier/mock.go +++ b/coordinator/internal/logic/verifier/mock.go @@ -21,7 +21,7 @@ func NewVerifier(cfg *config.VerifierConfig, _ bool) (*Verifier, error) { // VerifyChunkProof return a mock verification result for a ChunkProof. func (v *Verifier) VerifyChunkProof(proof *message.OpenVMChunkProof, forkName string) (bool, error) { - if proof.VmProof != nil && string(proof.VmProof.Proof) == InvalidTestProof { + if proof.StarkProof != nil && string(proof.StarkProof.Proof) == InvalidTestProof { return false, nil } return true, nil @@ -29,7 +29,7 @@ func (v *Verifier) VerifyChunkProof(proof *message.OpenVMChunkProof, forkName st // VerifyBatchProof return a mock verification result for a BatchProof. func (v *Verifier) VerifyBatchProof(proof *message.OpenVMBatchProof, forkName string) (bool, error) { - if proof.VmProof != nil && string(proof.VmProof.Proof) == InvalidTestProof { + if proof.StarkProof != nil && string(proof.StarkProof.Proof) == InvalidTestProof { return false, nil } return true, nil diff --git a/coordinator/test/api_test.go b/coordinator/test/api_test.go index 9fc303d760..68ad38f392 100644 --- a/coordinator/test/api_test.go +++ b/coordinator/test/api_test.go @@ -687,7 +687,7 @@ func testTimeoutProof(t *testing.T) { assert.NoError(t, err) err = chunkOrm.UpdateBatchHashInRange(context.Background(), 0, 100, batch.Hash) assert.NoError(t, err) - encodeData, err := json.Marshal(message.OpenVMChunkProof{VmProof: &message.OpenVMProof{}, MetaData: struct { + encodeData, err := json.Marshal(message.OpenVMChunkProof{StarkProof: &message.OpenVMStarkProof{}, MetaData: struct { ChunkInfo *message.ChunkInfo `json:"chunk_info"` TotalGasUsed uint64 `json:"chunk_total_gas"` }{ChunkInfo: &message.ChunkInfo{}}}) diff --git a/coordinator/test/mock_prover.go b/coordinator/test/mock_prover.go index 913344e856..d2c29946ec 100644 --- a/coordinator/test/mock_prover.go +++ b/coordinator/test/mock_prover.go @@ -229,7 +229,7 @@ func (r *mockProver) submitProof(t *testing.T, proverTaskSchema *types.GetTaskSc case message.ProofTypeChunk: fallthrough case message.ProofTypeBatch: - encodeData, err := json.Marshal(&message.OpenVMProof{}) + encodeData, err := json.Marshal(&message.OpenVMStarkProof{}) assert.NoError(t, err) assert.NotEmpty(t, encodeData) proof = encodeData @@ -245,7 +245,7 @@ func (r *mockProver) submitProof(t *testing.T, proverTaskSchema *types.GetTaskSc case message.ProofTypeChunk: fallthrough case message.ProofTypeBatch: - encodeData, err := json.Marshal(&message.OpenVMProof{Proof: []byte(verifier.InvalidTestProof)}) + encodeData, err := json.Marshal(&message.OpenVMStarkProof{Proof: []byte(verifier.InvalidTestProof), UserPvsProof: []byte{0x01}}) assert.NoError(t, err) assert.NotEmpty(t, encodeData) proof = encodeData diff --git a/crates/libzkp/Cargo.toml b/crates/libzkp/Cargo.toml index d673efc9f0..abafd17a2b 100644 --- a/crates/libzkp/Cargo.toml +++ b/crates/libzkp/Cargo.toml @@ -7,6 +7,8 @@ edition.workspace = true [dependencies] scroll-zkvm-types = { workspace = true, features = ["scroll"] } scroll-zkvm-verifier.workspace = true +openvm-sdk = { git = "https://github.com/openvm-org/openvm.git", tag = "v2.0.0" } +openvm-stark-sdk = { git = "https://github.com/openvm-org/stark-backend.git", tag = "v2.0.0" } alloy-primitives.workspace = true #depress the effect of "native-keccak" sbv-primitives = {workspace = true, features = ["scroll-compress-info", "scroll"]} diff --git a/crates/libzkp/src/lib.rs b/crates/libzkp/src/lib.rs index f808cf7cad..8351b8723a 100644 --- a/crates/libzkp/src/lib.rs +++ b/crates/libzkp/src/lib.rs @@ -55,43 +55,8 @@ pub fn checkout_chunk_task( /// Convert the universal task json into compatible form for old prover pub fn univ_task_compatibility_fix(task_json: &str) -> eyre::Result { - use scroll_zkvm_types::proof::VmInternalStarkProof; - - let task: tasks::ProvingTask = serde_json::from_str(task_json)?; - let aggregated_proofs: Vec = task - .aggregated_proofs - .into_iter() - .map(|proof| VmInternalStarkProof { - proofs: proof.proofs, - public_values: proof.public_values, - }) - .collect(); - - #[derive(Serialize)] - struct CompatibleProvingTask { - /// seralized witness which should be written into stdin first - pub serialized_witness: Vec>, - /// aggregated proof carried by babybear fields, should be written into stdin - /// followed `serialized_witness` - pub aggregated_proofs: Vec, - /// Fork name specify - pub fork_name: String, - /// The vk of app which is expcted to prove this task - pub vk: Vec, - /// An identifier assigned by coordinator, it should be kept identify for the - /// same task (for example, using chunk, batch and bundle hashes) - pub identifier: String, - } - - let compatible_u_task = CompatibleProvingTask { - serialized_witness: task.serialized_witness, - aggregated_proofs, - fork_name: task.fork_name, - vk: task.vk, - identifier: task.identifier, - }; - - Ok(serde_json::to_string(&compatible_u_task)?) + // v0.9.0+ provers consume the new ProvingTask format directly; no translation needed. + Ok(task_json.to_string()) } /// Generate required staff for proving tasks diff --git a/crates/libzkp/src/tasks/batch.rs b/crates/libzkp/src/tasks/batch.rs index 9d36d1f01f..46ba7cd516 100644 --- a/crates/libzkp/src/tasks/batch.rs +++ b/crates/libzkp/src/tasks/batch.rs @@ -131,6 +131,7 @@ impl BatchProvingTask { .collect(), serialized_witness: vec![serialized_witness], vk: Vec::new(), + input_commits: Vec::new(), }; Ok((proving_task, metadata, batch_pi_hash)) diff --git a/crates/libzkp/src/tasks/bundle.rs b/crates/libzkp/src/tasks/bundle.rs index e1b9aca6a0..abd75aef11 100644 --- a/crates/libzkp/src/tasks/bundle.rs +++ b/crates/libzkp/src/tasks/bundle.rs @@ -38,6 +38,7 @@ impl BundleProvingTask { .collect(), serialized_witness: vec![serialized_witness], vk: Vec::new(), + input_commits: Vec::new(), }; Ok((proving_task, bundle_info, bundle_pi_hash)) diff --git a/crates/libzkp/src/tasks/chunk.rs b/crates/libzkp/src/tasks/chunk.rs index 863f080bef..5cf8059403 100644 --- a/crates/libzkp/src/tasks/chunk.rs +++ b/crates/libzkp/src/tasks/chunk.rs @@ -124,6 +124,7 @@ impl ChunkProvingTask { aggregated_proofs: Vec::new(), serialized_witness: vec![serialized_witness], vk: Vec::new(), + input_commits: Vec::new(), }; Ok((proving_task, chunk_info, chunk_pi_hash)) diff --git a/crates/libzkp/src/verifier/universal.rs b/crates/libzkp/src/verifier/universal.rs index e50fe16f40..b9e8c0c9f6 100644 --- a/crates/libzkp/src/verifier/universal.rs +++ b/crates/libzkp/src/verifier/universal.rs @@ -6,12 +6,16 @@ use crate::{ proofs::{AsRootProof, BatchProof, BundleProof, ChunkProof, IntoEvmProof}, utils::panic_catch, }; +use openvm_sdk::SC; use scroll_zkvm_types::version::Version; use scroll_zkvm_verifier::verifier::UniversalVerifier; use std::path::Path; pub struct Verifier { verifier: UniversalVerifier, + /// Deferral-enabled root verifier VK for batch proofs (v0.9.0+). + /// Loaded from `batch_root_verifier_vk` if present in the assets directory. + batch_mvk: Option>, version: Version, } @@ -19,8 +23,22 @@ impl Verifier { pub fn new(assets_dir: &str, ver_n: u8) -> Self { let verifier_bin = Path::new(assets_dir); + let verifier = + UniversalVerifier::setup(verifier_bin).expect("Setting up universal verifier"); + + let batch_mvk_path = verifier_bin.join("batch_root_verifier_vk"); + let batch_mvk = if batch_mvk_path.exists() { + Some( + openvm_sdk::fs::read_object_from_file(&batch_mvk_path) + .expect("Reading batch root verifier vk"), + ) + } else { + None + }; + Self { - verifier: UniversalVerifier::setup(verifier_bin).expect("Setting up chunk verifier"), + verifier, + batch_mvk, version: Version::from(ver_n), } } @@ -39,16 +57,23 @@ impl ProofVerifier for Verifier { TaskType::Batch => { let proof = serde_json::from_slice::(proof).unwrap(); assert!(proof.pi_hash_check(self.version)); - self.verifier - .verify_stark_proof(proof.as_root_proof(), &proof.vk) - .unwrap() + let mvk = self + .batch_mvk + .as_ref() + .expect("batch_root_verifier_vk missing from assets"); + UniversalVerifier::verify_stark_proof_with_vk( + mvk, + proof.as_root_proof(), + &proof.vk, + ) + .unwrap() } TaskType::Bundle => { let proof = serde_json::from_slice::(proof).unwrap(); assert!(proof.pi_hash_check(self.version)); let vk = proof.vk.clone(); let evm_proof = proof.into_evm_proof(); - self.verifier.verify_evm_proof(&evm_proof, &vk).unwrap() + self.verifier.verify_evm_proof(&evm_proof, &vk).unwrap(); } }) .map(|_| true) diff --git a/crates/prover-bin/src/dumper.rs b/crates/prover-bin/src/dumper.rs index c8360384c0..0bc0c6e796 100644 --- a/crates/prover-bin/src/dumper.rs +++ b/crates/prover-bin/src/dumper.rs @@ -39,7 +39,7 @@ impl Dumper { let mut agg_writer = std::io::BufWriter::new(agg_file); for proof in &task.aggregated_proofs { let sz = bincode::serde::encode_into_std_write( - &proof.proofs, + &proof.proof, &mut agg_writer, bincode::config::standard(), )?; diff --git a/crates/prover-bin/src/prover.rs b/crates/prover-bin/src/prover.rs index 7fac8419f6..2264563518 100644 --- a/crates/prover-bin/src/prover.rs +++ b/crates/prover-bin/src/prover.rs @@ -191,6 +191,10 @@ pub struct CircuitConfig { /// cached vk value to save some initial cost, for debugging only #[serde(default)] pub vks: HashMap, + /// Child circuit VKs used to enable OpenVM deferral for aggregation tasks. + /// Required for batch (child=chunk) and bundle (child=batch) proving in v0.9.0+. + #[serde(default)] + pub child_circuit_vks: HashMap, } pub struct LocalProver { @@ -198,7 +202,7 @@ pub struct LocalProver { next_task_id: u64, current_task: Option>>, - handlers: HashMap>, + handlers: HashMap>>, } #[async_trait] @@ -325,39 +329,44 @@ impl LocalProver { } let prover_task: ProvingTask = prover_task.into(); let vk = hex::encode(&prover_task.vk); - let handler = if let Some(handler) = self.handlers.get(&vk) { - handler.clone() - } else { - let base_config = self + + let parent_handler = self + .get_or_load_handler(&req.hard_fork_name, req.proof_type, &vk) + .await?; + + // OpenVM v2+ aggregation circuits (batch/bundle) need deferral enabled + // using their immediate child circuit's prover. + let child_proof_type = match req.proof_type { + ProofType::Batch => Some(ProofType::Chunk), + ProofType::Bundle => Some(ProofType::Batch), + _ => None, + }; + if let Some(child_type) = child_proof_type { + let child_vk = self .config .circuits .get(&req.hard_fork_name) + .and_then(|c| c.child_circuit_vks.get(&child_type)) .ok_or_else(|| { eyre::eyre!( - "coordinator sent unexpected forkname {}", + "missing child circuit vk for {:?} in fork {}", + child_type, req.hard_fork_name ) - })?; - let url_base = if let Some(url) = base_config.location_data.asset_detours.get(&vk) { - url.clone() - } else { - base_config - .location_data - .gen_asset_url(&vk, req.proof_type)? - }; - let asset_path = base_config - .location_data - .get_asset(&vk, &url_base, &base_config.workspace_path) + })? + .clone(); + let child_handler = self + .get_or_load_handler(&req.hard_fork_name, child_type, &child_vk) .await?; - let circuits_handler = Arc::new(Mutex::new(UniversalHandler::new(&asset_path)?)); - self.handlers.insert(vk, circuits_handler.clone()); - circuits_handler - }; + let mut parent_guard = parent_handler.lock().await; + let child_guard = child_handler.lock().await; + parent_guard.enable_deferral(&*child_guard)?; + } let handle = Handle::current(); let is_evm = req.proof_type == ProofType::Bundle; let task_handle = tokio::task::spawn_blocking(move || { - handle.block_on(handler.get_proof_data(&prover_task, is_evm)) + handle.block_on(parent_handler.get_proof_data(&prover_task, is_evm)) }); self.current_task = Some(task_handle); @@ -372,4 +381,34 @@ impl LocalProver { ..Default::default() }) } + + /// Load a handler for the given fork/proof-type/vk, reusing a cached one if available. + async fn get_or_load_handler( + &mut self, + fork_name: &str, + proof_type: ProofType, + vk: &str, + ) -> Result>> { + if let Some(handler) = self.handlers.get(vk) { + return Ok(handler.clone()); + } + + let base_config = self + .config + .circuits + .get(fork_name) + .ok_or_else(|| eyre::eyre!("coordinator sent unexpected forkname {}", fork_name))?; + let url_base = if let Some(url) = base_config.location_data.asset_detours.get(vk) { + url.clone() + } else { + base_config.location_data.gen_asset_url(vk, proof_type)? + }; + let asset_path = base_config + .location_data + .get_asset(vk, &url_base, &base_config.workspace_path) + .await?; + let handler = Arc::new(Mutex::new(UniversalHandler::new(&asset_path)?)); + self.handlers.insert(vk.to_string(), handler.clone()); + Ok(handler) + } } diff --git a/crates/prover-bin/src/zk_circuits_handler/universal.rs b/crates/prover-bin/src/zk_circuits_handler/universal.rs index e332092a8f..23ef6bf040 100644 --- a/crates/prover-bin/src/zk_circuits_handler/universal.rs +++ b/crates/prover-bin/src/zk_circuits_handler/universal.rs @@ -19,17 +19,24 @@ impl UniversalHandler { pub fn new(workspace_path: impl AsRef) -> Result { let path_app_exe = workspace_path.as_ref().join("app.vmexe"); let path_app_config = workspace_path.as_ref().join("openvm.toml"); - let segment_len = Some((1 << 22) - 100); let config = ProverConfig { path_app_config, path_app_exe, - segment_len, }; let prover = Prover::setup(config, None)?; Ok(Self { prover }) } + /// Enable OpenVM deferral using `child_prover` as the child circuit prover. + /// Required for batch (child=chunk) and bundle (child=batch) aggregation proofs. + pub fn enable_deferral(&mut self, child: &UniversalHandler) -> Result<()> { + self.prover + .enable_deferral(&child.prover) + .map_err(|e| eyre::eyre!("failed to enable deferral: {}", e))?; + Ok(()) + } + /// get_prover get the inner prover, later we would replace chunk/batch/bundle_prover with /// universal prover, before that, use bundle_prover as the represent one pub fn get_prover(&mut self) -> &mut Prover { diff --git a/docs/testing/single-chunk-reproving.md b/docs/testing/single-chunk-reproving.md new file mode 100644 index 0000000000..317f6b0e61 --- /dev/null +++ b/docs/testing/single-chunk-reproving.md @@ -0,0 +1,260 @@ +# Re-proving a Single Mainnet Chunk + +This guide describes how to re-prove one specific chunk that already exists in the mainnet production database, without running a full shadow fork or replaying an entire chain segment. + +Typical use cases: + +- A chunk was proven with an old guest / circuit version and the existing proof no longer validates against current verifier assets. +- You want to reproduce a mainnet chunk proof locally for debugging or verification. + +## High-level idea + +The mainnet DB user available to agents is **read-only**, so a local coordinator cannot update `proving_status` or insert `prover_task` records against mainnet RDS directly. The workaround is: + +1. Export the target `chunk` row and its `l2_block` rows from mainnet RDS. +2. Import them into the local **shadow DB** (`localhost:5433/shadow_rollup`), which is writable. +3. Run a temporary coordinator against the shadow DB but with **mainnet L2 RPC** and the production verifier assets. +4. Run the prover in `handle` mode pointing at that coordinator and request exactly the chunk hash. +5. Extract the new proof from the shadow DB, verify it independently, and save it. + +## Prerequisites + +- `psql` and access to both: + - Mainnet RDS via the local tunnel (`localhost:15432/mainnet_rollup`) + - Shadow Postgres (`localhost:5433/shadow_rollup`, writable) +- Built coordinator binary: `coordinator/build/bin/coordinator_api` +- Built prover binary: `target/release/prover` +- Verifier assets matching the current circuit version, e.g. `coordinator/build/bin/assets_v2` +- Cached circuit assets for the prover (the S3 `circuit-release` bucket may return 403 from this environment). Look for an existing `.work/galileo//` directory and copy it into the prover workspace. +- Mainnet genesis file, e.g. `tests/prover-e2e/mainnet-galileoV2/genesis.json` + +## Step-by-step + +### 1. Export the chunk and its blocks from mainnet + +Use `enable_seqscan = off` when querying `l2_block`; the table is huge and a plain `BETWEEN` scan can time out even with a partial index. + +```bash +EXPORT_DIR=/tmp/chunk-6641451-export +mkdir -p $EXPORT_DIR + +# chunk row +PGPASSWORD='' psql -h localhost -p 15432 \ + -U mainnet_infra_team_read_only -d mainnet_rollup -Atq \ + -c "COPY (SELECT * FROM chunk WHERE index = 6641451) TO STDOUT WITH CSV HEADER;" \ + > $EXPORT_DIR/chunk.csv + +# l2_block rows for the chunk's block range +PGPASSWORD='' psql -h localhost -p 15432 \ + -U mainnet_infra_team_read_only -d mainnet_rollup -Atq \ + -c " + SET enable_seqscan = off; + COPY ( + SELECT * FROM l2_block + WHERE number BETWEEN 34180693 AND 34180761 + AND deleted_at IS NULL + ) TO STDOUT WITH CSV HEADER; + " > $EXPORT_DIR/l2_blocks.csv +``` + +### 2. Import into the shadow DB + +```bash +PGPASSWORD='shadow_pass' psql -h localhost -p 5433 \ + -U postgres -d shadow_rollup \ + -f /dev/stdin < $EXPORT_DIR/handle-set.json <<'EOF' +{ + "chunks": [ + "0x90861ddc4e0effb030f59644b03c8bd80e0b2ca8632c8c3500a25029fe4f4081" + ], + "batches": [], + "bundles": [] +} +EOF +``` + +### 6. Configure the prover + +Key settings: + +- `coordinator.base_url`: `http://localhost:8390` +- `circuits.galileoV2.workspace_path`: directory containing the cached circuit assets +- `circuits.galileoV2.debug_mode`: `true` to skip S3 preflight / download (S3 may 403) +- `sdk_config.db_path`: separate from other prover runs + +Example: + +```json +{ + "sdk_config": { + "prover_name_prefix": "mainnet-reprove-chunk-6641451", + "keys_dir": "/tmp/chunk-6641451-export/prover-keys", + "coordinator": { + "base_url": "http://localhost:8390", + "retry_count": 10, + "retry_wait_time_sec": 10, + "connection_timeout_sec": 1800 + }, + "prover": { + "supported_proof_types": [1], + "circuit_version": "v0.13.1" + }, + "health_listener_addr": "127.0.0.1:10080", + "db_path": "/tmp/chunk-6641451-export/prover-db" + }, + "circuits": { + "galileoV2": { + "base_url": "https://circuit-release.s3.us-west-2.amazonaws.com/scroll-zkvm/releases/v0.9.0/", + "workspace_path": "/tmp/prover-multi-gpu/gpu0/.work/galileo", + "debug_mode": true + } + } +} +``` + +If circuit assets are not already in the workspace, copy them from an existing cache: + +```bash +mkdir -p /tmp/prover-multi-gpu/gpu0/.work/galileo +cp -r /home/scroll/zzhang/scroll/.work/galileo/64cf16439a284e4449666c479a3ae42b568fea5e88610777ff6b5f2cda19d91182a47957139d0d1c1c3fbb28b9579c23f2823c0c6ff05669fe71ad4a0c92620e \ + /tmp/prover-multi-gpu/gpu0/.work/galileo/ +``` + +### 7. Run the prover + +OpenVM proving can overflow the default Rust thread stack, so set `RUST_MIN_STACK`. Run with no timeout: + +```bash +cd /home/scroll/zzhang/scroll +RUST_MIN_STACK=33554432 ./target/release/prover \ + --config /tmp/chunk-6641451-export/prover-config.json \ + handle /tmp/chunk-6641451-export/handle-set.json +``` + +For a chunk of ~70 blocks, expect roughly 10–15 minutes on GPU. + +### 8. Extract, verify, and save the proof + +After the coordinator logs `proof verified and valid`, extract the proof from the shadow DB: + +```bash +PGPASSWORD='shadow_pass' psql -h localhost -p 5433 \ + -U postgres -d shadow_rollup -Atq \ + -c "SELECT encode(proof, 'hex') FROM chunk WHERE index = 6641451;" \ + > /tmp/chunk-6641451-export/new-proof.hex + +xxd -r -p /tmp/chunk-6641451-export/new-proof.hex > /tmp/chunk-6641451-export/new-proof.json + +# independent verification +cd coordinator/build/bin +LD_LIBRARY_PATH=../internal/logic/libzkp/lib:$LD_LIBRARY_PATH \ + ./coordinator_tool verify chunk /tmp/chunk-6641451-export/new-proof.json +``` + +Save the final proof to a clear location: + +```bash +cp /tmp/chunk-6641451-export/new-proof.json \ + /tmp/chunk-6641451/chunk_6641451_proof.json +``` + +## Common pitfalls + +| Symptom | Cause | Fix | +|---------|-------|-----| +| `cannot execute UPDATE in a read-only transaction` | Coordinator connected to mainnet RDS with read-only user | Use shadow DB for coordinator writes | +| `server closed the connection unexpectedly` on `localhost:15432` | Mainnet RDS tunnel (stunnel) is down or broken | Retry later or ask ops to restart the tunnel | +| `record not found, uuid:...` during proof submission | Coordinator was restarted/killed after assigning the task; `prover_task` record was lost or not committed | Keep coordinator alive for the entire proving session; use `disable_timeout=true` | +| Prover aborts with stack overflow | Default Rust thread stack too small for OpenVM | `RUST_MIN_STACK=33554432` | +| S3 403 on circuit asset URLs | Directory listings are blocked or bucket is not public | Copy cached circuit assets into the prover workspace and set `debug_mode: true` | +| Query on `l2_block` times out | Table is huge; planner may seq-scan | `SET enable_seqscan = off;` and include `deleted_at IS NULL` | + +## Cleanup + +Stop the temporary coordinator when done. The shadow DB still contains the imported mainnet chunk; delete it if you no longer need it: + +```bash +PGPASSWORD='shadow_pass' psql -h localhost -p 5433 \ + -U postgres -d shadow_rollup -Atq -c " + DELETE FROM l2_block WHERE number BETWEEN 34180693 AND 34180761; + DELETE FROM chunk WHERE index = 6641451; + " +``` diff --git a/rust-toolchain b/rust-toolchain index c17a78fd9e..fd7eda1132 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-08-18" +channel = "nightly-2025-11-20" targets = ["riscv32im-unknown-none-elf", "x86_64-unknown-linux-gnu"] -components = ["llvm-tools", "rustc-dev"] \ No newline at end of file +components = ["llvm-tools", "rust-src"] \ No newline at end of file diff --git a/tests/prover-e2e/cloak-galileoV2/.make.env b/tests/prover-e2e/cloak-galileoV2/.make.env index 75ffd1e544..adb4711f97 100644 --- a/tests/prover-e2e/cloak-galileoV2/.make.env +++ b/tests/prover-e2e/cloak-galileoV2/.make.env @@ -1,4 +1,4 @@ BEGIN_BLOCK?=33750000 END_BLOCK?=33750005 SCROLL_FORK_NAME=galileoV2 -SCROLL_ZKVM_VERSION?=v0.8.0 \ No newline at end of file +SCROLL_ZKVM_VERSION?=releases/v0.9.0 \ No newline at end of file diff --git a/tests/prover-e2e/docker-e2e/conf/prover.json b/tests/prover-e2e/docker-e2e/conf/prover.json index 241b61adc1..2f9be1ef95 100644 --- a/tests/prover-e2e/docker-e2e/conf/prover.json +++ b/tests/prover-e2e/docker-e2e/conf/prover.json @@ -17,7 +17,7 @@ }, "circuits": { "galileoV2": { - "base_url": "https://circuit-release.s3.us-west-2.amazonaws.com/scroll-zkvm/galileov2/", + "base_url": "https://circuit-release.s3.us-west-2.amazonaws.com/scroll-zkvm/releases/v0.9.0/", "workspace_path": ".work/galileo" } } diff --git a/tests/prover-e2e/mainnet-galileoV2/.make.env b/tests/prover-e2e/mainnet-galileoV2/.make.env index c7f03a5a33..525b337cb5 100644 --- a/tests/prover-e2e/mainnet-galileoV2/.make.env +++ b/tests/prover-e2e/mainnet-galileoV2/.make.env @@ -5,4 +5,4 @@ BEGIN_BLOCK?=33750000 END_BLOCK?=33750005 SCROLL_FORK_NAME=galileoV2 -SCROLL_ZKVM_VERSION?=v0.8.0 +SCROLL_ZKVM_VERSION?=releases/v0.9.0 diff --git a/tests/shadow-testing/.env.example b/tests/shadow-testing/.env.example new file mode 100644 index 0000000000..3a44df2cc2 --- /dev/null +++ b/tests/shadow-testing/.env.example @@ -0,0 +1,57 @@ +# Shadow Coordinator + Prover Environment Variables +# Copy this file to .env and fill in real values + +# ============================================================================ +# PRODUCTION RDS (read-only, via IDC port-forward) +# ============================================================================ +PROD_DB_HOST=localhost +PROD_DB_PORT=15432 +PROD_DB_NAME=rollup +PROD_DB_USER=YOUR_PROD_USER_HERE +PROD_DB_PASSWORD=YOUR_PROD_PASSWORD_HERE + +# Full DSN (constructed from above, or override directly) +# PROD_DB=postgresql://YOUR_PROD_USER_HERE:YOUR_PROD_PASSWORD_HERE@localhost:15432/rollup + +# ============================================================================ +# SHADOW DATABASE (local PostgreSQL in Docker) +# ============================================================================ +SHADOW_DB_HOST=localhost +SHADOW_DB_PORT=5433 +SHADOW_DB_NAME=shadow_rollup +SHADOW_DB_USER=postgres +SHADOW_DB_PASSWORD=YOUR_SHADOW_PASSWORD_HERE + +# Full DSN (constructed from above, or override directly) +# SHADOW_DB=postgresql://postgres:YOUR_SHADOW_PASSWORD_HERE@localhost:5433/shadow_rollup + +# ============================================================================ +# COORDINATOR AUTH +# ============================================================================ +# JWT secret for prover login challenge-response. +# MUST match between coordinator config and prover expectations. +COORDINATOR_AUTH_SECRET=YOUR_RANDOM_SECRET_HERE + +# ============================================================================ +# DOCKER IMAGE TAG +# ============================================================================ +IMAGE_TAG=v4.7.13-openvm16 + +# ============================================================================ +# L2 RPC ENDPOINT +# Must support debug_executionWitness and debug_dbGet. +# https://mainnet-rpc.scroll.io works; https://rpc.scroll.io does NOT. +# ============================================================================ +L2_RPC=https://mainnet-rpc.scroll.io + +# ============================================================================ +# VERIFIER ASSETS PATH +# Directory containing subdirectories: openvm-0.5.6, openvm-v0.7.1, openvm-v0.8.0 +# ============================================================================ +VERIFIER_DIR=/tmp/shadow-verifier-assets + +# ============================================================================ +# DATA IMPORT LIMITS +# ============================================================================ +BATCH_LIMIT=50 +BUNDLE_LIMIT=20000 diff --git a/tests/shadow-testing/.gitignore b/tests/shadow-testing/.gitignore new file mode 100644 index 0000000000..1977096c6c --- /dev/null +++ b/tests/shadow-testing/.gitignore @@ -0,0 +1,21 @@ +# Work directory (logs, pid files, generated configs) +.work/ + +# Anvil state files (large, environment-specific) +states/*.json + +# Generated configs (from templates) +.work/*.json + +# Prover work directories +.work/prover-*/ + +# Relayer logs +.work/relayer-*.log + +# Coordinator logs +.work/coordinator-*.log + +# Actual config files with secrets (use .template files instead) +configs/*.json +__pycache__/ diff --git a/tests/shadow-testing/Makefile b/tests/shadow-testing/Makefile new file mode 100644 index 0000000000..44c0ec1fe6 --- /dev/null +++ b/tests/shadow-testing/Makefile @@ -0,0 +1,230 @@ +# Shadow Testing Makefile +# Usage: +# make all CONFIG=mainnet BUNDLE_RANGE=17297:17301 +# make env CONFIG=mainnet BUNDLE_RANGE=17297:17301 +# make prove CONFIG=mainnet BUNDLE_RANGE=17297:17301 +# make finalize CONFIG=mainnet BUNDLE_RANGE=17297:17301 +# make stop + +CONFIG ?= mainnet +BUNDLE_RANGE ?= 17297:17301 +SCRIPT_DIR := $(shell cd "$(dir $(lastword $(MAKEFILE_LIST)))" && pwd) +CONFIG_FILE := $(SCRIPT_DIR)/configs/$(CONFIG).json +WORK_DIR := $(SCRIPT_DIR)/.work + +# Extract values from JSON config (requires jq) +FORK_URL := $(shell jq -r '.fork.url' $(CONFIG_FILE) 2>/dev/null) +FORK_BLOCK := $(shell jq -r '.fork.block_number' $(CONFIG_FILE) 2>/dev/null) +ANVIL_RPC := $(shell jq -r '.fork.anvil_rpc' $(CONFIG_FILE) 2>/dev/null) +DB_DSN := $(shell jq -r '.db.dsn' $(CONFIG_FILE) 2>/dev/null) +GENESIS := $(shell jq -r '.genesis' $(CONFIG_FILE) 2>/dev/null) +SCROLL_CHAIN := $(shell jq -r '.contracts.scroll_chain' $(CONFIG_FILE) 2>/dev/null) +L1_MSG_QUEUE := $(shell jq -r '.contracts.l1_message_queue_v2' $(CONFIG_FILE) 2>/dev/null) +ROLLUP_VERIF := $(shell jq -r '.contracts.rollup_verifier' $(CONFIG_FILE) 2>/dev/null) +DEPLOYED_VERIF:= $(shell jq -r '.contracts.deployed_verifier' $(CONFIG_FILE) 2>/dev/null) +OWNER := $(shell jq -r '.contracts.owner' $(CONFIG_FILE) 2>/dev/null) +PROVER_EOA := $(shell jq -r '.accounts.prover_eoa' $(CONFIG_FILE) 2>/dev/null) +COMMIT_EOA := $(shell jq -r '.accounts.commit_eoa' $(CONFIG_FILE) 2>/dev/null) +LAST_FINALIZED:= $(shell jq -r '.reset.last_finalized_batch_index' $(CONFIG_FILE) 2>/dev/null) +LAST_COMMITTED:= $(shell jq -r '.reset.last_committed_batch_index // empty' $(CONFIG_FILE) 2>/dev/null) +NEXT_QUEUE := $(shell jq -r '.reset.next_unfinalized_queue_index' $(CONFIG_FILE) 2>/dev/null) +CODEC_VERSION := $(shell jq -r '.reset.codec_version' $(CONFIG_FILE) 2>/dev/null) + +# ─── Validation ────────────────────────────────────────────────────────────── +.PHONY: check-deps + +check-deps: + @command -v jq >/dev/null 2>&1 || { echo "jq is required"; exit 1; } + @command -v cast >/dev/null 2>&1 || { echo "cast (Foundry) is required"; exit 1; } + @test -f $(CONFIG_FILE) || { echo "Config file not found: $(CONFIG_FILE)"; exit 1; } + +# ─── Environment Setup ─────────────────────────────────────────────────────── + +env: check-deps anvil-up db-reset + @echo "" + @echo "✅ Environment ready for $(CONFIG)" + @echo " Anvil RPC: $(ANVIL_RPC)" + @echo " Bundle range: $(BUNDLE_RANGE)" + +anvil-up: check-deps + @echo "🚀 Setting up Anvil fork ($(CONFIG))..." + $(SCRIPT_DIR)/scripts/01-setup-anvil.sh \ + --fork-url "$(FORK_URL)" \ + --fork-block "$(FORK_BLOCK)" \ + --anvil-rpc "$(ANVIL_RPC)" \ + --state-file "$(WORK_DIR)/anvil-$(CONFIG).state.json" \ + --last-finalized "$(LAST_FINALIZED)" \ + --last-committed "$(LAST_COMMITTED)" \ + --next-queue "$(NEXT_QUEUE)" \ + --deployed-verifier "$(DEPLOYED_VERIF)" \ + --prover-eoa "$(PROVER_EOA)" \ + --commit-eoa "$(COMMIT_EOA)" \ + --owner "$(OWNER)" \ + --scroll-chain "$(SCROLL_CHAIN)" \ + --l1-msg-queue "$(L1_MSG_QUEUE)" \ + --rollup-verifier "$(ROLLUP_VERIF)" + +db-reset: check-deps + @echo "🗄️ Preparing shadow DB..." + $(SCRIPT_DIR)/scripts/02-prepare-db.sh \ + --db-dsn "$(DB_DSN)" \ + --bundle-range "$(BUNDLE_RANGE)" + +# ─── Proving Phase ──────────────────────────────────────────────────────────── +.PHONY: prove prover-up wait-proofs + +prove: prover-up wait-proofs + +prover-up: + @echo "🔬 Starting provers..." + $(SCRIPT_DIR)/scripts/04-prover-up.sh \ + --config "$(CONFIG)" \ + --bundle-range "$(BUNDLE_RANGE)" + +wait-proofs: + @echo "⏳ Waiting for proofs to complete..." + $(SCRIPT_DIR)/scripts/05-wait-for-proofs.sh \ + --db-dsn "$(DB_DSN)" \ + --bundle-range "$(BUNDLE_RANGE)" + +# ─── Finalization Phase ────────────────────────────────────────────────────── +.PHONY: finalize relayer-up wait-finalize + +finalize: relayer-up wait-finalize + +relayer-up: + @echo "📤 Starting relayer..." + $(SCRIPT_DIR)/scripts/06-run-relayer.sh \ + --config "$(CONFIG)" + +wait-finalize: + @echo "⏳ Waiting for finalization..." + $(SCRIPT_DIR)/scripts/07-wait-for-finalize.sh \ + --anvil-rpc "$(ANVIL_RPC)" \ + --scroll-chain "$(SCROLL_CHAIN)" \ + --bundle-range "$(BUNDLE_RANGE)" + +# ─── Sepolia-specific Pipeline ─────────────────────────────────────────────── +.PHONY: sepolia-all + +sepolia-all: env prove finalize + @echo "" + @echo "🎉 Sepolia shadow test complete!" + @echo " Bundles: $(BUNDLE_RANGE)" + @echo " Anvil RPC: $(ANVIL_RPC)" + +# ─── Full Pipeline ──────────────────────────────────────────────────────────── +.PHONY: all + +all: env prove finalize + @echo "" + @echo "🎉 Shadow test complete for $(CONFIG)!" + @echo " Bundles: $(BUNDLE_RANGE)" + @echo " Anvil RPC: $(ANVIL_RPC)" + +# ─── Status & Verification ─────────────────────────────────────────────────── +.PHONY: status verify + +status: check-deps + @echo "📊 Current status:" + @echo "" + @echo "Anvil lastFinalizedBatchIndex:" + @cast call "$(SCROLL_CHAIN)" "lastFinalizedBatchIndex()(uint256)" --rpc-url "$(ANVIL_RPC)" 2>/dev/null || echo " (Anvil not running)" + @echo "" + @echo "Bundle proving status:" + @psql "$(DB_DSN)" -c "SELECT index, proving_status, rollup_status FROM bundle WHERE index BETWEEN $(subst :, AND ,$(BUNDLE_RANGE)) ORDER BY index;" 2>/dev/null || echo " (DB not accessible)" + +verify: check-deps + @echo "🔍 Verifying on-chain finalization..." + $(SCRIPT_DIR)/scripts/07-wait-for-finalize.sh \ + --anvil-rpc "$(ANVIL_RPC)" \ + --scroll-chain "$(SCROLL_CHAIN)" \ + --bundle-range "$(BUNDLE_RANGE)" \ + --verify-only + +# ─── Docker-Orchestrated Pipeline ────────────────────────────────────────────── +.PHONY: docker-all docker-env docker-prove docker-finalize docker-stop + +docker-all: + @echo "🐳 Docker-orchestrated full pipeline..." + $(SCRIPT_DIR)/scripts/08-docker-orchestrate.sh \ + --config $(CONFIG) \ + --bundle-range $(BUNDLE_RANGE) \ + --phase all + +docker-env: + @echo "🐳 Docker environment setup..." + $(SCRIPT_DIR)/scripts/08-docker-orchestrate.sh \ + --config $(CONFIG) \ + --bundle-range $(BUNDLE_RANGE) \ + --phase env + +docker-prove: + @echo "🐳 Docker proving phase..." + $(SCRIPT_DIR)/scripts/08-docker-orchestrate.sh \ + --config $(CONFIG) \ + --bundle-range $(BUNDLE_RANGE) \ + --phase prove + +docker-finalize: + @echo "🐳 Docker finalization phase..." + $(SCRIPT_DIR)/scripts/08-docker-orchestrate.sh \ + --config $(CONFIG) \ + --bundle-range $(BUNDLE_RANGE) \ + --phase finalize + +docker-stop: + @echo "🛑 Stopping Docker services..." + -docker compose -f $(SCRIPT_DIR)/docker-compose.yml down 2>/dev/null || true + @if [ -f $(WORK_DIR)/anvil-$(CONFIG).pid ]; then \ + kill $$(cat $(WORK_DIR)/anvil-$(CONFIG).pid) 2>/dev/null || true; \ + rm -f $(WORK_DIR)/anvil-$(CONFIG).pid; \ + fi + @echo "Done." + +# ─── Cleanup ───────────────────────────────────────────────────────────────── +.PHONY: stop clean + +stop: docker-stop + @echo "🛑 Stopping bare-metal services..." + @if [ -f $(WORK_DIR)/anvil.pid ]; then \ + kill $$(cat $(WORK_DIR)/anvil.pid) 2>/dev/null || true; \ + rm -f $(WORK_DIR)/anvil.pid; \ + fi + @echo "Done." + +clean: stop + @echo "🧹 Cleaning up..." + rm -rf $(WORK_DIR)/* + @echo "Done." + +# ─── Help ──────────────────────────────────────────────────────────────────── +.PHONY: help + +help: + @echo "Shadow Testing Makefile" + @echo "" + @echo "Docker Targets (recommended):" + @echo " make docker-all CONFIG= BUNDLE_RANGE= Full docker pipeline" + @echo " make docker-env CONFIG= BUNDLE_RANGE= Setup env (postgres + anvil + import)" + @echo " make docker-prove CONFIG= BUNDLE_RANGE= Prove (coordinator + prover)" + @echo " make docker-finalize CONFIG= BUNDLE_RANGE= Finalize (relayer)" + @echo " make docker-stop Stop docker services" + @echo "" + @echo "Bare-Metal Targets:" + @echo " make all CONFIG= BUNDLE_RANGE= Full pipeline" + @echo " make env CONFIG= BUNDLE_RANGE= Setup Anvil + DB" + @echo " make prove CONFIG= BUNDLE_RANGE= Prove bundles" + @echo " make finalize CONFIG= BUNDLE_RANGE= Finalize bundles" + @echo " make status CONFIG= BUNDLE_RANGE= Check status" + @echo " make verify CONFIG= BUNDLE_RANGE= Verify on-chain" + @echo " make stop Stop all services" + @echo " make clean Stop + cleanup" + @echo "" + @echo "Configs: $(shell ls $(SCRIPT_DIR)/configs/*.json 2>/dev/null | xargs -n1 basename | sed 's/.json//g' | xargs)" + @echo "" + @echo "Example (docker):" + @echo " make docker-all CONFIG=mainnet BUNDLE_RANGE=17302:17305" + @echo "" + @echo "Example (bare-metal):" + @echo " make all CONFIG=mainnet BUNDLE_RANGE=17297:17301" diff --git a/tests/shadow-testing/README.md b/tests/shadow-testing/README.md new file mode 100644 index 0000000000..f49c125676 --- /dev/null +++ b/tests/shadow-testing/README.md @@ -0,0 +1,77 @@ +# Shadow Testing Toolkit + +One-command toolkit for running Scroll shadow fork tests against Anvil. + +## Quick Start + +### Docker (Recommended) + +```bash +cd tests/shadow-testing +make docker-all CONFIG=mainnet BUNDLE_RANGE=17302:17305 +``` + +### Bare-Metal + +```bash +cd tests/shadow-testing +make all CONFIG=mainnet BUNDLE_RANGE=17297:17301 +``` + +See `make help` for all targets. + +## Documentation + +| Document | What It Covers | +|----------|----------------| +| [`docs/GUIDE.md`](docs/GUIDE.md) | Full setup guide — step-by-step manual setup, architecture, configuration | +| [`docs/TROUBLESHOOTING.md`](docs/TROUBLESHOOTING.md) | Structured pitfalls, traps, and agent checklists | +| [`docs/contract-addresses.md`](docs/contract-addresses.md) | L1 contract addresses per network | + +## Directory Structure + +``` +configs/ # JSON config templates (copy and edit) +scripts/ # Numbered pipeline scripts (01-setup-anvil.sh …) +docs/ # Documentation +states/ # Anvil state files (gitignored) +.work/ # Runtime logs, pid files (gitignored) +``` + +## Prerequisites + +- [Foundry](https://book.getfoundry.sh/) (`cast`, `forge`) +- `jq` +- `docker compose` (for Docker mode) +- PostgreSQL client (`psql`) +- Access to production RDS (via IDC port-forward) + +## Configurations + +Copy templates and fill in secrets: + +```bash +cp configs/mainnet.json.template configs/mainnet.json +cp configs/sepolia.json.template configs/sepolia.json +cp configs/coordinator.json.template configs/coordinator.json +# Edit the files and replace placeholders: +# - YOUR_ALCHEMY_API_KEY (in mainnet.json / sepolia.json fork.url) +# - YOUR_SHADOW_DB_PASSWORD (in mainnet.json / sepolia.json db.dsn) +``` + +## How It Works + +The pipeline has three phases: + +1. **Environment Setup** (`make env` or `make docker-env`) + Start Anvil fork, import bundle data from production RDS, reset status. + +2. **Proving** (`make prove` or `make docker-prove`) + Start coordinator + provers, wait for proofs to complete. + +3. **Finalization** (`make finalize` or `make docker-finalize`) + Start relayer, wait for on-chain finalization. + +## Contributing + +When you discover a new trap or workaround, add it to `docs/TROUBLESHOOTING.md` (structured). diff --git a/tests/shadow-testing/configs/coordinator.json.template b/tests/shadow-testing/configs/coordinator.json.template new file mode 100644 index 0000000000..2d6f356250 --- /dev/null +++ b/tests/shadow-testing/configs/coordinator.json.template @@ -0,0 +1,40 @@ +{ + "prover_manager": { + "provers_per_session": 1, + "session_attempts": 5, + "external_prover_threshold": 32, + "bundle_collection_time_sec": 180, + "batch_collection_time_sec": 180, + "chunk_collection_time_sec": 3600, + "verifier": { + "min_prover_version": "v4.4.45", + "verifiers": [ + { + "assets_path": "assets", + "fork_name": "galileoV2" + } + ] + } + }, + "db": { + "driver_name": "postgres", + "dsn": "postgres://postgres:YOUR_SHADOW_DB_PASSWORD@shadow-postgres:5432/shadow_rollup?sslmode=disable", + "maxOpenNum": 200, + "maxIdleNum": 20 + }, + "l2": { + "validium_mode": false, + "chain_id": 534352, + "l2geth": { + "endpoint": "https://l2geth-rpc-proxy.mainnet.aws.scroll.io" + } + }, + "auth": { + "secret": "YOUR_COORDINATOR_AUTH_SECRET", + "challenge_expire_duration_sec": 3600, + "login_expire_duration_sec": 3600 + }, + "sequencer": { + "decryption_key": "" + } +} diff --git a/tests/shadow-testing/configs/mainnet.json.template b/tests/shadow-testing/configs/mainnet.json.template new file mode 100644 index 0000000000..ff02fdc90d --- /dev/null +++ b/tests/shadow-testing/configs/mainnet.json.template @@ -0,0 +1,45 @@ +{ + "name": "mainnet-shadow-fork", + "fork": { + "url": "https://eth-mainnet.g.alchemy.com/v2/YOUR_ALCHEMY_API_KEY", + "block_number": 25202217, + "anvil_rpc": "http://localhost:18545" + }, + "contracts": { + "scroll_chain": "0xa13BAF47339d63B743e7Da8741db5456DAc1E556", + "l1_message_queue_v2": "0x56971da63A3C0205184FEF096E9ddFc7A8C2D18a", + "rollup_verifier": "0x4CEA3E866e7c57fD75CB0CA3E9F5f1151D4Ead3F", + "deployed_verifier": "0xb1F2C5c1ea2885278a1070350d12d3D8824265B0", + "owner": "0x798576400F7D662961BA15C6b3F3d813447a26a6" + }, + "accounts": { + "prover_eoa": "0x410E7FD80a3Fc1E62A4D3450d11b71b812006eB9", + "commit_eoa": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + }, + "reset": { + "last_finalized_batch_index": 517765, + "next_unfinalized_queue_index": 0, + "codec_version": 10, + "last_committed_batch_index": 517819 + }, + "db": { + "dsn": "postgresql://postgres:YOUR_SHADOW_DB_PASSWORD@localhost:5433/shadow_rollup" + }, + "genesis": "tests/prover-e2e/mainnet-galileoV2/genesis.json", + "assets": { + "assets_v2": "coordinator/build/bin/assets_v2" + }, + "prover": { + "name_prefix": "galileo6-shadowfork-prover", + "circuit_version": "v0.13.1", + "s3_base_url": "https://circuit-release.s3.us-west-2.amazonaws.com/scroll-zkvm/releases/v0.9.0/" + }, + "relayer": { + "validium_mode": false, + "min_codec_version": 7, + "chain_monitor_enabled": false + }, + "e2e": { + "l2_rpc": "https://l2geth-rpc-proxy.mainnet.aws.scroll.io" + } +} diff --git a/tests/shadow-testing/configs/relayer.json.template b/tests/shadow-testing/configs/relayer.json.template new file mode 100644 index 0000000000..6d84879cc3 --- /dev/null +++ b/tests/shadow-testing/configs/relayer.json.template @@ -0,0 +1,75 @@ +{ + "l2_config": { + "endpoint": "{{L2_ENDPOINT}}", + "relayer_config": { + "sender_config": { + "endpoint": "{{ANVIL_RPC}}", + "check_balance": false, + "dry_run": false, + "tx_type": "DynamicFeeTx", + "escalate_blocks": 10, + "escalate_multiple_num": 11, + "escalate_multiple_den": 10, + "confirmations": "0x0", + "max_gas_price": 10000000000000, + "max_blob_gas_price": 10000000000000, + "min_gas_tip": 0, + "check_pending_time": 60, + "max_pending_blob_txs": 3, + "fusaka_timestamp": 9999999999 + }, + "commit_sender_signer_config": { + "signer_type": "PrivateKey", + "private_key_signer_config": { + "private_key": "{{COMMIT_KEY}}" + } + }, + "finalize_sender_signer_config": { + "signer_type": "PrivateKey", + "private_key_signer_config": { + "private_key": "{{FINALIZE_KEY}}" + } + }, + "rollup_contract_address": "{{SCROLL_CHAIN}}", + "batch_submission": { + "min_batches": 1, + "max_batches": 1, + "timeout": 7200, + "backlog_max": 200, + "blob_fee_tolerance": 500000000 + }, + "gas_oracle": { + "enabled": false + }, + "chain_monitor": { + "enabled": {{CHAIN_MONITOR_ENABLED}} + }, + "batch_committer": { + "enable_test_env_bypass_features": true + }, + "validium_mode": {{VALIDIUM_MODE}} + }, + "chunk_proposer_config": { + "propose_interval_milliseconds": 10000, + "max_l2_gas_per_chunk": 100000000, + "chunk_timeout_sec": 900, + "max_uncompressed_batch_bytes_size": 63488 + }, + "batch_proposer_config": { + "propose_interval_milliseconds": 10000, + "batch_timeout_sec": 1800, + "max_chunks_per_batch": 15, + "max_uncompressed_batch_bytes_size": 129024 + }, + "bundle_proposer_config": { + "max_batch_num_per_bundle": 30, + "bundle_timeout_sec": 3600 + }, + "blob_uploader_config": { + "start_batch": 0 + } + }, + "db_config": { + "dsn": "{{DB_DSN}}" + } +} diff --git a/tests/shadow-testing/configs/sepolia.json.template b/tests/shadow-testing/configs/sepolia.json.template new file mode 100644 index 0000000000..4a236b490d --- /dev/null +++ b/tests/shadow-testing/configs/sepolia.json.template @@ -0,0 +1,51 @@ +{ + "name": "sepolia-shadow-fork", + "fork": { + "url": "https://eth-sepolia.g.alchemy.com/v2/YOUR_ALCHEMY_API_KEY", + "block_number": 10878976, + "anvil_rpc": "http://localhost:18546" + }, + "contracts": { + "scroll_chain": "0x2D567EcE699Eabe5afCd141eDB7A4f2D0D6ce8a0", + "l1_message_queue_v2": "0xA0673eC0A48aa924f067F1274EcD281A10c5f19F", + "rollup_verifier": "0x8A360c7F6fca548507017DdeD732bFe7E078F963", + "deployed_verifier": "", + "owner": "0xbE57544Eaf3515E888614a464EC9e0ad38f73e37" + }, + "accounts": { + "prover_eoa": "0x410E7FD80a3Fc1E62A4D3450d11b71b812006eB9", + "commit_eoa": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + }, + "reset": { + "last_finalized_batch_index": 127915, + "next_unfinalized_queue_index": 0, + "codec_version": 10 + }, + "db": { + "dsn": "postgresql://YOUR_SHADOW_DB_USER:YOUR_SHADOW_DB_PASSWORD@localhost:5442/sepolia_scroll" + }, + "genesis": "tests/prover-e2e/sepolia-galileoV2/genesis.json", + "assets": { + "assets_v2": "coordinator/build/bin/assets_v2" + }, + "prover": { + "name_prefix": "sepolia-shadowfork-prover", + "circuit_version": "v0.13.1", + "s3_base_url": "https://circuit-release.s3.us-west-2.amazonaws.com/scroll-zkvm/releases/v0.9.0/" + }, + "coordinator": { + "l2geth": "https://l2geth-rpc-proxy.sepolia.aws.scroll.io" + }, + "relayer": { + "validium_mode": false, + "min_codec_version": 7, + "chain_monitor_enabled": false + }, + "e2e": { + "begin_block": 17086000, + "end_block": 17086005, + "l2_rpc": "https://sepolia-rpc.scroll.io", + "fork_name": "galileoV2", + "zkvm_version": "v0.9.0" + } +} diff --git a/tests/shadow-testing/contracts/IZkEvmVerifier.sol b/tests/shadow-testing/contracts/IZkEvmVerifier.sol new file mode 100644 index 0000000000..244b0deebe --- /dev/null +++ b/tests/shadow-testing/contracts/IZkEvmVerifier.sol @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.24; + +interface IZkEvmVerifierV1 { + /// @notice Verify aggregate zk proof. + /// @param aggrProof The aggregated proof. + /// @param publicInputHash The public input hash. + function verify(bytes calldata aggrProof, bytes32 publicInputHash) external view; +} + +interface IZkEvmVerifierV2 { + /// @notice Verify bundle zk proof. + /// @param bundleProof The bundle recursion proof. + /// @param publicInput The public input. + function verify(bytes calldata bundleProof, bytes calldata publicInput) external view; +} diff --git a/tests/shadow-testing/contracts/ZkEvmVerifierPostFeynman.sol b/tests/shadow-testing/contracts/ZkEvmVerifierPostFeynman.sol new file mode 100644 index 0000000000..62ac3c7e2f --- /dev/null +++ b/tests/shadow-testing/contracts/ZkEvmVerifierPostFeynman.sol @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: MIT + +pragma solidity =0.8.24; + +import {IZkEvmVerifierV2} from "./IZkEvmVerifier.sol"; + +// solhint-disable no-inline-assembly + +/// @notice Wrapper around the OpenVM Halo2 plonk verifier for GalileoV2 (post-Feynman) proofs. +/// +/// @dev Identical to ZkEvmVerifierPostEuclid, except the public input hash is computed as +/// keccak256(abi.encodePacked(protocolVersion, publicInput)). The protocol version is +/// stored as an immutable and corresponds to the batch version (10 for GalileoV2). +contract ZkEvmVerifierPostFeynman is IZkEvmVerifierV2 { + /********** + * Errors * + **********/ + + /// @dev Thrown when bundle recursion zk proof verification is failed. + error VerificationFailed(); + + /************* + * Constants * + *************/ + + /// @notice The address of highly optimized plonk verifier contract. + address public immutable plonkVerifier; + + /// @notice A predetermined digest for the `plonkVerifier`. + bytes32 public immutable verifierDigest1; + + /// @notice A predetermined digest for the `plonkVerifier`. + bytes32 public immutable verifierDigest2; + + /// @notice The protocol version prepended to the public input before hashing. + uint256 public immutable protocolVersion; + + /*************** + * Constructor * + ***************/ + + constructor( + address _verifier, + bytes32 _verifierDigest1, + bytes32 _verifierDigest2, + uint256 _protocolVersion + ) { + plonkVerifier = _verifier; + verifierDigest1 = _verifierDigest1; + verifierDigest2 = _verifierDigest2; + protocolVersion = _protocolVersion; + } + + /************************* + * Public View Functions * + *************************/ + + /// @inheritdoc IZkEvmVerifierV2 + /// + /// @dev Encoding for `publicInput`: + /// ```text + /// | layer2ChainId | numBatches | prevStateRoot | prevBatchHash | postStateRoot | batchHash | withdrawRoot | + /// | 8 bytes | 4 bytes | 32 bytes | 32 bytes | 32 bytes | 32 bytes | 32 bytes | + /// ``` + /// The hash passed to the plonk verifier is `keccak256(abi.encodePacked(protocolVersion, publicInput))`. + function verify(bytes calldata bundleProof, bytes calldata publicInput) external view override { + address _verifier = plonkVerifier; + bytes32 _verifierDigest1 = verifierDigest1; + bytes32 _verifierDigest2 = verifierDigest2; + bytes32 publicInputHash = keccak256(abi.encodePacked(protocolVersion, publicInput)); + bool success; + + // 1. the first 12 * 32 (0x180) bytes of `bundleProof` is `accumulator` + // 2. the rest bytes of `bundleProof` is the actual `bundle_proof` + // 3. Inserted between `accumulator` and `bundle_proof` are + // 32 * 34 (0x440) bytes, such that: + // | start | end | field | + // |---------------|---------------|-------------------------| + // | 0x00 | 0x180 | bundleProof[0x00:0x180] | + // | 0x180 | 0x180 + 0x20 | verifierDigest1 | + // | 0x180 + 0x20 | 0x180 + 0x40 | verifierDigest2 | + // | 0x180 + 0x40 | 0x180 + 0x60 | publicInputHash[0] | + // | 0x180 + 0x60 | 0x180 + 0x80 | publicInputHash[1] | + // ... + // | 0x180 + 0x420 | 0x180 + 0x440 | publicInputHash[31] | + // | 0x180 + 0x440 | dynamic | bundleProof[0x180:] | + assembly { + let p := mload(0x40) + // 1. copy the accumulator's 0x180 bytes + calldatacopy(p, bundleProof.offset, 0x180) + // 2. insert the public input's 0x440 bytes + mstore(add(p, 0x180), _verifierDigest1) // verifierDigest1 + mstore(add(p, 0x1a0), _verifierDigest2) // verifierDigest2 + for { + let i := 0 + } lt(i, 0x400) { + i := add(i, 0x20) + } { + mstore(add(p, sub(0x5a0, i)), and(publicInputHash, 0xff)) + publicInputHash := shr(8, publicInputHash) + } + // 3. copy all remaining bytes from bundleProof + calldatacopy(add(p, 0x5c0), add(bundleProof.offset, 0x180), sub(bundleProof.length, 0x180)) + // 4. call plonk verifier + success := staticcall(gas(), _verifier, p, add(bundleProof.length, 0x440), 0x00, 0x00) + } + if (!success) { + revert VerificationFailed(); + } + } +} diff --git a/tests/shadow-testing/docker-compose.yml b/tests/shadow-testing/docker-compose.yml new file mode 100644 index 0000000000..87bcedc5fc --- /dev/null +++ b/tests/shadow-testing/docker-compose.yml @@ -0,0 +1,213 @@ +version: "3.8" + +services: + # ─── PostgreSQL (Shadow DB) ──────────────────────────────────────────────── + postgres: + image: postgres:15-alpine + container_name: shadow-postgres + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: shadow_pass + POSTGRES_DB: shadow_rollup + ports: + - "5433:5432" + volumes: + - postgres-data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres"] + interval: 5s + timeout: 5s + retries: 5 + networks: + - shadow-net + + # ─── Coordinator API ─────────────────────────────────────────────────────── + coordinator: + image: scrolltech/coordinator-api:e2e-test + container_name: shadow-coordinator + profiles: ["coordinator"] + command: + - "--config" + - "/app/conf/config.json" + - "--http" + - "--http.addr" + - "0.0.0.0" + - "--http.port" + - "8390" + ports: + - "8390:8390" + volumes: + - ./configs/coordinator.json:/app/conf/config.json:ro + - ../../coordinator/build/bin/assets_v2:/app/assets:ro + - ../../tests/prover-e2e/mainnet-galileoV2/genesis.json:/app/conf/genesis.json:ro + depends_on: + postgres: + condition: service_healthy + networks: + - shadow-net + restart: unless-stopped + + # ─── Relayer ─────────────────────────────────────────────────────────────── + relayer: + image: ubuntu:22.04 + container_name: shadow-relayer + profiles: ["relayer"] + entrypoint: ["/app/rollup_relayer"] + command: + - "--config" + - "/app/config.json" + - "--genesis" + - "/app/conf/genesis.json" + - "--min-codec-version" + - "7" + - "--verbosity" + - "3" + volumes: + - ./.work/relayer-${CONFIG:-mainnet}.json:/app/config.json:ro + - ../../tests/prover-e2e/mainnet-galileoV2/genesis.json:/app/conf/genesis.json:ro + - ../../rollup/build/bin/rollup_relayer:/app/rollup_relayer:ro + depends_on: + - postgres + networks: + - shadow-net + restart: unless-stopped + + # ─── Anvil (optional — usually started by script for fork flexibility) ───── + anvil: + image: ghcr.io/foundry-rs/foundry:latest + container_name: shadow-anvil + profiles: ["anvil"] + entrypoint: ["anvil"] + command: + - "--fork-url" + - "${FORK_URL:-https://eth-mainnet.g.alchemy.com/v2/demo}" + - "--fork-block-number" + - "${FORK_BLOCK:-25202217}" + - "--block-time" + - "12" + - "--port" + - "8545" + - "--state" + - "/data/anvil.state.json" + ports: + - "18545:8545" + volumes: + - ./states:/data + networks: + - shadow-net + restart: unless-stopped + + # ─── Prover GPU-0 ────────────────────────────────────────────────────────── + prover-gpu-0: + image: scrolltech/prover:${PROVER_VERSION:-e2e-test} + container_name: shadow-prover-gpu-0 + profiles: ["prover"] + ports: + - "10080:10080" + environment: + - RUST_MIN_STACK=16777216 + - CUDA_VISIBLE_DEVICES=0 + volumes: + - ./.work/prover-0.json:/prover/conf/config.json:ro + - ./.work/prover-0:/prover/.work + - ~/.openvm/params:/root/.openvm/params:ro + deploy: + resources: + reservations: + devices: + - driver: nvidia + device_ids: ['0'] + capabilities: [gpu] + depends_on: + - coordinator + networks: + - shadow-net + restart: unless-stopped + + # ─── Prover GPU-1 ────────────────────────────────────────────────────────── + prover-gpu-1: + image: scrolltech/prover:${PROVER_VERSION:-e2e-test} + container_name: shadow-prover-gpu-1 + profiles: ["prover"] + ports: + - "10081:10080" + environment: + - RUST_MIN_STACK=16777216 + - CUDA_VISIBLE_DEVICES=0 + volumes: + - ./.work/prover-1.json:/prover/conf/config.json:ro + - ./.work/prover-1:/prover/.work + - ~/.openvm/params:/root/.openvm/params:ro + deploy: + resources: + reservations: + devices: + - driver: nvidia + device_ids: ['1'] + capabilities: [gpu] + depends_on: + - coordinator + networks: + - shadow-net + restart: unless-stopped + + # ─── Prover GPU-2 ────────────────────────────────────────────────────────── + prover-gpu-2: + image: scrolltech/prover:${PROVER_VERSION:-e2e-test} + container_name: shadow-prover-gpu-2 + profiles: ["prover"] + ports: + - "10082:10080" + environment: + - RUST_MIN_STACK=16777216 + - CUDA_VISIBLE_DEVICES=0 + volumes: + - ./.work/prover-2.json:/prover/conf/config.json:ro + - ./.work/prover-2:/prover/.work + - ~/.openvm/params:/root/.openvm/params:ro + deploy: + resources: + reservations: + devices: + - driver: nvidia + device_ids: ['2'] + capabilities: [gpu] + depends_on: + - coordinator + networks: + - shadow-net + restart: unless-stopped + + # ─── Prover GPU-3 ────────────────────────────────────────────────────────── + prover-gpu-3: + image: scrolltech/prover:${PROVER_VERSION:-e2e-test} + container_name: shadow-prover-gpu-3 + profiles: ["prover"] + ports: + - "10083:10080" + environment: + - RUST_MIN_STACK=16777216 + - CUDA_VISIBLE_DEVICES=0 + volumes: + - ./.work/prover-3.json:/prover/conf/config.json:ro + - ./.work/prover-3:/prover/.work + - ~/.openvm/params:/root/.openvm/params:ro + deploy: + resources: + reservations: + devices: + - driver: nvidia + device_ids: ['3'] + capabilities: [gpu] + depends_on: + - coordinator + networks: + - shadow-net + restart: unless-stopped + +volumes: + postgres-data: + +networks: + shadow-net: + driver: bridge diff --git a/tests/shadow-testing/docs/GUIDE.md b/tests/shadow-testing/docs/GUIDE.md new file mode 100644 index 0000000000..2ca933081c --- /dev/null +++ b/tests/shadow-testing/docs/GUIDE.md @@ -0,0 +1,1047 @@ +# Shadow Coordinator + Prover Testing Guide + +This guide documents how to set up a **shadow coordinator** + **local prover** environment for testing proof generation without interfering with production. This approach is significantly simpler than a full shadow fork — we use a local coordinator with imported production task data and a local prover that fetches tasks from it. + +## Architecture + +``` +┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ +│ Production RDS │ │ Shadow DB │ │ Shadow │ +│ (read-only via │────▶│ (local :5433) │────▶│ Coordinator │ +│ port-forward) │ │ │ │ (localhost:8390)│ +└──────────────────┘ └──────────────────┘ └────────┬─────────┘ + │ + │ assigns tasks + ▼ +┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ +│ L2 RPC │ │ Local Prover │ │ Verifier Assets │ +│ (mainnet-rpc. │◀────│ (GPU/CPU) │ │ (/tmp/shadow- │ +│ scroll.io) │ │ │ │ verifier-assets)│ +└──────────────────┘ └──────────────────┘ └──────────────────┘ +``` + +## Prerequisites + +### Hardware +- GPU with CUDA support (tested on RTX 3090) +- ~50GB disk space for Docker images + verifier assets + circuit downloads +- 16GB+ RAM + +### Software +- Docker + docker-compose +- PostgreSQL client (`psql`) +- Rust toolchain (for local prover binary) +- `kubectl` or SSH access to IDC for port-forwarding to production RDS + +### Network +- Access to IDC machine with port-forward to mainnet RDS (e.g., `idc-us-1-19`) +- Internet access for L2 RPC and S3 circuit downloads + +## Quick Start + +If you just want to get running, use the provided script: + +```bash +# 1. Set up shadow PostgreSQL +cd tests/shadow-testing +./setup.sh --postgres + +# 2. Import production task data (requires RDS port-forward) +./import-production-data.sh + +# 3. Start shadow coordinator +./setup.sh --coordinator + +# 4. Start prover (in another terminal) +./setup.sh --prover +``` + +## Step-by-Step Setup + +### Step 1: Set up IDC Port-Forward to Production RDS + +On the IDC machine (e.g., `idc-us-1-19`), ensure the port-forward is active: + +```bash +# Mainnet RDS should be accessible on localhost:15432 +# Credentials are loaded from .env (see .env.example) +psql -h localhost -p 15432 -U "$PROD_DB_USER" -d rollup -c "SELECT version();" +``` + +If not already set up, configure SSH tunnel or kubectl port-forward from your workstation. + +### Step 2: Start Local PostgreSQL (Shadow DB) + +```bash +docker run -d \ + --name shadow-coordinator-postgres \ + -e POSTGRES_USER=postgres \ + -e POSTGRES_PASSWORD="${SHADOW_DB_PASSWORD}" \ + -e POSTGRES_DB=shadow_rollup \ + -p 5433:5432 \ + -v shadow-coordinator-postgres-data:/var/lib/postgresql/data \ + postgres:15 + +# Wait for DB to be ready +sleep 5 +docker exec shadow-coordinator-postgres pg_isready -U postgres +``` + +### Step 3: Download Verifier Assets + +The coordinator needs verifier assets for each supported fork: + +```bash +VERIFIER_DIR="/tmp/shadow-verifier-assets" +mkdir -p "$VERIFIER_DIR" + +# feynman (OpenVM 0.5.6) +mkdir -p "$VERIFIER_DIR/openvm-0.5.6" +# Download or copy verifier assets for feynman + +# galileo (v0.7.1) +mkdir -p "$VERIFIER_DIR/openvm-v0.7.1" +# Download or copy verifier assets for galileo + +# galileoV2 (v0.9.0) +mkdir -p "$VERIFIER_DIR/openvm-v0.9.0" +# Download or copy verifier assets for galileoV2 from .../scroll-zkvm/releases/v0.9.0/verifier/ +``` + +> ⚠️ **Important**: v0.9.0 assets are under `scroll-zkvm/releases/v0.9.0/`. Earlier v0.8.0 assets used `scroll-zkvm/v0.8.0/` (no `/releases/`). Using the wrong prefix causes HTTP 403 errors. + +### Step 4: Initialize Shadow DB Schema + +Use the coordinator's built-in migration or apply schema manually. The coordinator container will auto-migrate on first start. + +### Step 5: Import Production Task Data + +Export the latest N batches + their chunks + bundles from production RDS and import into shadow DB: + +```bash +# Edit these variables as needed +# Credentials loaded from .env (see tests/shadow-testing/.env.example) +PROD_DB="postgresql://${PROD_DB_USER}:${PROD_DB_PASSWORD}@${PROD_DB_HOST}:${PROD_DB_PORT}/${PROD_DB_NAME}" +SHADOW_DB="postgresql://${SHADOW_DB_USER}:${SHADOW_DB_PASSWORD}@${SHADOW_DB_HOST}:${SHADOW_DB_PORT}/${SHADOW_DB_NAME}" +BATCH_LIMIT=50 + +# Export batches +psql "$PROD_DB" -c " + COPY ( + SELECT * FROM batch + ORDER BY index DESC + LIMIT $BATCH_LIMIT + ) TO STDOUT WITH CSV HEADER; +" > /tmp/batches.csv + +# Export chunks in those batches +psql "$PROD_DB" -c " + COPY ( + SELECT c.* FROM chunk c + JOIN batch b ON b.start_chunk_index <= c.index AND c.index <= b.end_chunk_index + WHERE b.index IN (SELECT index FROM batch ORDER BY index DESC LIMIT $BATCH_LIMIT) + ORDER BY c.index + ) TO STDOUT WITH CSV HEADER; +" > /tmp/chunks.csv + +# Export bundles (all or limited) +psql "$PROD_DB" -c " + COPY ( + SELECT * FROM bundle + ORDER BY index DESC + LIMIT 20000 + ) TO STDOUT WITH CSV HEADER; +" > /tmp/bundles.csv + +# Import into shadow DB (truncate first) +psql "$SHADOW_DB" -c "TRUNCATE batch, chunk, bundle CASCADE;" + +# Use \copy for local import +psql "$SHADOW_DB" -c "\\copy batch FROM '/tmp/batches.csv' WITH CSV HEADER;" +psql "$SHADOW_DB" -c "\\copy chunk FROM '/tmp/chunks.csv' WITH CSV HEADER;" +psql "$SHADOW_DB" -c "\\copy bundle FROM '/tmp/bundles.csv' WITH CSV HEADER;" + +# Reset proving status to unassigned (1) +psql "$SHADOW_DB" -c "UPDATE chunk SET proving_status = 1, total_attempts = 0, active_attempts = 0;" +psql "$SHADOW_DB" -c "UPDATE batch SET proving_status = 1, total_attempts = 0, active_attempts = 0, chunk_proofs_status = 0;" +psql "$SHADOW_DB" -c "UPDATE bundle SET proving_status = 1, total_attempts = 0, active_attempts = 0;" +``` + +### Step 6: Populate l2_block Table + +The coordinator needs `l2_block` records to format chunk tasks (for block hashes and hardfork name resolution). + +Use the provided Python script or fetch blocks via L2 RPC: + +```bash +python3 tests/shadow-testing/scripts/fetch-l2-blocks.py \ + --rpc https://mainnet-rpc.scroll.io \ + --db "postgresql://$SHADOW_DB_USER:$SHADOW_DB_PASSWORD@$SHADOW_DB_HOST:$SHADOW_DB_PORT/$SHADOW_DB_NAME" \ + --start-block 26000000 \ + --end-block 27000000 +``` + +After inserting blocks, link them to chunks: + +```bash +psql "$SHADOW_DB" -c " + UPDATE l2_block lb + SET chunk_hash = c.hash + FROM chunk c + WHERE lb.number >= c.start_block_number + AND lb.number <= c.end_block_number; +" +``` + +### Step 7: Start Shadow Coordinator + +Use Docker (recommended) or run locally: + +```bash +# Via Docker +docker run -d \ + --name shadow-coordinator-api-test \ + --network host \ + -v /tmp/shadow-coordinator-config.json:/app/conf/config.json \ + -v /tmp/shadow-verifier-assets:/verifier \ + zhuoatscroll/coordinator-api:v4.7.13-openvm16 + +# Wait for startup (takes 2-3 min for OpenVM keygen) +docker logs -f shadow-coordinator-api-test | grep -m1 "Start coordinator api successfully" +``` + +### Step 8: Start Prover + +Build or use prebuilt binary: + +```bash +# Build locally +cd /path/to/scroll-repo +cargo build --release -p prover-bin + +# Or use Docker image +docker run -d \ + --name shadow-prover \ + --network host \ + --gpus all \ + -v /tmp/prover-local.json:/app/config.json \ + -v ~/.openvm/params:/root/.openvm/params:ro \ + zhuoatscroll/prover:v4.7.13-openvm16 + +# Or run binary directly +./target/release/prover --config /tmp/prover-local.json +``` + +> ℹ️ **Note**: Prover will download circuit assets from S3 on first run (several GB). Subsequent runs use cached assets in `.work/galileo/`. + +## Monitoring + +### Check coordinator health +```bash +curl -s http://localhost:8390/ | head +``` + +### Check prover health +```bash +curl -s http://localhost:10080/health +``` + +### Watch coordinator logs +```bash +docker logs -f shadow-coordinator-api-test --tail 100 +``` + +### Watch prover logs +```bash +# If running via docker +docker logs -f shadow-prover --tail 100 + +# If running binary directly, logs go to stdout +``` + +### Check DB task status +```bash +psql "$SHADOW_DB" -c " + SELECT proving_status, COUNT(*) FROM chunk GROUP BY proving_status; +" +``` + +Proving status values: +- `1` = Unassigned +- `2` = Assigned +- `3` = Proving +- `4` = Proven (success) +- `5` = Failed + +### Verify bundle readiness before finalization + +After all batch proofs are done (status 4), verify the bundle-level status: + +```bash +psql "$SHADOW_DB" -c " + SELECT index, batch_proofs_status, finalization_status + FROM bundle WHERE index = 13470; +" +``` + +Bundle `batch_proofs_status` values: +- `1` = Pending — waiting for coordinator cron to scan and transition +- `2` = Ready — all batch proofs verified, bundle can be finalized + +The coordinator runs `checkBundleAllBatchReady()` every 10s to transition bundles from `1` to `2`. If this hasn't happened yet (e.g., cron is lagging), manually update: + +```sql +UPDATE bundle SET batch_proofs_status = 2 WHERE index = 13470; +``` + +> **Important**: The relayer will not call `finalizeBundleWithProof` until `batch_proofs_status >= 2`, even if all individual batch proofs are already status 4. + +## Troubleshooting + +### Coordinator says "Start coordinator api successfully" but prover gets no tasks +- Verify `l2_block` table has records for the chunk's block range +- Check `proving_status = 1` on chunks +- Check `codec_version != 5` (chunks with codec_version = 5 are skipped) +- Ensure chunk's `end_block_number <= coordinator's block height` + +### "mismatched post-state root" or codec errors +- Verify you're using blocks after the hardfork. For GalileoV2 (codec V10), use blocks ≥ 33,750,000 on mainnet. +- Ensure `SCROLL_FORK_NAME` and verifier assets match the block's fork. + +### "Failed to execute witness" or "Method not found" +- The L2 RPC must support `debug_executionWitness` and `debug_dbGet`. +- `https://mainnet-rpc.scroll.io` supports these; `https://rpc.scroll.io` does not. + +### "Failed to get l1 messages in block" (-32601) +- Your RPC does not support `scroll_getL1MessagesInBlock`. This is non-fatal if the block contains no L1 messages. +- If L1 messages exist, you need an RPC that supports this method. + +### S3 403 errors when downloading circuit assets +- v0.9.0 assets: `https://circuit-release.s3.us-west-2.amazonaws.com/scroll-zkvm/releases/v0.9.0/` +- v0.8.0 assets: `https://circuit-release.s3.us-west-2.amazonaws.com/scroll-zkvm/v0.8.0/` +- v0.7.1 and earlier: `https://circuit-release.s3.us-west-2.amazonaws.com/scroll-zkvm/releases/v0.7.1/` +- Verify with `curl -sI ` before running. + +### "bind: address already in use" (port 8390) +- Kill old coordinator: `pkill -f coordinator_api` or `docker rm -f shadow-coordinator-api-test` + +### Port conflicts with local PostgreSQL +- If you have system PostgreSQL on 5432, use 5433 for shadow DB (already configured). +- Ensure all configs use the correct port. + +### Multi-GPU prover cache conflicts +When running multiple prover instances on the same machine, the shared `.work/galileo` cache directory can cause `File exists (os error 17)` conflicts if two provers write the same temp file simultaneously. + +**Mitigation**: Ensure each prover has its own work directory, or symlink `.work/galileo` to a shared read-only cache while giving each instance a distinct write directory. Example launch script: +```bash +for i in 0 1 2 3; do + mkdir -p /tmp/prover-gpu${i}/work + ln -s /shared/cache/galileo /tmp/prover-gpu${i}/work/galileo + CUDA_VISIBLE_DEVICES=$i ./prover --config /tmp/prover-gpu${i}/config.json & +done +``` + +### Bundle proving never starts +If coordinator is actively assigning chunk/batch tasks but never assigns bundle tasks, the most likely cause is **orphan bundles** — bundle records whose corresponding batch data no longer exists in the shadow DB. + +**Diagnosis**: +```sql +-- Count bundles with no linked batches +SELECT COUNT(*) FROM bundle b +WHERE NOT EXISTS ( + SELECT 1 FROM batch bat + WHERE bat.index BETWEEN b.start_batch_index AND b.end_batch_index +); +``` + +**Root cause**: The bundle table often retains historical records from production (e.g., batch 308516+) while the batch table only holds recently imported batches (e.g., 517760+). Coordinator's `GetUnassignedBundle` picks the lowest-index bundle with `batch_proofs_status = 2`, finds it has no batches, and fails silently in a loop. + +**Fix**: +```sql +UPDATE bundle +SET batch_proofs_status = 1 +WHERE index NOT IN ( + SELECT DISTINCT b.index + FROM bundle b + JOIN batch bat ON bat.index BETWEEN b.start_batch_index AND b.end_batch_index +); +``` + +### DB data inconsistency after import +If imported chunks have `proving_status = 2` (assigned) but `proof = NULL`, coordinator may incorrectly set `batch.chunk_proofs_status = 2` and then fail when formatting batch tasks. + +**Fix**: +```sql +UPDATE chunk SET proving_status = 1, total_attempts = 0, active_attempts = 0 +WHERE proving_status = 2 AND proof IS NULL; + +UPDATE batch SET chunk_proofs_status = 0 +WHERE chunk_proofs_status != 0 + AND EXISTS ( + SELECT 1 FROM chunk c + WHERE c.batch_hash = batch.hash AND c.proving_status != 4 + ); +``` + +## Configuration Reference + +### Shadow Coordinator Config + +See `configs/shadow-coordinator-config.json` in this directory. + +Key fields: +- `db.dsn`: Points to shadow PostgreSQL +- `l2.l2geth.endpoint`: L2 RPC with `debug_executionWitness` support +- `prover_manager.verifier.verifiers`: List of verifier asset paths and fork names + +### Prover Config + +See `configs/prover-local.json` in this directory. + +Key fields: +- `sdk_config.coordinator.base_url`: Shadow coordinator API (`http://localhost:8390`) +- `circuits.galileoV2.base_url`: S3 path for circuit assets (`.../scroll-zkvm/releases/v0.9.0/` for v0.9.0) +- `sdk_config.prover.supported_proof_types`: `[1, 2, 3]` for chunk, batch, bundle + +## Rollup Relayer Dry-Run Mode + +For testing the **rollup-relayer's transaction construction logic** (e.g., `finalizeBundle` calldata) without spending real gas or modifying chain state, the sender module supports a **dry-run mode**. + +When `"dry_run": true` is set in the sender config: +- Transactions are **simulated** via `eth_call` instead of being broadcast +- `pending_transaction` table is **not** populated (avoids DB pollution) +- Nonce is still incremented to simulate real behavior +- If the `eth_call` fails (e.g., contract revert), the error is propagated just like a real send failure + +### Usage + +1. Build the rollup-relayer binary: +```bash +cd rollup && go build -o rollup_relayer ./cmd/rollup_relayer/app +``` + +2. Configure `dry_run: true` in the sender config (see `tests/shadow-testing/configs/rollup-relayer-dryrun.json`) + +3. Start the relayer: +```bash +./rollup_relayer --config /path/to/rollup-relayer-dryrun.json +``` + +### What Dry-Run Verifies + +| Aspect | Verified? | Notes | +|--------|-----------|-------| +| Calldata encoding (ABI pack) | ✅ | `constructFinalizeBundlePayloadCodecV7` etc. | +| Gas estimation | ✅ | Full `EstimateGas` + `CreateAccessList` path | +| Contract revert | ✅ | `eth_call` returns revert reason | +| Signature / nonce | ⚠️ | Nonce incremented but tx not broadcast | +| Pending tx lifecycle | ❌ | Skipped to avoid DB pollution | +| Receipt confirmation | ❌ | No real tx = no receipt | + +For **full end-to-end** validation (including signature + receipt), use **Anvil** with `evm_snapshot`/`evm_revert` instead. + +### Anvil + Mock ScrollChain Setup (Recommended for Dry-Run) + +For the most realistic dry-run testing, deploy a minimal mock ScrollChain contract on a local Anvil node: + +```bash +# 1. Start Anvil forked from mainnet (or standalone) +anvil --fork-url https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY --fork-block-number 33878313 + +# 2. Deploy mock contract (minimal Solidity with no-op commitBatches / finalizeBundle) +cat > MockScrollChain.sol << 'EOF' +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; +contract MockScrollChain { + mapping(address => bool) public isProver; + address public owner; + constructor() { owner = msg.sender; } + function addProver(address _prover) external { + require(msg.sender == owner, "Not owner"); + isProver[_prover] = true; + } + function commitBatches(uint8 version, bytes32 parentBatchHash, bytes32 batchHash) external {} + function finalizeBundlePostEuclidV2NoProof(bytes calldata, uint256, bytes32, bytes32) external {} + function finalizeBundlePostEuclidV2(bytes calldata, uint256, bytes32, bytes32, bytes calldata) external {} +} +EOF + +# Compile and deploy +solc --bin MockScrollChain.sol -o /tmp/mock +BYTECODE=$(cat /tmp/mock/MockScrollChain.bin) +cast send --rpc-url http://localhost:18545 \ + --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \ + --create "0x$BYTECODE" +# → contractAddress: 0x1fA02b2d6A771842690194Cf62D91bdd92BfE28d + +# 3. Fund sender accounts and add prover +COMMIT_ADDR="0x1e32ABcfE6db15c1570709E3fC02725335f50A47" +FINALIZE_ADDR="0x33e0F539E31B35170FAaA062af703b76a8282bf7" +cast rpc anvil_setBalance "$COMMIT_ADDR" "0x3635c9adc5dea00000" --rpc-url http://localhost:18545 +cast rpc anvil_setBalance "$FINALIZE_ADDR" "0x3635c9adc5dea00000" --rpc-url http://localhost:18545 +cast send "addProver(address)" "$FINALIZE_ADDR" --rpc-url http://localhost:18545 \ + --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 +``` + +**Key sender config changes**: +```json +{ + "sender_config": { + "endpoint": "http://localhost:18545", + "dry_run": true + } +} +``` + +**Dry-run gas estimation skip**: Anvil may fail `EstimateGas` on blob transactions or missing functions. A small patch to `rollup/internal/controller/sender/estimategas.go` skips gas estimation in dry-run mode: +```go +func (s *Sender) estimateGasLimit(...) (uint64, *types.AccessList, error) { + if s.config.DryRun { + return 10000000, nil, nil // skip estimation + } + // ... original logic +} +``` + +### What We Verified in Practice + +| Transaction | Status | Notes | +|-------------|--------|-------| +| `commitBatches` | ✅ `eth_call` succeeded | Selector `0x9bbaa2ba` via mock `commitBatches(uint8,bytes32,bytes32)` | +| `finalizeBundlePostEuclidV2NoProof` | ✅ `eth_call` succeeded | Selector `0xbd6f916b` via mock no-op | +| `finalizeBundlePostEuclidV2` (with proof) | ✅ `eth_call` succeeded | Bundle 17301 with valid `OpenVMBundleProof` | + +### ⚠️ Critical Discovery: Anvil Must Fork Ethereum Mainnet, NOT Scroll Mainnet + +When querying `0xa13BAF47339d63B743e7Da8741db5456DAc1E556` on **Scroll L2** (`scroll-mainnet.g.alchemy.com`), the contract appears to have no ScrollChain functions and an empty implementation slot. This led to confusion — the address seemed to be a ProxyAdmin rather than the ScrollChain proxy. + +**The root cause**: We were querying the **wrong chain**. The ScrollChain proxy `0xa13B...` is deployed on **Ethereum L1**, not Scroll L2. When queried on Ethereum mainnet: + +- **Implementation**: `0x0a20703878e68e587c59204cc0ea86098b8c3ba7` (ScrollChain logic) +- **Admin**: `0xEB803eb3F501998126bf37bB823646Ed3D59d072` (ProxyAdmin) +- **Functions verified**: `lastFinalizedBatchIndex()`, `committedBatches(uint256)`, `isSequencer(address)`, `isProver(address)`, `commitBatches(uint8,bytes32,bytes32)`, `finalizeBundlePostEuclidV2(bytes,uint256,bytes32,bytes32,bytes)` + +### Real ScrollChain Proxy Dry-Run Testing + +For testing against the **actual deployed ScrollChain contract** on an Anvil fork: + +```bash +# 1. Start Anvil forked from ETHEREUM mainnet (NOT Scroll mainnet) +anvil --fork-url https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY \ + --fork-block-number 25206000 \ + --port 18545 \ + --no-rate-limit \ + --block-time 5 + +# 2. Run takeover script (impersonate owner, add sequencer/prover) +# See scroll-devnets/charts/shadow-fork/rollup-relayer/scripts/takeover-l1-contracts.sh +# Key addresses: +# L1_SCROLL_CHAIN_PROXY_ADDR=0xa13BAF47339d63B743e7Da8741db5456DAc1E556 +# L1_SCROLL_OWNER_ADDR=0x798576400F7D662961BA15C6b3F3d813447a26a6 +# FORKED_L1_SCROLL_OWNER_ADDR=0x909D2900A1Ec2B518EAFe11811Da0c1Fc8729a73 +# FORKED_L1_SCROLL_OWNER_PRIVATE_KEY=0x93d9b2e68479131dfa877a77cef8a286986940ab2de677a4790d17267462dd5e + +# 3. Set balances for relayer senders +COMMIT_ADDR="0x1e32ABcfE6db15c1570709E3fC02725335f50A47" +FINALIZE_ADDR="0x33e0F539E31B35170FAaA062af703b76a8282bf7" +cast rpc anvil_setBalance "$COMMIT_ADDR" "0x21e19e0c9bab2400000" --rpc-url http://localhost:18545 +cast rpc anvil_setBalance "$FINALIZE_ADDR" "0x21e19e0c9bab2400000" --rpc-url http://localhost:18545 + +# 4. Configure relayer to use REAL proxy address +# In config: "rollup_contract_address": "0xa13BAF47339d63B743e7Da8741db5456DAc1E556" +``` + +**Important**: If blob base fee is extremely high on the forked block (causing `Insufficient funds`), mine empty blocks to reduce `excessBlobGas`: +```bash +cast rpc anvil_mine 400 --rpc-url http://localhost:18545 +``` + +### Dry-Run Results with Real ScrollChain Proxy + +| Transaction | Status | Notes | +|-------------|--------|-------| +| `commitBatches` | ⚠️ `eth_call` reached contract | Reverted with `ErrorIncorrectBatchHash()` — shadow DB batch data is ahead of fork block state | +| `finalizeBundlePostEuclidV2` | ✅ **Succeeded** | Bundle 17330 (batch 517809) finalized successfully with real mainnet proof. See "End-to-End finalizeBundlePostEuclidV2 Dry-Run Success" below. | + +**Why `commitBatches` reverts**: The shadow DB contains batches 518565+ but the Anvil fork block (25206000) only has batches committed up to ~517816. The parent batch hash in the calldata doesn't match what the contract expects, triggering `ErrorIncorrectBatchHash()`. + +This is **expected and actually confirms the pipeline works** — the relayer is successfully constructing and sending calldata to the real ScrollChain implementation, and the contract's validation logic is executing correctly. + +For `finalizeBundlePostEuclidV2`, the batch was already committed on mainnet at the fork block, so no `commitBatches` call is needed — we only need the proof and verifier to match. + +--- + +## Real Verifier Deployment + +### Option 1: Copy the Mainnet Verifier (Fastest — Only if Digests Match) + +For quick testing, copy the exact mainnet verifier contract code to Anvil using `anvil_setCode`: + +```bash +# Copy mainnet ZkEvmVerifierPostFeynman wrapper (0x0dE1...) +MAINNET_VERIFIER="0x0dE180164Dc571522457101F5c47B2eaB36d0A82" +CODE=$(cast code $MAINNET_VERIFIER --rpc-url https://ethereum-rpc.publicnode.com) +cast rpc anvil_setCode $MAINNET_VERIFIER $CODE --rpc-url http://localhost:18545 + +# Copy its Plonk verifier (0x749f...) +PLONK="0x749fc77a1a131632a8b88e8703e489557660c75e" +PLONK_CODE=$(cast code $PLONK --rpc-url https://ethereum-rpc.publicnode.com) +cast rpc anvil_setCode $PLONK $PLONK_CODE --rpc-url http://localhost:18545 +``` + +This preserves the exact immutables (plonkVerifier address, digests, protocolVersion) from mainnet and works **only** if your proofs use the same digests as mainnet. When testing a new guest / circuit version (e.g., v0.9.0) whose digests differ from mainnet, this will produce `VerificationFailed`; use Option 2 instead. + +### Option 2: Deploy a Fresh Verifier Using S3 Digests + +When testing a new guest / circuit version (e.g., v0.9.0), deploy a fresh `ZkEvmVerifierPostFeynman` with digests taken from the release S3 bucket: + +```bash +BASE_URL="https://circuit-release.s3.us-west-2.amazonaws.com/scroll-zkvm/releases/v0.9.0" +DIGEST1=$(curl -fsSL "${BASE_URL}/bundle/digest_1.hex" | tr -d '[:space:]') +DIGEST2=$(curl -fsSL "${BASE_URL}/bundle/digest_2.hex" | tr -d '[:space:]') + +forge create --broadcast --evm-version cancun --rpc-url http://localhost:18545 \ + --from "$OWNER" --unlocked \ + src/libraries/verifier/ZkEvmVerifierPostFeynman.sol:ZkEvmVerifierPostFeynman \ + --constructor-args "$PLONK_VERIFIER" "0x$DIGEST1" "0x$DIGEST2" 10 +``` + +For v0.9.0 release assets are under `scroll-zkvm/releases/v0.9.0/`: + +| File | S3 Path | +|------|---------| +| Chunk/batch/bundle circuits | `.../releases/v0.9.0/{chunk,batch,bundle}//` | +| Verifier assets | `.../releases/v0.9.0/verifier/{openVmVk.json,verifier.bin,root_verifier_vk}` | +| Bundle digests | `.../releases/v0.9.0/bundle/{digest_1.hex,digest_2.hex}` | + +> ✅ **Use the S3 digest files directly.** For guest v0.9.0, `digest_1.hex` / `digest_2.hex` are published in the canonical form expected by the Plonk verifier. You no longer need to extract digests from a proof's `instances` array. + +### Important: `finalizeBundlePostEuclidV2` uses a `ZkEvmVerifierPostFeynman` verifier + +Do not be misled by the contract function name. `ScrollChain` only has one bundle-finalize entry point: + +```text +finalizeBundlePostEuclidV2(bytes,uint256,bytes32,bytes32,bytes) +``` + +There is **no** `finalizeBundlePostFeynman` function. The actual verifier used by this function is selected by `MultipleVersionRollupVerifier.getVerifier(version, batchIndex)`. For the current mainnet GalileoV2 range, that verifier is a `ZkEvmVerifierPostFeynman`-style wrapper whose `protocolVersion` immutable equals `10`. + +- `ZkEvmVerifierPostEuclid` computes `keccak256(publicInput)`. This is old code and is **not** used for current GalileoV2 / v0.9.0 proofs. +- `ZkEvmVerifierPostFeynman` computes `keccak256(abi.encodePacked(protocolVersion, publicInput))` with `protocolVersion = 10`. This matches the `bundle_pi_hash` produced by v0.9.0 guest provers. + +So on a shadow fork you must either: + +1. Copy the exact mainnet `ZkEvmVerifierPostFeynman` wrapper (only works if your local proofs use the **same digests** as mainnet), or +2. Deploy a fresh `ZkEvmVerifierPostFeynman` with the digests from the v0.9.0 S3 release and register it on the MVRV. + +### Verifying Digests Match Your Proofs + +If you want to double-check, compare the canonical digests from S3 against the values stored in the deployed wrapper: + +```bash +cast call "$WRAPPER" "verifierDigest1()(bytes32)" --rpc-url "$ANVIL_RPC" +cast call "$WRAPPER" "verifierDigest2()(bytes32)" --rpc-url "$ANVIL_RPC" +``` + +These must match the digests published at `.../releases/v0.9.0/bundle/{digest_1.hex,digest_2.hex}`. + +### Register the Verifier + +```bash +MVRV="0x4cea3e866e7c57fd75cb0ca3e9f5f1151d4ead3f" +OWNER="0x909d2900a1ec2b518eafe11811da0c1fc8729a73" +ANVIL_VERIFIER="0x0dE180164Dc571522457101F5c47B2eaB36d0A82" + +# Impersonate owner and register +cast rpc anvil_impersonateAccount $OWNER --rpc-url http://localhost:18545 +cast send $MVRV \ + "updateVerifier(uint256,uint64,address)" \ + 10 0 $ANVIL_VERIFIER \ + --from $OWNER --rpc-url http://localhost:18545 --unlocked +``` + +> **Note**: `latestVerifier[10]` returns a struct; use `getVerifier(10, batchIndex)` to confirm routing. + +### Verify MVRV Routing + +After registering a new verifier, **always verify that MVRV routes target batches to the correct verifier** before starting finalization tests. This is especially critical when testing new prover digests on batch ranges that may already be mapped to a legacy verifier. + +```bash +# Check which verifier MVRV returns for each batch in your target range +for idx in 128069 128070 128071; do + echo -n "Batch $idx → " + cast call $MVRV "getVerifier(uint256,uint256)(address)" 10 $idx --rpc-url http://localhost:18545 +done +``` + +If any batch returns the **wrong verifier** (e.g., an old production verifier whose digests don't match your proofs), update the MVRV mapping: + +```bash +# Route batches ≥ START_BATCH to the new verifier +START_BATCH=128069 +NEW_VERIFIER="0x16110D4e0CBE54530cE46D1aB2b22574BeEEa105" + +cast rpc anvil_impersonateAccount $OWNER --rpc-url http://localhost:18545 +cast send $MVRV \ + "updateVerifier(uint256,uint64,address)" \ + 10 $START_BATCH $NEW_VERIFIER \ + --from $OWNER --rpc-url http://localhost:18545 --unlocked +``` + +> **Critical**: If MVRV routes to the wrong verifier, finalization will revert with `VerificationFailed(0x439cc0cd)` even though your deployed verifier and proof digests are correct. + +### Critical Discovery: Anvil `eth_call` vs `anvil_setStorageAt` + +**Refined conclusion** (updated after further testing): + +- `anvil_setStorageAt` on **mapping slots** (e.g., `committedBatches[batchIndex]`) is visible to `eth_getStorageAt` but is **cached and ignored** by `eth_call` / `eth_sendTransaction` during contract execution. This is an Anvil bug. +- `anvil_setStorageAt` on **direct variable slots** (e.g., `miscData` at slot 161, `nextUnfinalizedQueueIndex` at slot 104) **does work** and is visible to `eth_call`. + +**Implications**: +- You **can** override simple state variables like `lastFinalizedBatchIndex`, `nextUnfinalizedQueueIndex`, etc. +- You **cannot** override mapping entries like `committedBatches[517809]` or `finalizedStateRoots[517808]`. +- For mappings, either fork at a block where the desired state already exists, or use a mock contract. + +### Deployed Contract Addresses (Anvil Fork) + +| Contract | Address | Notes | +|----------|---------|-------| +| ScrollChain Proxy | `0xa13BAF47339d63B743e7Da8741db5456DAc1E556` | Forked from mainnet | +| MultipleVersionRollupVerifier | `0x4CEA3E866e7c57fD75CB0CA3E9F5f1151D4Ead3F` | Forked from mainnet | +| **ZkEvmVerifierPostFeynman (v10)** | `0x0dE180164Dc571522457101F5c47B2eaB36d0A82` | **Copied from mainnet** ✅ | +| Plonk Verifier (v10) | `0x749fc77a1a131632a8b88e8703e489557660c75e` | Copied from mainnet | +| ZkEvmVerifierPostFeynman (wrong) | `0xc3230A4C89a5Ce0455414215e533de4D8849b3f8` | Deployed with S3 digests — **do not use** | + +--- + +## End-to-End finalizeBundlePostEuclidV2 Dry-Run Success + +We successfully executed `finalizeBundlePostEuclidV2` end-to-end on Anvil using **real mainnet proof data** from shadow DB bundle 17330. + +### Bundle 17330 Parameters + +| Field | Value | +|-------|-------| +| Bundle index | 17330 | +| Batch index | 517809 | +| Codec version | 10 (GalileoV2) | +| Num batches | 1 | +| `postStateRoot` | `0x28ff638e237ad6a0f2eebaab84f254dd4fca8a16297413c29fcd70f8b1b3fd85` | +| `withdrawRoot` | `0xe88d24e9153438c91f94c32026cb49730212f32ac4652367b07c71f96ce063d9` | +| `batchHash` | `0xeadeee9af865c6d13df6b66a45b3f3f161e6211aeb7d86e075a645f0e6a58f9e` | +| `prevStateRoot` | `0x4d21a5ca662bffc2d650a4d24a445617c3eb7159a28b13548ec5421a3ba08ee7` | +| `prevBatchHash` | `0xd6d7d027ef32d393a4aff7b04c1577bcb1f7fdc44834797e48f7e01581615a58` | +| `totalL1MessagesPoppedOverall` | 998288 | +| `msgQueueHash` | `0x5b08e5befde15d3acbf1a3e0e99622a6ac3fa62049cdfa62ba984ab700000000` | +| Mainnet finalize tx | `0x753f8f9ca01d4e67f710c6dab8ce0b17a17a7ad46a9d7480d92657803a36ca24` | + +### Public Input Verification + +The 204-byte public input is constructed as: + +``` +chain_id(8) || msg_queue_hash(32) || num_batches(4) || prev_state_root(32) || prev_batch_hash(32) || post_state_root(32) || batch_hash(32) || withdraw_root(32) +``` + +The `ZkEvmVerifierPostFeynman` contract prepends `protocolVersion = 10` (32 bytes) and computes: + +```solidity +publicInputHash = keccak256(abi.encodePacked(protocolVersion, publicInput)) +``` + +- `protocolVersion` = 10 (GalileoV2) +- `publicInput` = 204 bytes (standard EuclidV2 format) +- Actual input to keccak256 = **236 bytes** (32-byte version prefix + 204-byte public input) + +Computed hash: `0xcd4421bad526bd108d9ae8c2af3d46ea1a986207f0b8c1af781b601c1ae50e5a` + +This **exactly matches** `bundle_pi_hash` from the proof metadata. + +#### Bundle Proof Format + +The `aggrProof` passed to `finalizeBundlePostEuclidV2` is: + +``` +bundleProof = instances[:384] + proof_bytes = 1760 bytes total +├── 384 bytes = accumulator (12 Fr elements) +└── 1376 bytes = Plonk proof +``` + +The `ZkEvmVerifierPostFeynman.verify()` function inserts `digest1`, `digest2`, and `publicInputHash` expansion into the calldata before forwarding to the Plonk verifier. + +### Pre-Execution Setup Required + +Because the Anvil fork block (25213457) is **after** the real finalization block (25198501), several state variables had already advanced past the values needed for the dry-run. We applied the following fixes: + +#### 1. Add Authorized Prover + +The prover authorization was lost after `anvil_reset`. Re-add: + +```bash +SCROLL_CHAIN="0xa13BAF47339d63B743e7Da8741db5456DAc1E556" +OWNER="0x798576400F7D662961BA15C6b3F3d813447a26a6" +PROVER="0xc48DfbcdC4ef4cdACFf94eE7385020b7a7CE195f" + +cast rpc anvil_setBalance $OWNER 0x56bc75e2d63100000 --rpc-url http://localhost:18545 +cast send $SCROLL_CHAIN "addProver(address)" $PROVER \ + --from $OWNER --rpc-url http://localhost:18545 --unlocked +``` + +> ⚠️ **Anvil Default Account Is Not an EOA**: Anvil's default test account `0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266` has contract code (`0xef0100...`) in fork mode. `ScrollChain.addProver()` checks `_account.code.length == 0` and will revert with `ErrorAccountIsNotEOA`. Always use a freshly generated EOA (e.g., from `cast wallet new`) as the prover address. +> +> If the real owner account is an EOA with delegation code (e.g., ERC-7702), you may need to temporarily swap the proxy owner via `anvil_setStorageAt` on slot 51, call `addProver`, then restore the original owner. + +#### 2. Override `lastFinalizedBatchIndex` + +Set `miscData` (slot 161) so `lastFinalizedBatchIndex = 517808`: + +```bash +cast rpc anvil_setStorageAt $SCROLL_CHAIN 0xa1 \ + 0x0000000000000000000000016a1bb977000000000007e6b0000000000007e6d3 \ + --rpc-url http://localhost:18545 +``` + +> Layout: `lastCommitted(8) | lastFinalized(8) | lastFinalizeTimestamp(4) | flags(1) | reserved(7)` + +#### 3. Override `L1MessageQueueV2.nextUnfinalizedQueueIndex` + +Set slot 104 to `0` (the finalize call will update it to 998288): + +```bash +MQV2="0x56971da63A3C0205184FEF096E9ddFc7A8C2D18a" +cast rpc anvil_setStorageAt $MQV2 0x68 0x0 --rpc-url http://localhost:18545 +``` + +#### 4. Copy Mainnet Verifier + +See "Real Verifier Deployment" above for the `anvil_setCode` commands to copy the mainnet verifier wrapper and its Plonk verifier. + +### Execution + +```bash +# Extract proof from mainnet finalize transaction +python3 << 'PYEOF' +import subprocess, json +result = subprocess.run([ + 'cast', 'tx', '0x753f8f9ca01d4e67f710c6dab8ce0b17a17a7ad46a9d7480d92657803a36ca24', + '--json', '--rpc-url', 'https://ethereum-rpc.publicnode.com' +], capture_output=True, text=True) +tx = json.loads(result.stdout) +input_hex = tx['input'] +data = bytes.fromhex(input_hex[2:]) +# ... decode batchHeader, totalL1MessagesPoppedOverall, postStateRoot, withdrawRoot, aggrProof +PYEOF + +# Send transaction +SCROLL_CHAIN="0xa13BAF47339d63B743e7Da8741db5456DAc1E556" +PROVER="0xc48DfbcdC4ef4cdACFf94eE7385020b7a7CE195f" + +cast rpc anvil_setBalance $PROVER 0x56bc75e2d63100000 --rpc-url http://localhost:18545 +cast send $SCROLL_CHAIN --from $PROVER $(cat /tmp/finalize_calldata.hex) \ + --rpc-url http://localhost:18545 --unlocked +``` + +### Result + +- **Transaction Hash**: `0x0000ba738dbcc27e89db8e545532cdc125a9d50c42683032d92ed30203ea8d65` +- **Status**: Success ✅ +- **Gas Used**: 425,719 +- **Block**: 25213522 + +### Post-Execution State + +| Variable | Value | +|----------|-------| +| `lastFinalizedBatchIndex` | 517809 | +| `finalizedStateRoots[517809]` | `0x28ff638e237ad6a0f2eebaab84f254dd4fca8a16297413c29fcd70f8b1b3fd85` | +| `L1MessageQueueV2.nextUnfinalizedQueueIndex` | 998288 | + +### Key Takeaways + +1. **Always deploy `ZkEvmVerifierPostFeynman` with S3 digests** — For guest v0.9.0 the canonical digests are published at `.../releases/v0.9.0/bundle/digest_*.hex`. Use them directly; do not attempt to copy the mainnet verifier wrapper (`anvil_setCode` preserves the original immutables and will fail verification). +2. **`anvil_setStorageAt` works for direct variables** but not for mapping entries. Use it for `miscData`, `nextUnfinalizedQueueIndex`, etc. +3. **Fork block matters** — If the fork block is after the real finalization, you must manually reset `lastFinalizedBatchIndex` and `nextUnfinalizedQueueIndex`. +4. **Public input hash must match exactly** — Any discrepancy in `msg_queue_hash`, `chain_id`, `num_batches`, or roots will cause `VerificationFailed`. +5. **Anvil default account is not an EOA in fork mode** — Use a freshly generated EOA for `addProver`; `0xf39F...` has contract code and will fail the EOA check. +6. **Reset `rollup_status` before relayer finalize** — The shadow DB retains mainnet rollup state (`RollupFinalized` = 5). The relayer's `GetFirstPendingBundle` only queries `rollup_status = RollupPending` (1). You must reset both `bundle` and `batch` tables before the relayer will pick up bundles for finalization. + +## Multi-Bundle Relayer Finalize Test (5 Bundles) + +This test demonstrates running the actual `rollup_relayer` binary against an Anvil mainnet fork to finalize **5 consecutive bundles** (17297–17301, batches 517761–517765) using shadow proofs. + +### Prerequisites + +- Anvil fork running with `lastFinalizedBatchIndex` reset to `517760` +- Shadow proofs generated for all 5 bundles (`proving_status = 4`) +- Verifier `0xb1F2C5c1ea2885278a1070350d12d3D8824265B0` registered as `latestVerifier[10]` +- Prover/finalize EOA `0x410E...` authorized on `ScrollChain` + +### Step 1: Reset DB Rollup Status + +The shadow DB retains mainnet rollup state. Before the relayer can pick up bundles, reset their status: + +```sql +UPDATE bundle SET rollup_status = 1 WHERE index BETWEEN 17297 AND 17301; +UPDATE batch SET rollup_status = 1 WHERE index BETWEEN 517761 AND 517765; +``` + +(`1` = `RollupPending`; without this, `GetFirstPendingBundle` returns nothing.) + +### Step 2: Build and Configure Relayer + +```bash +cd rollup +go build -o /tmp/rollup_relayer ./cmd/rollup_relayer +``` + +Create `/tmp/rollup-relayer-anvil.json`: + +```json +{ + "l2_config": { + "l2_geth": { "endpoint": "https://mainnet-galileo.scroll.io/l2" }, + "relayer_config": { + "sender_config": { + "endpoint": "http://localhost:18545", + "check_balance": false, + "dry_run": false + }, + "commit_sender_signer_config": { + "private_key": "0xac09..." + }, + "finalize_sender_signer_config": { + "private_key": "0x01f1..." + }, + "rollup_contract_address": "0xa13BAF47339d63B743e7Da8741db5456DAc1E556", + "chain_monitor": { "enabled": false }, + "gas_oracle": { "enabled": false }, + "batch_committer": { + "enable_test_env_bypass_features": true + }, + "validium_mode": false + } + }, + "db_config": { + "dsn": "postgresql://postgres:shadow_pass@localhost:5433/shadow_rollup" + } +} +``` + +**Important**: `commit_sender` and `finalize_sender` must be **different addresses**. The relayer enforces this at startup. + +### Step 3: Launch Relayer + +```bash +/tmp/rollup_relayer \ + --config /tmp/rollup-relayer-anvil.json \ + --genesis /home/scroll/zzhang/scroll/tests/prover-e2e/mainnet-galileoV2/genesis.json \ + --min-codec-version 7 \ + --verbosity 3 \ + 2>&1 | tee /tmp/relayer.log +``` + +The relayer starts all modules (L2 watcher, proposers, batch committer, bundle finalizer). The batch committer will fail with `ErrorCallerIsNotSequencer` (expected — the commit sender is not a sequencer), but the **bundle finalizer runs independently every 15 seconds** and will pick up the pending bundles. + +### Step 4: Monitor Finalization + +Watch `/tmp/relayer.log` for: + +``` +{"msg":"Start to roll up zk proof","index":17297,...} +{"msg":"finalizeBundle in layer1","index":17297,"tx hash":"0x6d62...","with proof":"true"} +``` + +### Results + +| Bundle | Batch | Transaction Hash | Status | Gas Used | +|--------|-------|------------------|--------|----------| +| 17297 | 517761 | `0x6d6264...cdaa725` | ✅ Success | 439,987 | +| 17298 | 517762 | `0x071268...1136516` | ✅ Success | 407,455 | +| 17299 | 517763 | `0x8f8894...6cabd5` | ✅ Success | 407,479 | +| 17300 | 517764 | `0xa87721...302cd3` | ✅ Success | 407,419 | +| 17301 | 517765 | `0x41ee42...c9cf89` | ✅ Success | 401,404 | + +**Final `lastFinalizedBatchIndex`**: `517765` (was `517760`) + +All 5 bundles finalized consecutively without manual intervention. Each bundle proof was verified on-chain by the `ZkEvmVerifierPostFeynman` contract deployed at `0xb1F2C5c1ea2885278a1070350d12d3D8824265B0`. + +### Key Differences from CLI Approach + +| Aspect | CLI (`cast send`) | Relayer | +|--------|-------------------|---------| +| Calldata construction | Manual Python script | Relayer reads from DB + constructs automatically | +| Sender management | Single EOA | Separate commit/finalize senders | +| Batch status tracking | None | Updates `bundle` and `batch` `rollup_status` in DB | +| Error handling | Manual retry | Built-in retry and status polling | +| Multi-bundle support | One at a time | Processes all pending bundles automatically | + +## Known Limitations + +1. **L1 messages**: If chunks contain L1 messages, the prover needs `scroll_getL1MessagesInBlock` RPC support. Most public RPCs don't expose this. Workaround: select chunks/blocks with no L1 messages, or use an internal RPC. In non-validium mode, the prover does not call this RPC at all. + +2. **Full batch proving**: Batch tasks require `chunk_proofs_status = 2` (all chunks proven). For quick chunk-only testing, you don't need to prove full batches. + +3. **Coordinator startup time**: First startup performs OpenVM keygen (~2-3 min). Be patient. + +4. **Circuit download**: First prover run downloads ~5-10GB of circuit assets. Ensure good internet. + +5. **Bundle vs batch count mismatch**: The shadow DB's `bundle` table may contain 10,000+ historical records while `batch` only holds ~500 recent ones. This is expected when importing production data — the bundle table retains full history but batches are truncated. **Crucially**, orphan bundles (those with no matching batches) must have `batch_proofs_status = 1` or coordinator will deadlock trying to prove them. See "Bundle proving never starts" in Troubleshooting. + +6. **`finalizeBundlePostEuclidV2` and multi-batch bundles**: The contract computes `numBatches = batchIndex - lastFinalizedBatchIndex`. The proof's `num_batches` must exactly match this value. Single-batch bundles (e.g., bundle 17330 = batch 517809) are the easiest to test because `numBatches = 1`. Multi-batch bundles also work as long as `lastFinalizedBatchIndex` is set so that `batchIndex - lastFinalizedBatchIndex` equals the proof's `num_batches`. + +7. **Local E2E proofs cannot be used on mainnet fork**: Local E2E proofs are generated against a different chain state (genesis batch, different state roots, different message queue). Even if you deploy matching verifier digests, the public input (state roots, batch hashes, message queue hash) will not match the forked mainnet contract state, causing `VerificationFailed`. + +## Automated DB Replication from Mainnet RDS + +The `~/.pgpass` file on this machine contains valid credentials for the mainnet RDS read-only replica: + +```bash +# Verify access +cast psql -h localhost -p 15432 -U mainnet_infra_team_read_only -d mainnet_rollup -c "SELECT COUNT(*) FROM batch;" +# → 517,830 batches +``` + +For automated DB sync, see `scroll-devnets/charts/shadow-fork/rollup-relayer/scripts/copy-db.sh` which uses `postgres-tunnel` to stream data from mainnet RDS to local shadow DB via `COPY ... TO STDOUT | COPY ... FROM STDIN`. + +## Common DB Fixes + +After importing production data or running for extended periods, these SQL fixes resolve common coordinator deadlocks: + +### 1. Reset proving status after import +```sql +UPDATE chunk SET proving_status = 1, total_attempts = 0, active_attempts = 0; +UPDATE batch SET proving_status = 1, total_attempts = 0, active_attempts = 0, chunk_proofs_status = 0; +UPDATE bundle SET proving_status = 1, total_attempts = 0, active_attempts = 0; +``` + +### 2. Mark orphan bundles (no linked batches) +```sql +UPDATE bundle +SET batch_proofs_status = 1 +WHERE index NOT IN ( + SELECT DISTINCT b.index + FROM bundle b + JOIN batch bat ON bat.index BETWEEN b.start_batch_index AND b.end_batch_index +); +``` + +### 3. Fix stale assigned chunks without proofs +```sql +UPDATE chunk SET proving_status = 1, total_attempts = 0, active_attempts = 0 +WHERE proving_status = 2 AND proof IS NULL; + +UPDATE batch SET chunk_proofs_status = 0 +WHERE chunk_proofs_status != 0 + AND EXISTS ( + SELECT 1 FROM chunk c + WHERE c.batch_hash = batch.hash AND c.proving_status != 4 + ); +``` + +## Scripts Reference + +| Script | Purpose | +|--------|---------| +| `setup.sh` | One-command setup for PostgreSQL, coordinator, or prover | +| `import-production-data.sh` | Export from production RDS and import to shadow DB | +| `fetch-l2-blocks.py` | Fetch block headers from L2 RPC and populate `l2_block` table | diff --git a/tests/shadow-testing/docs/TROUBLESHOOTING.md b/tests/shadow-testing/docs/TROUBLESHOOTING.md new file mode 100644 index 0000000000..29d0f6f7ff --- /dev/null +++ b/tests/shadow-testing/docs/TROUBLESHOOTING.md @@ -0,0 +1,286 @@ +# Troubleshooting & Pitfalls + +> **Read this file first** before starting any shadow fork or shadow coordinator test. +> This directory contains hard-won knowledge from multiple debugging sessions. Blind experimentation will repeat documented mistakes. + +## Pre-Flight Ritual (Mandatory) + +Before executing a single command: + +1. [ ] **Read root `AGENTS.md`** (this file) — refresh the trap list. +2. [ ] **Read `docs/TROUBLESHOOTING.md`** — check if your planned task matches any documented failure mode. +3. [ ] **Read `docs/GUIDE.md`** — verify the specific section matching your task (e.g., "Real Verifier Deployment", "Multi-Bundle Relayer Finalize Test"). +4. [ ] **Verify network** — confirm you are testing **Mainnet** or **Sepolia**, and all configs/ports/RPCs match that network. +5. [ ] **Verify target bundle range** — query the DB to confirm: + - Bundles exist and have `proving_status = 4` (or will be regenerated) + - Parent batch of the first target batch exists in the DB + - All bundle end batches have `committedBatches` entries on Anvil (or will be seeded) + +## Mainnet vs Sepolia — Decision Table + +| Check | Mainnet | Sepolia | Verification Command | +|-------|---------|---------|---------------------| +| DB port | `5433` or `15432` | `25432` | `psql -h localhost -p -c "SELECT version();"` | +| L2 RPC | `l2geth-rpc-proxy.mainnet.aws.scroll.io` | `l2geth-rpc-proxy.sepolia.aws.scroll.io` | `curl -X POST -d '{"method":"debug_executionWitness","params":["latest"],"id":1}'` | +| Anvil fork URL | `eth-mainnet.g.alchemy.com` | `eth-sepolia.g.alchemy.com` | `cast block-number --rpc-url ` | +| ScrollChain proxy | `0xa13BAF47339d63B743e7Da8741db5456DAc1E556` | `0x2D567EcE699Eabe5afCd141eDB7A4f2D0D6ce8a0` | `cast call "lastFinalizedBatchIndex()(uint256)"` | +| MVRV | `0x4CEA3E866e7c57fD75CB0CA3E9F5f1151D4Ead3F` | `0x8A360c7F6fca548507017DdeD732bFe7E078F963` | `cast call "latestVerifier(uint256)" 10` | +| L1MessageQueueV2 | `0x56971da63A3C0205184FEF096E9ddFc7A8C2D18a` | `0xA0673eC0A48aa924f067F1274EcD281A10c5f19F` | `cast call "nextUnfinalizedQueueIndex()(uint256)"` | +| Verifier | Copy from mainnet (`anvil_setCode`) | Check MVRV first; may already match | `cast call "getVerifier(uint256,uint256)" 10 ` | + +## Critical Traps (Do Not Skip) + +### Trap 1: Wrong Verifier Contract or Wrong Digest Form +- **Symptom**: `VerificationFailed(0x439cc0cd)` even with correct digests. +- **Cause A**: Deployed `ZkEvmVerifierPostEuclid` instead of `ZkEvmVerifierPostFeynman`. +- **Cause B**: Used digests in the wrong form. For v0.9.0 the S3 `digest_1.hex` / `digest_2.hex` files are published in **canonical form**, but if you are re-using an old v0.8.0 workflow that converted from Montgomery form, double-check you are not applying the conversion twice. +- **Cause C**: **MVRV routes the batch to the wrong verifier**. The deployed verifier's digests are correct, but `MultipleVersionRollupVerifier.getVerifier(10, batchIndex)` returns an old verifier with different digests. This happens when re-proving bundles with a new prover (new digests) whose batch indices fall in a range still mapped to a legacy verifier. +- **Rule**: For guest v0.9.0 proofs, **always use `PostFeynman`** with digests from `.../releases/v0.9.0/bundle/digest_*.hex`, and **verify MVRV routing** before finalizing. +- **Verification — Digests**: Fetch canonical digests from S3 and deploy with `protocolVersion = 10`: + ```bash + BASE_URL="https://circuit-release.s3.us-west-2.amazonaws.com/scroll-zkvm/releases/v0.9.0" + DIGEST1=$(curl -fsSL "${BASE_URL}/bundle/digest_1.hex" | tr -d '[:space:]') + DIGEST2=$(curl -fsSL "${BASE_URL}/bundle/digest_2.hex" | tr -d '[:space:]') + ``` + The S3 files are already in canonical form; no conversion or proof extraction is required. +- **Verification — MVRV Routing**: Before finalizing, confirm the verifier returned by MVRV for each target batch matches the verifier whose digests match the proofs: + ```bash + for idx in 128069 128070 128071; do + cast call $MVRV "getVerifier(uint256,uint256)(address)" 10 $idx --rpc-url $ANVIL_RPC + done + ``` + If any batch returns the old verifier while proofs use new digests, update MVRV: + ```bash + cast rpc anvil_impersonateAccount $OWNER --rpc-url $ANVIL_RPC + cast send $MVRV \ + "updateVerifier(uint256,uint64,address)" \ + 10 $START_BATCH $NEW_VERIFIER \ + --from $OWNER --rpc-url $ANVIL_RPC --unlocked + ``` + +### Trap 2: Anvil Forks Wrong Chain +- **Symptom**: `ScrollChain` proxy has no code, or `eth_chainId` returns `534352`. +- **Cause**: Anvil pointed at Scroll L2 RPC instead of Ethereum L1 RPC. +- **Rule**: Anvil must fork **Ethereum L1** (`chainId=1`). The ScrollChain proxy lives on L1. + +### Trap 3: L2 RPC Missing `debug_executionWitness` +- **Symptom**: Coordinator panics at startup or chunks never get assigned. +- **Cause**: Public RPC (`mainnet-rpc.scroll.io`, `sepolia-rpc.scroll.io`) blocks debug methods. +- **Rule**: Use **internal** L2 RPC proxies only. + +### Trap 4: `committedBatches` Sparse (EuclidV2) +- **Symptom**: `ErrorIncorrectBatchHash(0x2a1c1442)`. +- **Cause**: EuclidV2 only stores the **last batch hash** of each commit tx. Intermediate batches have `committedBatches[index] = 0x0`. +- **Rule**: The contract checks `committedBatches[batchIndex]` where `batchIndex` is the **end batch** of the bundle. Verify this is non-zero before finalizing. + +### Trap 5: `L1MessageQueueV2` Index Mismatch (Sepolia) +- **Symptom**: `ErrorFinalizedIndexTooLarge(0x16465978)` or `ErrorFinalizedIndexTooSmall`. +- **Cause**: `nextUnfinalizedQueueIndex` does not match the pre-finalization state expected by the first target batch. The fork block is AFTER real finalization, so the real state has post-finalization values. +- **Rule**: + 1. Set `nextUnfinalizedQueueIndex` to `MIN(total_l1_messages_popped_before)` of the first target batch's chunks (from DB). + 2. **Use `forge inspect L1MessageQueueV2 storage-layout`** to find the exact storage slot (it's slot 104, NOT slot 0 or 4, due to OpenZeppelin `__gap`). + 3. Never guess storage slots from source code. + +### Trap 6: Parent Batch Missing +- **Symptom**: Relayer logs `Batch.GetBatchByIndex error: record not found, index: `. +- **Cause**: Shadow DB imported bundles starting at batch N, but batch N-1 was not imported. +- **Rule**: Always insert the parent batch skeleton before starting the relayer. Only `state_root` must be accurate. + +### Trap 7: Relayer Nonce Desync +- **Symptom**: Tx sent but never mined; `eth_getTransactionReceipt` returns null forever. +- **Cause**: `pending_transaction` table retains nonces from previous runs that were never confirmed. Relayer initializes nonce from `maxDbNonce + 1`, which is ahead of the on-chain nonce. +- **Rule**: After any relayer crash or Anvil restart: + ```sql + DELETE FROM pending_transaction WHERE sender_address = ''; + ``` + Then restart the relayer. + +### Trap 8: Production Proof Overwrite +- **Symptom**: `VerificationFailed` after importing production data. +- **Cause**: Import script copied `proof` columns from production RDS, overwriting locally-valid shadow proofs. +- **Rule**: **Never import `proof` columns**. Import only metadata, then reset `proving_status = 1` and re-prove locally. + +### Trap 9: Anvil `eth_estimateGas` Rejects Fee Caps +- **Symptom**: `failed to get fee data, err: Out of gas: gas required exceeds allowance: 0`. +- **Cause**: Anvil's `eth_estimateGas` fails when `CallMsg` has `GasFeeCap`/`GasTipCap` set but `Gas` is 0 (Go Ethereum client's default). +- **Rule**: If you hit this on a shadow fork, the correct fix belongs in the upstream `rollup/internal/controller/sender/estimategas.go` (do not maintain a local patch in this branch). Verify with the latest `develop` code and, if still present, fix it there so all shadow tests benefit. + +### Trap 10: Sender Balance Lost After Anvil Restart +- **Symptom**: `failed to send transaction, err: Insufficient funds for gas * price + value` even after successful gas estimation. +- **Cause**: `anvil_setBalance` funds do not persist across Anvil restarts. +- **Rule**: After every Anvil restart, verify and re-fund sender EOAs before starting the relayer: + ```bash + cast balance 0x410E7FD80a3Fc1E62A4D3450d11b71b812006eB9 --rpc-url http://localhost:18546 + ``` + +### Trap 11: Relayer Started Without Required Flags +- **Symptom**: Relayer prints help and exits with `Required flag "min-codec-version" not set`, or connects to wrong DB. +- **Cause**: `ROLLUP_RELAYER_CONFIG` env var is NOT supported. The relayer uses `--config` CLI flag. +- **Rule**: Always start relayer with BOTH flags: + ```bash + ./rollup_relayer --config /path/to/config.json --min-codec-version 10 + ``` + +### Trap 12: halo2 SRS Not in `~/.openvm/params/` +- **Symptom**: chunk/batch proofs succeed; the **first bundle proof** crashes the prover with + `Params file ".../.openvm/params/kzg_bn254_23.srs" does not exist`. Bundle stuck at `proving_status=2`. +- **Cause**: openvm reads the KZG SRS from `$HOME/.openvm/params/kzg_bn254_{22,23,24}.srs` only at the + bundle proof's halo2 stage; if the `.srs` files sit in `~/.openvm/` root (or anywhere else) they are + silently not found. +- **Rule**: `mkdir -p ~/.openvm/params && mv ~/.openvm/kzg_bn254_2{2,3,4}.srs ~/.openvm/params/`. Mount the + host openvm dir to `/root/.openvm` (writable) for the prover container and confirm the path resolves. + +### Trap 13: Prover Docker `--gpus device=N` + Wrong `CUDA_VISIBLE_DEVICES` +- **Symptom**: prover container exits (code 139) with `cudaErrorNoDevice: no CUDA-capable device is detected`; + only the GPU-0 prover works. +- **Cause**: `--gpus "device=N"` exposes only that GPU and **renumbers it to index 0** inside the container, + so `CUDA_VISIBLE_DEVICES=N` points at a nonexistent device. +- **Rule**: use `--gpus "device=$i"` with `CUDA_VISIBLE_DEVICES=0` (or `--gpus all` with `CUDA_VISIBLE_DEVICES=$i`). + +### Trap 14: Coordinator Verifier Assets vs Prover Circuit S3 Paths (v0.9.0) +- **Symptom**: coordinator asset download 403s or prover cannot find circuit apps. +- **Cause**: Starting with v0.9.0, both verifier assets and circuit apps are released under a unified `scroll-zkvm/releases/v0.9.0/` prefix. Earlier versions split them across `v0.8.0/verifier/` and `scroll-zkvm/galileov2/`. +- **Rule**: For v0.9.0, point both coordinator verifier assets and prover `circuits.galileoV2.base_url` at `…/scroll-zkvm/releases/v0.9.0/`. The expected layout is `{chunk,batch,bundle}//` for circuits and `verifier/` for coordinator assets. + +### Trap 15: Slow `l2_block` Export by `chunk_hash` JOIN +- **Symptom**: `00-import-bundle-range.sh` hangs for minutes on the `l2_block` export (0-byte CSV) — the + `l2_block ⋈ chunk ON chunk_hash` JOIN full-scans the huge prod table. +- **Rule**: export `l2_block` by **block-number range** instead: + `COPY (SELECT * FROM l2_block WHERE number BETWEEN AND ) TO STDOUT …` + (PK-indexed, seconds). Derive the range from the target batches' chunks' `start_block_number` / + `end_block_number`. + +## Step-by-Step Checklist + +### Phase 0: Environment Validation +- [ ] DB reachable on correct port +- [ ] L2 RPC supports `debug_executionWitness` +- [ ] Anvil not already running on target port +- [ ] Coordinator port 8390 free +- [ ] Prover GPU available (`nvidia-smi`) + +### Phase 1: DB Setup +- [ ] Import bundle range from production RDS +- [ ] **Exclude `proof` columns** from import +- [ ] Reset `proving_status = 1` for chunks, batches, bundles +- [ ] Insert missing parent batch skeleton +- [ ] Populate `l2_block` table and link via `chunk_hash` + +### Phase 2: Anvil Fork Setup +- [ ] Start Anvil forked from **Ethereum L1** (not Scroll L2) +- [ ] Verify `eth_chainId == 1` +- [ ] Fund owner and sender accounts (verify balances after any Anvil restart) +- [ ] Add prover EOA to `ScrollChain` +- [ ] Set `lastFinalizedBatchIndex` to `(first_target_batch - 1)` +- [ ] Set `lastCommittedBatchIndex` to mainnet value (do NOT reset to lastFinalized) +- [ ] (Sepolia) Verify end-batch `committedBatches` hashes are non-zero on Anvil +- [ ] (Sepolia) Set `L1MessageQueueV2.nextUnfinalizedQueueIndex` to pre-finalization value: + ```sql + SELECT MIN(total_l1_messages_popped_before) + FROM chunk + WHERE batch_hash = (SELECT hash FROM batch WHERE index = ); + ``` +- [ ] (Sepolia) **Verify slot number with `forge inspect L1MessageQueueV2 storage-layout`** before `anvil_setStorageAt` + +### Phase 3: Verifier Setup + +**Determine which scenario you are in:** + +**Scenario A — Re-using production proofs (like bundles 13445-13449)** +- [ ] Extract digests from proof instances +- [ ] Query Sepolia MVRV: `cast call "getVerifier(uint256,uint256)" 10 ` +- [ ] Query verifier digests: `cast call "verifierDigest1()"` / `"verifierDigest2()"` +- [ ] If digests match → **skip deployment**, use existing verifier +- [ ] If digests DON'T match → you are actually in Scenario B + +**Scenario B — Testing new guest / circuit version (0.8.0 / openvm 1.6+)** +- [ ] Generate new proofs with the new prover (coordinator + prover pipeline) +- [ ] Extract digests from **newly-generated** proof instances +- [ ] Deploy plonk verifier from `coordinator/build/bin/assets_v2/verifier.bin` +- [ ] Deploy `ZkEvmVerifierPostFeynman` with new digests + `protocolVersion = 10` +- [ ] Register on `MultipleVersionRollupVerifier` via `updateVerifier(10, startBatch, verifier)` +- [ ] Verify with `getVerifier(10, batchIndex)` + +### Phase 4: Coordinator + Prover +- [ ] Coordinator config points to correct `assets_v2/` directory +- [ ] Coordinator L2 RPC is internal/debug-enabled +- [ ] Prover config `base_url` uses correct S3 path (no `/releases/` for v0.8.0) +- [ ] Start coordinator, wait for `Start coordinator api successfully` +- [ ] Start prover(s), verify `Got task from coordinator` + +### Phase 5: Relayer Finalize +- [ ] Build relayer with latest code (rebuild if `estimategas.go` was patched for Anvil) +- [ ] Relayer config has `dry_run: false`, correct contract addresses +- [ ] Clear stale `pending_transaction` entries +- [ ] Reset target bundles/batches to `rollup_status = 1` +- [ ] **Start relayer with `--config ` AND `--min-codec-version 10`** +- [ ] Monitor logs for `finalizeBundle in layer1` success +- [ ] Verify `lastFinalizedBatchIndex` advanced on Anvil + +## When Things Go Wrong + +| Error / Symptom | Most Likely Cause | See | +|-----------------|-------------------|-----| +| `VerificationFailed(0x439cc0cd)` | Wrong verifier type or digest mismatch | Trap 1 | +| `ErrorIncorrectBatchHash(0x2a1c1442)` | Sparse `committedBatches`, end batch hash is zero | Trap 4 | +| `ErrorFinalizedIndexTooLarge(0x16465978)` | `nextUnfinalizedQueueIndex` too low or too high | Trap 5 | +| `record not found` (parent batch) | Parent batch not imported | Trap 6 | +| `Out of gas: gas required exceeds allowance: 0` | Anvil gas estimation bug with fee caps | Trap 9 | +| `Insufficient funds for gas * price + value` | Sender balance is 0 on Anvil | Trap 10 | +| Tx sent but never mined | Nonce desync (`pending_transaction` stale) | Trap 7 | +| Relayer exits with `Required flag "min-codec-version" not set` | Missing CLI flags | Trap 11 | +| Coordinator assigns but prover gets nothing | L2 RPC missing `debug_executionWitness` | README.md | +| `CoordinatorEmptyProofData` | Prover crashed; reset stuck tasks | README.md | +| `Params file ".../kzg_bn254_23.srs" does not exist` (bundle proof crash) | halo2 SRS not in `~/.openvm/params/` | Trap 12 | +| Prover exits 139 `cudaErrorNoDevice` | `--gpus device=N` + wrong `CUDA_VISIBLE_DEVICES` | Trap 13 | +| Coordinator asset download 403 (`galileov2/verifier/...`) | Wrong S3 prefix; use `v0.8.0/verifier/` | Trap 14 | +| `l2_block` export hangs for minutes | Slow `chunk_hash` JOIN; export by block-number range | Trap 15 | + +## Lessons from the v0.9.0 Multi-Bundle Shadow Test + +The following issues were hit while finalizing bundles 17297–17301 (batches 517761–517765) on an Anvil mainnet fork with zkvm guest prover v0.9.0. Keep them in mind for future upgrades. + +### 1. Do not `git checkout --` uncommitted source changes blindly + +When cleaning up the branch, the v0.9.0 source adaptations (`libzkp`, `prover-bin`, Go `message` types, `rust-toolchain`, `Cargo.lock`) were accidentally reverted because they were not committed. They had to be reconstructed from compiler errors. Always check `git diff --stat` before a bulk revert, and stage or stash anything you intend to keep. + +### 2. `finalizeBundlePostEuclidV2` is the only finalize function, but the verifier must be Post-Feynman + +`ScrollChain` exposes only one bundle-finalize selector (`0xc1aa4e19`). The name says `PostEuclidV2`, but the verifier it actually calls is chosen by `MultipleVersionRollupVerifier.getVerifier(10, batchIndex)`. For GalileoV2 / v0.9.0 this must be a `ZkEvmVerifierPostFeynman`-style wrapper whose `protocolVersion` immutable is `10`. + +- `ZkEvmVerifierPostEuclid` computes `keccak256(publicInput)` — this is old code and will reject current proofs. +- `ZkEvmVerifierPostFeynman` computes `keccak256(protocolVersion || publicInput)` — this matches v0.9.0 `bundle_pi_hash`. + +### 3. Copying the mainnet verifier via `anvil_setCode` fails for new guest versions + +`anvil_setCode` copies runtime bytecode but **preserves the original immutables** (`plonkVerifier`, `verifierDigest1/2`, `protocolVersion`). If your local v0.9.0 proofs use different digests than mainnet, the wrapper will return `VerificationFailed`. For a new guest version, deploy a fresh `ZkEvmVerifierPostFeynman` using the S3 release digests. + +### 4. MVRV routing must be verified per target batch + +After deploying a new verifier, confirm that `MVRV.getVerifier(10, batchIndex)` returns your wrapper for every batch you intend to finalize. If the fork block already contains a later mainnet verifier registration, a plain `updateVerifier` may be rejected; force the storage slot or impersonate the owner as needed for the shadow fork. + +### 5. v0.9.0 dependency graph needs a fresh `Cargo.lock` + +Pointing `Cargo.toml` to v0.9.0 is not enough. The first `cargo check` hit a revm version conflict because the old `Cargo.lock` pinned incompatible crate versions. Regenerating `Cargo.lock` resolved it. + +### 6. Prover aggregation circuits need deferral enabled + +OpenVM v2+ requires `Prover::enable_deferral(child_prover)` before proving aggregation tasks: + +- Batch proving needs a chunk child prover. +- Bundle proving needs a batch child prover. + +The prover config therefore needs `child_circuit_vks` so the prover can load the correct child circuit assets. + +### 7. S3 digest files are canonical — no proof extraction needed + +For v0.9.0, `.../releases/v0.9.0/bundle/digest_1.hex` and `digest_2.hex` are published in the canonical form expected by the Plonk verifier. Do not apply Montgomery→canonical conversion and do not extract digests from proof `instances` unless you are double-checking a specific artifact. + +## Documentation Priority + +When debugging, read docs in this order: + +1. `docs/TROUBLESHOOTING.md` — fastest path to known traps +2. `docs/GUIDE.md` — detailed setup and procedures +3. `README.md` — quick reference for common commands +4. `../../AGENTS.md` (repo root) — cross-network rules and secrets reference diff --git a/tests/shadow-testing/docs/contract-addresses.md b/tests/shadow-testing/docs/contract-addresses.md new file mode 100644 index 0000000000..c9fdec1c8e --- /dev/null +++ b/tests/shadow-testing/docs/contract-addresses.md @@ -0,0 +1,81 @@ +# Scroll L1 Contract Addresses + +> Auto-generated from genesis configs and on-chain queries. +> Last updated: 2026-05-31 + +## Mainnet (Ethereum L1) + +| Contract | Address | Verified Source | +|----------|---------|-----------------| +| **ScrollChain Proxy** | `0xa13BAF47339d63B743e7Da8741db5456DAc1E556` | [Etherscan](https://etherscan.io/address/0xa13BAF47339d63B743e7Da8741db5456DAc1E556) | +| ScrollChain Implementation | `0x0a20703878e68E587c59204cc0EA86098B8c3bA7` | (from proxy slot) | +| **MultipleVersionRollupVerifier** | `0x4CEA3E866e7c57fD75CB0CA3E9F5f1151D4Ead3F` | [Etherscan](https://etherscan.io/address/0x4CEA3E866e7c57fD75CB0CA3E9F5f1151D4Ead3F) | +| L1MessageQueueV1 | `0x0d7E906BD9cAFa154b048cFa766Cc1E54E39AF9B` | genesis.json | +| L1MessageQueueV2 | `0x56971da63A3C0205184FEF096E9ddFc7A8C2D18a` | genesis.json | +| L2SystemConfig | `0x331A873a2a85219863d80d248F9e2978fE88D0Ea` | genesis.json | +| Scroll Owner | `0x798576400F7D662961BA15C6b3F3d813447a26a6` | `owner()` on-chain | + +### Mainnet Verifier History (from on-chain) + +| Version | Start Batch | Verifier Address | Type | +|---------|-------------|------------------|------| +| 7 | 364,588 | `0xc084a6De8b0F2742396572d6f110eC87ca9329bA` | legacy | +| 8 | 0 | `0xa8d4702Aa5c09AF5dD1323E1842a43789021F485` | pre-v0.8.0 | +| 8 | 0 | `0xc3230A4C89a5Ce0455414215e533de4D8849b3f8` | Anvil-deployed (wrong digests) | +| **10** | 0 | `0x0dE180164Dc571522457101F5c47B2eaB36d0A82` | **GalileoV2 (mainnet)** | + +### Mainnet Batch Status (as of block ~25,213,000) + +- `lastCommittedBatchIndex`: ~517,843 +- `lastFinalizedBatchIndex`: 517,843 +- `committedBatches(517809)`: `0xeadeee9af865c6d13df6b66a45b3f3f161e6211aeb7d86e075a645f0e6a58f9e` +- `committedBatches(517843)`: `0x40545c71ed8fdcaabc06ad64599e9fdd4a62c1e2fd599a6642f64d229f7762a6` + +--- + +## Sepolia (Ethereum Testnet) + +| Contract | Address | Source | +|----------|---------|--------| +| **ScrollChain Proxy** | `0x2D567EcE699Eabe5afCd141eDB7A4f2D0D6ce8a0` | genesis.json | +| **MultipleVersionRollupVerifier** | `0x8A360c7F6fca548507017DdeD732bFe7E078F963` | `verifier()` on Sepolia | +| L1MessageQueueV1 | `0xF0B2293F5D834eAe920c6974D50957A1732de763` | genesis.json | +| L1MessageQueueV2 | `0xA0673eC0A48aa924f067F1274EcD281A10c5f19F` | genesis.json | +| L2SystemConfig | `0xF444cF06A3E3724e20B35c2989d3942ea8b59124` | genesis.json | +| Scroll Owner | `0xbE57544Eaf3515E888614a464EC9e0ad38f73e37` | `owner()` on Sepolia | + +### Sepolia Batch Status + +- `lastFinalizedBatchIndex`: 127,878 (0x1f386) + +--- + +## Cloak (Validium Testnet) + +| Contract | Address | Source | +|----------|---------|--------| +| **ScrollChain Proxy** | `0x9110B582327f6de87d8f833Ef7FAcD38CB093f64` | genesis.json | + +--- + +## How These Addresses Were Found + +### ScrollChain Proxy +The address `0xa13BAF47339d63B743e7Da8741db5456DAc1E556` appears in multiple places: +- `tests/prover-e2e/mainnet-galileoV2/genesis.json`: `"scrollChainAddress"` +- `coordinator/build/bin/conf/genesis.json` +- `bridge-history-api/conf/config.json` +- `scroll-devnets/charts/shadow-fork/e2e-test/values.yaml` + +**Critical verification step**: Initially, Anvil was mistakenly forking Scroll L2 (chainId=534352) instead of Ethereum L1. On Scroll L2, `0xa13B...` had no ScrollChain code. After correcting Anvil to fork Ethereum mainnet (chainId=1), the address correctly resolved to the ScrollChain proxy with: +- Implementation slot: `0x0a20703878e68E587c59204cc0EA86098B8c3bA7` +- `lastFinalizedBatchIndex()`: 517,828 +- `owner()`: `0x798576400F7D662961BA15C6b3F3d813447a26a6` + +### MultipleVersionRollupVerifier +- **Mainnet**: Queried via `cast call 0xa13BAF... "verifier()(address)"` on Ethereum mainnet RPC → `0x4CEA3E866e7c57fD75CB0CA3E9F5f1151D4Ead3F` +- **Sepolia**: Queried via `cast call 0x2D567... "verifier()(address)"` on Sepolia RPC → `0x8A360c7F6fca548507017DdeD732bFe7E078F963` +- Also referenced in `scroll-devnets/charts/shadow-fork/jobs/upgrade-contract.yaml` + +### Other Addresses +All other L1 contract addresses are extracted from the corresponding `genesis.json` files in `tests/prover-e2e//genesis.json`. diff --git a/tests/shadow-testing/scripts/00-import-bundle-range.sh b/tests/shadow-testing/scripts/00-import-bundle-range.sh new file mode 100755 index 0000000000..382b75e6fe --- /dev/null +++ b/tests/shadow-testing/scripts/00-import-bundle-range.sh @@ -0,0 +1,216 @@ +#!/bin/bash +# Import a specific bundle range from production RDS into the shadow DB. +# Usage: ./00-import-bundle-range.sh [options] +# +# Options: +# --bundle-range RANGE Bundle index range, e.g. 17302:17305 +# --prod-dsn DSN Production RDS connection string +# --shadow-dsn DSN Shadow DB connection string +# --dry-run Show SQL without executing +# -h, --help Show this help + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "${SCRIPT_DIR}/lib/anvil-utils.sh" + +# ─── Defaults ──────────────────────────────────────────────────────────────── +PROD_DSN="${PROD_DSN:-postgresql://postgres:postgres@localhost:15432/rollup}" +SHADOW_DSN="${SHADOW_DSN:-postgresql://postgres:shadow_pass@localhost:5433/shadow_rollup}" +BUNDLE_RANGE="" +DRY_RUN=false + +# ─── Parse args ────────────────────────────────────────────────────────────── +while [[ $# -gt 0 ]]; do + case "$1" in + --bundle-range) BUNDLE_RANGE="$2"; shift 2 ;; + --prod-dsn) PROD_DSN="$2"; shift 2 ;; + --shadow-dsn) SHADOW_DSN="$2"; shift 2 ;; + --dry-run) DRY_RUN=true; shift ;; + -h|--help) + sed -n '2,12p' "$0" + exit 0 + ;; + *) log_error "Unknown option: $1"; exit 1 ;; + esac +done + +if [[ -z "$BUNDLE_RANGE" ]]; then + log_error "Must specify --bundle-range (e.g., 17302:17305)" + exit 1 +fi + +BUNDLE_START="${BUNDLE_RANGE%%:*}" +BUNDLE_END="${BUNDLE_RANGE##*:}" + +require_cmd psql + +# ─── Verify connectivity ───────────────────────────────────────────────────── +log_info "Checking production RDS connectivity..." +if ! psql "$PROD_DSN" -c "SELECT 1;" >/dev/null 2>&1; then + log_error "Cannot connect to production RDS at $PROD_DSN" + log_error "Ensure IDC port-forward is active (e.g., ssh -L 15432:...:5432 idc-us-1-19)" + exit 1 +fi + +log_info "Checking shadow DB connectivity..." +if ! psql "$SHADOW_DSN" -c "SELECT 1;" >/dev/null 2>&1; then + log_error "Cannot connect to shadow DB at $SHADOW_DSN" + log_error "Run: docker compose up postgres -d" + exit 1 +fi + +# ─── Resolve batch range from bundles ──────────────────────────────────────── +log_info "Resolving batch range from bundles $BUNDLE_RANGE ..." + +RANGE_SQL=" +SELECT MIN(start_batch_index), MAX(end_batch_index) +FROM bundle +WHERE index BETWEEN $BUNDLE_START AND $BUNDLE_END +" + +result=$(psql "$PROD_DSN" -Atq -c "$RANGE_SQL" 2>/dev/null | xargs) +BATCH_START=$(echo "$result" | cut -d'|' -f1 | tr -d ' ') +BATCH_END=$(echo "$result" | cut -d'|' -f2 | tr -d ' ') + +if [[ -z "$BATCH_START" || "$BATCH_START" == "NULL" ]]; then + log_error "No bundles found in range $BUNDLE_RANGE on production RDS" + exit 1 +fi + +log_info " Bundle range: $BUNDLE_START → $BUNDLE_END" +log_info " Batch range: $BATCH_START → $BATCH_END" + +# ─── Export dir ────────────────────────────────────────────────────────────── +TIMESTAMP=$(date +%Y%m%d_%H%M%S) +EXPORT_DIR="/tmp/shadow-export-$TIMESTAMP" +mkdir -p "$EXPORT_DIR" + +# ─── Export from production RDS ────────────────────────────────────────────── +log_info "Exporting bundles $BUNDLE_START..$BUNDLE_END from production..." +psql "$PROD_DSN" -c " + COPY ( + SELECT * FROM bundle + WHERE index BETWEEN $BUNDLE_START AND $BUNDLE_END + ORDER BY index + ) TO STDOUT WITH CSV HEADER; +" > "$EXPORT_DIR/bundles.csv" + +BUNDLE_COUNT=$(tail -n +2 "$EXPORT_DIR/bundles.csv" | wc -l) +log_info " Exported $BUNDLE_COUNT bundles" + +log_info "Exporting batches $BATCH_START..$BATCH_END from production..." +psql "$PROD_DSN" -c " + COPY ( + SELECT * FROM batch + WHERE index BETWEEN $BATCH_START AND $BATCH_END + ORDER BY index + ) TO STDOUT WITH CSV HEADER; +" > "$EXPORT_DIR/batches.csv" + +BATCH_COUNT=$(tail -n +2 "$EXPORT_DIR/batches.csv" | wc -l) +log_info " Exported $BATCH_COUNT batches" + +log_info "Exporting chunks for batches $BATCH_START..$BATCH_END..." +psql "$PROD_DSN" -c " + COPY ( + SELECT c.* FROM chunk c + JOIN batch b ON b.start_chunk_index <= c.index AND c.index <= b.end_chunk_index + WHERE b.index BETWEEN $BATCH_START AND $BATCH_END + ORDER BY c.index + ) TO STDOUT WITH CSV HEADER; +" > "$EXPORT_DIR/chunks.csv" + +CHUNK_COUNT=$(tail -n +2 "$EXPORT_DIR/chunks.csv" | wc -l) +log_info " Exported $CHUNK_COUNT chunks" + +log_info "Exporting l2_blocks for chunks..." +psql "$PROD_DSN" -c " + COPY ( + SELECT l.* FROM l2_block l + JOIN chunk c ON c.hash = l.chunk_hash + JOIN batch b ON b.start_chunk_index <= c.index AND c.index <= b.end_chunk_index + WHERE b.index BETWEEN $BATCH_START AND $BATCH_END + ORDER BY l.number + ) TO STDOUT WITH CSV HEADER; +" > "$EXPORT_DIR/l2_blocks.csv" + +L2BLOCK_COUNT=$(tail -n +2 "$EXPORT_DIR/l2_blocks.csv" | wc -l) +log_info " Exported $L2BLOCK_COUNT l2_blocks" + +# ─── Check for parent batch ──────────────────────────────────────────────────── +log_info "Checking parent batch (batch $((BATCH_START - 1)))..." +PARENT_EXISTS=$(psql "$PROD_DSN" -Atq -c " + SELECT COUNT(*) FROM batch WHERE index = $((BATCH_START - 1)) +" 2>/dev/null | tr -d ' ') + +if [[ "$PARENT_EXISTS" == "0" ]]; then + log_warn " Parent batch $((BATCH_START - 1)) not found in production" + log_warn " Coordinator bundle task generation will fail without parent batch" +else + log_info " Exporting parent batch $((BATCH_START - 1))..." + psql "$PROD_DSN" -c " + COPY ( + SELECT * FROM batch WHERE index = $((BATCH_START - 1)) + ) TO STDOUT WITH CSV HEADER; + " > "$EXPORT_DIR/parent_batch.csv" +fi + +# ─── Truncate shadow tables ────────────────────────────────────────────────── +log_info "Clearing shadow tables..." +if [[ "$DRY_RUN" == "true" ]]; then + log_info "DRY RUN — would execute: TRUNCATE batch, chunk, bundle, l2_block CASCADE;" +else + psql "$SHADOW_DSN" -c "TRUNCATE batch, chunk, bundle, l2_block CASCADE;" >/dev/null +fi + +# ─── Import into shadow DB ─────────────────────────────────────────────────── +log_info "Importing into shadow DB..." + +import_csv() { + local table="$1" + local file="$2" + if [[ -f "$file" ]]; then + local count=$(tail -n +2 "$file" | wc -l) + if [[ "$count" -gt 0 ]]; then + if [[ "$DRY_RUN" == "true" ]]; then + log_info " DRY RUN: would import $count rows into $table" + else + psql "$SHADOW_DSN" -c "\copy $table FROM '$file' WITH CSV HEADER;" >/dev/null + log_ok " Imported $count rows into $table" + fi + fi + fi +} + +import_csv "bundle" "$EXPORT_DIR/bundles.csv" +import_csv "batch" "$EXPORT_DIR/batches.csv" +import_csv "chunk" "$EXPORT_DIR/chunks.csv" +import_csv "l2_block" "$EXPORT_DIR/l2_blocks.csv" + +if [[ -f "$EXPORT_DIR/parent_batch.csv" ]]; then + import_csv "batch" "$EXPORT_DIR/parent_batch.csv" +fi + +# ─── Reset status ──────────────────────────────────────────────────────────── +log_info "Resetting proving & rollup status..." +if [[ "$DRY_RUN" == "true" ]]; then + log_info " DRY RUN: would reset proving_status and rollup_status" +else + psql "$SHADOW_DSN" -c " + UPDATE chunk SET proving_status = 1, total_attempts = 0, active_attempts = 0; + UPDATE batch SET proving_status = 1, total_attempts = 0, active_attempts = 0, chunk_proofs_status = 0; + UPDATE bundle SET proving_status = 1, total_attempts = 0, active_attempts = 0, rollup_status = 1; + " >/dev/null + log_ok " Status reset complete" +fi + +# ─── Verify ────────────────────────────────────────────────────────────────── +log_info "Verifying shadow DB..." +psql "$SHADOW_DSN" -c " + SELECT 'batch' as table, COUNT(*) as cnt FROM batch + UNION ALL SELECT 'chunk', COUNT(*) FROM chunk + UNION ALL SELECT 'bundle', COUNT(*) FROM bundle; +" 2>/dev/null + +log_ok "Import complete! Export files saved to: $EXPORT_DIR" diff --git a/tests/shadow-testing/scripts/01-setup-anvil.sh b/tests/shadow-testing/scripts/01-setup-anvil.sh new file mode 100755 index 0000000000..6ba526d759 --- /dev/null +++ b/tests/shadow-testing/scripts/01-setup-anvil.sh @@ -0,0 +1,314 @@ +#!/usr/bin/env bash +# Setup Anvil shadow fork for Scroll testing +# Usage: ./01-setup-anvil.sh [options] +# +# Options: +# --fork-url URL Ethereum RPC to fork from (default: mainnet) +# --fork-block NUM Block number to fork at +# --anvil-rpc URL Anvil RPC endpoint (default: http://localhost:18545) +# --state-file PATH Save Anvil state to this file after setup +# --last-finalized NUM Reset lastFinalizedBatchIndex to this value +# --last-committed NUM Reset lastCommittedBatchIndex to this value (default: last-finalized) +# --committed-batch-hash HASH Set committedBatches[last-committed] to this hash +# --next-queue NUM Reset nextUnfinalizedQueueIndex to this value +# --deployed-verifier ADDR Address of ZkEvmVerifierPostFeynman to register +# --prover-eoa ADDR EOA to authorize as prover +# --commit-eoa ADDR EOA to authorize as sequencer (optional) +# --owner ADDR Contract owner address for impersonation +# --no-anvil Skip starting Anvil (assume already running) +# -h, --help Show this help + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "${SCRIPT_DIR}/lib/anvil-utils.sh" + +# ─── Defaults ──────────────────────────────────────────────────────────────── +FORK_URL="${FORK_URL:-https://eth-mainnet.g.alchemy.com/v2/demo}" +FORK_BLOCK="${FORK_BLOCK:-25202217}" +ANVIL_RPC="${ANVIL_RPC:-http://localhost:18545}" +STATE_FILE="" +LAST_FINALIZED="${LAST_FINALIZED:-517760}" +LAST_COMMITTED="${LAST_COMMITTED:-}" +COMMITTED_BATCH_HASH="${COMMITTED_BATCH_HASH:-}" +NEXT_QUEUE="${NEXT_QUEUE:-0}" + +# Mainnet contract addresses (can be overridden for Sepolia) +SCROLL_CHAIN="${SCROLL_CHAIN:-0xa13BAF47339d63B743e7Da8741db5456DAc1E556}" +L1_MSG_QUEUE_V2="${L1_MSG_QUEUE_V2:-0x56971da63A3C0205184FEF096E9ddFc7A8C2D18a}" +ROLLUP_VERIFIER="${ROLLUP_VERIFIER:-0x4CEA3E866e7c57fD75CB0CA3E9F5f1151D4Ead3F}" +DEPLOYED_VERIFIER="${DEPLOYED_VERIFIER:-0xb1F2C5c1ea2885278a1070350d12d3D8824265B0}" +OWNER="${OWNER:-0x798576400F7D662961BA15C6b3F3d813447a26a6}" +PROVER_EOA="${PROVER_EOA:-0x410E7FD80a3Fc1E62A4D3450d11b71b812006eB9}" +COMMIT_EOA="${COMMIT_EOA:-}" +CODEC_VERSION="${CODEC_VERSION:-10}" + +NO_ANVIL=false +ANVIL_PID="" + +# ─── Parse args ────────────────────────────────────────────────────────────── +while [[ $# -gt 0 ]]; do + case "$1" in + --fork-url) FORK_URL="$2"; shift 2 ;; + --fork-block) FORK_BLOCK="$2"; shift 2 ;; + --anvil-rpc) ANVIL_RPC="$2"; shift 2 ;; + --state-file) STATE_FILE="$2"; shift 2 ;; + --last-finalized) LAST_FINALIZED="$2"; shift 2 ;; + --last-committed) LAST_COMMITTED="$2"; shift 2 ;; + --committed-batch-hash) COMMITTED_BATCH_HASH="$2"; shift 2 ;; + --next-queue) NEXT_QUEUE="$2"; shift 2 ;; + --deployed-verifier) DEPLOYED_VERIFIER="$2"; shift 2 ;; + --prover-eoa) PROVER_EOA="$2"; shift 2 ;; + --commit-eoa) COMMIT_EOA="$2"; shift 2 ;; + --owner) OWNER="$2"; shift 2 ;; + --no-anvil) NO_ANVIL=true; shift ;; + --scroll-chain) SCROLL_CHAIN="$2"; shift 2 ;; + --l1-msg-queue) L1_MSG_QUEUE_V2="$2"; shift 2 ;; + --rollup-verifier) ROLLUP_VERIFIER="$2"; shift 2 ;; + --db-dsn) DB_DSN="$2"; shift 2 ;; + --codec-version) CODEC_VERSION="$2"; shift 2 ;; + -h|--help) + sed -n '2,20p' "$0" + exit 0 + ;; + *) log_error "Unknown option: $1"; exit 1 ;; + esac +done + +# If last-committed not provided, default to last-finalized (mainnet behavior) +# For Sepolia shadow forks, set last-committed = last-finalized + 1 +# NOTE: This must run AFTER argument parsing, because LAST_FINALIZED may be overridden by --last-finalized. +LAST_COMMITTED="${LAST_COMMITTED:-$LAST_FINALIZED}" + +# ─── Validate deps ─────────────────────────────────────────────────────────── +require_cmd cast +require_cmd anvil + +# ─── Step 1: Start Anvil ───────────────────────────────────────────────────── +if [[ "$NO_ANVIL" == "false" ]]; then + log_info "Starting Anvil fork..." + log_info " Fork URL: $FORK_URL" + log_info " Fork Block: $FORK_BLOCK" + log_info " RPC: $ANVIL_RPC" + + # Kill any existing Anvil on the same port + anvil_port="${ANVIL_RPC##*:}" + existing_pid=$(lsof -ti :"$anvil_port" 2>/dev/null || true) + if [[ -n "$existing_pid" ]]; then + log_warn "Killing existing Anvil on port $anvil_port (PID $existing_pid)" + kill "$existing_pid" 2>/dev/null || true + sleep 2 + fi + + setsid nohup anvil \ + --fork-url "$FORK_URL" \ + --fork-block-number "$FORK_BLOCK" \ + --block-time 12 \ + --port "$anvil_port" \ + --host 0.0.0.0 \ + ${STATE_FILE:+--state "$STATE_FILE"} \ + >/dev/null 2>&1 & + ANVIL_PID=$! + + log_info "Anvil started (PID $ANVIL_PID)" + sleep 3 +else + log_info "Skipping Anvil startup (using existing instance)" +fi + +wait_for_anvil "$ANVIL_RPC" + +# ─── Step 2: Reset ScrollChain miscData ────────────────────────────────────── +log_info "Resetting ScrollChain state..." +log_info " lastFinalizedBatchIndex → $LAST_FINALIZED" + +# ScrollChainMiscData is packed into one slot (slot 161): +# bytes 0-7: lastCommittedBatchIndex (uint64) +# bytes 8-15: lastFinalizedBatchIndex (uint64) +# bytes 16-19: lastFinalizeTimestamp (uint32) +# byte 20: flags (uint8) +# bytes 21-31: reserved (uint88) +# We set committed and finalized, zero out timestamp & flags. +committed_hex=$(printf '%016x' "$LAST_COMMITTED") +finalized_hex=$(printf '%016x' "$LAST_FINALIZED") +# ScrollChainMiscData layout (32 bytes), little-endian: +# bytes 0-7: lastCommittedBatchIndex (uint64 LE) - 16 hex +# bytes 8-15: lastFinalizedBatchIndex (uint64 LE) - 16 hex +# bytes 16-19: lastFinalizeTimestamp (uint32) - 8 hex +# byte 20: flags (uint8) - 2 hex +# bytes 21-31: reserved (uint88) - 22 hex +# Total: 64 hex chars. We zero out timestamp & flags. +new_miscdata="0x00000000000000000000000000000000${finalized_hex}${committed_hex}" + +set_storage "$SCROLL_CHAIN" "0x00000000000000000000000000000000000000000000000000000000000000a1" "$new_miscdata" "$ANVIL_RPC" + +# If a committed batch hash is provided, set committedBatches[lastCommittedBatchIndex] +# This is required for shadow forks where we need the parent batch hash +# to match when the relayer calls commitBatches. +# If --db-dsn is provided but no hash, auto-fetch from DB. +if [[ -z "$COMMITTED_BATCH_HASH" || "$COMMITTED_BATCH_HASH" == "0x0000000000000000000000000000000000000000000000000000000000000000" ]]; then + if [[ -n "${DB_DSN:-}" ]]; then + log_info " Fetching committedBatches[$LAST_COMMITTED] hash from DB..." + COMMITTED_BATCH_HASH=$(psql "$DB_DSN" -Atq -c " + SELECT hash FROM batch WHERE index = $LAST_COMMITTED + " 2>/dev/null | tr -d ' ') + if [[ -n "$COMMITTED_BATCH_HASH" && "$COMMITTED_BATCH_HASH" != "NULL" ]]; then + log_info " Found hash: $COMMITTED_BATCH_HASH" + else + log_warn " Batch $LAST_COMMITTED not found in DB; committedBatches will not be seeded" + COMMITTED_BATCH_HASH="" + fi + fi +fi + +if [[ -n "$COMMITTED_BATCH_HASH" && "$COMMITTED_BATCH_HASH" != "0x0000000000000000000000000000000000000000000000000000000000000000" ]]; then + log_info " Setting committedBatches[$LAST_COMMITTED] = $COMMITTED_BATCH_HASH" + # committedBatches is mapping(uint256 => bytes32) at slot 157 + committed_slot=$(cast index uint256 "$LAST_COMMITTED" 157 2>/dev/null) + set_storage "$SCROLL_CHAIN" "$committed_slot" "$COMMITTED_BATCH_HASH" "$ANVIL_RPC" + log_ok " committedBatches[$LAST_COMMITTED] set" +fi + +# Verify +actual_finalized=$(cast call "$SCROLL_CHAIN" "lastFinalizedBatchIndex()(uint256)" --rpc-url "$ANVIL_RPC" 2>/dev/null) +actual_committed=$(cast call "$SCROLL_CHAIN" "miscData()(uint64,uint64,uint32,uint8,uint88)" --rpc-url "$ANVIL_RPC" 2>/dev/null | cut -d',' -f1 | tr -d ' ') +log_ok " lastFinalizedBatchIndex = $actual_finalized" +log_ok " lastCommittedBatchIndex = $actual_committed" + +# ─── Step 3: Reset L1MessageQueueV2 ────────────────────────────────────────── +log_info "Resetting L1MessageQueueV2..." +log_info " nextUnfinalizedQueueIndex → $NEXT_QUEUE" + +# Slot 104 holds nextUnfinalizedQueueIndex (uint256) +queue_hex=$(encode_uint256 "$NEXT_QUEUE") +set_storage "$L1_MSG_QUEUE_V2" "0x0000000000000000000000000000000000000000000000000000000000000068" "$queue_hex" "$ANVIL_RPC" + +actual_queue=$(cast call "$L1_MSG_QUEUE_V2" "nextUnfinalizedQueueIndex()(uint256)" --rpc-url "$ANVIL_RPC" 2>/dev/null) +log_ok " nextUnfinalizedQueueIndex = $actual_queue" + +# ─── Step 4: Deploy / copy verifier ────────────────────────────────────────── +if [[ -n "$DEPLOYED_VERIFIER" && "$DEPLOYED_VERIFIER" != "0x0000000000000000000000000000000000000000" ]]; then + log_info "Using provided verifier..." + log_info " Verifier: $DEPLOYED_VERIFIER" +else + log_info "No deployed verifier provided. Attempting to copy from known shadow-compatible verifier..." + # Copy mainnet shadow verifier (0xb1F2...) to a deterministic address on this Anvil fork + SHADOW_VERIFIER="0xb1F2C5c1ea2885278a1070350d12d3D8824265B0" + SHADOW_PLONK="0x4A2CA4AB67922F9a9212C6ab20eFF23bdE132263" + + # These addresses must exist on the source RPC (mainnet Anvil from previous test) + SRC_RPC="${SRC_RPC:-http://localhost:18545}" + + verifier_code=$(cast code "$SHADOW_VERIFIER" --rpc-url "$SRC_RPC" 2>/dev/null || echo "") + plonk_code=$(cast code "$SHADOW_PLONK" --rpc-url "$SRC_RPC" 2>/dev/null || echo "") + + if [[ -n "$verifier_code" && -n "$plonk_code" ]]; then + cast rpc anvil_setCode "$SHADOW_PLONK" "$plonk_code" --rpc-url "$ANVIL_RPC" >/dev/null 2>&1 + cast rpc anvil_setCode "$SHADOW_VERIFIER" "$verifier_code" --rpc-url "$ANVIL_RPC" >/dev/null 2>&1 + DEPLOYED_VERIFIER="$SHADOW_VERIFIER" + log_ok " Copied verifier to $DEPLOYED_VERIFIER" + else + log_warn " Could not copy verifier from $SRC_RPC" + log_warn " You will need to manually deploy a verifier matching your proofs" + fi +fi + +# ─── Step 4b: Set owner balance (needed for impersonated transactions) ────── +log_info "Setting owner balance..." +set_balance "$OWNER" "0x56bc75e2d63100000" "$ANVIL_RPC" +log_ok " Owner balance = 100 ETH" + +# ─── Step 4c: Clear EIP-7702 delegation from commit EOA ───────────────────── +if [[ -n "$COMMIT_EOA" ]]; then + commit_code=$(cast code "$COMMIT_EOA" --rpc-url "$ANVIL_RPC" 2>/dev/null) + if [[ "$commit_code" == 0xef01* ]]; then + log_warn " Commit EOA has EIP-7702 delegation, clearing..." + cast rpc anvil_setCode "$COMMIT_EOA" "0x" --rpc-url "$ANVIL_RPC" >/dev/null 2>&1 + log_ok " EIP-7702 delegation cleared" + fi +fi + +# ─── Step 5: Register verifier ─────────────────────────────────────────────── +if [[ -n "$DEPLOYED_VERIFIER" && "$DEPLOYED_VERIFIER" != "0x0000000000000000000000000000000000000000" ]]; then + log_info "Registering verifier..." + log_info " Verifier: $DEPLOYED_VERIFIER" + log_info " Codec: $CODEC_VERSION" + + impersonate "$OWNER" "$ANVIL_RPC" + + # startBatchIndex must be > lastFinalizedBatchIndex to pass contract checks + start_batch_index=$((LAST_FINALIZED + 1)) + + # Use eth_sendTransaction directly to avoid cast send --unlocked bugs with impersonation + verifier_calldata=$(cast calldata "updateVerifier(uint256,uint64,address)" "$CODEC_VERSION" "$start_batch_index" "$DEPLOYED_VERIFIER") + cast rpc eth_sendTransaction \ + "{\"from\":\"$OWNER\",\"to\":\"$ROLLUP_VERIFIER\",\"data\":\"$verifier_calldata\",\"gas\":\"0x4c4b40\"}" \ + --rpc-url "$ANVIL_RPC" >/dev/null 2>&1 + + stop_impersonate "$OWNER" "$ANVIL_RPC" + + # latestVerifier returns (uint64 startBatchIndex, address verifier) + registered=$(cast call "$ROLLUP_VERIFIER" "latestVerifier(uint256)" "$CODEC_VERSION" --rpc-url "$ANVIL_RPC" 2>/dev/null | sed 's/0x//' | cut -c65-128 | sed 's/^0*//') + log_ok " latestVerifier[$CODEC_VERSION] = 0x$registered (startBatchIndex=$start_batch_index)" +else + log_warn "Skipping verifier registration (no verifier address available)" +fi + +# ─── Step 5: Authorize prover ──────────────────────────────────────────────── +log_info "Authorizing prover EOA..." +log_info " Prover: $PROVER_EOA" + +impersonate "$OWNER" "$ANVIL_RPC" + +cast send "$SCROLL_CHAIN" \ + "addProver(address)" "$PROVER_EOA" \ + --from "$OWNER" --rpc-url "$ANVIL_RPC" --unlocked >/dev/null 2>&1 + +stop_impersonate "$OWNER" "$ANVIL_RPC" + +is_prover=$(cast call "$SCROLL_CHAIN" "isProver(address)(bool)" "$PROVER_EOA" --rpc-url "$ANVIL_RPC" 2>/dev/null) +log_ok " isProver[$PROVER_EOA] = $is_prover" + +# ─── Step 6: Authorize commit EOA as sequencer (optional) ──────────────────── +if [[ -n "$COMMIT_EOA" ]]; then + log_info "Authorizing commit EOA as sequencer..." + log_info " Sequencer: $COMMIT_EOA" + + impersonate "$OWNER" "$ANVIL_RPC" + + if cast send --gas-limit 5000000 "$SCROLL_CHAIN" \ + "addSequencer(address)" "$COMMIT_EOA" \ + --from "$OWNER" --rpc-url "$ANVIL_RPC" --unlocked >/dev/null 2>&1; then + stop_impersonate "$OWNER" "$ANVIL_RPC" + is_seq=$(cast call "$SCROLL_CHAIN" "isSequencer(address)(bool)" "$COMMIT_EOA" --rpc-url "$ANVIL_RPC" 2>/dev/null) + log_ok " isSequencer[$COMMIT_EOA] = $is_seq" + else + stop_impersonate "$OWNER" "$ANVIL_RPC" + log_warn " addSequencer failed (account may have code, e.g. EIP-7702). Skipping." + fi +fi + +# ─── Step 7: Set balances ──────────────────────────────────────────────────── +log_info "Setting balances..." +set_balance "$PROVER_EOA" "0x56bc75e2d63100000" "$ANVIL_RPC" +log_ok " Prover balance = 100 ETH" + +if [[ -n "$COMMIT_EOA" ]]; then + set_balance "$COMMIT_EOA" "0x56bc75e2d63100000" "$ANVIL_RPC" + log_ok " Commit balance = 100 ETH" +fi + +# ─── Step 8: Save state ────────────────────────────────────────────────────── +if [[ -n "$STATE_FILE" ]]; then + log_info "Saving Anvil state to $STATE_FILE..." + cast rpc anvil_dumpState --rpc-url "$ANVIL_RPC" > "$STATE_FILE" + log_ok " State saved ($(wc -c < "$STATE_FILE" | numfmt --to=iec-i))" +fi + +log_ok "Anvil setup complete!" + +# If we started Anvil, keep it running in foreground +if [[ "$NO_ANVIL" == "false" && -n "$ANVIL_PID" ]]; then + log_info "Anvil running in background (PID $ANVIL_PID)" + echo "$ANVIL_PID" > "${SCRIPT_DIR}/../../.work/anvil.pid" +fi diff --git a/tests/shadow-testing/scripts/02-prepare-db.sh b/tests/shadow-testing/scripts/02-prepare-db.sh new file mode 100755 index 0000000000..b49b0278af --- /dev/null +++ b/tests/shadow-testing/scripts/02-prepare-db.sh @@ -0,0 +1,155 @@ +#!/usr/bin/env bash +# Reset shadow DB rollup_status for target bundles/batches +# Usage: ./02-prepare-db.sh [options] +# +# Options: +# --db-dsn URL PostgreSQL DSN (default: shadow_rollup local) +# --bundle-range RANGE Bundle index range, e.g. 17297:17301 +# --batch-range RANGE Batch index range (auto-derived from bundles if omitted) +# --no-reset-proofs Skip resetting proving_status (only reset rollup_status) +# --dry-run Show SQL without executing +# -h, --help Show this help + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "${SCRIPT_DIR}/lib/anvil-utils.sh" + +# ─── Defaults ──────────────────────────────────────────────────────────────── +DB_DSN="${DB_DSN:-postgresql://postgres:shadow_pass@localhost:5433/shadow_rollup}" +BUNDLE_RANGE="" +BATCH_RANGE="" +RESET_PROOFS=true +DRY_RUN=false + +# ─── Parse args ────────────────────────────────────────────────────────────── +while [[ $# -gt 0 ]]; do + case "$1" in + --db-dsn) DB_DSN="$2"; shift 2 ;; + --bundle-range) BUNDLE_RANGE="$2"; shift 2 ;; + --batch-range) BATCH_RANGE="$2"; shift 2 ;; + --no-reset-proofs) RESET_PROOFS=false; shift ;; + --dry-run) DRY_RUN=true; shift ;; + -h|--help) + sed -n '2,16p' "$0" + exit 0 + ;; + *) log_error "Unknown option: $1"; exit 1 ;; + esac +done + +if [[ -z "$BUNDLE_RANGE" && -z "$BATCH_RANGE" ]]; then + log_error "Must specify --bundle-range or --batch-range" + exit 1 +fi + +require_cmd psql + +# ─── Resolve batch range from bundles ──────────────────────────────────────── +if [[ -n "$BUNDLE_RANGE" && -z "$BATCH_RANGE" ]]; then + log_info "Resolving batch range from bundles $BUNDLE_RANGE ..." + + bundle_start="${BUNDLE_RANGE%%:*}" + bundle_end="${BUNDLE_RANGE##*:}" + + result=$(psql "$DB_DSN" -Atq -c " + SELECT MIN(start_batch_index), MAX(end_batch_index) + FROM bundle + WHERE index BETWEEN $bundle_start AND $bundle_end + " 2>/dev/null) + + batch_start=$(echo "$result" | cut -d'|' -f1) + batch_end=$(echo "$result" | cut -d'|' -f2) + + if [[ -z "$batch_start" || "$batch_start" == "NULL" ]]; then + log_error "No bundles found in range $BUNDLE_RANGE" + exit 1 + fi + + BATCH_RANGE="${batch_start}:${batch_end}" + log_info " Derived batch range: $BATCH_RANGE" +fi + +# ─── Build SQL ─────────────────────────────────────────────────────────────── +log_info "Preparing DB reset..." +log_info " DB: $DB_DSN" +log_info " Bundle: ${BUNDLE_RANGE:-(n/a)}" +log_info " Batch: ${BATCH_RANGE:-(n/a)}" + +sql_bundle="" +sql_batch="" +sql_chunk="" + +if [[ -n "$BUNDLE_RANGE" ]]; then + b_start="${BUNDLE_RANGE%%:*}" + b_end="${BUNDLE_RANGE##*:}" + sql_bundle="UPDATE bundle SET rollup_status = 1 WHERE index BETWEEN $b_start AND $b_end;" + if [[ "$RESET_PROOFS" == "true" ]]; then + sql_bundle="$sql_bundle +UPDATE bundle SET proving_status = 1, total_attempts = 0, active_attempts = 0 WHERE index BETWEEN $b_start AND $b_end;" + fi +fi + +if [[ -n "$BATCH_RANGE" ]]; then + ba_start="${BATCH_RANGE%%:*}" + ba_end="${BATCH_RANGE##*:}" + sql_batch="UPDATE batch SET rollup_status = 1 WHERE index BETWEEN $ba_start AND $ba_end;" + if [[ "$RESET_PROOFS" == "true" ]]; then + sql_batch="$sql_batch +UPDATE batch SET proving_status = 1, total_attempts = 0, active_attempts = 0, chunk_proofs_status = 0 WHERE index BETWEEN $ba_start AND $ba_end;" + sql_chunk="UPDATE chunk SET proving_status = 1, total_attempts = 0, active_attempts = 0 WHERE batch_hash IN (SELECT hash FROM batch WHERE index BETWEEN $ba_start AND $ba_end);" + fi +fi + +# ─── Execute or dry-run ────────────────────────────────────────────────────── +if [[ "$DRY_RUN" == "true" ]]; then + log_info "DRY RUN — would execute:" + echo "---" + echo "$sql_bundle" + echo "$sql_batch" + echo "$sql_chunk" + echo "---" + exit 0 +fi + +log_info "Executing SQL..." + +if [[ -n "$sql_bundle" ]]; then + count=$(psql "$DB_DSN" -Atq -c "$sql_bundle" 2>/dev/null) + log_ok " Bundle rows updated: $count" +fi + +if [[ -n "$sql_batch" ]]; then + count=$(psql "$DB_DSN" -Atq -c "$sql_batch" 2>/dev/null) + log_ok " Batch rows updated: $count" +fi + +if [[ -n "$sql_chunk" ]]; then + count=$(psql "$DB_DSN" -Atq -c "$sql_chunk" 2>/dev/null) + log_ok " Chunk rows updated: $count" +fi + +# ─── Verify ────────────────────────────────────────────────────────────────── +if [[ -n "$BUNDLE_RANGE" ]]; then + log_info "Verifying bundle status..." + psql "$DB_DSN" -c " + SELECT index, proving_status, rollup_status, + finalize_tx_hash IS NOT NULL AS has_finalize_tx + FROM bundle + WHERE index BETWEEN ${b_start} AND ${b_end} + ORDER BY index + " 2>/dev/null +fi + +if [[ -n "$BATCH_RANGE" ]]; then + log_info "Verifying batch status..." + psql "$DB_DSN" -c " + SELECT index, proving_status, rollup_status, + finalize_tx_hash IS NOT NULL AS has_finalize_tx + FROM batch + WHERE index BETWEEN ${ba_start} AND ${ba_end} + ORDER BY index + " 2>/dev/null +fi + +log_ok "DB preparation complete!" diff --git a/tests/shadow-testing/scripts/03-deploy-verifier.sh b/tests/shadow-testing/scripts/03-deploy-verifier.sh new file mode 100755 index 0000000000..06bfd86a1e --- /dev/null +++ b/tests/shadow-testing/scripts/03-deploy-verifier.sh @@ -0,0 +1,308 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" + +# Colors +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' + +log_info() { echo -e "${GREEN}[INFO]${NC} $*"; } +log_warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } +log_error() { echo -e "${RED}[ERROR]${NC} $*"; } + +# --------------------------------------------------------------------------- +# Defaults +# --------------------------------------------------------------------------- +CONFIG_FILE="${PROJECT_ROOT}/configs/mainnet.json" +ASSETS_DIR="${PROJECT_ROOT}/../../coordinator/build/bin/assets_v2" +DB_BUNDLE_INDEX="17302" + +deploy_plonk=true +extract_digests=true +deploy_wrapper=true +register=true + +# --------------------------------------------------------------------------- +# Parse args +# --------------------------------------------------------------------------- +while [[ $# -gt 0 ]]; do + case "$1" in + --config) + CONFIG_FILE="$2"; shift 2 ;; + --assets-dir) + ASSETS_DIR="$2"; shift 2 ;; + --bundle-index) + DB_BUNDLE_INDEX="$2"; shift 2 ;; + --skip-plonk) + deploy_plonk=false; shift ;; + --skip-wrapper) + deploy_wrapper=false; shift ;; + --skip-register) + register=false; shift ;; + --help|-h) + cat << 'USAGE' +Usage: 03-deploy-verifier.sh [options] + +Deploy a new ZkEvmVerifierPostFeynman (with new plonk verifier + digests +fetched from S3) and register it on Anvil. + +Options: + --config Config file (default: configs/mainnet.json) + --assets-dir Path to coordinator assets_v2/ (default: ../../coordinator/build/bin/assets_v2) + --bundle-index Unused legacy option (kept for compatibility) + --skip-plonk Skip deploying a new plonk verifier (reuse existing) + --skip-wrapper Skip deploying the ZkEvmVerifierPostFeynman wrapper + --skip-register Skip registering on MultipleVersionRollupVerifier + -h, --help Show this help +USAGE + exit 0 ;; + *) + log_error "Unknown option: $1" + exit 1 ;; + esac +done + +# --------------------------------------------------------------------------- +# Load config +# --------------------------------------------------------------------------- +if [[ ! -f "$CONFIG_FILE" ]]; then + log_error "Config file not found: $CONFIG_FILE" + exit 1 +fi + +# Resolve to absolute path before we cd into scroll-contracts for deployment. +CONFIG_FILE="$(cd "$(dirname "$CONFIG_FILE")" && pwd)/$(basename "$CONFIG_FILE")" + +ANVIL_RPC=$(jq -r '.fork.anvil_rpc // empty' "$CONFIG_FILE") +SCROLL_CHAIN=$(jq -r '.contracts.scroll_chain // empty' "$CONFIG_FILE") +MVRV=$(jq -r '.contracts.rollup_verifier // empty' "$CONFIG_FILE") +OWNER=$(jq -r '.contracts.owner // empty' "$CONFIG_FILE") +DB_DSN=$(jq -r '.db.dsn // empty' "$CONFIG_FILE") +LAST_FINALIZED=$(jq -r '.reset.last_finalized_batch_index // empty' "$CONFIG_FILE") + +if [[ -z "$ANVIL_RPC" || -z "$MVRV" || -z "$OWNER" || -z "$DB_DSN" ]]; then + log_error "Missing required fields in config" + exit 1 +fi + +# Compute start batch: must be >= lastFinalized + 1 AND >= existing latestVerifier startBatchIndex +EXISTING_START=$(cast call "$MVRV" "latestVerifier(uint256)(uint64,address)" 10 --rpc-url "$ANVIL_RPC" 2>/dev/null | grep -oP '^\d+' | head -1 || echo "0") +MIN_START=$((LAST_FINALIZED + 1)) +if [[ "$EXISTING_START" -gt "$MIN_START" ]]; then + START_BATCH="$EXISTING_START" +else + START_BATCH="$MIN_START" +fi + +log_info "Anvil RPC: $ANVIL_RPC" +log_info "MVRV: $MVRV" +log_info "Owner: $OWNER" +log_info "Min start: $MIN_START" +log_info "Existing start: $EXISTING_START" +log_info "Using start: $START_BATCH" +log_info "Bundle index: $DB_BUNDLE_INDEX" + +# --------------------------------------------------------------------------- +# Pre-flight: unlock owner for all impersonated transactions +# --------------------------------------------------------------------------- +cast rpc anvil_impersonateAccount "$OWNER" --rpc-url "$ANVIL_RPC" >/dev/null 2>&1 || true + +# --------------------------------------------------------------------------- +# 1. Deploy new Plonk Verifier from assets_v2/verifier.bin +# --------------------------------------------------------------------------- +PLONK_VERIFIER="" +if $deploy_plonk; then + VERIFIER_BIN="${ASSETS_DIR}/verifier.bin" + if [[ ! -f "$VERIFIER_BIN" ]]; then + S3_BASE_URL=$(jq -r '.prover.s3_base_url // empty' "$CONFIG_FILE") + if [[ -n "$S3_BASE_URL" ]]; then + log_info " Downloading plonk verifier binary from S3..." + mkdir -p "$ASSETS_DIR" + curl -fsSL "${S3_BASE_URL}verifier/verifier.bin" -o "$VERIFIER_BIN" || true + fi + fi + + if [[ ! -f "$VERIFIER_BIN" ]]; then + log_error "Plonk verifier binary not found: $VERIFIER_BIN" + log_error "Make sure coordinator assets are downloaded (run coordinator once or download from S3)." + exit 1 + fi + + PLONK_BYTECODE=$(xxd -p "$VERIFIER_BIN" | tr -d '\n') + log_info "Deploying plonk verifier from $VERIFIER_BIN ($((${#PLONK_BYTECODE} / 2)) bytes) ..." + + # Anvil allows impersonation of any address with --unlocked + PLONK_DEPLOY_OUTPUT=$(cast send --rpc-url "$ANVIL_RPC" --chain 1 \ + --from "$OWNER" --unlocked --create "$PLONK_BYTECODE" 2>&1) + + # Extract deployed contract address from output + PLONK_VERIFIER=$(echo "$PLONK_DEPLOY_OUTPUT" | grep -oP 'contractAddress\s+\K0x[a-fA-F0-9]{40}' || true) + + if [[ -z "$PLONK_VERIFIER" ]]; then + log_error "Failed to extract plonk verifier address from cast output. Raw output:" + echo "$PLONK_DEPLOY_OUTPUT" + exit 1 + fi + + log_info "Plonk verifier deployed at: $PLONK_VERIFIER" +else + # If skipping plonk deploy, read existing deployed_verifier and extract its plonkVerifier + EXISTING_WRAPPER=$(jq -r '.contracts.deployed_verifier // empty' "$CONFIG_FILE") + if [[ -n "$EXISTING_WRAPPER" && "$EXISTING_WRAPPER" != "null" ]]; then + PLONK_VERIFIER=$(cast call "$EXISTING_WRAPPER" "plonkVerifier()(address)" --rpc-url "$ANVIL_RPC" 2>/dev/null || true) + log_info "Reusing plonk verifier from existing wrapper: $PLONK_VERIFIER" + fi + if [[ -z "$PLONK_VERIFIER" ]]; then + log_error "Cannot determine plonk verifier address. Either deploy one or provide an existing wrapper." + exit 1 + fi +fi + +# --------------------------------------------------------------------------- +# 2. Fetch digests from S3 release +# --------------------------------------------------------------------------- +DIGEST1="" +DIGEST2="" +if $extract_digests; then + S3_BASE_URL=$(jq -r '.prover.s3_base_url // empty' "$CONFIG_FILE") + if [[ -z "$S3_BASE_URL" ]]; then + log_error "Missing prover.s3_base_url in config; cannot download digest files" + exit 1 + fi + + log_info "Fetching digests from S3: ${S3_BASE_URL}bundle/digest_*.hex" + + DIGEST1_HEX=$(curl -fsSL "${S3_BASE_URL}bundle/digest_1.hex" 2>/dev/null | tr -d '[:space:]') + DIGEST2_HEX=$(curl -fsSL "${S3_BASE_URL}bundle/digest_2.hex" 2>/dev/null | tr -d '[:space:]') + + if [[ -z "$DIGEST1_HEX" || -z "$DIGEST2_HEX" ]]; then + log_error "Failed to download digest files from S3" + exit 1 + fi + + DIGEST1="0x${DIGEST1_HEX}" + DIGEST2="0x${DIGEST2_HEX}" + + log_info "Fetched digest1: $DIGEST1" + log_info "Fetched digest2: $DIGEST2" +else + log_error "--skip-digests not supported; digests must be fetched from S3" + exit 1 +fi + +# --------------------------------------------------------------------------- +# 3. Deploy ZkEvmVerifierPostFeynman wrapper +# --------------------------------------------------------------------------- +WRAPPER_ADDR="" +PROTOCOL_VERSION=$(jq -r '.reset.codec_version // 10' "$CONFIG_FILE") +if $deploy_wrapper; then + log_info "Deploying ZkEvmVerifierPostFeynman ..." + log_info " plonkVerifier: $PLONK_VERIFIER" + log_info " digest1: $DIGEST1" + log_info " digest2: $DIGEST2" + log_info " protocolVersion: $PROTOCOL_VERSION" + + cd "${PROJECT_ROOT}/../../scroll-contracts" + + WRAPPER_CONTRACT_PATH="../../tests/shadow-testing/contracts/ZkEvmVerifierPostFeynman.sol" + if [[ ! -f "$WRAPPER_CONTRACT_PATH" ]]; then + log_error "Wrapper contract not found: $WRAPPER_CONTRACT_PATH" + exit 1 + fi + + WRAPPER_OUTPUT=$(forge create --broadcast --evm-version cancun --rpc-url "$ANVIL_RPC" \ + --from "$OWNER" --unlocked \ + "$WRAPPER_CONTRACT_PATH:ZkEvmVerifierPostFeynman" \ + --constructor-args "$PLONK_VERIFIER" "$DIGEST1" "$DIGEST2" "$PROTOCOL_VERSION" 2>&1) + + WRAPPER_ADDR=$(echo "$WRAPPER_OUTPUT" | grep -oP 'Deployed to:\s+\K0x[a-fA-F0-9]{40}' || true) + + if [[ -z "$WRAPPER_ADDR" ]]; then + log_error "Failed to extract wrapper address from forge output. Raw output:" + echo "$WRAPPER_OUTPUT" + exit 1 + fi + + log_info "ZkEvmVerifierPostFeynman deployed at: $WRAPPER_ADDR" + + # Verify on-chain + ONCHAIN_DIGEST1=$(cast call "$WRAPPER_ADDR" "verifierDigest1()(bytes32)" --rpc-url "$ANVIL_RPC") + ONCHAIN_DIGEST2=$(cast call "$WRAPPER_ADDR" "verifierDigest2()(bytes32)" --rpc-url "$ANVIL_RPC") + ONCHAIN_PLONK=$(cast call "$WRAPPER_ADDR" "plonkVerifier()(address)" --rpc-url "$ANVIL_RPC") + ONCHAIN_PROTOCOL_VERSION=$(cast call "$WRAPPER_ADDR" "protocolVersion()(uint256)" --rpc-url "$ANVIL_RPC") + + log_info "On-chain verification:" + log_info " plonkVerifier: $ONCHAIN_PLONK" + log_info " digest1: $ONCHAIN_DIGEST1" + log_info " digest2: $ONCHAIN_DIGEST2" + log_info " protocolVersion: $ONCHAIN_PROTOCOL_VERSION" +else + WRAPPER_ADDR=$(jq -r '.contracts.deployed_verifier // empty' "$CONFIG_FILE") + log_info "Reusing existing wrapper: $WRAPPER_ADDR" +fi + +# --------------------------------------------------------------------------- +# 4. Register on MultipleVersionRollupVerifier +# --------------------------------------------------------------------------- +if $register; then + log_info "Registering verifier on MultipleVersionRollupVerifier ..." + log_info " version: 10" + log_info " startBatch: $MIN_START" + log_info " verifier: $WRAPPER_ADDR" + + # The contract enforces startBatchIndex >= existing latest.startBatchIndex. + # On a shadow fork the production verifier may already be registered at a + # later batch (e.g. 517767), so a normal updateVerifier at 517761 would be + # rejected or ignored. We therefore force the storage slot for + # latestVerifier[10] to point to our wrapper at the desired start batch. + # This is acceptable for a local shadow fork because we only care about the + # target batch range. + + # latestVerifier is state slot 2 (slot 0 = Ownable owner, slot 1 = legacyVerifiers). + LATEST_VERIFIER_SLOT=$(cast index uint256 10 2 2>/dev/null) + START_BATCH_HEX=$(printf '%016x' "$MIN_START") + WRAPPER_NO_0X=${WRAPPER_ADDR#0x} + NEW_SLOT_VALUE="0x00000000${WRAPPER_NO_0X}${START_BATCH_HEX}" + + cast rpc anvil_setStorageAt "$MVRV" "$LATEST_VERIFIER_SLOT" "$NEW_SLOT_VALUE" --rpc-url "$ANVIL_RPC" >/dev/null 2>&1 + + # Also push the previous production verifier into legacyVerifiers so that + # getVerifier still behaves reasonably for older batches. This is optional + # but keeps the MVRV state closer to reality. + cast send "$MVRV" \ + "updateVerifier(uint256,uint64,address)" \ + 10 "$MIN_START" "$WRAPPER_ADDR" \ + --from "$OWNER" --rpc-url "$ANVIL_RPC" --unlocked >/dev/null 2>&1 || true + + # Verify registration for the target batch range + for BATCH_IDX in $MIN_START $((MIN_START + 1)) $((MIN_START + 2)) $((MIN_START + 3)) $((MIN_START + 4)); do + REGISTERED=$(cast call "$MVRV" "getVerifier(uint256,uint256)(address)" 10 "$BATCH_IDX" --rpc-url "$ANVIL_RPC") + log_info "getVerifier(10, $BATCH_IDX) = $REGISTERED" + if [[ "${REGISTERED,,}" != "${WRAPPER_ADDR,,}" ]]; then + log_error "Registration verification failed for batch $BATCH_IDX!" + exit 1 + fi + done + + log_info "Registration verified ✅" +fi + +# --------------------------------------------------------------------------- +# 5. Update config file +# --------------------------------------------------------------------------- +log_info "Updating config file: $CONFIG_FILE" +tmp=$(mktemp) +jq --arg addr "$WRAPPER_ADDR" '.contracts.deployed_verifier = $addr' "$CONFIG_FILE" > "$tmp" && mv "$tmp" "$CONFIG_FILE" +log_info "Config updated with deployed_verifier = $WRAPPER_ADDR" + +log_info "Done! 🎉" +log_info "" +log_info "Summary:" +log_info " Plonk Verifier: $PLONK_VERIFIER" +log_info " Wrapper: $WRAPPER_ADDR" +log_info " Digest1: $DIGEST1" +log_info " Digest2: $DIGEST2" diff --git a/tests/shadow-testing/scripts/04-prover-up.sh b/tests/shadow-testing/scripts/04-prover-up.sh new file mode 100755 index 0000000000..eb833be0ee --- /dev/null +++ b/tests/shadow-testing/scripts/04-prover-up.sh @@ -0,0 +1,121 @@ +#!/usr/bin/env bash +# Start prover(s) for shadow testing +# Usage: ./04-prover-up.sh --config mainnet --bundle-range 17297:17301 [--gpus 0,1] + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "${SCRIPT_DIR}/lib/anvil-utils.sh" + +CONFIG="${CONFIG:-mainnet}" +GPUS="${GPUS:-0,1}" +DOCKER=false + +while [[ $# -gt 0 ]]; do + case "$1" in + --config) CONFIG="$2"; shift 2 ;; + --gpus) GPUS="$2"; shift 2 ;; + --docker) DOCKER=true; shift ;; + -h|--help) sed -n '2,5p' "$0"; exit 0 ;; + *) log_error "Unknown option: $1"; exit 1 ;; + esac +done + +CONFIG_FILE="${SCRIPT_DIR}/../configs/${CONFIG}.json" +if [[ ! -f "$CONFIG_FILE" ]]; then + log_error "Config not found: $CONFIG_FILE" + exit 1 +fi + +# Read config +PROVER_NAME=$(jq -r '.prover.name_prefix' "$CONFIG_FILE") +CIRCUIT_VERSION=$(jq -r '.prover.circuit_version' "$CONFIG_FILE") +S3_URL=$(jq -r '.prover.s3_base_url' "$CONFIG_FILE") +DB_DSN=$(jq -r '.db.dsn' "$CONFIG_FILE") + +REPO_ROOT="$(cd "${SCRIPT_DIR}/../../.." && pwd)" + +# Load circuit VKs from coordinator assets so we can set per-circuit S3 detours. +# v0.9.0 stores app.vmexe at /app.vmexe (no VK subdir), +# while the prover's default URL builder appends //. +ASSETS_V2="${REPO_ROOT}/coordinator/build/bin/assets_v2" +CHUNK_VK=$(jq -r '.chunk_vk' "${ASSETS_V2}/openVmVk.json" 2>/dev/null || echo "") +BATCH_VK=$(jq -r '.batch_vk' "${ASSETS_V2}/openVmVk.json" 2>/dev/null || echo "") +BUNDLE_VK=$(jq -r '.bundle_vk' "${ASSETS_V2}/openVmVk.json" 2>/dev/null || echo "") + +# ─── Build prover if needed ────────────────────────────────────────────────── +PROVER_BIN="${REPO_ROOT}/target/release/prover" + +if [[ ! -f "$PROVER_BIN" ]]; then + log_info "Building prover (GPU)..." + cd "${REPO_ROOT}/zkvm-prover" + make prover + log_ok " Built: $PROVER_BIN" +fi + +# ─── Launch provers ────────────────────────────────────────────────────────── +IFS=',' read -ra GPU_ARRAY <<< "$GPUS" + +for i in "${!GPU_ARRAY[@]}"; do + gpu_id="${GPU_ARRAY[$i]}" + prover_name="${PROVER_NAME}-${gpu_id}" + work_dir="${SCRIPT_DIR}/../.work/prover-${gpu_id}" + config_file="${work_dir}/prover.json" + log_file="${work_dir}/prover.log" + + mkdir -p "$work_dir" + + # Generate per-GPU config + cat > "$config_file" </dev/null || true + + log_info "Starting prover on GPU $gpu_id..." + + export RUST_MIN_STACK=16777216 + CUDA_VISIBLE_DEVICES="$gpu_id" nohup "$PROVER_BIN" \ + --config "$config_file" \ + >> "$log_file" 2>&1 & + + pid=$! + echo "$pid" > "${work_dir}/prover.pid" + log_ok " Prover $gpu_id started (PID $pid, health :$((10080 + gpu_id)))" +done + +log_ok "All provers launched" diff --git a/tests/shadow-testing/scripts/05-wait-for-proofs.sh b/tests/shadow-testing/scripts/05-wait-for-proofs.sh new file mode 100755 index 0000000000..3c5ac3f4df --- /dev/null +++ b/tests/shadow-testing/scripts/05-wait-for-proofs.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash +# Wait for bundle proofs to reach proving_status=4 (verified) +# Usage: ./05-wait-for-proofs.sh --bundle-range 17297:17301 [--timeout 3600] + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "${SCRIPT_DIR}/lib/anvil-utils.sh" + +DB_DSN="${DB_DSN:-postgresql://postgres:shadow_pass@localhost:5433/shadow_rollup}" +BUNDLE_RANGE="" +TIMEOUT="${TIMEOUT:-7200}" # Default 2 hours +INTERVAL="${INTERVAL:-30}" # Check every 30s + +while [[ $# -gt 0 ]]; do + case "$1" in + --db-dsn) DB_DSN="$2"; shift 2 ;; + --bundle-range) BUNDLE_RANGE="$2"; shift 2 ;; + --timeout) TIMEOUT="$2"; shift 2 ;; + --interval) INTERVAL="$2"; shift 2 ;; + -h|--help) sed -n '2,5p' "$0"; exit 0 ;; + *) log_error "Unknown option: $1"; exit 1 ;; + esac +done + +if [[ -z "$BUNDLE_RANGE" ]]; then + log_error "Must specify --bundle-range" + exit 1 +fi + +b_start="${BUNDLE_RANGE%%:*}" +b_end="${BUNDLE_RANGE##*:}" +total=$((b_end - b_start + 1)) + +log_info "Waiting for $total bundles to be proven..." +log_info " Range: $BUNDLE_RANGE" +log_info " Timeout: ${TIMEOUT}s" + +start_time=$(date +%s) + +while true; do + result=$(psql "$DB_DSN" -Atq -c " + SELECT COUNT(*) FROM bundle + WHERE index BETWEEN $b_start AND $b_end + AND proving_status = 4 + " 2>/dev/null) + + done_count=$(echo "$result" | tr -d '\n') + elapsed=$(($(date +%s) - start_time)) + + printf "\r ⏳ %d/%d proven (%ds elapsed)" "$done_count" "$total" "$elapsed" + + if [[ "$done_count" -eq "$total" ]]; then + echo "" + log_ok "All $total bundles proven!" + break + fi + + if [[ "$elapsed" -ge "$TIMEOUT" ]]; then + echo "" + log_error "Timeout after ${TIMEOUT}s — only $done_count/$total proven" + exit 1 + fi + + sleep "$INTERVAL" +done diff --git a/tests/shadow-testing/scripts/06-run-relayer.sh b/tests/shadow-testing/scripts/06-run-relayer.sh new file mode 100755 index 0000000000..1181dec16d --- /dev/null +++ b/tests/shadow-testing/scripts/06-run-relayer.sh @@ -0,0 +1,118 @@ +#!/usr/bin/env bash +# Build and launch the rollup relayer +# Usage: ./06-run-relayer.sh --config mainnet [--build] + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "${SCRIPT_DIR}/lib/anvil-utils.sh" + +CONFIG="${CONFIG:-mainnet}" +BUILD=false +DOCKER=false + +while [[ $# -gt 0 ]]; do + case "$1" in + --config) CONFIG="$2"; shift 2 ;; + --build) BUILD=true; shift ;; + --docker) DOCKER=true; shift ;; + -h|--help) sed -n '2,5p' "$0"; exit 0 ;; + *) log_error "Unknown option: $1"; exit 1 ;; + esac +done + +CONFIG_FILE="${SCRIPT_DIR}/../configs/${CONFIG}.json" +if [[ ! -f "$CONFIG_FILE" ]]; then + log_error "Config not found: $CONFIG_FILE" + exit 1 +fi + +# Read values from config +ANVIL_RPC=$(jq -r '.fork.anvil_rpc' "$CONFIG_FILE") +DB_DSN=$(jq -r '.db.dsn' "$CONFIG_FILE") +SCROLL_CHAIN=$(jq -r '.contracts.scroll_chain' "$CONFIG_FILE") +L2_ENDPOINT=$(jq -r '.e2e.l2_rpc' "$CONFIG_FILE") +VALIDIUM_MODE=$(jq -r '.relayer.validium_mode' "$CONFIG_FILE") +MIN_CODEC=$(jq -r '.relayer.min_codec_version' "$CONFIG_FILE") +CHAIN_MONITOR=$(jq -r '.relayer.chain_monitor_enabled' "$CONFIG_FILE") +GENESIS=$(jq -r '.genesis' "$CONFIG_FILE") + +# Use hardcoded dev keys for shadow testing +# Anvil default account #0 (commit) and the prover/finalize EOA +COMMIT_KEY="0x0afd95b5f1d9ef456b33c4e3720fbe70de7b4ff6e868fef454dc0aa60b09d8dc" +FINALIZE_KEY="0x01f1e12ee33f91d63172c3d51baa3cecb4469284b0ab45eed48e57fb5329ac4d" + +# ─── Render config ─────────────────────────────────────────────────────────── +RELAYER_CONFIG="${SCRIPT_DIR}/../.work/relayer-${CONFIG}.json" +mkdir -p "$(dirname "$RELAYER_CONFIG")" + +log_info "Rendering relayer config..." + +# Simple envsubst-style rendering +export ANVIL_RPC DB_DSN SCROLL_CHAIN L2_ENDPOINT COMMIT_KEY FINALIZE_KEY +export VALIDIUM_MODE CHAIN_MONITOR + +sed \ + -e "s|{{ANVIL_RPC}}|$ANVIL_RPC|g" \ + -e "s|{{DB_DSN}}|$DB_DSN|g" \ + -e "s|{{SCROLL_CHAIN}}|$SCROLL_CHAIN|g" \ + -e "s|{{L2_ENDPOINT}}|$L2_ENDPOINT|g" \ + -e "s|{{COMMIT_KEY}}|$COMMIT_KEY|g" \ + -e "s|{{FINALIZE_KEY}}|$FINALIZE_KEY|g" \ + -e "s|{{VALIDIUM_MODE}}|$VALIDIUM_MODE|g" \ + -e "s|{{CHAIN_MONITOR_ENABLED}}|$CHAIN_MONITOR|g" \ + "${SCRIPT_DIR}/../configs/relayer.json.template" > "$RELAYER_CONFIG" + +log_ok " Config written to $RELAYER_CONFIG" + +# ─── Build relayer ──────────────────────────────────────────────────────────── +# Resolve genesis path relative to repo root +REPO_ROOT="$(cd "${SCRIPT_DIR}/../../.." && pwd)" + +RELAYER_BIN="${REPO_ROOT}/rollup/build/bin/rollup_relayer" + +if [[ "$BUILD" == "true" || ! -f "$RELAYER_BIN" ]]; then + log_info "Building relayer..." + cd "${REPO_ROOT}/rollup" + go build -o build/bin/rollup_relayer ./cmd/rollup_relayer + log_ok " Built: $RELAYER_BIN" +fi +if [[ ! "$GENESIS" = /* ]]; then + GENESIS="$REPO_ROOT/$GENESIS" +fi + +# ─── Launch relayer ─────────────────────────────────────────────────────────── +log_info "Starting relayer..." + +if [[ "$DOCKER" == "true" ]]; then + log_warn "Docker mode not yet implemented, falling back to bare metal" +fi + +# Kill any existing relayer +pkill -f "rollup_relayer.*relayer-${CONFIG}" 2>/dev/null || true +sleep 1 + +nohup "$RELAYER_BIN" \ + --config "$RELAYER_CONFIG" \ + --genesis "$GENESIS" \ + --min-codec-version "$MIN_CODEC" \ + --verbosity 3 \ + > "${SCRIPT_DIR}/../.work/relayer-${CONFIG}.log" 2>&1 & + +RELAYER_PID=$! +echo "$RELAYER_PID" > "${SCRIPT_DIR}/../.work/relayer-${CONFIG}.pid" + +log_ok " Relayer started (PID $RELAYER_PID)" +log_info " Logs: ${SCRIPT_DIR}/../.work/relayer-${CONFIG}.log" + +# Give it a moment to start +sleep 3 + +# Quick health check +if ! kill -0 "$RELAYER_PID" 2>/dev/null; then + log_error "Relayer exited immediately! Check logs." + tail -20 "${SCRIPT_DIR}/../.work/relayer-${CONFIG}.log" + exit 1 +fi + +log_ok "Relayer is running" diff --git a/tests/shadow-testing/scripts/07-wait-for-finalize.sh b/tests/shadow-testing/scripts/07-wait-for-finalize.sh new file mode 100755 index 0000000000..55ec75b93f --- /dev/null +++ b/tests/shadow-testing/scripts/07-wait-for-finalize.sh @@ -0,0 +1,89 @@ +#!/usr/bin/env bash +# Wait for on-chain finalization of bundles +# Usage: ./07-wait-for-finalize.sh --bundle-range 17297:17301 --anvil-rpc ... --scroll-chain ... + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "${SCRIPT_DIR}/lib/anvil-utils.sh" + +ANVIL_RPC="${ANVIL_RPC:-http://localhost:18545}" +SCROLL_CHAIN="${SCROLL_CHAIN:-0xa13BAF47339d63B743e7Da8741db5456DAc1E556}" +DB_DSN="${DB_DSN:-postgresql://postgres:shadow_pass@localhost:5433/shadow_rollup}" +BUNDLE_RANGE="" +TIMEOUT="${TIMEOUT:-1800}" # 30 min default +INTERVAL="${INTERVAL:-15}" +VERIFY_ONLY=false + +while [[ $# -gt 0 ]]; do + case "$1" in + --anvil-rpc) ANVIL_RPC="$2"; shift 2 ;; + --scroll-chain) SCROLL_CHAIN="$2"; shift 2 ;; + --db-dsn) DB_DSN="$2"; shift 2 ;; + --bundle-range) BUNDLE_RANGE="$2"; shift 2 ;; + --timeout) TIMEOUT="$2"; shift 2 ;; + --interval) INTERVAL="$2"; shift 2 ;; + --verify-only) VERIFY_ONLY=true; shift ;; + -h|--help) sed -n '2,5p' "$0"; exit 0 ;; + *) log_error "Unknown option: $1"; exit 1 ;; + esac +done + +if [[ -z "$BUNDLE_RANGE" ]]; then + log_error "Must specify --bundle-range" + exit 1 +fi + +b_start="${BUNDLE_RANGE%%:*}" +b_end="${BUNDLE_RANGE##*:}" + +# We need to map bundle index to batch index. +# Query the DB to get the actual end_batch_index for the last bundle. +last_batch=$(psql "$DB_DSN" -Atq -c " + SELECT end_batch_index FROM bundle WHERE index = $b_end +" 2>/dev/null | tr -d '\n') + +if [[ -z "$last_batch" || "$last_batch" == "NULL" ]]; then + log_warn "Could not resolve batch index for bundle $b_end, falling back to bundle index" + last_batch="$b_end" +fi + +if [[ "$VERIFY_ONLY" == "true" ]]; then + current=$(cast call "$SCROLL_CHAIN" "lastFinalizedBatchIndex()(uint256)" --rpc-url "$ANVIL_RPC" 2>/dev/null | awk '{print $1}') + log_info "Current lastFinalizedBatchIndex: $current" + log_info "Target batch index: $last_batch" + if [[ "$current" -ge "$last_batch" ]]; then + log_ok "All bundles finalized!" + exit 0 + else + log_error "Not yet finalized ($current < $last_batch)" + exit 1 + fi +fi + +log_info "Waiting for finalization..." +log_info " Target batch: $last_batch" +log_info " Timeout: ${TIMEOUT}s" + +start_time=$(date +%s) + +while true; do + current=$(cast call "$SCROLL_CHAIN" "lastFinalizedBatchIndex()(uint256)" --rpc-url "$ANVIL_RPC" 2>/dev/null | awk '{print $1}' || echo "0") + elapsed=$(($(date +%s) - start_time)) + + printf "\r ⏳ lastFinalizedBatchIndex = %s / %s (%ds elapsed)" "$current" "$last_batch" "$elapsed" + + if [[ "$current" -ge "$last_batch" ]]; then + echo "" + log_ok "Finalization complete! lastFinalizedBatchIndex = $current" + break + fi + + if [[ "$elapsed" -ge "$TIMEOUT" ]]; then + echo "" + log_error "Timeout after ${TIMEOUT}s — lastFinalizedBatchIndex = $current" + exit 1 + fi + + sleep "$INTERVAL" +done diff --git a/tests/shadow-testing/scripts/08-docker-orchestrate.sh b/tests/shadow-testing/scripts/08-docker-orchestrate.sh new file mode 100755 index 0000000000..19a11318b5 --- /dev/null +++ b/tests/shadow-testing/scripts/08-docker-orchestrate.sh @@ -0,0 +1,359 @@ +#!/bin/bash +# One-command orchestrator for shadow fork testing. +# Usage: ./08-docker-orchestrate.sh [options] +# +# Options: +# --bundle-range RANGE Bundle index range, e.g. 17302:17305 +# --config NAME Config name (mainnet|sepolia), default: mainnet +# --phase PHASE Phase to run: env|prove|finalize|all (default: all) +# --skip-anvil-setup Skip Anvil state setup (use existing state) +# -h, --help Show this help + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "${SCRIPT_DIR}/../../.." && pwd)" +source "${SCRIPT_DIR}/lib/anvil-utils.sh" + +# ─── Defaults ──────────────────────────────────────────────────────────────── +CONFIG="${CONFIG:-mainnet}" +export CONFIG +BUNDLE_RANGE="" +PHASE="all" +SKIP_ANVIL_SETUP=false + +# ─── Parse args ────────────────────────────────────────────────────────────── +while [[ $# -gt 0 ]]; do + case "$1" in + --bundle-range) BUNDLE_RANGE="$2"; shift 2 ;; + --config) CONFIG="$2"; shift 2 ;; + --phase) PHASE="$2"; shift 2 ;; + --skip-anvil-setup) SKIP_ANVIL_SETUP=true; shift ;; + -h|--help) + sed -n '2,14p' "$0" + exit 0 + ;; + *) log_error "Unknown option: $1"; exit 1 ;; + esac +done + +if [[ -z "$BUNDLE_RANGE" ]]; then + log_error "Must specify --bundle-range (e.g., 17302:17305)" + exit 1 +fi + +BUNDLE_START="${BUNDLE_RANGE%%:*}" +BUNDLE_END="${BUNDLE_RANGE##*:}" + +CONFIG_FILE="${SCRIPT_DIR}/../configs/${CONFIG}.json" +if [[ ! -f "$CONFIG_FILE" ]]; then + log_error "Config file not found: $CONFIG_FILE" + exit 1 +fi + +# ─── Read config ───────────────────────────────────────────────────────────── +log_info "Loading config: $CONFIG" + +FORK_URL=$(jq -r '.fork.url' "$CONFIG_FILE") +FORK_BLOCK=$(jq -r '.fork.block_number' "$CONFIG_FILE") +ANVIL_RPC=$(jq -r '.fork.anvil_rpc' "$CONFIG_FILE") +DB_DSN=$(jq -r '.db.dsn' "$CONFIG_FILE") +PROD_DSN="${PROD_DSN:-postgresql://mainnet_infra_team_read_only:AuexDUuaarskbG6tr9CH9gXsJqp4at67mddAbMrt@localhost:15432/mainnet_rollup}" +SCROLL_CHAIN=$(jq -r '.contracts.scroll_chain' "$CONFIG_FILE") +L1_MSG_QUEUE=$(jq -r '.contracts.l1_message_queue_v2' "$CONFIG_FILE") +ROLLUP_VERIF=$(jq -r '.contracts.rollup_verifier' "$CONFIG_FILE") +DEPLOYED_VERIF=$(jq -r '.contracts.deployed_verifier' "$CONFIG_FILE") +OWNER=$(jq -r '.contracts.owner' "$CONFIG_FILE") +PROVER_EOA=$(jq -r '.accounts.prover_eoa' "$CONFIG_FILE") +COMMIT_EOA=$(jq -r '.accounts.commit_eoa' "$CONFIG_FILE") +LAST_FINALIZED=$(jq -r '.reset.last_finalized_batch_index' "$CONFIG_FILE") +NEXT_QUEUE=$(jq -r '.reset.next_unfinalized_queue_index' "$CONFIG_FILE") +CODEC_VERSION=$(jq -r '.reset.codec_version' "$CONFIG_FILE") +GENESIS=$(jq -r '.genesis' "$CONFIG_FILE") +L2_RPC=$(jq -r '.e2e.l2_rpc // .coordinator.l2geth // "https://mainnet-rpc.scroll.io"' "$CONFIG_FILE") +VALIDIUM_MODE=$(jq -r '.relayer.validium_mode // false' "$CONFIG_FILE") +CHAIN_MONITOR=$(jq -r '.relayer.chain_monitor_enabled // false' "$CONFIG_FILE") + +# Docker compose file (run from repo root) +COMPOSE_FILE="${REPO_ROOT}/tests/shadow-testing/docker-compose.yml" + +# ─── Helpers ───────────────────────────────────────────────────────────────── + +compose() { + docker compose -f "$COMPOSE_FILE" "$@" +} + +wait_for_postgres() { + local max=30 + local i=1 + while [ $i -le $max ]; do + if compose exec -T postgres pg_isready -U postgres >/dev/null 2>&1; then + log_ok "PostgreSQL is ready" + return 0 + fi + log_info "Waiting for PostgreSQL... ($i/$max)" + sleep 2 + ((i++)) + done + log_error "PostgreSQL failed to start" + return 1 +} + +wait_for_coordinator() { + local max=60 + local i=1 + while [ $i -le $max ]; do + if curl -s http://localhost:8390/ >/dev/null 2>&1; then + log_ok "Coordinator is ready at :8390" + return 0 + fi + log_info "Waiting for coordinator... ($i/$max)" + sleep 5 + ((i++)) + done + log_error "Coordinator failed to start" + return 1 +} + +wait_for_prover() { + local max=120 + local i=1 + while [ $i -le $max ]; do + # Check prover health via docker exec (no port mapping needed) + if docker exec shadow-prover-gpu-0 sh -c "curl -sf http://localhost:10080/health >/dev/null 2>&1" 2>/dev/null; then + log_ok "Prover is ready at :10080" + return 0 + fi + # Fallback: check if container is still running + if ! docker ps --format '{{.Names}}' | grep -q "^shadow-prover-gpu-0$"; then + log_error "Prover container exited unexpectedly" + return 1 + fi + log_info "Waiting for prover... ($i/$max)" + sleep 10 + ((i++)) + done + log_error "Prover failed to start" + return 1 +} + +render_relayer_config() { + local output="${SCRIPT_DIR}/../.work/relayer-${CONFIG}.json" + mkdir -p "$(dirname "$output")" + + local template="${SCRIPT_DIR}/../configs/relayer.json.template" + sed \ + -e "s|{{ANVIL_RPC}}|$ANVIL_RPC|g" \ + -e "s|{{DB_DSN}}|$DB_DSN|g" \ + -e "s|{{SCROLL_CHAIN}}|$SCROLL_CHAIN|g" \ + -e "s|{{L2_ENDPOINT}}|$L2_RPC|g" \ + -e "s|{{COMMIT_KEY}}|0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80|g" \ + -e "s|{{FINALIZE_KEY}}|0x01f1e12ee33f91d63172c3d51baa3cecb4469284b0ab45eed48e57fb5329ac4d|g" \ + -e "s|{{VALIDIUM_MODE}}|$VALIDIUM_MODE|g" \ + -e "s|{{CHAIN_MONITOR_ENABLED}}|$CHAIN_MONITOR|g" \ + "$template" > "$output" + log_ok "Relayer config rendered: $output" +} + +render_prover_config() { + local gpu_id="${1:-0}" + local output="${SCRIPT_DIR}/../.work/prover-${gpu_id}.json" + mkdir -p "$(dirname "$output")" + + local prover_name + prover_name=$(jq -r '.prover.name_prefix' "$CONFIG_FILE") + local s3_url + s3_url=$(jq -r '.prover.s3_base_url' "$CONFIG_FILE") + + cat > "$output" </dev/null 2>&1 || { log_error "docker is required"; exit 1; } + command -v jq >/dev/null 2>&1 || { log_error "jq is required"; exit 1; } + command -v anvil >/dev/null 2>&1 || { log_error "anvil (Foundry) is required"; exit 1; } + + # 2. Start / reset PostgreSQL + log_info "Starting PostgreSQL..." + if compose ps postgres 2>/dev/null | grep -q "running"; then + log_info " PostgreSQL already running, stopping first..." + compose stop postgres >/dev/null 2>&1 || true + compose rm -f postgres >/dev/null 2>&1 || true + fi + compose up postgres -d + wait_for_postgres + + # 3. Import bundle range + log_info "Importing bundle range $BUNDLE_RANGE..." + "${SCRIPT_DIR}/00-import-bundle-range.sh" \ + --bundle-range "$BUNDLE_RANGE" \ + --prod-dsn "$PROD_DSN" \ + --shadow-dsn "$DB_DSN" + + # 4. Start Anvil (bare metal) + log_info "Starting Anvil fork..." + local anvil_port="${ANVIL_RPC##*:}" + local existing_pid + existing_pid=$(lsof -ti :"$anvil_port" 2>/dev/null || true) + if [[ -n "$existing_pid" ]]; then + log_warn "Killing existing Anvil on port $anvil_port (PID $existing_pid)" + kill "$existing_pid" 2>/dev/null || true + sleep 2 + fi + + local state_file="${SCRIPT_DIR}/../.work/anvil-${CONFIG}.state.json" + mkdir -p "$(dirname "$state_file")" + + nohup anvil \ + --fork-url "$FORK_URL" \ + --fork-block-number "$FORK_BLOCK" \ + --block-time 12 \ + --port "$anvil_port" \ + --host 0.0.0.0 \ + --state "$state_file" \ + >/dev/null 2>&1 & + ANVIL_PID=$! + log_info "Anvil started (PID $ANVIL_PID, port $anvil_port)" + echo "$ANVIL_PID" > "${SCRIPT_DIR}/../.work/anvil-${CONFIG}.pid" + sleep 3 + + # 5. Setup Anvil state + if [[ "$SKIP_ANVIL_SETUP" == "false" ]]; then + log_info "Setting up Anvil state..." + "${SCRIPT_DIR}/01-setup-anvil.sh" \ + --no-anvil \ + --anvil-rpc "$ANVIL_RPC" \ + --last-finalized "$LAST_FINALIZED" \ + --next-queue "$NEXT_QUEUE" \ + --deployed-verifier "$DEPLOYED_VERIF" \ + --prover-eoa "$PROVER_EOA" \ + --commit-eoa "$COMMIT_EOA" \ + --owner "$OWNER" \ + --scroll-chain "$SCROLL_CHAIN" \ + --l1-msg-queue "$L1_MSG_QUEUE" \ + --rollup-verifier "$ROLLUP_VERIF" \ + --db-dsn "$DB_DSN" \ + --codec-version "$CODEC_VERSION" + else + log_info "Skipping Anvil state setup (--skip-anvil-setup)" + fi + + log_ok "Phase env complete!" +} + +# ─── Phase: prove ──────────────────────────────────────────────────────────── + +run_prove() { + log_info "=== Phase: prove ===" + + # 6. Start coordinator + log_info "Starting coordinator..." + compose up coordinator -d + wait_for_coordinator + + # 7. Render prover config and start prover + log_info "Rendering prover config..." + render_prover_config 0 + log_info "Starting prover (GPU 0)..." + compose --profile coordinator --profile prover up prover-gpu-0 -d + wait_for_prover + + # 8. Wait for proofs + log_info "Waiting for proofs..." + "${SCRIPT_DIR}/05-wait-for-proofs.sh" \ + --db-dsn "$DB_DSN" \ + --bundle-range "$BUNDLE_RANGE" + + log_ok "Phase prove complete!" +} + +# ─── Phase: finalize ───────────────────────────────────────────────────────── + +run_finalize() { + log_info "=== Phase: finalize ===" + + # 9. Render relayer config + render_relayer_config + + # 10. Start relayer + log_info "Starting relayer..." + compose up relayer -d + sleep 3 + + # 11. Wait for finalization + log_info "Waiting for finalization..." + "${SCRIPT_DIR}/07-wait-for-finalize.sh" \ + --anvil-rpc "$ANVIL_RPC" \ + --scroll-chain "$SCROLL_CHAIN" \ + --bundle-range "$BUNDLE_RANGE" \ + --db-dsn "$DB_DSN" + + log_ok "Phase finalize complete!" +} + +# ─── Main ──────────────────────────────────────────────────────────────────── + +log_info "Shadow Fork Orchestrator" +log_info " Config: $CONFIG" +log_info " Bundles: $BUNDLE_RANGE" +log_info " Phase: $PHASE" + +# Ensure .work dir exists +mkdir -p "${SCRIPT_DIR}/../.work" + +case "$PHASE" in + env) + run_env + ;; + prove) + run_prove + ;; + finalize) + run_finalize + ;; + all) + run_env + run_prove + run_finalize + log_info "" + log_ok "🎉 Full pipeline complete!" + log_info " Config: $CONFIG" + log_info " Bundles: $BUNDLE_RANGE" + ;; + *) + log_error "Unknown phase: $PHASE (expected: env|prove|finalize|all)" + exit 1 + ;; +esac diff --git a/tests/shadow-testing/scripts/fetch-l2-blocks.py b/tests/shadow-testing/scripts/fetch-l2-blocks.py new file mode 100755 index 0000000000..ebb6b53e9f --- /dev/null +++ b/tests/shadow-testing/scripts/fetch-l2-blocks.py @@ -0,0 +1,248 @@ +#!/usr/bin/env python3 +""" +Fetch L2 block data from RPC and populate the l2_block table in shadow DB. + +The coordinator needs l2_block records (specifically the `header` column) to +format chunk tasks (for block hashes and hardfork name resolution). This script +fetches full blocks in batches and inserts them into the shadow database. Columns +not available from a standard RPC (withdraw_root, row_consumption) are filled +with sentinel values because the coordinator chunk-task path only reads `header`. + +Usage: + python3 fetch-l2-blocks.py --rpc https://mainnet-rpc.scroll.io \ + --db "postgresql://:@localhost:5433/shadow_rollup" \ + --start-block 26000000 --end-block 27000000 + +After running, link blocks to chunks: + UPDATE l2_block lb + SET chunk_hash = c.hash + FROM chunk c + WHERE lb.number >= c.start_block_number + AND lb.number <= c.end_block_number; +""" + +import argparse +import json +import sys +import time +import concurrent.futures +from typing import Optional + +import requests +import psycopg2 +from psycopg2.extras import execute_values + + +def fetch_block_batch(rpc_url: str, block_numbers: list[int]) -> list[dict]: + """Fetch multiple full blocks via batch JSON-RPC request.""" + payload = [ + { + "jsonrpc": "2.0", + "method": "eth_getBlockByNumber", + "params": [hex(num), True], + "id": i, + } + for i, num in enumerate(block_numbers) + ] + + try: + resp = requests.post(rpc_url, json=payload, headers={"Content-Type": "application/json"}, timeout=60) + resp.raise_for_status() + results = resp.json() + + blocks = [] + for result in results: + if "error" in result: + print(f" Error fetching block: {result['error']}", file=sys.stderr) + continue + block = result.get("result") + if block is None: + continue + blocks.append(block) + return blocks + except Exception as e: + print(f" Request failed: {e}", file=sys.stderr) + return [] + + +def insert_blocks(db_url: str, blocks: list[dict]) -> int: + """Insert full blocks into the l2_block table.""" + if not blocks: + return 0 + + rows = [] + for block in blocks: + try: + number = int(block["number"], 16) + hash_val = block["hash"] + parent_hash = block["parentHash"] + state_root = block["stateRoot"] + tx_num = len(block.get("transactions", [])) + gas_used = int(block["gasUsed"], 16) + block_timestamp = int(block["timestamp"], 16) + + # Header JSON: the geth-types.Header fields only; drop the RPC-only + # `hash` and the embedded `transactions` array. + header_obj = {k: v for k, v in block.items() if k not in ("hash", "transactions")} + header = json.dumps(header_obj, separators=(",", ":")) + transactions = json.dumps(block.get("transactions", []), separators=(",", ":")) + + # Sentinel values for columns the coordinator does not use for chunk + # task generation. They must be non-null to satisfy the schema. + withdraw_root = "0x0000000000000000000000000000000000000000000000000000000000000000" + row_consumption = "null" + + rows.append(( + number, + hash_val, + parent_hash, + header, + transactions, + withdraw_root, + state_root, + tx_num, + gas_used, + block_timestamp, + row_consumption, + )) + except (KeyError, ValueError) as e: + print(f" Skipping malformed block: {e}", file=sys.stderr) + continue + + if not rows: + return 0 + + conn = psycopg2.connect(db_url) + try: + with conn.cursor() as cur: + execute_values( + cur, + """ + INSERT INTO l2_block ( + number, hash, parent_hash, header, transactions, withdraw_root, + state_root, tx_num, gas_used, block_timestamp, row_consumption + ) + VALUES %s + ON CONFLICT (number) WHERE deleted_at IS NULL DO UPDATE SET + hash = EXCLUDED.hash, + parent_hash = EXCLUDED.parent_hash, + header = EXCLUDED.header, + transactions = EXCLUDED.transactions, + withdraw_root = EXCLUDED.withdraw_root, + state_root = EXCLUDED.state_root, + tx_num = EXCLUDED.tx_num, + gas_used = EXCLUDED.gas_used, + block_timestamp = EXCLUDED.block_timestamp, + row_consumption = EXCLUDED.row_consumption + """, + rows, + ) + conn.commit() + return len(rows) + finally: + conn.close() + + +def get_existing_block_range(db_url: str) -> tuple[Optional[int], Optional[int]]: + """Get min/max block numbers already in the DB.""" + conn = psycopg2.connect(db_url) + try: + with conn.cursor() as cur: + cur.execute("SELECT MIN(number), MAX(number) FROM l2_block") + return cur.fetchone() + finally: + conn.close() + + +def link_blocks_to_chunks(db_url: str) -> int: + """Update chunk_hash for all blocks that fall inside a known chunk range.""" + conn = psycopg2.connect(db_url) + try: + with conn.cursor() as cur: + cur.execute(""" + UPDATE l2_block lb + SET chunk_hash = c.hash + FROM chunk c + WHERE lb.number >= c.start_block_number + AND lb.number <= c.end_block_number + AND lb.chunk_hash IS DISTINCT FROM c.hash + """) + updated = cur.rowcount + conn.commit() + return updated + finally: + conn.close() + + +def main(): + parser = argparse.ArgumentParser(description="Fetch L2 blocks into shadow DB") + parser.add_argument("--rpc", required=True, help="L2 RPC endpoint URL") + parser.add_argument("--db", required=True, help="Shadow DB connection string") + parser.add_argument("--start-block", type=int, required=True, help="First block to fetch") + parser.add_argument("--end-block", type=int, required=True, help="Last block to fetch") + parser.add_argument("--batch-size", type=int, default=100, help="RPC batch size (default: 100)") + parser.add_argument("--workers", type=int, default=4, help="Concurrent workers (default: 4)") + parser.add_argument("--delay", type=float, default=0.1, help="Delay between batches in seconds (default: 0.1)") + parser.add_argument("--skip-existing", action="store_true", help="Skip blocks already in DB") + parser.add_argument("--link-chunks", action="store_true", default=True, help="Link blocks to chunks after fetch (default: True)") + args = parser.parse_args() + + existing_min, existing_max = get_existing_block_range(args.db) + print(f"Existing blocks in DB: {existing_min or 'none'} to {existing_max or 'none'}") + + start = args.start_block + end = args.end_block + + if args.skip_existing and existing_min is not None: + # Simple approach: fetch the requested range, ON CONFLICT will handle it. + pass + + total_blocks = end - start + 1 + print(f"Fetching {total_blocks} blocks from {start} to {end} via {args.rpc}") + + fetched = 0 + failed = 0 + + # Generate batch ranges + ranges = [] + current = start + while current <= end: + batch_end = min(current + args.batch_size - 1, end) + ranges.append(list(range(current, batch_end + 1))) + current = batch_end + 1 + + with concurrent.futures.ThreadPoolExecutor(max_workers=args.workers) as executor: + futures = { + executor.submit(fetch_block_batch, args.rpc, block_nums): block_nums + for block_nums in ranges + } + + for future in concurrent.futures.as_completed(futures): + block_nums = futures[future] + try: + blocks = future.result() + if blocks: + inserted = insert_blocks(args.db, blocks) + fetched += inserted + print(f" Blocks {block_nums[0]}-{block_nums[-1]}: inserted {inserted}/{len(blocks)}") + else: + failed += len(block_nums) + print(f" Blocks {block_nums[0]}-{block_nums[-1]}: FAILED") + except Exception as e: + failed += len(block_nums) + print(f" Blocks {block_nums[0]}-{block_nums[-1]}: ERROR {e}") + + time.sleep(args.delay) + + print(f"\nFetched: {fetched}, Failed: {failed}") + + if args.link_chunks: + print("Linking blocks to chunks...") + linked = link_blocks_to_chunks(args.db) + print(f" Linked {linked} blocks to chunks") + + print("\nDone!") + + +if __name__ == "__main__": + main() diff --git a/tests/shadow-testing/scripts/fix_gas_in_db_transactions.py b/tests/shadow-testing/scripts/fix_gas_in_db_transactions.py new file mode 100644 index 0000000000..a310ef87fd --- /dev/null +++ b/tests/shadow-testing/scripts/fix_gas_in_db_transactions.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python3 +"""Normalize l2_block.transactions JSON for relayer/da-codec unmarshalling.""" + +import json +import psycopg2 +import sys + +DB_DSN = "postgresql://postgres:shadow_pass@localhost:5433/shadow_rollup" +L1_MESSAGE_TX_TYPE = 0x7E + + +def hex_to_int(v): + if isinstance(v, str) and v.startswith("0x"): + return int(v, 16) + return v + + +def int_to_hex(v): + if isinstance(v, int): + return f"0x{v:x}" + return v + + +def fix_txs(txs): + changed = False + for tx in txs: + # Numeric fields expected as integers by types.TransactionData. + for field in ("gas", "nonce", "type"): + v = tx.get(field) + if isinstance(v, str): + tx[field] = hex_to_int(v) + changed = True + + # chainId must be a hex string for *hexutil.Big unmarshalling. + chain_id = tx.get("chainId") + if isinstance(chain_id, int): + tx["chainId"] = int_to_hex(chain_id) + changed = True + + # RPC uses 'input'; da-codec/types.TransactionData expects 'data'. + if "data" not in tx and "input" in tx: + tx["data"] = tx["input"] + changed = True + + # RPC uses maxFeePerGas/maxPriorityFeePerGas; da-codec uses gasFeeCap/gasTipCap. + if "gasFeeCap" not in tx and "maxFeePerGas" in tx: + tx["gasFeeCap"] = tx["maxFeePerGas"] + changed = True + if "gasTipCap" not in tx and "maxPriorityFeePerGas" in tx: + tx["gasTipCap"] = tx["maxPriorityFeePerGas"] + changed = True + + # Ensure hex string fields are actually strings (some may be integers in DB). + for field in ("gasPrice", "gasFeeCap", "gasTipCap", "value", "v", "r", "s", + "maxFeePerGas", "maxPriorityFeePerGas"): + if field in tx and isinstance(tx[field], int): + tx[field] = int_to_hex(tx[field]) + changed = True + + # L1 message txs: RPC stores the queue index in 'queueIndex' and leaves + # 'nonce' as 0. da-codec reuses 'nonce' for the queue index. + if tx.get("type") == L1_MESSAGE_TX_TYPE and "queueIndex" in tx: + queue_index = tx["queueIndex"] + if isinstance(queue_index, str): + queue_index = hex_to_int(queue_index) + if tx.get("nonce") != queue_index: + tx["nonce"] = queue_index + changed = True + + return changed + + +def main(): + start_block = int(sys.argv[1]) if len(sys.argv) > 1 else 33848707 + end_block = int(sys.argv[2]) if len(sys.argv) > 2 else 33851426 + + conn = psycopg2.connect(DB_DSN) + cur = conn.cursor() + try: + cur.execute( + "SELECT number, transactions FROM l2_block WHERE number BETWEEN %s AND %s", + (start_block, end_block), + ) + rows = cur.fetchall() + print(f"Found {len(rows)} blocks to inspect ({start_block}-{end_block})") + + updated = 0 + for number, tx_json in rows: + if not tx_json: + continue + try: + txs = json.loads(tx_json) + except Exception as e: + print(f"Skip block {number}: parse error {e}", file=sys.stderr) + continue + if not isinstance(txs, list): + continue + if fix_txs(txs): + cur.execute( + "UPDATE l2_block SET transactions = %s WHERE number = %s", + (json.dumps(txs, separators=(",", ":")), number), + ) + updated += 1 + if updated % 100 == 0: + conn.commit() + print(f" updated {updated} blocks so far...") + + conn.commit() + print(f"Done: updated {updated} blocks.") + finally: + cur.close() + conn.close() + + +if __name__ == "__main__": + main() diff --git a/tests/shadow-testing/scripts/fix_l2_block_transactions.py b/tests/shadow-testing/scripts/fix_l2_block_transactions.py new file mode 100644 index 0000000000..c25f8e9582 --- /dev/null +++ b/tests/shadow-testing/scripts/fix_l2_block_transactions.py @@ -0,0 +1,199 @@ +#!/usr/bin/env python3 +""" +Fix missing l2_block.transactions data by fetching from L2 RPC. +""" + +import json +import psycopg2 +import requests +import sys +import time +from concurrent.futures import ThreadPoolExecutor, as_completed +from typing import Optional + +L2_RPC = "https://l2geth-rpc-proxy.mainnet.aws.scroll.io" +DB_DSN = "postgresql://postgres:shadow_pass@localhost:5433/shadow_rollup" +BATCH_SIZE = 50 +MAX_WORKERS = 20 + + +def hex_to_int(hex_str: str) -> int: + if hex_str is None: + return 0 + return int(hex_str, 16) + + +def rpc_get_block(block_num: int) -> Optional[dict]: + """Fetch full block with transactions from L2 RPC.""" + try: + resp = requests.post( + L2_RPC, + json={ + "jsonrpc": "2.0", + "method": "eth_getBlockByNumber", + "params": [hex(block_num), True], + "id": 1, + }, + timeout=30, + ) + resp.raise_for_status() + result = resp.json().get("result") + return result + except Exception as e: + print(f"Error fetching block {block_num}: {e}", file=sys.stderr) + return None + + +def convert_tx_to_transaction_data(rpc_tx: dict) -> dict: + """Convert RPC transaction JSON to TransactionData format.""" + tx_type = hex_to_int(rpc_tx.get("type", "0x0")) + + # Handle L1 message tx: nonce should be queueIndex, not tx.Nonce() + if tx_type == 0x7E: + nonce = hex_to_int(rpc_tx.get("queueIndex", "0x0")) + else: + nonce = hex_to_int(rpc_tx.get("nonce", "0x0")) + + # gasPrice: for legacy txs, use gasPrice; for EIP-1559, use effective gasPrice + gas_price = rpc_tx.get("gasPrice") + if gas_price is None: + gas_price = rpc_tx.get("maxFeePerGas", "0x0") + + # gasTipCap / gasFeeCap + gas_tip_cap = rpc_tx.get("maxPriorityFeePerGas", gas_price) + gas_fee_cap = rpc_tx.get("maxFeePerGas", gas_price) + + # isCreate: true if 'to' is null + to_addr = rpc_tx.get("to") + is_create = to_addr is None + + # accessList: use null if empty or absent + access_list = rpc_tx.get("accessList") + if access_list == []: + access_list = None + + # authorizationList + auth_list = rpc_tx.get("authorizationList") + if auth_list == []: + auth_list = None + + # v: use yParity if available for EIP-1559, otherwise use v + v = rpc_tx.get("v") + if v is None: + v = rpc_tx.get("yParity", "0x0") + + tx_data = { + "type": tx_type, + "nonce": nonce, + "txHash": rpc_tx.get("hash", ""), + "gas": hex_to_int(rpc_tx.get("gas", "0x0")), + "gasPrice": gas_price, + "gasTipCap": gas_tip_cap, + "gasFeeCap": gas_fee_cap, + "from": rpc_tx.get("from", ""), + "to": to_addr, + "chainId": rpc_tx.get("chainId", "0x82750"), + "value": rpc_tx.get("value", "0x0"), + "data": rpc_tx.get("input", "0x"), + "isCreate": is_create, + "accessList": access_list, + "authorizationList": auth_list, + "v": v, + "r": rpc_tx.get("r", "0x0"), + "s": rpc_tx.get("s", "0x0"), + } + + return tx_data + + +def process_block(block_num: int) -> Optional[tuple]: + """Fetch and convert transactions for a single block.""" + block = rpc_get_block(block_num) + if block is None: + return None + + rpc_txs = block.get("transactions", []) + if not rpc_txs: + tx_data = "[]" + else: + tx_list = [convert_tx_to_transaction_data(tx) for tx in rpc_txs] + tx_data = json.dumps(tx_list, separators=(',', ':')) + + return (block_num, tx_data) + + +def update_blocks_in_db(blocks_data: list): + """Update transactions for multiple blocks in shadow DB.""" + conn = psycopg2.connect(DB_DSN) + cur = conn.cursor() + + try: + for block_num, tx_data in blocks_data: + cur.execute( + "UPDATE l2_block SET transactions = %s WHERE number = %s", + (tx_data, block_num) + ) + conn.commit() + except Exception as e: + conn.rollback() + print(f"DB update error: {e}", file=sys.stderr) + raise + finally: + cur.close() + conn.close() + + +def get_empty_blocks() -> list: + """Get list of block numbers with empty transactions.""" + conn = psycopg2.connect(DB_DSN) + cur = conn.cursor() + cur.execute( + "SELECT number FROM l2_block WHERE transactions = '' ORDER BY number" + ) + blocks = [row[0] for row in cur.fetchall()] + cur.close() + conn.close() + return blocks + + +def main(): + empty_blocks = get_empty_blocks() + total = len(empty_blocks) + print(f"Found {total} blocks with empty transactions") + + if total == 0: + print("No empty transactions to fix.") + return + + processed = 0 + failed_blocks = [] + + for batch_start in range(0, total, BATCH_SIZE): + batch = empty_blocks[batch_start:batch_start + BATCH_SIZE] + print(f"Processing batch {batch_start//BATCH_SIZE + 1}/{(total-1)//BATCH_SIZE + 1}: blocks {batch[0]} to {batch[-1]}") + + blocks_data = [] + with ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor: + futures = {executor.submit(process_block, bn): bn for bn in batch} + for future in as_completed(futures): + result = future.result() + if result: + blocks_data.append(result) + else: + failed_blocks.append(futures[future]) + + if blocks_data: + update_blocks_in_db(blocks_data) + processed += len(blocks_data) + print(f" Updated {len(blocks_data)} blocks. Total processed: {processed}/{total}") + + # Small delay between batches to avoid rate limiting + time.sleep(0.5) + + print(f"\nDone! Processed {processed}/{total} blocks.") + if failed_blocks: + print(f"Failed blocks: {failed_blocks}") + + +if __name__ == "__main__": + main() diff --git a/tests/shadow-testing/scripts/lib/anvil-utils.sh b/tests/shadow-testing/scripts/lib/anvil-utils.sh new file mode 100755 index 0000000000..981e51c60c --- /dev/null +++ b/tests/shadow-testing/scripts/lib/anvil-utils.sh @@ -0,0 +1,103 @@ +#!/usr/bin/env bash +# Shared Anvil utility functions for shadow testing +set -euo pipefail + +# Note: do not define SCRIPT_DIR here, as this file is sourced by other scripts +# and would overwrite their SCRIPT_DIR variable. + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +log_info() { echo -e "${BLUE}[INFO]${NC} $*"; } +log_warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } +log_error() { echo -e "${RED}[ERROR]${NC} $*"; } +log_ok() { echo -e "${GREEN}[OK]${NC} $*"; } + +# Wait for Anvil to be ready +wait_for_anvil() { + local rpc_url="${1:-http://localhost:18545}" + local max_wait="${2:-60}" + log_info "Waiting for Anvil at $rpc_url ..." + for ((i=0; i/dev/null 2>&1; then + log_ok "Anvil is ready" + return 0 + fi + sleep 1 + done + log_error "Anvil did not become ready within ${max_wait}s" + return 1 +} + +# Get storage slot value +get_storage() { + local contract="$1" + local slot="$2" + local rpc_url="${3:-http://localhost:18545}" + cast storage "$contract" "$slot" --rpc-url "$rpc_url" 2>/dev/null | tr -d '\n' +} + +# Set storage slot value (Anvil only) +set_storage() { + local contract="$1" + local slot="$2" + local value="$3" + local rpc_url="${4:-http://localhost:18545}" + cast rpc anvil_setStorageAt "$contract" "$slot" "$value" --rpc-url "$rpc_url" >/dev/null +} + +# Impersonate an account (Anvil only) +impersonate() { + local addr="$1" + local rpc_url="${2:-http://localhost:18545}" + cast rpc anvil_impersonateAccount "$addr" --rpc-url "$rpc_url" >/dev/null +} + +# Stop impersonating +stop_impersonate() { + local addr="$1" + local rpc_url="${2:-http://localhost:18545}" + cast rpc anvil_stopImpersonatingAccount "$addr" --rpc-url "$rpc_url" >/dev/null +} + +# Send ETH to an address +set_balance() { + local addr="$1" + local wei="${2:-0x56bc75e2d63100000}" # 100 ETH default + local rpc_url="${3:-http://localhost:18545}" + cast rpc anvil_setBalance "$addr" "$wei" --rpc-url "$rpc_url" >/dev/null +} + +# Encode uint256 for storage +encode_uint256() { + local val="$1" + printf '%064x' "$val" +} + +# Extract lower 64 bits from a 32-byte hex string +lower64() { + local hex="$1" + echo "${hex: -16}" +} + +# Check if a command exists +require_cmd() { + if ! command -v "$1" &>/dev/null; then + log_error "Required command not found: $1" + exit 1 + fi +} + +# Parse bundle range like "17297:17301" into individual indices +parse_bundle_range() { + local range="$1" + local start="${range%%:*}" + local end="${range##*:}" + for ((i=start; i<=end; i++)); do + echo "$i" + done +} diff --git a/zkvm-prover/config.json.template b/zkvm-prover/config.json.template index 6cb893c131..366e8d6bdc 100644 --- a/zkvm-prover/config.json.template +++ b/zkvm-prover/config.json.template @@ -29,7 +29,7 @@ "base_url": "https://circuit-release.s3.us-west-2.amazonaws.com/scroll-zkvm/releases/galileo/" }, "galileoV2": { - "base_url": "https://circuit-release.s3.us-west-2.amazonaws.com/scroll-zkvm/galileov2/", + "base_url": "https://circuit-release.s3.us-west-2.amazonaws.com/scroll-zkvm/releases/v0.9.0/", "workspace_path": ".work/galileo" } }