Skip to content

Merge main-v0.14.3 into main#14522

Open
Yoni-Starkware wants to merge 53 commits into
mainfrom
yonatan/merge-main-v0.14.3-into-main-1781629189
Open

Merge main-v0.14.3 into main#14522
Yoni-Starkware wants to merge 53 commits into
mainfrom
yonatan/merge-main-v0.14.3-into-main-1781629189

Conversation

@Yoni-Starkware

Copy link
Copy Markdown
Collaborator

No description provided.

avi-starkware and others added 30 commits April 30, 2026 13:32
…proving-utils to 18f6cac

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…-utils 18f6cac

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…RC.7-fix-1.1

starknet_proof_verifier: bump proving-utils to 18f6cac and regenerate proof fixture
* deployment: wait for node healthcheck before starting the simulator

* apollo_dashboard: make SNIP-35 fee target USD panel a stat
Signed-off-by: Dori Medini <dori@starkware.co>
…rifier bump

The privacy-circuit-verify-v0 dependency was bumped (580135e -> 18f6cac),
which made the new V0 verifier reject the previously committed 0.14.2
regression proof, failing regression_verify_proof_from_old_prover::case_1.

Replace it with the V0 proof produced by the old prover (privacy-prove
@ 18f6cac) as committed on main-v0.14.2. The proof facts are unchanged.

https://claude.ai/code/session_01JNrvNrRFsfMGVh6zKu5eDt
…14317) (#14319)

- Exclude glob 'scripts/prod/**/*' missed top-level files under fnmatch; use 'scripts/prod/**' so prod-script-only PRs skip this infra-heavy test.
- Quote the trigger interpolations so a glob value isn't shell-expanded before reaching check_test_trigger.py.
- Pin k3d-version=v5.5.0 (action input): the default v5.4.6 predates the checksums.txt release asset the current k3d install.sh fetches with --fail, causing a 404.
- Wait on the local-path-provisioner Deployment rollout instead of a racy pod-label wait that errored 'no matching resources found'.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…-into-main-v0.14.3-1780483904

Merge main-v0.14.2 into main-v0.14.3
Signed-off-by: Dori Medini <dori@starkware.co>
…act in get_class_hash_at syscall (#14394)

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…act in state diff (#14407)

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
#14409)

Follow-up to #14254 (which moved both to v0.14.3-rc-1). v0.14.3 is the
proving-utils tag of commit abdc99c (same commit as v0.14.3-rc-2). Upstream
changes since v0.14.3-rc-1:
- PrivacyProofOutput gained a version field recording which privacy-prove
  version generated the proof (proving-utils#349): populate it at the two
  sequencer construction sites; the verifier ignores it.
- stwo-circuits bumped 618db0a -> 24f39918 (proving-utils#361), changing the
  circuit preprocessed root and therefore the on-chain proof bytes.

Since the proof bytes change, regenerate the serialized proof fixtures:
- proof_flow/proof.bin (apollo_integration_tests) via
  `cargo +nightly-2025-07-14 test -p starknet_os_flow_tests --features
  starknet_transaction_prover/stwo_proving --release generate_proof_fixtures
  -- --ignored`
- example_proof.bin (apollo_transaction_converter) via
  `cargo +nightly-2025-07-14 test -p starknet_transaction_prover --features
  stwo_proving --release -- --ignored regenerate_proof_fixtures`
- regression_test/0.14.3/example_proof.bin (starknet_proof_verifier) is a
  copy of the apollo_transaction_converter fixture.
The proof facts JSONs are unchanged: the circuit bump changes proof bytes but
not the program output.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…14413)

cargo-chef bakes the repo's .cargo/config.toml (which sets rustc-wrapper =
sccache) into recipe.json during prepare and restores it during cook. sccache
is not installed in the replay image, so the cook step failed with 'could not
execute process sccache ... rustc'. Set CARGO_BUILD_RUSTC_WRAPPER= to override
the config and skip the wrapper.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…deserializer to starknet_api (#14408)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… call (#14406)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
….2-into-main-v0.14.3-1780922981

Merge main-v0.14.2 into main-v0.14.3
einat-starkware and others added 21 commits June 10, 2026 12:34
…response (#14410)

The external check's allow response may carry an opaque additional_data
object for screened transactions. BlockingCheckResult::Allowed carries it
verbatim as a serde_json object; the prover never interprets its contents.
additional_data must be a JSON object — a non-object value fails parsing
and maps to Inconclusive (deferring to the fail-open policy).
…ore DA mode) (#14428)

get_deploy_account_transaction_v3_hash chained data_availability_mode
before nonce, diverging from invoke_v3, declare_v3, the Cairo OS
hash_tx_common_fields, and SNIP-8, which all chain
chain_id -> nonce -> data_availability_mode.

The existing fixtures have nonce=0 and DA=L1=0, so the Poseidon hash was
order-invariant and the bug was masked. Any deploy_account V3 with a
non-L1 nonce DA mode would hash differently in the Rust sequencer than
in the Cairo prover/consensus.

Swap the two chained fields so nonce is chained before
data_availability_mode.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…d regen OS hash (#14455)

Bump cairo-lang Python package 0.14.3a2 -> 0.14.3a3 (requirements, prover Dockerfile, EXPECTED_CAIRO0_VERSION). The new compiler changes the OS program hash; regenerate program_hash.json, bytecode lengths, and the versioned-constants diff regression. Reduce allowed_virtual_os_program_hashes in the 0.14.3 versioned constants to only the new virtual-OS hash (LEN=1 in constants.cairo and execution_constraints.cairo). Regenerate the proof-flow fixtures (proof.bin, proof_facts.json) via the prover for the new virtual-OS hash.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…14452)

For current_block_number < STORED_BLOCK_HASH_BUFFER the felt subtraction
current - buffer underflowed, so the hint reported "not in buffer" and the Cairo
program then hit assert_nn_le(request, current - buffer), which also underflowed
and aborted the OS while blockifier reverted the syscall gracefully. This
committed-but-unprovable block caused a reorg on the first 10 blocks of a fresh
chain. Guard the subtraction so early blocks are treated as in-buffer, matching
blockifier's block_number_in_range.

https://claude.ai/code/session_01VojMWzQzxTF7APVG7hzqnZ
…int OS flow test (#14454)

Add an OS flow test exercising the secp256r1 affine point with x == 0 (which exists on secp256r1 but
not secp256k1) through three txs in one flow: add(x==0, generator), mul(x==0, 3), and a mul whose
scalar-mul precompute table reaches that point as an intermediate (2 * P/2). Each tx checks the EC
result in the contract, exercising the OS handling of the x == 0 point end-to-end.

Adds test_add_secp256r1_checked and test_mul_point_secp256r1_checked entry points to the cairo1 test
feature contract. Growing TestContract shifts two size-dependent expectations, updated here: the
bouncer migration-gas expects and the V2 compiled-class-hash estimation margin (350 -> 400; the
estimate's per-entry-point/segment overhead slightly under-counts, proportional to size).

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The V2 (Blake) compiled_class_hash step estimator systematically under-estimated, with a deficit
that grows with the number of entry points. The per-entry-point `hash_entry_points_inner` step
count is now a required per-implementation const (BASE_HASH_ENTRY_POINTS_INNER_STEPS): V1 keeps 27,
V2 uses 31 (the extra 4 is the Blake per-entry-point overhead the structure-driven estimate
undercounts). V1/Poseidon is byte-for-byte unchanged. The remaining residual is a small
content-dependent constant absorbed by the test margin; worst-case V2 |margin| over the sample
feature contracts drops from 350 to 88, so ALLOWED_MARGIN_BLAKE_N_STEPS is tightened from 350 to 100.

The bouncer class-hash migration gas derives from the V2 estimate, so its expects are updated.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ErrorStack::Display trims over-long traces by keeping a head slice
([..TRACE_LENGTH_CAP/2]) and a tail slice ([len - TRACE_LENGTH_CAP/2..]),
using raw byte indices. Rust str slicing panics if an index isn't a char
boundary, so any multi-byte UTF-8 character straddling either cut point
panics the formatter. Trace content includes contract/VM-controlled
strings (revert reasons, VM error attributes), so this is reachable from
external input.

Snap both cut points to char boundaries via floor_char_boundary /
ceil_char_boundary helpers (the std equivalents are still unstable),
mirroring the char-safe truncation already used by Cairo1RevertSummary.

Add a regression test (head and tail cut-point cases) that places a 2-byte
'é' straddling each cut point; it panics on the old byte-slice code and
passes on the fix.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Starting from the valid pinned proof fixture, each test applies one
mutation and asserts verification fails: empty proof, too-short facts,
unsupported and V0 version markers, tampered facts, a corrupted
compressed byte, and corrupting/truncating the decompressed proof (so
the noise reaches the circuit verifier rather than failing as a mere
decompression error). Shared fixture loading is factored into a helper.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* workspace,blockifier,starknet_os_flow_tests: upgrade cairo compiler to v2.19.0-rc.3

Bump cairo-lang workspace dependencies and the cairo_compiler_version.txt
pin from 2.19.0-rc.2 to 2.19.0-rc.3.

Apply the snapshot value changes caused by rc.3 codegen:
- blockifier secp test_secp256k1_point_from_x gas: 183190 -> 181710
- blockifier bouncer migration_sierra_gas: 107086865 -> 106858386
- blockifier bouncer migration_proving_gas: 231505645 -> 230976513
- starknet_os_flow_tests experimental_libfuncs poseidon usage: 66->67, 57->58
- starknet_os_flow_tests fuzz orchestrator address
- central_systest_blobs cende operator + fee-token addresses, plus the
  regenerated chain_info.json + preconfirmed_block.json and the regression
  blob re-uploaded to GCS (generation 30 -> 39)

The fuzz cairo0/cairo1 addresses and the proof-flow fee-token and
genesis-root constants were verified unchanged under rc.3.

rc.3 raises its MSRV to rustc 1.94. To keep the prover's stwo stack building,
bump proving-utils (privacy-prove, privacy-circuit-verify-v1) to tag
v0.14.3-rust-bump, which pulls the fixed stwo at git rev 489a0f3e, and bump
crates/starknet_transaction_prover/rust-toolchain.toml to nightly-2026-01-15
(rustc 1.94.0-nightly). The fixed stwo was verified to compile on this
toolchain.
Adapt starknet_proof_verifier and the prover test to the new privacy-circuit-verify API: the
PrivacyProofOutput `version` field was removed (the prover now embeds the
version as a prefix in the proof bytes), so drop it at the construction site.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* starknet_proof_verifier: restore deleted proof regression test

The cairo rc.3 bump commit silently dropped the
`regression_verify_proof_from_old_prover` test and its 0.14.3 proof
fixtures. Restore both.

The `v0.14.3-rust-bump` proving-utils tag changed the proof format
("Unknown frame descriptor" on the old fixture), so regenerate the
0.14.3 fixture from the PR's freshly-generated example proof, per the
test's documented procedure. `cargo test -p starknet_proof_verifier`
passes (roundtrip + regression).

* starknet_proof_verifier: fix negative proof tests for version-prefixed wire format

The rc.3 proving-utils (`v0.14.3-rust-bump`) changed the on-the-wire proof
format to a `VERSION_BYTES`-long version prefix followed by the
zstd-compressed payload (the verifier strips it via `split_proof_version`).
The uncompressed-domain negative tests added in #14462 zstd-decompressed
the whole blob, which now fails with "Unknown frame descriptor" on the
version prefix.

Split off the version prefix before decompressing and re-prepend it after
recompressing, mirroring the verifier's own framing via the public
`VERSION_BYTES`. All 10 starknet_proof_verifier tests pass.

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nsaction response (#14411)

ProveTransactionResult gains an optional additional_data field carrying
the opaque object the blocking check relayed; it is passed through verbatim
(omitted from the JSON response when absent) and the prover never interprets
its contents. A transaction allowed via the fail-open policy carries none.
…as inconclusive (#14492)

The blocking check never inspected the HTTP status. Since `error` is
`#[serde(default)]`, any response body lacking an `error` field (e.g. a 5xx
`{"jsonrpc":"2.0","id":1}` from a broken upstream) deserialized to
`Allowed` and proceeded straight to proving, bypassing the operator's
fail-close policy.

Check `response.status().is_success()` before parsing the body; on a
non-success status return `Inconclusive` so the configured fail-open /
fail-close policy applies.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rithmetic (#14433)

Batch of low-risk hardening fixes found by the nightly bug-hunt routine
(confirmed bugs 4, 6, 7, 10). All align with the "never panic on data
reachable from external input / prefer defensive arithmetic" guideline.

- starknet_os os_output: parse_messages_to_l1 and the messages-to-L2 loop
  used assert_eq! to verify the declared segment was fully consumed, and a
  raw `-=` that could underflow on a malformed output vector. Both now
  return a new OsOutputError::MessagesSegmentNotConsumed via checked_sub
  instead of panicking.
- blockifier GasCosts::from_raw: default_initial_gas_cost,
  entry_point_initial_budget and syscall_base_gas_cost used bare `*`, while
  the sibling OsConstants::from_raw computes the same values with
  checked_factor_mul(...).expect(...). Use the checked form so the two
  copies of these constants can't silently diverge (one wrapping, one
  aborting) in release.
- blockifier round_up_to_mb: `div_ceil(MB) * MB` wraps to 0 for sizes near
  u64::MAX; saturate to the largest multiple of MB that fits.
- starknet_os _get_tx_info_ptr: read `version` from a DeprecatedTxInfo
  pointer using CairoStruct::DeprecatedTxInfo instead of CairoStruct::TxInfo
  (behavior-preserving today since version is field 0 in both, but the
  pointer is a DeprecatedTxInfo* and the other accesses already use it).

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ng queued proposals (#14493)

The round comparison in set_height_and_round was inverted: future-round
proposals were deleted and a stale past-round entry caused an early return,
permanently poisoning queued_proposals and halting consensus liveness for the
height (H-20). Correct the arms so past rounds are dropped, the current round is
processed, and future rounds are preserved. Add a regression test covering a
round skip.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…calldata (#14495)

payload_size computed self.tx.calldata.0.len() - 1 unconditionally. Calldata
has no non-empty invariant and L1HandlerTransaction derives Deserialize, so an
empty calldata is constructible; len() - 1 then panics in debug or wraps to
usize::MAX in release (corrupting downstream fee/message-segment accounting).

Use saturating_sub(1) so an empty calldata yields a payload size of 0. Add a
regression test that constructs an executable L1HandlerTransaction with empty
calldata and asserts payload_size() == 0 (it panics on the old code).

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…der client (#14501)

The cende recorder client had no per-request timeout, so RetryTransientMiddleware
(which only retries attempts that return a transient error) could not recover from
a slow/hung recorder: a single stalled request blocked until the proposer's build
deadline, surfacing as CendeWriteError("...didn't return in time") with zero retries
attempted. Bound each attempt by max_retry_interval_ms so a hang becomes a timeout
error the retry policy can act on, with room for multiple attempts within
max_retry_duration_secs.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…Blake from V0_14_3 (#14499)

Switch the OS config hash from Pedersen to Blake for quantum safety, version-gated at
  V0_14_3: blocks below it keep Pedersen + 'StarknetOsConfig3', V0_14_3 onward use
  Blake + 'StarknetOsConfig4'. Gating keeps pre-cutover blocks re-executable/re-provable
  against their original hash. Cairo switches straight to Blake (per-binary versioning);
  the Rust mirror selects the hash at runtime by StarknetVersion. public_keys_hash stays
  Pedersen.

  Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…14318)

Goal: reduce false-positive pages on the L1 message scraper alert.

Since each sequencer moved to a single L1 provider, the
`l1_message_no_successes` alert (no successful scrapes within the
window) fires spuriously: a brief gap from the sole provider trips it
even though scraping recovers shortly after. Widening the evaluation
window from 5m to 15m tolerates these short gaps.

Change: bump the `increase(l1_message_scraper_success_count[...])`
range from 5m to 15m in the alert definition, and regenerate the
matching expression in dev_grafana_alerts.json.

Follow-up (not in this PR): revert to 5m once a fallback mechanism
that switches back to a specific provider per sequencer is in place.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Yoni-Starkware

Copy link
Copy Markdown
Collaborator Author

Src Dst Cargo.lock
Src Dst Cargo.toml
Src Dst crates/apollo_integration_tests/resources/proof_flow/proof.bin
Src Dst crates/apollo_integration_tests/resources/proof_flow/proof_facts.json
Src Dst crates/apollo_integration_tests/src/state_reader.rs
Src Dst crates/apollo_starknet_os_program/src/cairo/starkware/starknet/core/os/constants.cairo
Src Dst crates/apollo_starknet_os_program/src/cairo/starkware/starknet/core/os/execution/execution_constraints.cairo
Src Dst crates/apollo_starknet_os_program/src/program_hash.json
Src Dst crates/apollo_starknet_os_program/src/virtual_os_test.rs
Src Dst crates/blockifier/src/bouncer_test.rs
Src Dst crates/blockifier_test_utils/src/fee_token_addresses.rs
Src Dst crates/central_systest_blobs/resources/blob_file_generation
Src Dst crates/central_systest_blobs/resources/preconfirmed_block.json
Src Dst crates/starknet_os_flow_tests/src/fuzz_tests.rs
Src Dst crates/starknet_os_flow_tests/src/tests.rs

@cursor

cursor Bot commented Jun 16, 2026

Copy link
Copy Markdown

PR Summary

High Risk
Changes OS/virtual program hashes and proof acceptance rules (network-wide compatibility), plus a consensus queue bugfix and large proving/execution dependency updates.

Overview
This merge brings v0.14.3 / v0.14.4 protocol work into main: refreshed Starknet OS and virtual OS program hashes, client-side proving tightened to PROOF1 only (legacy PROOF0 removed in OS Cairo), and OS config hashing moved to Blake (StarknetOsConfig4) with updated allowed virtual program hashes. Blockifier gains allowed_proof_versions in versioned constants and enforces them at transaction pre-validation alongside the existing program-hash allowlist.

Cairo / proving stack bumps to 2.19.0-rc.3, privacy-prove / privacy-circuit-verify to v0.14.3-rust-bump, and refreshed stwo / stwo-cairo / stwo-circuits git pins; fixtures and integration expectations (proof facts, genesis root, central JSON) are updated to match.

Consensus orchestrator fixes an inverted round comparison when draining queued proposals after a skipped round (liveness regression), adds a per-attempt HTTP timeout on the Cende recorder client so hung requests can retry, and adds coverage for parent proposal commitment binding the parent fee. Gateway raises max Sierra to 1.9 and gates SHA-512 libfuncs to 1.9.0.

CI / deploy: sequencer CDK8s workflow runs port-uniqueness pytest and synthesizes mainnet / sepolia hybrid overlays; committer inner cache size is templated in deployment configs. Smaller fixes include blockifier_reexecution in-process Sierra compilation (shared tx deser moved to starknet_api), UTF-8-safe long revert trace trimming, and dashboard/alert tweaks (L1 message window, fee-target stat panel).

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

@reviewable-StarkWare

Copy link
Copy Markdown

This change is Reviewable

@github-actions

github-actions Bot commented Jun 16, 2026

Copy link
Copy Markdown

@Yoni-Starkware Yoni-Starkware left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

@Yoni-Starkware reviewed 130 files and all commit messages.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved (waiting on Yoni-Starkware).

@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 651f1cc. Configure here.

@Yoni-Starkware Yoni-Starkware force-pushed the yonatan/merge-main-v0.14.3-into-main-1781629189 branch from 651f1cc to 4c11498 Compare June 16, 2026 22:02
Resolve main-v0.14.3 → main merge conflicts:
- Cargo.toml/lock: keep main's 0.0.0 placeholder versions
- OS: allowed_virtual_os_program_hashes = [0x53f6c9fc (v0.14.3), 0x2cc4a0b7 (merged)];
  regenerate program_hash.json, constants.cairo, execution_constraints.cairo (LEN=2);
  add allowed_proof_versions to 0_14_4 versioned constants
- Bytecode lengths, bouncer migration gas, poseidon/blake counts, genesis root,
  fee-token address, fuzz addresses, cende preconfirmed_block: regenerate
- proof.bin/proof_facts.json: keep v0.14.3's (hash 0x53f6c9fc is in the allowed list)
- Refresh stale committed artifacts: drop 2.16.0 test_contract leftovers,
  take v0.14.3's account_with_dummy_validate casm

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Yoni-Starkware Yoni-Starkware force-pushed the yonatan/merge-main-v0.14.3-into-main-1781629189 branch from 4c11498 to f07c40d Compare June 17, 2026 04:37
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.