Skip to content

Retarget the recursive-tree canonical circuit to the leaf bootloader#391

Open
YairVaknin-starkware wants to merge 1 commit into
yairv/add_prove_leaf_from_filesfrom
yairv/retarget_canonical_to_leaf_bl
Open

Retarget the recursive-tree canonical circuit to the leaf bootloader#391
YairVaknin-starkware wants to merge 1 commit into
yairv/add_prove_leaf_from_filesfrom
yairv/retarget_canonical_to_leaf_bl

Conversation

@YairVaknin-starkware

@YairVaknin-starkware YairVaknin-starkware commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

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.

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 — so the full suite keeps running at this point of the stack. A true end-to-end that runs leaf_prover itself 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.json lands 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 Reviewable

@cursor

cursor Bot commented Jul 15, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Changes core STWO circuit dimensions and leaf verifier topology; mismatches with production leaf proofs would break verification, though the PR intentionally mirrors leaf_prover’s existing prove path.

Overview
Retargets the recursive tree’s canonical multiverifier/leaf circuit from the temporary privacy cairo-verifier fixture to the shape leaf_prover uses for the leaf simple bootloader under the canonical-small setup.

The canonical PCS and padding constants are renamed and updated (blowup 1, trace log size 23, larger TARGET_PADDING_SIZES). Leaf circuit construction now builds a CairoVerifierConfig from the bootloader program (test data for now), leaf_prover disabled-component constants, and Cairo prover params loaded from cairo_prover_params_canonical_small.json—instead of privacy_cairo_verifier_config.

Workspace and stwo_run_and_prove_recursive_tree gain a leaf-prover dependency; SerializedLeafProof and LeafInput add Clone for test duplication.

Slow e2e fold tests swap the privacy proof bin for test_data/leaf_fixture.json, drive the public stwo_run_and_prove_recursive_tree API with real LeafInput values (including output_values from the preimage), and drop hard-coded privacy roots/outputs.

Reviewed by Cursor Bugbot for commit cde498b. Bugbot is set up for automated code reviews on this repo. Configure here.

@codecov

codecov Bot commented Jul 15, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.83333% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 65.47%. Comparing base (df9e302) to head (cde498b).

Files with missing lines Patch % Lines
...stwo_run_and_prove_recursive_tree/src/canonical.rs 95.83% 2 Missing ⚠️
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     
Files with missing lines Coverage Δ
...s/stwo_run_and_prove_recursive_tree/src/leaf_io.rs 100.00% <ø> (ø)
...stwo_run_and_prove_recursive_tree/src/canonical.rs 97.11% <95.83%> (-1.25%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@YairVaknin-starkware
YairVaknin-starkware force-pushed the yairv/retarget_canonical_to_leaf_bl branch from 83b2201 to 7cfa0e4 Compare July 15, 2026 18:46
Comment thread crates/stwo_run_and_prove_recursive_tree/src/canonical.rs Outdated

@OmriEshhar1 OmriEshhar1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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)

Comment thread crates/stwo_run_and_prove_recursive_tree/src/canonical.rs Outdated
@YairVaknin-starkware
YairVaknin-starkware force-pushed the yairv/retarget_canonical_to_leaf_bl branch from 7cfa0e4 to 715985b Compare July 16, 2026 09:20
@YairVaknin-starkware
YairVaknin-starkware force-pushed the yairv/add_prove_leaf_from_files branch 2 times, most recently from 2e7f0ae to 083dd1a Compare July 16, 2026 09:25
@YairVaknin-starkware
YairVaknin-starkware force-pushed the yairv/retarget_canonical_to_leaf_bl branch 2 times, most recently from 99cb898 to 92490b4 Compare July 16, 2026 10:04

@YairVaknin-starkware YairVaknin-starkware left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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.

Comment thread crates/stwo_run_and_prove_recursive_tree/src/canonical.rs Outdated

@OmriEshhar1 OmriEshhar1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@OmriEshhar1 reviewed 2 files and all commit messages, and resolved 3 discussions.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved (waiting on Gali-StarkWare).

@YairVaknin-starkware
YairVaknin-starkware force-pushed the yairv/add_prove_leaf_from_files branch from 083dd1a to df9e302 Compare July 16, 2026 21:20
@YairVaknin-starkware
YairVaknin-starkware force-pushed the yairv/retarget_canonical_to_leaf_bl branch from 92490b4 to 8daaad0 Compare July 16, 2026 21:20

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ 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.

Comment thread crates/stwo_run_and_prove_recursive_tree/src/canonical.rs

@OmriEshhar1 OmriEshhar1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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>
@YairVaknin-starkware
YairVaknin-starkware force-pushed the yairv/retarget_canonical_to_leaf_bl branch from 8daaad0 to cde498b Compare July 20, 2026 08:50

@OmriEshhar1 OmriEshhar1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@OmriEshhar1 reviewed 1 file and all commit messages.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved (waiting on Gali-StarkWare).

@OmriEshhar1 OmriEshhar1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: :shipit: complete! all files reviewed, all discussions resolved (waiting on Gali-StarkWare).

@Gali-StarkWare Gali-StarkWare left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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 trace

crates/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?

@ilyalesokhin-starkware

Copy link
Copy Markdown
Contributor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants