Skip to content

chore: v6 L1 updates integration branch - #25401

Merged
spalladino merged 11 commits into
nextfrom
project/v6-l1-updates
Sep 10, 2026
Merged

chore: v6 L1 updates integration branch#25401
spalladino merged 11 commits into
nextfrom
project/v6-l1-updates

Conversation

@alexghr

@alexghr alexghr commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Rebuilds the v6 L1 integration branch on the latest next using cherry-picked commits.

This includes AZIPs 23, 24, 25 (all approved in last ACD), plus gas optimizations and refactors to work around the Rollup contract size limit.

Included PRs

  • #25260 — feat: introduce a protocol fee margin (AZIP-23)
  • #25370 — chore: update activity score to only track full epoch proofs (AZIP-25)
  • #25386 — refactor(l1): reduce full epoch proof gas overhead
  • #25389 — feat(l1): track which prover first proved each checkpoint (AZIP-24)
  • #25314 — perf(l1): hold the rollup config in immutables instead of storage
  • #25404 — feat: only verify new headers
  • #25406 — feat: optimize proof submission
  • #25419 — feat: submitProof takes only new headers

Gas

The reports were regenerated after removing reward overrides. The next comparison is unchanged because no L1 contract files changed on next since this branch point.

Epoch benchmark

No validators

Function next This branch Delta
propose avg 199,366 198,220 -1,146 (-0.6%)
submitEpochRootProof avg 991,020 925,398 -65,622 (-6.6%)
submitEpochRootProof max 1,029,513 966,444 -63,069 (-6.1%)
submitEpochRootProof calldata bytes 14,148 14,212 +64 (+0.5%)
setupEpoch avg 32,042 32,020 -22 (-0.1%)
Avg gas/second 3,643.1 3,570.2 -72.9 (-2.0%)

100 validators

Function next This branch Delta
propose avg 327,769 326,630 -1,139 (-0.3%)
submitEpochRootProof avg 1,572,054 1,505,290 -66,764 (-4.2%)
submitEpochRootProof max 1,669,957 1,605,780 -64,177 (-3.8%)
submitEpochRootProof calldata bytes 16,644 16,708 +64 (+0.4%)
aggregate3 avg 376,655 375,623 -1,032 (-0.3%)
setupEpoch avg 46,504 46,482 -22 (0.0%)
Avg gas/second 5,937.2 5,863.4 -73.8 (-1.2%)

Partial epoch proof benchmark

Proof submission next This branch Delta
1 checkpoint 661,245 654,868 -6,377 (-1.0%)
8 checkpoints 980,349 956,875 -23,474 (-2.4%)
8 more checkpoints 988,039 910,405 -77,634 (-7.9%)
16 checkpoints 1,291,446 1,246,224 -45,222 (-3.5%)
32 checkpoints 1,805,072 1,732,651 -72,421 (-4.0%)

The partial proof benchmark uses the mock epoch proof verifier; real ZK verification and top-level transaction calldata gas are excluded.

Tracked function gas report

The fixed RollupTest report now records a 41,936-byte preheated deployment, a 393,723-gas median for submitEpochRootProof(), and unchanged 283,135-gas median for propose(). The owner-only setters pay one extra delegatecall after moving fee and reward admin paths into RewardExtLib; hot proposal paths still call FeeLib directly.

Contract size

Without the admin-path extraction, the reward-free integration stack still produces a 24,744-byte Rollup, 168 bytes over EIP-170. Moving those paths into RewardExtLib brings runtime bytecode to 22,670 bytes, 1,906 under the 24,576-byte limit.

CI checks this directly under both the default and production Foundry profiles via scripts/check_contract_sizes.sh.

@spalladino spalladino changed the title chore: v6 l1 updates integration branch chore: v6 L1 updates integration branch Sep 8, 2026
@spalladino
spalladino force-pushed the project/v6-l1-updates branch from 457cfb7 to 8af2277 Compare September 8, 2026 21:56
@spalladino
spalladino marked this pull request as ready for review September 9, 2026 13:53
@spalladino
spalladino force-pushed the project/v6-l1-updates branch from cf0d363 to af732b3 Compare September 10, 2026 16:36
alexghr and others added 11 commits September 10, 2026 14:11
## Summary

- reuse the current epoch already computed during proof acceptance
- cache the packed chain tips for full-proof detection and proven-tip
advancement
- read the known-existing next checkpoint slot directly instead of
repeating checkpoint-number validation
- update the gas benchmark results; this saves 1,053 gas per proof
submission versus the parent PR implementation, leaving roughly 3,729
gas of net overhead versus the pre-PR baseline

## Tests

- `forge fmt --check`
- `forge test --offline --match-contract MultiProofTest`
- `forge test --offline --match-contract HandleRewardsTest`
- `python3 scripts/gas_benchmarks.py`
There was no on-chain record of who proved a given checkpoint.
`L2ProofVerified` carries the prover, but there is nothing queryable,
and the reward accounting only tracks per-epoch submissions.

Adds a `firstProvenBy` mapping to `RollupStore`, written in
`submitEpochRootProof` whenever a proof advances the proven tip. Only
the checkpoint the proof ended at gets an entry, so entries are sparse:
proofs of 1-10 and then 11-20 record entries at 10 and 20, with nothing
in between. Because a proof of an already proven range cannot advance
the tip, it never reaches the write and the original prover is
preserved.

`getFirstProvenBy(checkpointNumber)` resolves an arbitrary checkpoint by
walking forward to the next entry. The first entry at or after the
requested number belongs to the earliest proof that covered it, since
the proven tip only ever advances; the walk is bounded by the epoch
duration because a proof covers at most one epoch. The mapping stores
the address in its lower 160 bits and sets bit 160 as a presence flag,
so `address(0)` remains distinguishable from a sparse, unwritten entry.

The getter reverts with `Rollup__CheckpointNotProven` for checkpoint 0
or a checkpoint ahead of the proven tip.

The getter is routed through `RewardExtLib` (alongside the other STF
getters) rather than inlined in `Rollup.sol` — the Rollup deployed
bytecode is within 800 bytes of the size limit.

New `IRollup.getFirstProvenBy(uint256) returns (address)` and
`Errors.Rollup__CheckpointNotProven(uint256 proven, uint256 requested)`.

Fixes A-1927
This PR changes the checkpoint header verification from always verifying
from index 0 (in the epoch) up to the current proven tip to verifying
from the last proven index to up the new proven tip. This reduces the
gas cost for partial epoch proofs by about ~3-4k per previously verified
checkpoint header.

Fix A-1802
Further optimize the proof submission flow:
1. hash haeader from calldata instead of memory (avoids a copy)
2. read header hashes in bulk (avoid checks run on every iteration of a
loop)
3. reuse already read header hashes

Other than submitting a proof of the first checkpoint (which is +2k gas
compared to next) every other scenario is cheaper than the code on next.

| Scenario | Current gas | vs #25404 | vs origin/next |

|------------------|-------------|--------------------|--------------------|
| 1 fresh | 663,452 | −1,506 (−0.23%) | +2,243 (+0.34%) |
| 8 fresh | 965,328 | −21,594 (−2.19%) | −14,985 (−1.53%) |
| 8→16 extension | 930,160 | −28,490 (−2.97%) | −57,867 (−5.86%) |
| 16 fresh | 1,256,565 | −44,700 (−3.44%) | −34,869 (−2.70%) |
| 32 fresh | 1,729,965 | −91,388 (−5.02%) | −75,071 (−4.16%) |
This PR optimized the partial proof flow by enabling provers to only
send the headers for new checkpoints that are proven by the proof. The
provers can send smaller payloads (just fees + coinbase) for the already
proven checkpoints (which also have their rewards accounted for).

This PR slightly increases gas costs for full epoch proofs (because of
all the new checks we have to run on the proven-prefix) but it reduces
gas costs on partial epoch proofs that build on previously submitted
proof by about ~3.5K/already proven checkpoint (so in the scneario where
we prove 8 checkpoints and then another 8 checkpoints we save approx 27k
on the second proof)

This PR requires changes to be made to aztec-node to make it compatible
with the new contracts.
@spalladino
spalladino force-pushed the project/v6-l1-updates branch from c751592 to 6dce8ee Compare September 10, 2026 17:23
@spalladino
spalladino added this pull request to the merge queue Sep 10, 2026
Merged via the queue into next with commit e8e6465 Sep 10, 2026
17 checks passed
@spalladino
spalladino deleted the project/v6-l1-updates branch September 10, 2026 18:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants