Retarget the recursive-tree canonical circuit to the leaf bootloader#391
Conversation
PR SummaryMedium Risk Overview The canonical PCS and padding constants are renamed and updated (blowup 1, trace log size 23, larger Workspace and Slow e2e fold tests swap the privacy proof bin for Reviewed by Cursor Bugbot for commit cde498b. Bugbot is set up for automated code reviews on this repo. Configure here. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## yairv/add_prove_leaf_from_files #391 +/- ##
===================================================================
+ Coverage 65.25% 65.47% +0.21%
===================================================================
Files 45 45
Lines 5843 5886 +43
===================================================================
+ Hits 3813 3854 +41
- Misses 2030 2032 +2
🚀 New features to boost your workflow:
|
83b2201 to
7cfa0e4
Compare
OmriEshhar1
left a comment
There was a problem hiding this comment.
@OmriEshhar1 reviewed 10 files and all commit messages, and made 3 comments.
Reviewable status: all files reviewed, 3 unresolved discussions (waiting on Gali-StarkWare and YairVaknin-starkware).
crates/stwo_run_and_prove_recursive_tree/src/canonical.rs line 58 at r1 (raw file):
/// circuit reaches (its dominant components, `qm31_ops`/`blake_g_gate`, hit 2^23; see /// [`TARGET_PADDING_SIZES`]). pub const CIRCUIT_TRACE_LOG_SIZE: u32 = 23;
you're using here the same names for the public consts as is privacy (with different values).
consider using different names, so that it doesn't get messy in the future.
crates/stwo_run_and_prove_recursive_tree/src/canonical.rs line 189 at r1 (raw file):
/// Mirrors `circuit_cairo_verifier::privacy::privacy_cairo_verifier_config`, for the leaf simple /// bootloader under the canonical-small test setup instead of the privacy transaction. fn leaf_cairo_verifier_config() -> CairoVerifierConfig {
the function is similar to privacy_cairo_verifier_config().
would be good to call a shared function with parameters.
(maybe put a TODO for the future)
7cfa0e4 to
715985b
Compare
2e7f0ae to
083dd1a
Compare
99cb898 to
92490b4
Compare
YairVaknin-starkware
left a comment
There was a problem hiding this comment.
@YairVaknin-starkware made 3 comments.
Reviewable status: 8 of 10 files reviewed, 3 unresolved discussions (waiting on Gali-StarkWare and OmriEshhar1).
crates/stwo_run_and_prove_recursive_tree/src/canonical.rs line 58 at r1 (raw file):
Previously, OmriEshhar1 wrote…
you're using here the same names for the public consts as is privacy (with different values).
consider using different names, so that it doesn't get messy in the future.
Done.
crates/stwo_run_and_prove_recursive_tree/src/canonical.rs line 189 at r1 (raw file):
Previously, OmriEshhar1 wrote…
the function is similar to privacy_cairo_verifier_config().
would be good to call a shared function with parameters.
(maybe put a TODO for the future)
Done.
OmriEshhar1
left a comment
There was a problem hiding this comment.
@OmriEshhar1 reviewed 2 files and all commit messages, and resolved 3 discussions.
Reviewable status:complete! all files reviewed, all discussions resolved (waiting on Gali-StarkWare).
083dd1a to
df9e302
Compare
92490b4 to
8daaad0
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 8daaad0. Configure here.
OmriEshhar1
left a comment
There was a problem hiding this comment.
@OmriEshhar1 reviewed 9 files and all commit messages.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on Gali-StarkWare and YairVaknin-starkware).
Switch the canonical circuit from the temporary privacy fixture to the shape `leaf_prover` produces when proving the leaf simple bootloader with the canonical-small setup: the leaf bootloader program's felts (from `test_data`, TEMPORARY until production passes it via configuration), two public outputs (the hashed-output Uint256), `CanonicalSmall` preprocessed trace, and a blowup-1, 96-bit-secure circuit PCS config (`get_pcs_config(23, 1)`; blowup 1 keeps proving memory feasible on a local machine). `TARGET_PADDING_SIZES` is rederived — the leaf circuit dominates every component, so `leaf_prover`'s default next-power-of-two padding already produces the canonical shape. The recursive tree now depends on `leaf_prover` for the shared constants, and loads the leaf's inner-proof Cairo parameters (PCS config + preprocessed-trace variant) from `leaf_prover`'s canonical-small params file — the same file the golden e2e proves leaves with — so the canonical shape cannot drift from it (the leaf's Cairo preprocessed root is selected by the lifting size that config yields). The circuit-shape consts are `CANONICAL_`-prefixed to keep them apart from the privacy flow's same-purpose consts. The old privacy-fixture proof no longer verifies against the new canonical shape; it is replaced by `test_data/leaf_fixture.json`, a pre-generated `leaf_prover` output over the leaf simple bootloader (running a simple-output task), and the fold e2e tests are retargeted to duplicate it (loading a `LeafInput` from the file instead of hardcoded fixture constants — `SerializedLeafProof` and `LeafInput` derive `Clone` for the duplication). Folding through the full `LeafInput` path also makes the multiverifier attest `LeafInput::output_values`'s preimage derivation against a real leaf proof. A true end-to-end that runs `leaf_prover` itself and asserts against committed goldens is added separately. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
8daaad0 to
cde498b
Compare
OmriEshhar1
left a comment
There was a problem hiding this comment.
@OmriEshhar1 reviewed 1 file and all commit messages.
Reviewable status:complete! all files reviewed, all discussions resolved (waiting on Gali-StarkWare).
OmriEshhar1
left a comment
There was a problem hiding this comment.
Reviewable status:
complete! all files reviewed, all discussions resolved (waiting on Gali-StarkWare).
Gali-StarkWare
left a comment
There was a problem hiding this comment.
@Gali-StarkWare reviewed 10 files and all commit messages, and made 9 comments.
Reviewable status: all files reviewed, 9 unresolved discussions (waiting on YairVaknin-starkware).
Cargo.toml line 93 at r4 (raw file):
cairo-program-runner-lib = { path = "crates/cairo-program-runner-lib", version = "1.0.0" } leaf-proof-format = { path = "crates/leaf_proof_format" } leaf-prover = { path = "crates/leaf_prover" }
Don't we need to add here the version as well?
Code quote:
leaf-proof-format = { path = "crates/leaf_proof_format" }
leaf-prover = { path = "crates/leaf_prover" }crates/stwo_run_and_prove_recursive_tree/Cargo.toml line 31 at r4 (raw file):
leaf-proof-format.workspace = true # The real leaf producer: the canonical circuit shape is derived from the same constants # (disabled components, preprocessed-trace variant) `leaf_prover` proves leaves with.
Remove comment
Code quote:
# The real leaf producer: the canonical circuit shape is derived from the same constants
# (disabled components, preprocessed-trace variant) `leaf_prover` proves leaves with.crates/stwo_run_and_prove_recursive_tree/src/canonical.rs line 47 at r4 (raw file):
// // The tree is configured to the shape `leaf_prover` produces when proving the // `leaf_simple_bootloader` with the canonical-small setup: `CanonicalSmall` preprocessed trace for
Are we going to use it in sharp? I thought Canonical small is only for privacy, and we need the entire canonical when proving general cairo programs
Code quote:
`CanonicalSmall` preprocessed tracecrates/stwo_run_and_prove_recursive_tree/src/canonical.rs line 69 at r4 (raw file):
CANONICAL_CIRCUIT_TRACE_LOG_SIZE, CANONICAL_CIRCUIT_LOG_BLOWUP_FACTOR, );
I don't like the canonical prefix, maybe something like MULTIVERIFIER_/2TO1VERIFIER_?
Code quote:
/// Log blowup factor of the outer circuit proof.
pub const CANONICAL_CIRCUIT_LOG_BLOWUP_FACTOR: u32 = 1;
/// Cairo-verifier (leaf) circuit trace log size — the log size the leaf-bootloader verifier
/// circuit reaches (its dominant components, `qm31_ops`/`blake_g_gate`, hit 2^23; see
/// [`TARGET_PADDING_SIZES`]).
pub const CANONICAL_CIRCUIT_TRACE_LOG_SIZE: u32 = 23;
/// PCS config for proving each layer. MUST equal the config the leaf circuit proofs were produced
/// with: this constant is the single source of truth for the tree's circuit PCS shape, and the
/// backend must pass it (via the leaf prover's `circuit_prover_params_json`) when producing
/// leaves.
// TODO(yairv): Consider taking this from the backend via configuration (alongside the leaf
// bootloader program), so the backend passes one config to both `leaf_prover` and the recursive
// tree.
pub const CANONICAL_CIRCUIT_PCS_CONFIG: PcsConfig = get_pcs_config(
CANONICAL_CIRCUIT_TRACE_LOG_SIZE,
CANONICAL_CIRCUIT_LOG_BLOWUP_FACTOR,
);crates/stwo_run_and_prove_recursive_tree/src/canonical.rs line 76 at r4 (raw file):
/// per-component max of the two circuits — currently the leaf-bootloader verifier circuit /// dominates every component, so `leaf_prover`'s default next-power-of-two padding already /// produces exactly this shape.
Suggestion:
/// verifies every layer.
/// TODO(Yair): Update according to the maximum component sizes possible in given circuits to be verified.crates/stwo_run_and_prove_recursive_tree/src/canonical.rs line 168 at r4 (raw file):
/// when proving the leaf simple bootloader (see `leaf_prover::prove_leaf`): `CanonicalSmall` /// preprocessed trace, all components except [`DISABLED_COMPONENTS_SMALL_PREPROCESSED`], the /// bootloader program's felts, and its two public outputs (the hashed-output Uint256 low/high).
And in general, there are a lot of necessary comments in this file. I think most of them can be deleted
Suggestion:
/// The unpadded cairo-verifier (leaf) circuit context.crates/stwo_run_and_prove_recursive_tree/src/canonical.rs line 231 at r4 (raw file):
&leaf_cairo_params.pcs_config, cairo_air::verifier::INTERACTION_POW_BITS, );
I'm almost sure this code exist someplace else
Code quote:
// Build `enabled_bits` (one flag per component in the full list) and `components` (only the
// enabled entries, as expected by `ProofConfig::new`) in a single pass.
let (enabled_bits, components): (Vec<bool>, Vec<_>) = all_components::<NoValue>()
.into_iter()
.map(|(name, component)| {
let enabled = !disabled_components.contains(&name);
(enabled, enabled.then_some((name, component)))
})
.unzip();
let components: IndexMap<&'static str, Box<dyn CircuitEval<NoValue>>> =
components.into_iter().flatten().collect();
let proof_config = ProofConfig::new(
&components,
preprocessed_trace_variant.n_columns(),
&leaf_cairo_params.pcs_config,
cairo_air::verifier::INTERACTION_POW_BITS,
);crates/stwo_run_and_prove_recursive_tree/src/canonical.rs line 244 at r4 (raw file):
// The leaf simple bootloader outputs only the blake2s hash of `[task program hash, // task output...]`, as a Uint256 (low, high). n_outputs: 2,
There's a const
Code quote:
// The leaf simple bootloader outputs only the blake2s hash of `[task program hash,
// task output...]`, as a Uint256 (low, high).
n_outputs: 2,crates/stwo_run_and_prove_recursive_tree/src/tests.rs line 191 at r4 (raw file):
/// (the `cairo_prover_params_canonical_small.json` parameters and /// `CANONICAL_CIRCUIT_PCS_CONFIG`). fn fixture_leaf() -> LeafInput {
How can we FIX it if we need to?
|
|

Switch the canonical circuit from the temporary privacy fixture to the shape
leaf_proverproduces when proving the leaf simple bootloader with the canonical-small setup: the leaf bootloader program's felts (fromtest_data, TEMPORARY until production passes it via configuration), two public outputs (the hashed-output Uint256),CanonicalSmallpreprocessed trace, and a blowup-1, 96-bit-secure circuit PCS config (get_pcs_config(23, 1); blowup 1 keeps proving memory feasible on a local machine).TARGET_PADDING_SIZESis rederived — the leaf circuit dominates every component, soleaf_prover's default next-power-of-two padding already produces the canonical shape. The recursive tree now depends onleaf_proverfor the shared constants.The old privacy-fixture proof no longer verifies against the new canonical shape; it is replaced by
test_data/leaf_fixture.json(a pre-generatedleaf_proveroutput over the leaf simple bootloader running a simple-output task), and the fold e2e tests are retargeted to duplicate it — so the full suite keeps running at this point of the stack. A true end-to-end that runsleaf_proveritself and asserts against committed goldens lands in #388, which replaces the fixture with the golden leaf (same content).Note: the 29MB
leaf_simple_bootloader_compiled.jsonlands here because the canonical circuit embeds the program's felts.Stack (2/4): prove_leaf_from_files (#390) ← this ← PackedNode roots (#392) ← goldens e2e (#388).
🤖 Generated with Claude Code
This change is