Reuse cached batch provers and pin qp-zk-circuits to v4.4.0 - #156
Conversation
v4.4.0 makes the batch provers reusable, so building the public-batch circuit once per process drops later batches from ~65s to ~21s. Also keep multiround from starving a next-round address when assignment ignored the partition minimum. Co-authored-by: Cursor <cursoragent@cursor.com>
A full cargo update refreshed unrelated crates. Restore main's lockfile and only retarget the qp-zk-circuits packages at the v4.4.0 tag. Co-authored-by: Cursor <cursoragent@cursor.com>
|
@n13 please re-review — lockfile is now a surgical pin of the qp-zk-circuits crates to |
n13
left a comment
There was a problem hiding this comment.
Reviewer model: GPT 5.6 Sol
REQUEST_CHANGES: the output redistribution still permits the multiround starvation it is intended to prevent, and the git-only dependency declarations make this published crate unpackagable.
-
[P1] Do not submit a round while target deficits remain —
src/cli/wormhole.rs:625-650This loop returns
Ok(assignments)afterbreakeven whendeficit > 0. That is reachable with inputs admitted by this flow: for five distinct targets, quantized inputs[3, 3, 3, 3, 100]at 4 bps yield per-proof outputs[2, 2, 2, 2, 99]. Passes 1-2 pair one proof with each target; only the 99-unit proof has excess, and after its soleoutput_2slot tops up one target, no eligible donor remains. On this exact head, 20/20 targeted runs left three targets at 2 units. The initial partition explicitly permits 3-unit inputs, and subsequent fee rounding takes 2 to 1 and then 0, so the multiround command can still commit a round on-chain and later fail when a next-round mint disappears. Ensure every next-round target meets a pre-fee-safe minimum, or fail/reduce the proof set before submission when the two-output capacity cannot satisfy that invariant, and cover this skewed case deterministically. -
[P2] Retain package versions alongside the temporary git pins —
Cargo.toml:124-141All qp dependencies now specify only
git/tag.cargo package --locked --no-verify --allow-dirtyfails immediately withall dependencies must have a version requirement specified when packaging(first reported forqp-wormhole-aggregator). This repository's release workflow publishes to crates.io, so the manifest is no longer releasable even after qp 4.4.0 appears there. Addversion = "4.4.0"alongside each git/tag pin (including the build dependency); Cargo can build from git now and retain the registry requirement when packaging.
Validation on 1075b4e69cdb2ff6ee8a8ad2665007f08dfe09f1:
cargo +nightly-2026-08-31 fmt --all -- --check— passedtaplo format --check --config taplo.toml— passedcargo test --lockedwith full circuit generation — passed (334 lib + 332 bin; 1 doc test ignored)SKIP_CIRCUIT_BUILD=1 cargo clippy --all-targets --locked -- -D warnings— passed- Targeted starvation harness — reproduced in 20/20 runs
cargo package --locked --no-verify --allow-dirty— failed as described above
GitHub's Fast Checks job failed during runner setup on an external Google apt index hash mismatch, before repository checks ran.
Format only needs rustfmt and taplo. The shared Ubuntu setup was pulling clang, protobuf, wasm, and every third-party apt source, including Google Chrome, which is what hash-mismatched. Drop that Chrome list from compile jobs too. Co-authored-by: Cursor <cursoragent@cursor.com>
Deleting google-chrome.list was not enough: the runner still hash-mismatches Chrome via a .sources file. Restrict apt-get update to the distro sources.list so build, clippy, and examples do not depend on Google's index. Co-authored-by: Cursor <cursoragent@cursor.com>
A single rich proof cannot top up every dust sibling through one output_2 slot, so refuse that assignment instead of submitting a round that dies two hops later. Keep version = "4.4.0" beside the git pins so cargo package still works. Co-authored-by: Cursor <cursoragent@cursor.com>
|
@n13 both review points addressed:
Please re-review. |
n13
left a comment
There was a problem hiding this comment.
Reviewer model: GPT 5.6 Sol
APPROVE: The prior blockers are resolved, and I found no remaining blocking issues on 7f10e799b8f0052cdaa902de6b0c50c358c9adbb.
The skewed [3, 3, 3, 3, 100] path now fails before submission when limited output slots cannot fund every next-round address, with deterministic regression coverage. All qp dependencies retain version = "4.4.0" beside the temporary v4.4.0 git pins; the packaging preflight now gets past those entries and stops only at the pre-existing quantus_ur git dependency from the base branch. I also checked the pinned v4.4.0 PublicBatchProver::prove_batch path: it verifies supplied inner proofs and enforces block/asset/fee compatibility before proving.
Validation:
cargo +nightly-2026-08-31 fmt --all -- --check— passedtaplo format --check --config taplo.toml— passedSKIP_CIRCUIT_BUILD=1 cargo test --lib compute_random_output_assignments --locked— passed (6/6)SKIP_CIRCUIT_BUILD=1 cargo clippy --all-targets --locked -- -D warnings— passed- Current GitHub checks — all passed, including Ubuntu/macOS build-and-test, examples, analysis, security audit, formatting, and dependency cooldown
No live-node multiround was run during this re-review; the focused regression tests and complete CI matrix cover the changed code sufficiently for approval.
Summary
qp-zk-circuitsv4.4.0tag so the CLI can use the reusablePrivateBatchProver/PublicBatchProverAPI. crates.io still only has 4.3.0, so this is a git-tag pin rather than a crates.io bump.OnceLock) so multiround and prepare pay the public-batch circuit build once (~tens of seconds) instead of once per batch.Test plan
./clippy.sh(already run locally)cargo test --lib compute_random_output_assignments(includes the 200-round multiround starvation regression)quantus wormhole multiround --num-proofs 7 --rounds 2 --public ...against a local node: first public batch still pays circuit build, later batches should be ~20s, and step 5 should capture all 7 next-round transfersMade with Cursor