Repository navigation
chore: port-to-v6 rolling port - #25575
Merged
Merged
Conversation
AztecBot
force-pushed
the
cb/port-to-v6
branch
from
October 2, 2026 14:30
34e0b24 to
437850e
Compare
IlyasRidhuan
marked this pull request as ready for review
October 4, 2026 10:34
IlyasRidhuan
requested review from
IlyasRidhuan,
LeilaWang,
charlielye,
iAmMichaelConnor,
iakovenkos,
just-mitch,
koenmtb1,
ledwards2225 and
ludamad
as code owners
October 4, 2026 10:34
IlyasRidhuan
approved these changes
Oct 4, 2026
iAmMichaelConnor
approved these changes
Oct 4, 2026
Refs AztecProtocol/aztec-claude#857 ## Problem `meter_gas_used` (`private-kernel-lib/src/components/gas_meter.nr`) charges `FIXED_AVM_STARTUP_L2_GAS` (20_000, "base cost for a single public call") once per entry of `end.public_call_requests`. The teardown call is stored in its own field, `public_teardown_call_request`, so it is never counted there. For teardown the meter adds only `teardown_gas_limits`, and the AVM later refunds that against the teardown's actual usage (`total_gas = gas_used + (gas_used_by_teardown - teardown_gas_limit)`). The AVM dispatches the teardown call through the same enqueued-call path as setup and app-logic calls, and it charges no startup gas of its own. As a result, every public tx with a teardown call is metered 20_000 L2 gas below the per-call pricing model. `TailToPublicOutputValidator::validate_gas_used` pins `gas_used` to the meter's output. ## Change - `gas_meter.nr`: when a teardown call request is present, add `Gas::new(0, FIXED_AVM_STARTUP_L2_GAS)` alongside `teardown_gas_limits`. This reuses the existing `!is_for_public | is_empty()` branch rather than adding a second teardown predicate. Private-only txs and public txs without a teardown call are metered exactly as before. - `labs-patches/0001-...patch`: the PXE mirror in `generateSimulatedProvingResult` (`yarn-project/pxe/src/contract_function_simulator/contract_function_simulator.ts`) adds the same startup gas in its existing `if (publicTeardownCallRequest)` branch. The TS `meterGasUsed` only sees the accumulated-data halves, not the teardown request, so the teardown branch is the one place where both meters can charge it the same way. Gas estimation runs on kernelless simulation, so without this patch a tx with a teardown call would be estimated 20_000 L2 gas below the `gas_used` the kernel proves. ## Tests (red then green) In `validate_gas_used_tests.nr` (`tests/tail_to_public_validators/tail_to_public_output_validator/`): - `with_teardown_call_request` now expects `teardown_gas_limits + Gas::new(0, FIXED_AVM_STARTUP_L2_GAS)` on top of the minimum public tx. - `full_side_effects` now expects `(MAX_ENQUEUED_CALLS_PER_TX + 1) * FIXED_AVM_STARTUP_L2_GAS`; the `+1` is its teardown call. Both tests drive the real terminal path (`validate_previous_kernel_for_tail`, then `tail_to_public_finalize`, which runs `TailToPublicOutputValidator::validate`). Run on `next` @ `411a411842e` with `nargo 1.0.0-rc.3+5a7ee9bf` (the `noir/noir-repo` pin): ``` cd noir-projects/fnd/noir-protocol-circuits/crates/private-kernel-lib # tests updated, gas_meter.nr as on next: nargo test --silence-warnings validate_gas_used_tests # 23 passed, 2 failed (with_teardown_call_request, full_side_effects) # with the fix: nargo test --silence-warnings # 1043 passed nargo fmt --check # clean ``` The labs side has no unit-level test. Its red→green coverage is the e2e `single-node/fees/gas_estimation.parallel.test.ts` › "estimates gas with public payment method" (a tx with an FPC teardown call), which asserts the estimated fee equals the fee of the sent tx. It was not run locally; CI covers it. The patch applies with `git am --3way` onto the pinned `labs` commit `54e3383c4b`. ## Notes for review - This is a repricing: `gas_used.within(gas_limits)` means a public-with-teardown tx whose limits sit within 20_000 L2 gas of its usage becomes unprovable until it is re-estimated. - A teardown request that is present but has a zero callee (AztecProtocol/aztec-claude#533) now also pays the startup gas, which only increases what such a tx is charged. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- *Created by [claudebox](https://claudebox.work/v2/sessions/49b51266962c69a3/jobs/3) · group: `slackbot` · requested by Mike (@iAmMichaelConnor) · [Slack thread](https://aztecfoundation.slack.com/archives/D0B2N7W1WJD/p1790276959367319?thread_ts=1790276959.367319&cid=D0B2N7W1WJD)* (cherry picked from commit 21b2e32)
Drop labs-patches/0001: the labs pin on v6 (a0d73c0aed) already carries the PXE mirror upstream as aztec-labs-eng/aztec-node#364, so the patch has nothing to apply to and the series stays empty.
Charging the teardown call's AVM startup gas changes the private kernel circuits, so the VK tree root v6 builds moves to 0x21f06c3b82320ea5f80646751cdd9fa023dfd61400a42b8c952aa32e8f155793. Labs patch 0001 re-pins testnet_compatibility.test.ts to it; the protocol contracts hash and genesis root are unchanged.
…(labs patch) (#25576) This adds labs patch `0010`. With it, `DataTxValidator` rejects a contract class log whose `length` is anything other than its trimmed length (`1 + lastNonZeroIndex`). Before, it only rejected lengths below that. The tx base requires exactly the trimmed length. So a node that accepts `length > trimmed` can admit and include a tx that nobody can prove, and its epoch can't be proven either. Honest producers already emit the trimmed length, so valid txs are unaffected. The patch changes the comparison and its log message. In the existing `rejects txs with mismatched contract class logs length` test, the `length += 1` case that was asserted valid is now asserted invalid. Fixes AztecProtocol/aztec-claude#2485 Tested locally: the full series applies with `git am` on the labs gitlink `54e3383c4b`, and prettier passes on the changed files. The jest tests haven't run; CI will be their first run. --- *Created by [claudebox](https://claudebox.work/v2/sessions/0dda1b136c5cf7a7/jobs/9) · group: `slackbot` · requested by Mike (@iAmMichaelConnor) · [Slack thread](https://aztecfoundation.slack.com/archives/D0B2N7W1WJD/p1790933755978059?thread_ts=1790933755.978059&cid=D0B2N7W1WJD)* (cherry picked from commit a773535)
…5577) ## Problem `l1-contracts/generated/HonkVerifier.sol` is copied from `noir-projects/fnd/noir-protocol-circuits/target/keys/rollup_root_verifier.sol`, which is produced by compiling the protocol circuits with `nargo`. The `l1-contracts-verifier-$hash` and `l1-contracts-ts-$hash` artifacts therefore depend on the `noir/noir-repo` commit. The l1-contracts cache hash only listed `../noir/.rebuild_patterns`, which matches `^noir/bootstrap.sh` and not the submodule gitlink. So a Noir-only bump left the hash unchanged and reused the cached verifier and TypeScript artifacts from before the bump. ## Fix `l1-contracts/bootstrap.sh` now builds its hash the same way the other Noir consumers do (`avm-transpiler/bootstrap.sh`, and `NOIR_HASH` in `noir-projects/fnd/noir-protocol-circuits/bootstrap.sh`): ```bash export hash=$(hash_str $(../noir/bootstrap.sh hash) $(cache_content_hash \ .rebuild_patterns \ ../noir-projects/fnd/noir-protocol-circuits \ ../barretenberg/cpp/.rebuild_patterns )) ``` `noir/bootstrap.sh hash` is `hash_str <noir-repo commit> <noir rebuild patterns>`, so it already covers `noir/bootstrap.sh`. The explicit `../noir/.rebuild_patterns` entry is therefore removed. `hash_str` passes a `disabled-cache` content hash through unchanged, so dirty-tree behaviour is the same. ## Trade-off l1-contracts uses one hash for `build_src`, the verifier, the TS artifacts and its tests. A Noir bump now invalidates all of them, including `l1-contracts-src`, which does not depend on the circuits. The same hash already rotates on any change under `noir-protocol-circuits`, and Noir bumps are infrequent, so the single hash is kept. ## Tests There is no unit-test harness for bootstrap hashes, so this is a reproducible check across 7d61007 ("chore: update Noir to v1.0.0-rc.3"), which changes the `noir/noir-repo` gitlink plus two files that are not l1-contracts inputs. Run from `l1-contracts`: ```bash NO_CD=1 source ../ci3/source for c in 7d61007^ 7d61007; do export AZTEC_CACHE_COMMIT=$(git rev-parse $c) old=$(cache_content_hash .rebuild_patterns ../noir/.rebuild_patterns ../noir-projects/fnd/noir-protocol-circuits ../barretenberg/cpp/.rebuild_patterns) noir=$(hash_str $(git rev-parse $c:noir/noir-repo) $(cd ../noir && cache_content_hash .rebuild_patterns)) new=$(hash_str $noir $(cache_content_hash .rebuild_patterns ../noir-projects/fnd/noir-protocol-circuits ../barretenberg/cpp/.rebuild_patterns)) echo "$c noir-repo=$(git rev-parse --short $c:noir/noir-repo) old=$old new=$new" done ``` Output on this branch's base: ``` 7d61007^ noir-repo=0ecc97a242e old=d81cb180157f7564 new=011632566d883a46 7d61007 noir-repo=5a7ee9bf5ed old=d81cb180157f7564 new=0f66c61198db6e31 ``` The old formula gives the same hash on both sides of the bump; the new one does not. The same change was also run as a real build: with a different Noir commit checked out in the submodule, `./bootstrap.sh build_verifier` under the old hash restored the previously cached `generated/HonkVerifier.sol`, and under the new hash it missed the cache, copied the current circuits-side verifier and compiled it with forge. With the Noir commit unchanged the new hash is stable and hits the cache. ## Out of scope `noir/bootstrap.sh` reads the Noir commit with `git -C noir-repo rev-parse HEAD`. With the submodule uninitialised that resolves to the superproject HEAD, which is unique per commit and so only causes cache misses. Every Noir consumer shares this behaviour and it is left unchanged. Closes AztecProtocol/aztec-claude#1955 --- *Created by [claudebox](https://claudebox.work/v2/sessions/f45fcb875796a470/jobs/11) · group: `slackbot` · requested by Mike (@iAmMichaelConnor) · [Slack thread](https://aztecfoundation.slack.com/archives/D0B2N7W1WJD/p1790886022336469?thread_ts=1790886022.336469&cid=D0B2N7W1WJD)* (cherry picked from commit f7ee597)
…e L1 verifier (#25578) ## Problem `generate_vk` in `noir-projects/fnd/noir-protocol-circuits/bootstrap.sh` cached each circuit's VK under `BB_HASH`, the bytecode hash, the circuit name and a hand-bumped `-3`. Two inputs were missing: - **The scheme and circuit kind.** These are chosen by `circuit_kind` from `chonk_circuits.json` and `rollup_honk_circuits.json`, and mapped to `bb write_vk` flags by the script. A change to a manifest or to the flag mapping left the key unchanged, so the shared cache served the VK for the previous scheme. - **The Solidity verifier flags.** For `rollup_root`, the same cache entry also carried `rollup_root_verifier.sol`. A change to the `bb write_solidity_verifier` flags left the key unchanged, so the cache restored the previous verifier. `l1-contracts` then copied that file into `generated/HonkVerifier.sol` and compiled it. Nothing on `next` compares the compiled `HonkVerifier` with its source, so a stale L1 verifier would go unnoticed. ## Fix - **VK cache key.** The key is now `BB_HASH`, bytecode hash, name, the circuit's kind, and the content hash of `bootstrap.sh`. The kind captures what the manifests decide for that circuit. The script hash captures the kind-to-flags mapping. That hash is computed once as `script_hash` and shared with the `compile` key, which already used it; the `compile` key's value is unchanged. The manual `-3` epoch is gone. - **Solidity verifier.** It is no longer stored in the cache. `generate_vk` writes it on every build from the current VK and the current flags, so it cannot be stale. - **Freshness check.** `l1-contracts` `test_cmds` gains one test on every branch: `cmp generated/HonkVerifier.sol` against `target/keys/rollup_root_verifier.sol`. Its test-cache key includes the digest of the source verifier, so it reruns whenever that verifier changes even if the l1-contracts hash does not. ## Suggestions from the issue not taken - **Make `check_pinned_vk` bypass the cache.** With the complete key, a cache hit is a VK computed from the same bb, bytecode, kind and script. Bypassing the cache would regenerate every VK on every pinned build, which removes the benefit of the pin. - **Output-addressed `l1-contracts-verifier` key.** It does not help this path (a stale file has the same digest), and it needs `l1-contracts` hashing to be restructured. The freshness check covers the l1-side cache instead. ## Effects to expect - Every VK cache entry is regenerated once, because the key formula changed. - Any later edit to this `bootstrap.sh` regenerates all VKs. The `compile` key already recompiles all circuits in that case. - `bb write_solidity_verifier` runs once per build for `rollup_root` and `mock_rollup_root`, including on cache hits. It takes under a second. ## Tests On this branch: `bash -n` on both bootstrap scripts, and `scripts/circuit_kind.test.sh` passes (18 of 18). The full build is covered by CI. The same diff was exercised as a real build before this PR was opened, on a checkout where the touched hunks are identical, against the shared build cache with uploads disabled: 1. **Warm and cold paths agree.** `./bootstrap.sh compile rollup-root` (VK from the cache) and `NO_CACHE=1 ./bootstrap.sh generate_vk rollup_root` (VK regenerated) produced identical VK bytes and the same `rollup_root_verifier.sol` (sha256 `a7bf113d…`, 327,282 B). 2. **Verifier-flag change.** With a commit that only drops `--optimized`, the old code hit the VK cache and restored the optimized verifier (`a7bf113d…`). With this change the build wrote `c7f26a79…` (96,610 B), which equals a direct `bb write_solidity_verifier` without `--optimized` on the same VK. 3. **Manifest-only change.** With a commit that only adds `inbox_parity` to `rollup_honk_circuits.json`, the old code kept the same VK cache key and served the VK for the old kind. With this change the key moved and the VK was regenerated with different bytes. 4. **l1 freshness test.** With `generated/HonkVerifier.sol` restored from the l1 cache, the `cmp` test exited 1 (`differ: byte 1, line 1`) when the circuits-side verifier was different and 0 when it matched. Its test-cache key differed between the two cases. Not run: the pinned-build path (`pinned-build.tar.gz` is absent on `next`). ## Related #25577 fixes the separate Noir-commit omission in the `l1-contracts` hash (AztecProtocol/aztec-claude#1955). The two PRs touch different parts of `l1-contracts/bootstrap.sh` and do not depend on each other. Closes AztecProtocol/aztec-claude#2122 --- *Created by [claudebox](https://claudebox.work/v2/sessions/f45fcb875796a470/jobs/11) · group: `slackbot` · requested by Mike (@iAmMichaelConnor) · [Slack thread](https://aztecfoundation.slack.com/archives/D0B2N7W1WJD/p1790886022336469?thread_ts=1790886022.336469&cid=D0B2N7W1WJD)* (cherry picked from commit b0a7559)
… non-revertible note hash (#25579) ## Summary The tail kernel checks every nullifier that survives with a non-zero `note_hash` link: the link must equal the output value of a surviving note hash from the same contract with a lower counter. This PR adds one condition in tail-to-public: the matched note hash must be **non-revertible** (`counter < min_revertible_side_effect_counter`). The private-only tail does not run the new check. There every note hash is output unique, so the check could never fail, and the circuit is unchanged. ## Why The check compares the link with the terminal reset's output as-is. It does not recompute a unique note hash. In a tx with public calls that output is: ``` non-revertible note hash -> unique u = H(nonce, s) revertible note hash -> siloed s (the AVM applies the nonce later) ``` The one pair that legitimately survives to the tail is a note created before `end_setup` and nullified after it. Its link is `u`, and the check is what pins the oracle-supplied nonce behind it. A revertible note hash's output is `s`, so before this PR a nullifier linked to `s` passed the value check too. The note then settles as `u` while its nullifier was derived from `s`, so the note can be spent again later. Only the app circuit can write such a link. Honest aztec-nr never writes `s` (it writes `0`, the inner hash, or `u`), so no legitimate tx is rejected, and a prover cannot change an honest app's link. Siloing confines the effect to the misbehaving contract's own notes, so this is hardening: it makes the check match its intent. Comments next to the checks say what the note hash side of the comparison holds, why a revertible match is rejected, and what these checks cannot catch: an app that misstates its own link. ## Related issues This PR does not fully resolve an open issue, so it carries no closing keyword. - Part of AztecProtocol/aztec-claude#1605. That issue's executed witness links a nullifier to the siloed value of a revertible decoy note in a tx with public calls. This PR rejects it. Two shapes from that issue still pass after this PR: a decoy link to a non-revertible note's unique hash, and a zero link on a pending note (AztecProtocol/aztec-claude#1739). A nullifier's value is opaque to the kernel, so no kernel check can rule those out; the new code comment records that boundary. - Part of AztecProtocol/aztec-claude#2441. This PR adds two public-bound tests that run the terminal reset and then the tail check for a non-revertible linked pair, which that issue asks for. Its doc-comment and private-only fixture items are not addressed here. ## Tests `private_kernel_lib`, `nargo 1.0.0-rc.3` (tagged at the pinned `noir/noir-repo` commit `5a7ee9bf5e`): full crate, 1048 passed, 0 failed. `nargo fmt --check` clean. Validator tests, on a prebuilt previous kernel: - `tail_to_public_validators::nullifier_linked_to_revertible_note_hash`: link to a revertible note's siloed value, rejected. With the new assertion removed it reports `Test passed when it should have failed`. - `tail_to_public_validators::nullifier_linked_to_non_revertible_note_hash`: note before `end_setup`, nullifier after, accepted. - `tail_validators::nullifier_linked_to_note_hash_after_end_setup`: private-only tx, note after `end_setup`, accepted. It fails if the new check also runs in the private-only tail. Reset followed by the tail check, as `private_kernel_reset_tail_to_public` runs them (`private_kernel_reset::siloing_tests`): - `nullifier_linked_to_previous_phase_unique_note_hash_is_accepted_by_tail`: an unsiloed note hash before `end_setup` and a nullifier after it, linked to the unique hash computed for the note's index. The reset keeps both and the tail accepts the link. - `nullifier_linked_with_wrong_note_nonce_is_rejected_by_tail`: the same pair with the unique hash computed for a different index. The tail rejects it, which is the constraint that pins the nonce. ## Gate cost - **Private-only tail: +0.** `is_for_public` is known at compile time, so the check is not compiled in. The compiled `private-kernel-reset-tail` bytecode is byte-identical to the one built from `next`. - **Tail-to-public:** one `u32` comparison per nullifier slot, 64 slots in every variant (5 ACIR opcodes per slot). A costlier form of the same check (7 opcodes per slot) measured +400 gates per variant with `bb gates --scheme chonk`, so this should be at or below that. CI reports the exact count. ## Compatibility Changes behaviour only for a witness shape no honest client produces. Circuit bytecode and VKs change for `private-kernel-reset-tail-to-public` only; no genesis constant depends on them. --- *Created by [claudebox](https://claudebox.work/v2/sessions/7305da0f9f6e9e0c/jobs/22) · group: `slackbot` · requested by Mike (@iAmMichaelConnor) · [Slack thread](https://aztecfoundation.slack.com/archives/D0B2N7W1WJD/p1790888798827949?thread_ts=1790888798.827949&cid=D0B2N7W1WJD)* (cherry picked from commit 25cd834)
…esolve to a non-revertible note hash The non-revertible link check changes the private-kernel-reset-tail-to-public circuits, so the VK tree root v6 builds moves to 0x05b95d9ef57c61d1c6626545101db55ae2d1f98ecb618d1c220610c049ee522b. Labs patch 0001 pins testnet_compatibility.test.ts to it; the protocol contracts hash and genesis root are unchanged.
The Grumpkin IPA SRS is reproducible from a fixed seed, but the native loader only checked whether the first point was on curve and the BB API ingress did not authenticate its input. A modified cache or downloaded artifact could therefore substitute points with known discrete-log relationships and undermine IPA binding. Pin SHA-256 hashes for all four 65536-point chunks of the canonical v2 SRS and authenticate the bytes before deserializing points: - Native loads read and verify complete chunks covering the requested prefix. Short caches are regenerated to a complete chunk boundary when generation is allowed; otherwise they are rejected. Generated caches are verified before writing. - BB API ingress requires one to four complete chunks and verifies every supplied byte. Empty, partial, oversized, or corrupted buffers and out-of-range point counts are rejected. The requested point count may select a smaller prefix of the authenticated buffer. - Tests bind the pins to both the deterministic generator and the v2 artifact, and cover tampered caches, short-cache regeneration, corruption in every chunk, and API input coverage. Targets `next`, which already contains the canonical generator fix and v2 artifact migration. The standard bb.js initialization supplies one complete chunk and remains compatible. The canonical generators and pinned hashes are unchanged by the follow-up fixes. Validation: reproduced the short-cache and incomplete-buffer bypasses with failing regression tests before fixing them. The SRS suite passes (37 passed, one skipped; one additional test disabled). BB API tests excluding `ChonkPinnedIvcInputsTest.*` pass (39 passed). A WASM build and the pinned Chonk flow suite were not run locally. --------- Co-authored-by: iakovenkos <sergey.s.yakovenko@gmail.com> Co-authored-by: sergei iakovenko <105737703+iakovenkos@users.noreply.github.com> (cherry picked from commit 08f90e6)
…d an inactive squashing hint (#25580) Test-only. No circuit change and no VK change: one test and its import in `validate_transient_data_squashing_hints.nr`. Refs AztecProtocol/aztec-claude#2313. ## What the test covers `validate_transient_data_squashing_hints` proves that the active hints' nullifier indices are unique through a sorted side-table of `(elem, original_index)` tuples. A prover controls those tuples. `fails_duplicate_nullifier_index_with_sorted_tuple_from_inactive_hint` builds the forgery the last step of that argument exists to stop: - two active hints share nullifier index 0; - the second sorted tuple points at an inactive hint, so it carries the sentinel index instead of the repeated 0 and the "increasing order" check passes; - one extra `nullifier_squash_flags` entry is set, so the removed-count check balances and a nullifier that no hint names would be dropped. With a full nullifiers array (claimed length equal to the sentinel), the circuit rejects this at `Nullifier index hint exceeds claimed length`. The existing duplicate tests use honestly derived tuples and are rejected one step earlier, so nothing covered this path. ## Why it is worth having Mutation check: replacing the range check on the last sorted value with a range check on each active hint's `nullifier_index` (a plausible refactor that keeps every other test green) makes the circuit accept this witness. All 92 existing `reset::transient_data` tests still pass under that mutation; this test fails with `Test passed when it should have failed`. ## Checks run locally Pinned `nargo` 1.0.0-rc.3: the 9 tests in this file pass and `nargo fmt --check` is clean. The rest is left to CI. --- *Created by [claudebox](https://claudebox.work/v2/sessions/bcd0da92a2cf9af3/jobs/14) · group: `slackbot` · requested by Mike (@iAmMichaelConnor) · [Slack thread](https://aztecfoundation.slack.com/archives/D0B2N7W1WJD/p1790886272710929?thread_ts=1790886272.710929&cid=D0B2N7W1WJD)* (cherry picked from commit b1b6871)
Caused some issues to close while just being mentioned (cherry picked from commit 411a411)
…yte length (#25566) ## Summary `poseidon2_hash_bytes` packs its input into 31-byte little-endian chunks and returns `poseidon2_hash` of the resulting fields. The hash commits to the number of chunks but not to the byte length, so zero bytes at the end of the last chunk do not change the result: `[1]`, `[1, 0]` and `[1, 0×30]` hash to the same value. This PR documents that property and pins it with tests. It does not change the function. ## Why the function is unchanged All callers hash fixed identifiers: string literals (domain separator names, a few literal identifiers, hand-written selector signatures) or signatures the aztec-nr macros build from function and type names. None of these contains a zero byte, no Noir caller passes runtime bytes, and the derived domain separators are asserted unique by `constants_tests.nr`. Changing the encoding in place would rotate every selector and every derived domain separator, which is not justified. This is a statement about the current callers, not about the encoding: two identifiers that differ only by trailing zero bytes in the last chunk still hash to the same value, and a caller that commits to variable-length data with this function, for example a payload zero-padded to a maximum length, would accept `m` and `m‖0` as the same message. The doc comment tells callers to bind the length separately. ## Changes - Doc comment on `poseidon2_hash_bytes` describing the packing, the missing byte-length commitment, and the intended use (fixed strings). - `poseidon2_hash_bytes_matches_hash_of_packed_chunks`: the result equals `poseidon2_hash` of the little-endian 31-byte chunks. - `poseidon2_hash_bytes_ignores_trailing_zeros_in_last_chunk`: `[1]`, `[1, 0]` and `[1, 0×30]` hash to the same value. - `poseidon2_hash_bytes_commits_to_chunk_count`: the 31-byte and 32-byte inputs `[1, 0, ...]` hash differently. A comment and tests only: no constraints, VKs or constants change. ## Considered and dropped Adding `std::assert_constant(inputs)` in constrained code, so that a private function passing witness bytes would fail to compile, was tried and dropped: - it had no effect on current callers, which all pass constants; - it could not cover unconstrained code, which includes public functions, because helpers taking the string as a parameter are not inlined there (the aztec-nr domain separator test has that shape); - it rejected safe constrained uses, such as fixed-length runtime bytes and literals passed through a `#[fold]` function. ## Testing `nargo test poseidon2_hash_bytes` in `noir-protocol-circuits/crates/types`: 3 tests passed. `nargo fmt --check` is clean. (cherry picked from commit 4f4bef8)
Fixes AztecProtocol/aztec-claude#2467 (cherry picked from commit 9205859)
Review follow-up for #25582, which merged before this was opened. No contract logic changes. Refs AztecProtocol/aztec-claude#2467 ## Tests - **Shares are replaced on upgrade** (`handleRewards.t.sol`, `test_WhenTheProofIsFullEpoch`). Before, the prover had the minimum shares before and after the upgrade, so a version of the code that kept the old shares passed all tests. The test now raises the prover's score first (560 full-epoch proofs), then asserts that the upgrade stores different shares. - **Invalidated-tail trigger** (`ValidatorSelection.t.sol`, `testFullEpochProofUpgradesRegistrationAfterTailInvalidation`). An epoch ends with a valid checkpoint and a checkpoint with too few attestations. A proof of the first checkpoint is not full-epoch. After `invalidateInsufficientAttestations`, the same proof is full-epoch, upgrades the registration and increases the score. This is trigger (2) of the issue. - `test_GivenTheExistingRegistrationIsFullEpoch` asserts that a first full-epoch proof sets `getHasSubmittedFullEpoch`. ## Other changes - `RewardLib.sol`: one correction to the `fullEpoch` field comment. It said the flag is set when the registration "was submitted after the epoch is closed". A partial proof submitted after the epoch closed does not set it; the flag is set by a full epoch proof. - `RewardLibWrapper`: the two-argument `handleRewardsAndFees` calls the three-argument overload. ## Checks run locally - `forge fmt --check` - `forge test` on `MultiProof.t.sol`, `ValidatorSelection.t.sol` and `handleRewards.t.sol`: 43 pass. - Two deliberate breakages of `RewardLib.handleRewardsAndFees`, both fail the tests: keep the old shares on upgrade (fails `test_WhenTheProofIsFullEpoch`), and remove the upgrade path (fails the new integration test and two existing tests). The full suite is left to CI. ## Not in this PR The prover node still skips submission when `getHasSubmitted` is true (`yarn-project/prover-node/src/prover-node-publisher.ts`, aztec-node repo). It must use `getHasSubmittedFullEpoch` for full-epoch proofs before the issue is fixed for honest provers. That change needs a separate PR in `aztec-labs-eng/aztec-node`. --- *Created by [claudebox](https://claudebox.work/v2/sessions/966f467da8c8b731/jobs/7) · group: `slackbot` · requested by Mike (@iAmMichaelConnor) · [Slack thread](https://aztecfoundation.slack.com/archives/D0B2N7W1WJD/p1790965530798319?thread_ts=1790965530.798319&cid=D0B2N7W1WJD)* (cherry picked from commit 99b8b97)
Removes the per-registry checkpoint reward overrides built into the rollup (#25312, #25426, #25461), ahead of AZIP-28, which moves sequencer reward policy into a governance-set calculator contract (next PR in this stack). - Restores the pre-override reward path: every proposer gets the default sequencer share, with the pre-override arithmetic (including dust to the prover). - Keeps the proof-submission optimizations (#25404, #25406, #25419) and all later v6 work in the touched files. - Removes the override config (`RollupConfigInput.registryRewardOverrides`, `AZTEC_REGISTRY_REWARD_OVERRIDE_*`), the `getRegistryRewardOverrides` getter, the ATP probes, their errors, tests, mocks and the mainnet fixture (the fixture comes back in the reduction-calculator PR). - Gas reports regenerated; partial epoch proof gas is back to within ~100 gas of pre-override numbers. Rollup bytecode: 23,947 bytes (629 spare). `forge test`: 1089 passed, 0 failed. ## Gas across the stack Partial epoch proof submission gas from `partial_epoch_proof_gas_report.md` (mock epoch proof verifier, 48-member committee fixture). Rows 3–5 come from the top of the stack (#25573). Δ is measured against row 1 at 32 checkpoints. | | 1 checkpoint | 8 checkpoints | 16 checkpoints | 32 checkpoints | Δ at 32 | |---|---:|---:|---:|---:|---:| | 1. Before the reward-override stack (`819a18a4365`) | 654,930 | 956,937 | 1,246,308 | 1,732,713 | — | | 2. Reward-override stack merged (`6c514c6e442`), no overrides configured | 658,562 | 963,412 | 1,256,031 | 1,748,935 | +16,222 | | **2b. Reward-override stack, two overrides, two shared mock stakers** | 688,985 | 1,071,574 | 1,437,827 | 2,031,299 | +298,586 | | 3. This stack, no calculator configured | 656,517 | 954,825 | 1,239,917 | 1,717,875 | −14,838 | | 3b. This stack, table-lookup calculator (one storage read per proposer) | 677,325 | 1,017,817 | 1,346,913 | 1,893,982 | +161,269 | | **4a. Reduction calculator, two shared mock stakers (same scenario as 2b)** | 692,905 | 1,086,424 | 1,474,921 | 2,130,609 | +397,896 | | **5a. Premium calculator, two shared premium stakers (same scenario as 2b)** | 714,982 | 1,169,970 | 1,604,427 | 2,319,016 | +586,303 | | 4b. Reduction calculator, one cold mainnet-shaped position per validator | 702,626 | 1,165,408 | 1,621,316 | 2,363,373 | +630,660 | | 5b. Premium calculator, one cold position per validator | 700,404 | 1,173,877 | 1,633,453 | 2,430,012 | +697,299 | **Rows 4a and 5a are the ones to compare with the old implementation (2b).** - They use 2b's scenario: two registries, two shared stakers, validators alternating between them by index, and every proposer matched. - At 32 checkpoints the reduction calculator costs 99,310 more than the in-rollup overrides, and the premium calculator 287,717 more. - 4a uses the same 10e18 / 20e18 rewards as 2b. - 5a pays 30e18 / 40e18, above the 25e18 default. A premium calculator pays rewards at or below the default without checking provenance, so 2b's values would have skipped the three authentication probes (`isATP`, `getStaker`, `isAttester`). Its stakers are genuine positions created by the factory, so their `isAttester` reads are per attester. **Rows 4b and 5b** are the worst honest case. Every validator has its own position, so no lookup is warmed by another proposer. - 4b mirrors mainnet: a proxy staker and a clone ATP per validator, across three registries paying ½, ¼ and 1× the default. - 5b splits the validators into thirds: genuine premium positions, reduced positions, and fake withdrawers that are rejected. **Other notes** - Row 3 is below row 1 because this stack keeps the proof-submission optimizations (#25404, #25406, #25419). - With a calculator configured, the rollup's own overhead is about 14k fixed plus 1.3k per checkpoint, measured with a calculator that returns the defaults. The rest is the calculator's own execution, bounded by the stipend of 200k + 100k per checkpoint. (cherry picked from commit 8debae0)
Implements AZIP-28: the rollup calls a governance-set `ISequencerRewardCalculator` once per epoch proof to get one sequencer reward per newly proven checkpoint. **Rollup changes** - `sequencerRewardCalculator` in the namespaced reward storage; `setSequencerRewardCalculator` (owner only, emits `SequencerRewardCalculatorUpdated(old, new)`), `getSequencerRewardCalculator`, optional initial value via `RollupConfigInput.sequencerRewardCalculator` / `AZTEC_SEQUENCER_REWARD_CALCULATOR` (default zero). Setter/getter go through `RewardExtLib` for bytecode size. - Proposers are derived from the committee the proof already verifies (slot + sample seed). Escape-hatch epochs and empty committees skip the calculator. - `SequencerRewardCalculatorLib`: `staticcall` with exactly `CALCULATOR_GAS_BASE + n * CALCULATOR_GAS_PER_CHECKPOINT` (200k + 100k·n). Nothing is copied unless `returndatasize == 64 + 32n`; the head must be offset 32 / length n; every value `<= MAX_SEQUENCER_REWARD_PER_CHECKPOINT` (1e24). Any failure pays the default to every checkpoint. - Distribution: no calculator, skipped, or rejected response uses the pre-AZIP arithmetic exactly. An accepted response draws `n × (checkpointReward − default) + Σ rewards`, scales sequencer rewards by `available / desired` under shortfall, and gives the prover the remainder. Prover rewards are now written to storage once per proof. **Deviations from the AZIP text (spec should be amended)** - The rollup reverts with `SequencerRewardCalculatorLib__InsufficientGas` if the transaction cannot forward the full stipend (EIP-150 63/64 rule plus a 10k reserve). Otherwise the prover could starve the calculator and force defaults. The requirement depends on constants only (≈3.46M at n = 32), so `eth_estimateGas` covers it. - Under a distributor shortfall the prover's payout depends on the calculator's values (it is a consequence of the AZIP's proportional rule); "prover share MUST NOT depend on the calculator" holds only without a shortfall. - A calculator that returns exactly the default can differ from the zero-calculator split by at most 1 wei per checkpoint, only under a shortfall and only when `checkpointReward * bps` is not a multiple of 10,000. **Gas (partial epoch proof, mock verifier)**: no calculator 656,493 / 954,823 / 1,240,004 / 1,717,873 for 1 / 8 / 16 / 32 checkpoints (−14.9k at 32 vs. the previous PR). Rollup's own overhead with a calculator: ~14k + ~1.3k per checkpoint. Rollup bytecode: 24,131 bytes (445 spare). Every AZIP "Test Cases" bullet maps to a test (unit, fuzz, through-the-rollup, escape hatch, zero-size committee, deploy config, gas rows at 1/8/16/32). `forge test`: 1164 passed, 0 failed. `RollupConfigInput` gains a trailing `address`; no labs change needed. Client mirrors (node-side reward prediction) are left for a follow-up in aztec-node, since no predictor exists today. (cherry picked from commit c85ce19)
…25572) Adds a reference `ISequencerRewardCalculator` in `l1-contracts/test/reward-calculators/reduction/` that pays reduced rewards to positions of configured ATP registries, i.e. the policy from #25312/#25426 expressed as an AZIP-28 calculator. Test-only; no `src/` change. - Resolves `GSE.getWithdrawer(attester) → withdrawer.getATP() → atp.getRegistry()` with never-reverting probes (`ProbeLib`: code check, 20k gas stipend, exactly 32 bytes, clean upper bits). - Owner-set table `registry → reward`; pays `min(default, entry)` (capped at read time, so a later `setRewardConfig` can never turn an entry into a premium). Everyone else gets the default. - Dedupes proposers in memory, caches per attester, returns one value per input in order, never reverts. - Shared pieces for the premium calculator: `ProbeLib`, `IATP`, ATP mocks (incl. mainnet-shaped ERC1967 staker / EIP-1167 ATP and adversarial getters), `FakeGSE`. **Mainnet fork test**: `test/fork/MainnetReductionCalculator.t.sol` deploys the calculator against the real mainnet GSE using real attester/staker/ATP cases (auction and genesis-sale registries, v1/v2 stakers, a StakingRegistry-provided validator). It runs offline from `test/fixtures/mainnet_atp_reduction_calculator.json` (block 25,934,884); refresh with `MAINNET_ATP_FIXTURE_RPC_URL`. Real cold probe costs: `getATP` 7,288 gas, `getRegistry` 2,923. **Gas** (worst case: cold, distinct proposers, expensive successful probes): 62,799 / 450,789 / 907,957 / 1,866,299 at n = 1 / 8 / 16 / 32, i.e. ≤ 55% of the stipend. Through the rollup at n = 32: 2,363,417. `forge test`: 1239 passed, 0 failed. (cherry picked from commit cc4e90f)
…ce-tracking ATPs (#25573) Adds a reference premium `ISequencerRewardCalculator` that pays **above** the default, plus the provenance-tracking ATP flavour it needs, under `l1-contracts/test/reward-calculators/premium/`. Test-only; no `src/` change. **Why a new ATP flavour.** With today's ATPs a premium is unsafe: anyone can deploy a withdrawer whose `getATP()` points at a contract answering `getRegistry()` with the premium registry; anyone can clone the genuine ATP implementation; and anyone can deposit liquid stake naming a genuine ATP staker as withdrawer. **Contracts** - `PremiumATPFactory`: minter-only creation, `isATP` recorded at creation. Bound to one GSE, which every staker it creates inherits. - `PremiumATP`: clone, factory-only one-shot init, lock schedule, no sweep. `claim` is bounded by the lock and by `claimed + reserved <= allocation`. - `PremiumATPStaker`: non-upgradeable, bound once to its ATP. Reserves allocation before each deposit and records the attester. Provider path checks the entry queue grew by one with this staker as withdrawer. Stakes only into rollups on its factory's GSE (provider path included). Exits always pay the ATP. Release is operator-only. `returnTokensToATP` is permissionless (recovers failed-deposit refunds). - `PremiumRewardCalculator`: table `registry → {reward, provenanceSource}`. Entries without a source are capped at the default. A source is accepted only if its `getGSE()` is the calculator's GSE. Premiums require `factory.isATP(atp)`, `atp.getStaker() == withdrawer` and `staker.isAttester(attester)`, all via 10k-gas never-reverting probes. Per-attester cache only. **Invariant**: per position, `claimed + reserved <= allocation`, with `reserved = threshold × recorded attesters`; only recorded attesters earn a premium; stake exits land in the ATP. So premium-earning stake never exceeds the allocation, and an equal amount stays locked whoever funded the deposit. **GSE binding.** An attester address registers at most once per GSE, not across GSEs. Without the binding, a rollup registry holding rollups on two GSEs (for example after a GSE upgrade) let one reservation back two premium-earning validators: a liquid deposit for an attester on one GSE naming the staker, plus the staker's own stake of the same attester address on the other. If the thresholds differed, a record made on the lower-threshold GSE could also be paid by the higher-threshold calculator. Factories and stakers are now bound to one GSE, and calculators refuse factories bound to another, at configuration time, so the check costs nothing per proposer. `PremiumGSEBinding.t.sol` covers both scenarios with two rollups on two GSEs in one rollup registry. **Tests**: happy path and provider path on the real Rollup/GSE (real PoP and key-reuse checks), one test per threat (fake withdrawer, attacker clone, liquid deposit behind a genuine staker, duplicate/front-run deposit + refund recovery, top-up + claim, re-initialisation, two GSEs in one rollup registry, ejecting and in-exit slashes, migration to a new rollup, release before/after exit, re-registration, attester-initiated exit, full slash, registry-keyed cache confusion, hostile output at each of the six probes), invariant/fuzz over random stake/claim/release/exit/top-up sequences, a shortfall with premiums, gas rows through the rollup. **Gas** (n = 32, cold, distinct, stipend 3.4M): genuine premiums 1,025,924 (30%); worst attacker-built set 1,338,620 (39%); theoretical five-burned-probes worst 2,434,424 (72%). Through the rollup at n = 32: 2,430,012, or 2,319,016 with two shared premium stakers (same scenario as the old two-overrides bench; see the table in #25570). **Accepted residual risks** - Trust roots: factory owner/minters, registry owner, the staking registry used for the provider path (not trusted for the reservation invariant). - State at proof time: a fully slashed attester whose record remains still earns the premium for checkpoints it proposed before the slash and that are proven after it. Exposure is bounded to proposals already made. - GSE proof-of-possession does not bind the attester, so a third party can register a pending deposit's keys first. The genuine validator is delayed (refund is recoverable); no premium is gained. - Provider stakes: rewards, the premium included, go to the coinbase the provider's node sets; the protocol does not tie it to the split contract, so the premium's destination is provider-trusted, like base rewards. - `PROBE_GAS = 10k` fits the reference clone staker (~5.3k cold, ~5.7k under EIP-8038). A production calculator over proxied stakers (~7.3k) needs it, or `CALCULATOR_GAS_PER_CHECKPOINT`, re-derived. The mock staking registry matches ignition's `StakingRegistry` (provider ids from 1, exact approval, `QueueIsEmpty`). `stakeWithProvider` was also run end to end against the real `StakingRegistry` and 0xSplits contracts (not committed). `forge test`: 1385 passed, 0 failed. (cherry picked from commit 551aa41)
…laudeBox port-to-* labels (#25533) ## Why CI in this repo no longer triggers ClaudeBox. `.github/workflows/claudebox.yml` forwarded events to `claudebox.work/run` with `CLAUDEBOX_API_SECRET`. That secret is not in Aztec CI and won't be re-added, because it would let a ClaudeBox session credential pass through CI. Every dispatch has been failing without any error showing up. Ports between release lines move entirely to ClaudeBox. It watches merged PRs through the GitHub webhook, and a `port-to-<branch>` label is all that's needed. ClaudeBox ports the change onto one rolling `cb/…` branch per target and keeps a single PR into that branch, reporting in #backports. The server side, the `port-to-branch` procedure and the label list are in [claudebox#2633](AztecProtocol/claudebox#2633). ## What this removes **ClaudeBox dispatch** - `.github/workflows/claudebox.yml`, which includes the `/claudebox` comment command. Its `claude-review` job was also starting a second review session, because claudebox-server already handles that label from the PR webhook. - `ci3/slack_notify_with_claudebox_kickoff`. The merge-train, release-canary and barretenberg nightly failure alerts now post the same Slack message through `ci3/slack_notify`, without dispatching anything. **Backport machinery** - `.github/workflows/backport.yml`, `scripts/backport_to_staging.sh`, `scripts/find_missing_backports.sh`, `.backportrc.json`, `.claude/claudebox/backport.md`, and the `/backport` skill. - Staging-branch hooks: the backport-train auto-merge step in `merge-train-auto-merge.yml`, the `backport-to-*-staging` trigger in `merge-train-update-pr-body.yml`, and the backport CI-failure Slack step in `ci3.yml`. - `ci3/run_test_cmd`: the `backport-to-v2-staging` flake-notification case. **Docs** - The root `CLAUDE.md` gets a `<release_ports>` block. It says ports are done by ClaudeBox from `port-to-<branch>` labels, that backport workflows or dispatch steps must not be added here, and that label and behavior changes belong in the claudebox repo. - `.github/NOTES.md` is rewritten around `port-to-<branch>` labels and points to the claudebox repo. It no longer describes `v4-next`. - The `merge-trains` and `merge-train-infra` skills no longer describe backport trains, staging branches or dispatch. ## Labels A PR can't change labels, so a repo admin needs to apply these. Add the new labels before this PR and claudebox#2633 merge. **Add**, in both `AztecProtocol/aztec-packages` and `AztecProtocol/aztec-packages-private`: - `port-to-v6` - `port-to-next` **Remove** from `AztecProtocol/aztec-packages`: - `backport` - `backport-to-master` - `backport-to-staging` - `backport-to-v2` - `backport-to-v3` - `backport-to-v4` - `backport-to-v4-next` - `backport-to-v5-next` - `backport-to-v6` **Remove** from `AztecProtocol/aztec-packages-private`: - `backport-to-v5-next` - `backport-to-v6` `v5-next` has no `port-to-*` label. If that line still needs ports, it takes one entry per repo in claudebox's `config.yml` plus the label. Any open "Accumulated backports to …" PRs from `backport-to-*-staging` branches should be merged or closed by hand. Nothing updates them once this lands. ## Testing - The edited workflows parse as YAML, and `bash -n` passes on the edited ci3 scripts. - `git grep` finds no references to `backport`, `claudebox.yml`, `.claude/claudebox`, `slack_notify_with_claudebox_kickoff` or `CLAUDEBOX_API_SECRET` outside changelogs, the `labs` submodule, and a vendored header. - End-to-end check: once the labels exist and claudebox#2633 is deployed, merging a `port-to-v6` PR should open a #backports thread and a rolling `cb/port-to-v6` → `v6` PR. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- *Created by [claudebox](https://claudebox.work/v2/sessions/6f2edaa85335b3c0/jobs/3) · group: `slackbot` · requested by ludamad (@ludamad) · [Slack thread](https://aztecfoundation.slack.com/archives/C0B1HE6ELG2/p1790260907101329?thread_ts=1790260907.101329&cid=C0B1HE6ELG2)* --------- Co-authored-by: ludamad <adam.domurad@gmail.com> (cherry picked from commit 9fdb42c)
AztecBot
force-pushed
the
cb/port-to-v6
branch
from
October 4, 2026 12:54
52d7778 to
d50f3fa
Compare
This was referenced Oct 4, 2026
IlyasRidhuan
added a commit
that referenced
this pull request
Oct 5, 2026
Rolling integration PR for changes labelled `port-to-v6` on `next`. Each merged source PR is cherry-picked onto `cb/port-to-v6` as its own commit, keeping `(#N)` in the title. ## Ported - [x] [#25589](#25589) chore: blobs and docs (pick of the merge commit, `-m 1`, applied without conflicts, plus one `fix(port)` commit) - All eight files end up identical to `next` at 86d0021, as do the `blob` and `rollup-lib` crates and the whole `l1-contracts` directory. - It adds two labs patches, which keep their `next` numbering: - `0006-fix-blob-lib-bind-checkpoint-boundaries-into-the-blo.patch` (`yarn-project/blob-lib`, a test fixture path and the L1 publisher integration test) - `0007-docs-aztec-nr-private-log-fields-past-the-log-s-leng.patch` (a doc comment in `aztec-nr`'s `private_context.nr`) - Every file those two patches touch has the same pre-image blob on the `v6` labs pin `a0d73c0aed` as the patch expects. - The `fix(port)` commit updates labs patch `0001-test-pin-testnet-compatibility-to-the-v6-kernel-VK-t.patch` to the VK tree root `v6` builds with this change. ## Protocol impact - The blob commitments hash now binds checkpoint boundaries: each commitment is hashed with a one-byte flag that is `0x01` for a checkpoint's first blob and `0x00` otherwise. The change is made in three places that have to agree: - L1: `BlobLib.calculateBlobCommitmentsHash` - circuits: the `blob` crate (`blob_batching.nr`, the accumulator ABIs), consumed by the rollup circuits - node: `yarn-project/blob-lib`, through labs patch 0006 - This changes the rollup circuits, so the VK tree root that `v6` builds moves: - from `0x1032cbb2f61a9c1151370ebc35c8ea20d1a726e3388eb94e84291c2b2fecb5d3` (pinned on `v6` since #25587) - to `0x031139abb5b9f51ca0e55a6e2022d567029f50acc9428506f05c91ae27e7f75d` (taken from this PR's failing CI run on `b2cd9f3f`), which is what labs patch 0001 now pins - The testnet deployed from `v6` has root `0x2d89003cc2dc62b06f07d83d3635c66c63fc43668369d30e7ee516f908ee10e3`; `v6` has not matched it since #25575. The re-pin follows the decision recorded on #25549 (a breaking circuit change ported to `v6` re-pins testnet in the same PR). - The protocol contracts hash and the genesis root are unchanged; those two assertions passed on `b2cd9f3f`. - The L1 change takes effect only on a rollup deployed from this code. A node built from this branch computes the new hash, so it does not agree with a rollup deployed before it. ## Testing - CI3 on `b2cd9f3f` (before the re-pin): `testnet_compatibility.test.ts` › "has expected VK tree root" was the only failure in the fast run, which covers the `blob` and rollup circuit tests, the new `blobCommitmentsHash.t.sol` forge test and the labs `blob-lib` tests. - `./labs-patches/bootstrap.sh check`: the series (0001, 0006, 0007, 0010) applies cleanly to the labs pin `a0d73c0aed`. Patch 0001 was produced with `bootstrap.sh apply` / `export`. - No circuits or L1 contracts were built locally (no `nargo` and no pinned `solc` in the port environment); the re-pinned test runs on this PR's CI. --- *Created by [claudebox](https://claudebox.work/v2/sessions/134efca9a11ee14f/jobs/29) · group: `slackbot` · [Slack thread](https://aztecprotocol.slack.com/archives/C0AGN2WT3CP/p1790609320989739?thread_ts=1790609320.989739&cid=C0AGN2WT3CP)*
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Rolling integration PR for changes labelled
port-to-v6onnext. Each merged source PR is cherry-picked ontocb/port-to-v6as its own commit, keeping(#N)in the title.Ported
fix(port)commits)fix(port)1 dropslabs-patches/0001-fix-pxe-charge-the-teardown-call-s-AVM-startup-gas-i.patch, which the pick brings along. The labs pin onv6(a0d73c0aed) already carries that PXE change upstream as fix(pxe): charge the teardown call's AVM startup gas in kernelless simulation aztec-labs-eng/aztec-node#364, so the patch has nothing to apply to. The Noir side isgas_meter.nrandvalidate_gas_used_tests.nr, both identical tonext.fix(port)2 adds labs patch0001-test-pin-testnet-compatibility-to-the-v6-kernel-VK-t.patch, which re-pins the VK tree root inlabs/yarn-project/aztec/src/testnet_compatibility.test.ts.0010-fix-p2p-require-exact-contract-class-log-length-in-D.patch. Both files it touches (data_validator.ts,data_validator.test.ts) have the same pre-image blobs on thev6labs pin as onnext's.noir/bootstrap.sh hashis what the other Noir consumers onv6already use (avm-transpiler,noir-protocol-circuits,acir_tests).noir-protocol-circuits/bootstrap.shandscripts/circuit_kind.test.share identical tonextat b0a7559.fix(port)commit)private-kernel-reset-tail-to-publiccircuits, so the VK tree root moves again. Thefix(port)commit updates labs patch 0001 to the new root.nextat 08f90e6, as does the rest ofbarretenberg/cpp/src/barretenberg/srs. No later commit onnexttouches them.validate_transient_data_squashing_hints.nr.private-kernel-libcrate is identical tonextat b1b6871..github/workflows/auto-close-issues.ymlandscripts/auto_close_issues.py. Nothing else onv6invokes either.types/src/hash.nr, which ends up identical tonextat 4f4bef8.RewardLib.sol. No contract logic changes.v6carries the override stack this removes (feat: checkpoint reward overrides #25312, fix: resolve ATP registry through the staker for reward overrides #25426, feat(l1): add checkpoint reward overrides #25461) and the proof-submission optimizations it keeps (feat: only verify new headers #25404, feat: optimize proof submission #25406, feat: submitProof takes only new headers #25419).l1-contractsreferences what it removes (registryRewardOverrides,AZTEC_REGISTRY_REWARD_OVERRIDE_*,getRegistryRewardOverrides, the fourRewardLib__*errors): no hits in this repo or in thev6labs pina0d73c0aed.ISequencerRewardCalculator,SequencerRewardCalculatorLib, thesequencerRewardCalculatorrollup config field,setSequencerRewardCalculator/getSequencerRewardCalculator, and the optionalAZTEC_SEQUENCER_REWARD_CALCULATORdeploy variable (zero address by default).v6labs pin references the calculator. Labs importsnetwork-defaults.jsondirectly, where the new key is an added default.l1-contracts/test/reward-calculators, a fork test and its fixture), plus thefoundry.tomlread permission for the fixture and regenerated gas reports.l1-contracts/test/reward-calculators/premium), plus regenerated gas reports.l1-contractsdirectory is identical tonextat 551aa41.Protocol impact
v6builds moves:0x2d89003cc2dc62b06f07d83d3635c66c63fc43668369d30e7ee516f908ee10e3(the testnet deployed fromv6)0x05b95d9ef57c61d1c6626545101db55ae2d1f98ecb618d1c220610c049ee522b(taken from this PR's failing CI run on34e0b24f), which is what labs patch 0001 pins0x21f06c3b82320ea5f80646751cdd9fa023dfd61400a42b8c952aa32e8f155793(from the failing CI run onbed8264)v6no longer matches the currently deployed testnet until it is redeployed. The re-pin follows the decision recorded on chore: port-to-v6 rolling port #25549 (a breaking kernel change ported tov6re-pins testnet in the same PR).34e0b24f.RollupConfigInput.registryRewardOverrides,getRegistryRewardOverridesand theAZTEC_REGISTRY_REWARD_OVERRIDE_*deploy variablesl1-contracts/testonly; no calculator ships insrcor is configured by defaultRewardLibreward handling for early proof submissions, and a newgetHasSubmittedFullEpochview onIRollup/Rollup.prover-node-publisher.tsinaztec-labs-eng/aztec-node) still skips submission whengetHasSubmittedis true. It has to usegetHasSubmittedFullEpochfor full-epoch proofs before the fix helps honest provers; that change is not in this PR or in thev6labs pin's patch series.v6already estimates that amount.lengthexceeds its trimmed length is now rejected. Honest producers already emit the trimmed length.v6are no longer closed by the script.generated/HonkVerifier.solequals the circuits-side verifierTesting
fb097a89(the first eleven ports, through test: cover prover registration upgrade paths #25585), including the testnet compatibility test against the re-pinned root and the l1-contracts forge tests.34e0b24f(the first nine ports, before the second re-pin) ran about 10,400 tests; the only failure was the VK tree root assertion that the second re-pin fixes../labs-patches/bootstrap.sh check: the series (0001, 0010) applies cleanly toa0d73c0aed. Patch 0001 was produced withbootstrap.sh apply/export.bash -npasses on both bootstrap scripts andscripts/circuit_kind.test.shpasses locally.v6has nopinned-build.tar.gz, so the pinned-build path is not exercised.nargo, no bb build and no pinnedsolcin the port environment). The four AZIP-28 ports (refactor(l1): remove the built-in checkpoint reward overrides #25570 to test(l1): reference premium sequencer reward calculator with provenance-tracking ATPs #25573) have no CI result yet: the forge suite, the labs build against the changed rollup ABI and the deploy-script tests run on this PR's CI.v6at cf7ea33;v6has since gained chore(ci): notify the private repo on v6 and v6-next pushes #25551 (a notify workflow change), which merges without conflicts.Created by claudebox · group:
slackbot· Slack thread