You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: AGENTS.md
+93-17Lines changed: 93 additions & 17 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -13,27 +13,50 @@ Critical context for AI agents working on this repo. Read this before making cha
13
13
14
14
## OpenVM Version Sensitivity
15
15
16
-
This project uses **OpenVM** as its ZKVM. Guest executables (`.vmexe`) and host code **must be built from the exact same OpenVM version**. Even a minor version bump can change:
16
+
This project uses **OpenVM v2.0.0** as its ZKVM. Guest executables (`.vmexe`) and host code **must be built from the exact same OpenVM version**. Even a minor version bump can change:
17
17
18
18
- The guest/host data layout (hint streams, public inputs)
19
-
- The `root_verifier.asm` format
20
-
- The Halo2 SRS degree requirement (e.g. `k=23` → `k=24`)
19
+
- The Halo2 SRS degree requirement
21
20
- The EVM verifier contract ABI
22
-
- Field algebra APIs (`from_canonical_u32` → `from_int`)
23
-
- ECC constructor signatures (some became `unsafe`)
21
+
- Field algebra APIs
22
+
- ECC constructor signatures
23
+
24
+
### How to update OpenVM dependencies correctly
25
+
26
+
OpenVM is declared as a **git dependency** (`tag = "v2.0.0"`) in `Cargo.toml`, and the exact commit is also pinned in `Cargo.lock`. The `openvm-org/openvm.git` and `openvm-org/stark-backend.git` entries MUST stay on matching tags — `openvm`'s own `Cargo.toml` pins a specific `stark-backend` tag, and a mismatch produces duplicate-registry / type-mismatch errors. Because the tag is immutable, the declared ref and the locked commit should always agree. The real hazard is a bare `cargo update`: it will **not** change the OpenVM tag, but it will bump unrelated crates.io packages (e.g. `alloy`, `revm`) which often break compatibility with the `scroll-tech/reth` and `sbv` forks.
27
+
28
+
**Do NOT run a global `cargo update` unless you are prepared to upgrade the entire `alloy`/`revm`/`reth`/`sbv` dependency chain together.**
29
+
30
+
To move to a newer OpenVM tag, retarget every `openvm-org/openvm.git` and `openvm-org/stark-backend.git` entry in `Cargo.toml` to the new tag, then refresh only those git sources — `cargo metadata` is enough — rather than a global `cargo update`. Verify with `git diff Cargo.lock` that no other package's version/source changed. Then rebuild guests and run tests as described below.
24
31
25
32
### After ANY OpenVM version upgrade, you MUST:
26
33
27
34
1.**Update the hardcoded version string** in `crates/build-guest/src/verifier.rs`:
28
35
```rust
29
-
letopenvm_version="v1.6"; // MUST match Cargo.toml git rev
36
+
letsolidity_sdk_tag="v2.0"; // MUST match openvm-solidity-sdk tag
2.**Force-rebuild ALL guest assets** (auto mode skips existing files):
33
41
```bash
34
-
cargo run --release -p scroll-zkvm-build-guest -- --mode force
42
+
# Local build
43
+
OPENVM_RUST_TOOLCHAIN=nightly-2025-11-20 cargo run --release -p scroll-zkvm-build-guest -- --mode force
44
+
45
+
# Docker build (matches CI)
46
+
OPENVM_RUST_TOOLCHAIN=nightly-2025-11-20 make build-guest
35
47
```
36
-
This regenerates: `app.elf`, `app.vmexe`, `root_verifier.asm`, commitment `.rs` files, and `openVmVk.json`.
48
+
This regenerates: `app.elf`, `app.vmexe`, commitment `.rs` files, `openVmVk.json`,
49
+
and the EVM verifier (`verifier.sol` + `verifier.bin`).
50
+
51
+
> The default `RECOMPUTE_MODE=auto` tries to download the Solidity verifier from
52
+
> `openvm-solidity-sdk` and compiles it locally with `solc` to produce `verifier.bin`.
53
+
> If the download fails, it falls back to the full local OpenVM verifier generation.
54
+
> `RECOMPUTE_MODE=yes` skips the download and always generates the verifier locally;
55
+
> `RECOMPUTE_MODE=no` forces download-only and fails if no pre-built verifier is available.
56
+
57
+
> Building `batch` or `bundle` requires the SDK of the previous circuit
58
+
> (`batch` needs `chunk`, `bundle` needs `batch`). Always build in a single
59
+
> `force` run so dependencies are generated in the correct order.
37
60
38
61
3.**Verify commitments were updated** — check that `*_exe_commit.rs` and `*_vm_commit.rs` files changed, and that `openVmVk.json` timestamps are fresh.
39
62
@@ -44,8 +67,7 @@ This project uses **OpenVM** as its ZKVM. Guest executables (`.vmexe`) and host
44
67
These are cached proving keys. They are **not** automatically invalidated on version bumps.
**Cause**: The EVM verifier was generated with a different circuit config than the proof.
97
+
This happens when:
98
+
- The verifier was built with `RECOMPUTE_MODE=no` but the downloaded verifier is missing, stale, or has empty bytecode
99
+
- The verifier was built **without** the deferral prover, but the proof uses deferral (batch/bundle)
100
+
- The verifier's `AggregationTreeConfig` does not match the prover's (`num_children_internal/leaf`)
101
+
102
+
**Fix**: Regenerate with:
103
+
```bash
104
+
OPENVM_RUST_TOOLCHAIN=nightly-2025-11-20 cargo run --release -p scroll-zkvm-build-guest -- --mode force
105
+
```
106
+
(The default `auto` mode will fall back to local generation if the download fails; use `RECOMPUTE_MODE=yes` to force local generation immediately.)
107
+
108
+
### `cargo update` breaks compilation with alloy/revm type mismatches
109
+
**Symptoms**: Errors like `missing verify_and_compute_signer_unchecked in implementation` (alloy) or `mismatched types` between `revm_primitives::hardfork::SpecId` and `SpecId` (revm).
110
+
**Cause**: A global `cargo update` bumps `alloy` to 1.8.x and `revm` to 30.2.0, but the `scroll-tech/reth` and `sbv` forks were built against older versions. The `[patch.crates-io]` table pins `revm` to `scroll-v91` (30.1.1), which no longer satisfies the newer `alloy-evm` requirements, leading to duplicate registry versions of `revm-handler` / `revm-primitives` in the dependency graph.
111
+
**Fix**: Restore the original `Cargo.lock` (`git checkout HEAD -- Cargo.lock`) and update only what you actually need (e.g. `cargo metadata` scoped to the OpenVM git sources).
112
+
73
113
### Docker build fails with stale CID
74
114
The `build-guest.sh` script may fail if a stale `build-guest.cid` file exists. Use local build (`cargo run -p scroll-zkvm-build-guest`) as fallback.
75
115
76
116
## Build & Test Commands
77
117
78
118
```bash
79
-
# Force rebuild all guest assets (required after OpenVM upgrade)
80
-
cargo run --release -p scroll-zkvm-build-guest -- --mode force
119
+
# Force rebuild all guest assets (required after OpenVM upgrade).
120
+
# Default RECOMPUTE_MODE=auto falls back to local generation if the download fails.
121
+
# Use RECOMPUTE_MODE=yes to skip the download and force local generation.
122
+
OPENVM_RUST_TOOLCHAIN=nightly-2025-11-20 cargo run --release -p scroll-zkvm-build-guest -- --mode force
81
123
82
124
# Run end-to-end tests (ALWAYS use make, never raw cargo test)
83
125
GPU=1 make test-e2e-bundle
84
126
GPU=1 make test-e2e-batch
85
-
GPU=1 make test-e2e-chunk
127
+
GPU=1 make test-single-chunk
128
+
GPU=1 make test-multi-chunk
86
129
```
87
130
88
131
**⚠️ CRITICAL: Always use `make` for integration tests.**
89
132
The Makefile sets `RUST_MIN_STACK=16777216` (16 MB) and `CARGO_CONFIG_FLAG`. Running `cargo test` directly skips both, which causes:
90
133
- Stack overflow during prover initialization (default Rust stack is only ~2 MB)
91
134
- Missing CUDA features if `GPU=1` is set but `--features scroll-zkvm-integration/cuda` is not passed
92
135
136
+
**⚠️ CRITICAL: Use `--release` for any test that exercises halo2 verifier generation.**
137
+
The `test_verifier` test in `scroll-zkvm-build-guest` builds the full bundle SDK and runs
138
+
`generate_halo2_verifier_solidity()`. In debug mode this is orders of magnitude slower and
139
+
can waste hours of CPU time. Always run it as:
140
+
```bash
141
+
cargo test --release -p scroll-zkvm-build-guest test_verifier
142
+
```
143
+
144
+
## Deferral Model (OpenVM v2+)
145
+
146
+
OpenVM v2 replaces the traditional root-verifier recursion with a **deferred compute model**:
147
+
148
+
-**Chunk** (leaf circuit, 42 AIRs): no deferral
149
+
-**Batch** (aggregation, 44 AIRs): defers child STARK verification to the root
150
+
-**Bundle** (aggregation, 44 AIRs): defers child STARK verification to the root
151
+
152
+
The extra 2 AIRs in batch/bundle come from the deferral extension.
153
+
154
+
### Deferral circuit must use the parent VM's memory layout
155
+
156
+
The `MultiDeferralCircuitProver` (verify-stark deferral circuit) is constructed from the **child's aggregation VK**, but its `memory_dimensions` and `num_user_pvs` must come from the **parent's VM config** (the batch or bundle circuit that calls `verify_stark`). Using the child's config causes the deferral circuit to write public values to the wrong location in the parent VM, leading to `Proof verification failed for commit ...` inside the batch/bundle guest.
157
+
158
+
### Key configuration that must match between prover and verifier
-`batch-circuit` / `bundle-circuit`: include `leaf_fri_params` with `num_queries = 193`, `commit_proof_of_work_bits = 20`
109
-
- FRI params format changed in OpenVM 1.6.0: `proof_of_work_bits` →`commit_proof_of_work_bits` + `query_proof_of_work_bits`
184
+
-`batch-circuit` / `bundle-circuit`: aggregation FRI params are supplied in code via `AggregationConfig { params: default_agg_params() }`; the checked-in `openvm.toml` files do not contain `leaf_fri_params`
185
+
- FRI params format in OpenVM v2:`commit_proof_of_work_bits` + `query_proof_of_work_bits`
0 commit comments