feat(stm): add recursive IVC circuit benchmarks#3432
Conversation
Test Results 5 files ± 0 209 suites ±0 1h 54m 28s ⏱️ - 1h 19m 22s Results for commit ec40622. ± Comparison against base commit 2eedbd2. This pull request removes 23 and adds 8 tests. Note that renamed tests count towards both.♻️ This comment has been updated with latest results. |
There was a problem hiding this comment.
Pull request overview
This PR introduces an end-to-end benchmark suite for the recursive IVC Halo2 SNARK in mithril-stm, driven through a benchmark-internals-gated façade that delegates to the production proof-system paths. It also refactors the IVC golden-asset layer so both tests and benchmarks can share the same embedded fixtures, and adds a deterministic genesis benchmark fixture plus a fail-closed benchmark CLI filter.
Changes:
- Add a new
ivc_halo2_snarkbenchmark target with manual single-observation timing tables and a fail-closed CLI filter. - Move the read-only embedded golden-asset decoding into a shared
embedded_assetsmodule and add an additive genesis benchmark fixture (plus a test to guard determinism/validity). - Expose a small set of internal APIs under
benchmark-internalsto reuse production setup/prove/verify/fold code paths in benchmarks.
Reviewed changes
Copilot reviewed 16 out of 17 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| mithril-stm/src/proof_system/ivc_halo2_snark/verifier_setup.rs | Extends test-only verifier-setup constructor gating to benchmarks. |
| mithril-stm/src/proof_system/ivc_halo2_snark/proof.rs | Makes transcript-based proving helper accessible to the benchmark façade. |
| mithril-stm/src/proof_system/ivc_halo2_snark/mod.rs | Re-exports IvcProverInput for benchmarks/tests. |
| mithril-stm/src/circuits/trusted_setup.rs | Exposes unsafe-SRS helpers to benchmarks (previously tests only). |
| mithril-stm/src/circuits/halo2_ivc/types.rs | Allows test helper conversion (from_field) for benchmarks. |
| mithril-stm/src/circuits/halo2_ivc/tests/golden/positive.rs | Adds a determinism/validity guard test for the new genesis benchmark fixture. |
| mithril-stm/src/circuits/halo2_ivc/tests/common/generators/setup.rs | Adds filesystem path for the additive genesis benchmark fixture asset. |
| mithril-stm/src/circuits/halo2_ivc/tests/common/generators/asset_generation.rs | Adds generator + ignored entrypoint to produce the benchmark fixture asset. |
| mithril-stm/src/circuits/halo2_ivc/tests/common/field_encoding.rs | Re-exports field-encoding helper from the shared embedded asset layer. |
| mithril-stm/src/circuits/halo2_ivc/tests/common/asset_readers.rs | Keeps test-only asset writers; re-exports shared embedded loaders/types. |
| mithril-stm/src/circuits/halo2_ivc/mod.rs | Wires in benchmark-only modules and the shared embedded asset module. |
| mithril-stm/src/circuits/halo2_ivc/embedded_assets.rs | New shared read-only embedded asset layer (types + decoders + include_bytes!). |
| mithril-stm/src/circuits/halo2_ivc/bench_helpers.rs | New benchmark façade building setup/fixtures and delegating to production code paths. |
| mithril-stm/src/circuits/halo2_ivc/bench_cli.rs | New fail-closed CLI parser (unit-tested) for benchmark filtering. |
| mithril-stm/Cargo.toml | Registers the new ivc_halo2_snark benchmark with required features. |
| mithril-stm/benches/ivc_halo2_snark.rs | New benchmark harness producing consolidated timing tables (manual timing). |
Comments suppressed due to low confidence (1)
mithril-stm/src/circuits/trusted_setup.rs:212
TrustedSetupProvider::with_unsafe_srsnow compiles underfeature = "benchmark-internals", but it still uses multipleunwrap()calls for serialization and filesystem IO. This can panic during benchmark runs (e.g. permission / disk full / temp dir issues) and also violates the project’s “no unwrap outside tests” guideline. Consider returningStmResult<Self>and propagating errors with?(andContext) instead of panicking.
let mut srs_bytes = Vec::new();
srs.write_custom(&mut srs_bytes, SerdeFormat::RawBytes).unwrap();
let srs_dir = base_dir.join(MITHRIL_CIRCUIT_SRS_FOLDER);
create_dir_all(&srs_dir).unwrap();
…r benchmark reuse
…ing to the IVC bench façade
…, drop stale allow, doc wording)
…nch modules
Move the benchmark façades and the IVC bench CLI out of the production module namespace into dedicated `bench` submodules (`circuits::halo2_ivc::bench::{helpers,cli}` and `circuits::halo2::bench::helpers`), update the harness imports, and narrow the `IvcProverInput` re-export to the `benchmark-internals` feature.
Split the ~130-line `prepare_certificate_step` into an orchestrator plus `build_certificate_fold_inputs` and `ensure_certificate_prepared_matches_committed`, add a `CertificateStepAsset` (with `From` impls) to unify the same-/next-epoch assets, move the `IvcBenchEnv` definition above its `impl`, and rewrite comments to be self-explanatory (no implementation-plan item references).
Document how to run both circuits' Halo2 benchmarks and, in detail, the recursive IVC harness's CLI (`--list`, `--help`, literal id/prefix filters, the fail-closed rejection rules, and the full benchmark-id scheme), plus the certificate tiers and prerequisites.
Move the sha2 and BaseFieldElement `use` statements out of genesis_benchmark_fixture_is_deterministic_and_valid up to the module's top-level imports.
No benches are ignored, so the Ignored variant never did anything meaningful. Remove it; --ignored is now rejected as an unsupported option (still fail-closed), which also lets the control-mode conflict bookkeeping go. Tests and the harness dispatch updated.
The harness measures the SRS and circuit keys separately (measure_srs_cold_start / measure_srs_warm_start / measure_keys); the combined measure_full_setup loader was never called (undetected because pub lib items are not dead-code-checked).
Align the markdown tables to satisfy `make check-format` (prettier --check); no content change.
a51287a to
671a28b
Compare
A no-filter run does minutes of silent keygen and proving; emit per-phase progress to stderr (environment build, per-path prove/verify/fold, setup cold/warm) before each step so runs visibly advance. Logging happens outside the timed regions, so measurements are unaffected.
671a28b to
ec40622
Compare
Content
This PR adds benchmarks for the recursive IVC circuit's prover, verifier, off-circuit accumulator fold, and setup. They are driven end-to-end by a thin
benchmark-internals-gated façade that delegates to the production IVC proof-system code, so the measured operations are the same code paths run in production. The inner circuit is the small committed (degree-13) non-recursive certificate, sourced from the committed golden assets plus one additive genesis fixture, and every transition path (genesis, same-epoch, next-epoch) is covered.Each run builds the shared recursive setup once (a full keygen) and reports single-observation timings in consolidated tables. Given a degree-19 recursive proof costs tens of seconds and the keygen runs for minutes, Criterion's sampling is not used (mirroring the existing
halo2_prover_modesbench).Changes
mithril-stm/benches/ivc_halo2_snark.rs(gated behindfuture_snarkandbenchmark-internals), a single-observation report driven by theIvcBenchEnvfaçade. One shared keygenper run; a per-path prove/verify/fold table and a setup cold-vs-warm table.
embedded_assets)so benchmarks and tests can share it, and added one additive genesis benchmark fixture. Existing golden
assets are unchanged.
create_proof, Poseidon and Blake2b transcripts); verificationas both the isolated KZG opening and the full verification (opening plus the folded-accumulator check); the
off-circuit accumulator fold per transition path (genesis is an accumulator passthrough, so it has no fold);
and setup cold vs warm, measured separately for the SRS and for the certificate + recursive circuit keys.
production setup, symmetric
cold_start/warm_startnaming, and ameasure_keysthat mirrors productionsetup (certificate verifying key then recursive key pair) so cold and warm cover the same key layers.
benchmark-internals-gatedbench_climodule, unit-tested) —--listto print the ids, an optional single literal id/prefix filter, and rejection of anything thatcould otherwise trigger an accidental multi-minute keygen (e.g. value-taking options,
--test,--profile-time, regex filters).Pre-submit checklist
Issue(s)
Closes #3412