Skip to content

feat!: bump the contract address domain separator to v3 (#25521) [port to v6] - #25624

Merged
IlyasRidhuan merged 3 commits into
v6from
cb/port-to-v6-25521
Oct 8, 2026
Merged

IlyasRidhuan merged 3 commits into
v6from
cb/port-to-v6-25521

Conversation

@AztecBot

@AztecBot AztecBot commented Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator

Port of aztec-packages#25521 to v6, on its own branch so that the rolling port PR aztec-packages#25597 can merge without it (see Testnet compatibility pins). The two PRs touch different files and apply in either order. Together, the labs series is #25597's 0011 followed by 0012–0018 from this PR, and that combination applies cleanly to v6's labs pin ee1312cf.

Three commits:

  1. Raw pick of a36ddcc1c4c, with git's conflict markers, in the three world-state and genesis paths that sit in different places on v6 and next.
  2. fix(port):, which resolves those conflicts and regenerates the labs patches 0012–0014 against v6's labs pin.
  3. fix(port):, which adds 0018 to pin labs' testnet compatibility test to the V3 roots.

Foundation side

  • genesis_protocol_nullifiers.hpp keeps v6's bb::world_state layout and takes the new seed set. The only seed the V3 separator moves is ContractInstanceRegistry's registration nullifier, 0x2c1eb0… → 0x16f917….
  • world_state.test.cpp keeps asserting the GENESIS_* macros. On v6 those come from aztec_constants.hpp, generated from the in-tree constants.nr.
  • regenerate_genesis_constants.sh stays as v6 has it. The source change's genesis_*_root() functions (and the --check hunk for them) are there for next's wsdb package, which reads its constants from a pinned foundation release.
  • Everything else (AVM pil and C++, codegen selections, constants.nr, Prover.tomls, L1 checkpoint fixtures) picks clean.

Labs side (labs-patches)

v6's labs pin ee1312cf is 101 commits ahead of next's 54e3383c and has its own standard-contract pin, so next's 0012–0014 did not fit it. Those three patches were regenerated on a full build of this tree:

  • 0012: the separator rename and the address vectors from next, applied unchanged, plus the address tables the standard-contracts generator derives from v6's pinned artifacts under V3.
  • 0013: the migration note, with v6's V2 → V3 table.
  • 0014: noir-contracts/bootstrap.sh pin-standard-build with V3, plus the regenerated tables. The re-pin is intentional: HandshakeRegistry compiles the separator in through get_public_keys, and V3 moves these addresses regardless.
  • 0015–0017 are byte-identical to next's.
  • 0018: the testnet compatibility pins (below).
Contract V2 (v6 today) V3 (this PR)
AuthRegistry 0x2e05e8fb…f7c9 0x2ba87146…3a9c
MultiCallEntrypoint 0x09b93e8e…5137 0x265552a4…fcc2
PublicChecks 0x0468c918…dbbe 0x2cfebe97…d21a
HandshakeRegistry 0x24d2effa…0fc7 0x198aa5f2…6040

PublicChecks' V3 address matches next's exactly, because its V2 address was the same on both lines. The other three differ from next because v6's pinned artifacts differ. The re-pin also changes AuthRegistry's and MultiCallEntrypoint's bytecode: aztec-nr has moved on since v6's pin was cut, while nargo is the same build. PublicChecks' bytecode is unchanged. The pinned artifacts do not compile in the STANDARD_*_ADDRESS stamps (checked by recompiling with both stamp sets), so the pin and the address tables agree.

Testnet compatibility pins

labs/yarn-project/aztec/src/testnet_compatibility.test.ts pins the VK tree root, the protocol-contracts hash and the genesis archive root, and V3 moves all three. 0018 sets them to the values the V3 tree produces on v6, as reported by the test in CI3 run 37721289208:

Pin V2 V3
VK tree root 0x031139ab…f75d 0x13eeb174…9e02
Protocol-contracts hash 0x0030cdae…b378 0x0f54271c…54d7
Genesis archive root 0x2ef904bb…bfb6 0x29eb2c52…e5c4

Because of this, the v6 line is no longer compatible with the current testnet deployment; that is the intended effect of shipping V3 on v6.

Checks run locally

  • Built with make labs-yarn-project, plus the labs yarn-project build: no generator drift after regeneration.
  • labs-patches/bootstrap.sh check passes. The series also applies after chore: port-to-v6 rolling ports #25597's 0011.
  • Jest:
    • stdlib derivation, contract_address and complete_address (14/14)
    • noir_test_gen (6/6)
    • standard_contract_data drift (5/5)
    • contract_instance_published_event (1/1)
    • key_store (4/4)
    • PXE storage backwards compatibility (16/16)
  • Noir:
    • aztec-nr domain_separators_are_valid
    • HandshakeRegistry recipient_signature (8/8)
    • protocol types crate: constants_tests (4/4) and address::aztec_address (9/9)
  • C++: world_state_tests GetInitialTreeInfoForAllTrees.
  • regenerate_genesis_constants.sh --check: up to date. Measured from v6's own artifacts, the roots equal the constants.nr values.

Everything else is covered by CI3, which passes on 1e629c1.

The next step after this lands on v6 and a V3 rc is published: upstream 0012–0018 to aztec-node main, then bump and drain the queue as in aztec-packages#25594.

Refs #25521


Created by claudebox · group: slackbot · requested by Santiago Palladino · Slack thread

@AztecBot AztecBot added ci-draft Run CI on draft PRs. ci-no-fail-fast Sets NO_FAIL_FAST in the CI so the run is not aborted on the first failure claudebox Owned by claudebox. it can push to this PR. labels Oct 8, 2026
@IlyasRidhuan IlyasRidhuan added the ci-full Run all master checks. label Oct 8, 2026
@IlyasRidhuan
IlyasRidhuan marked this pull request as ready for review October 8, 2026 05:34
@IlyasRidhuan
IlyasRidhuan enabled auto-merge (squash) October 8, 2026 06:34
iAmMichaelConnor and others added 3 commits October 8, 2026 06:36
Raw cherry-pick of a36ddcc onto v6, committed with the conflict markers git produced. The resolution is in the following fix(port) commit.

Conflicted paths:
- barretenberg/cpp/src/barretenberg/world_state/genesis_protocol_nullifiers.hpp
- barretenberg/cpp/src/barretenberg/world_state/world_state.test.cpp
- noir-projects/fnd/scripts/regenerate_genesis_constants.sh

(cherry picked from commit a36ddcc)
…25521)

Resolves the raw pick for v6.

World state lives under barretenberg/cpp/src/barretenberg/world_state on v6
and reads the GENESIS_* macros from aztec_constants.hpp, which v6 generates
from the in-tree constants.nr. So the seed header keeps v6's bb::world_state
layout and only takes the new seed set: the ContractInstanceRegistry
registration nullifier 0x2c1eb0... becomes 0x16f917..., the one seed the V3
separator moves. The world-state test keeps asserting the GENESIS_* macros,
and regenerate_genesis_constants.sh keeps v6's version. The genesis_*_root()
functions in the source change exist only for a wsdb package that consumes a
pinned foundation release, so they are not part of the v6 tree.

labs-patches 0012-0014 are regenerated against v6's labs pin ee1312cf,
which carries its own standard-contract pin:
- 0012 applies the separator rename and the address vectors unchanged, and
  takes the address tables the standard-contracts generator derives from
  v6's pinned artifacts under V3.
- 0013 records v6's V2 -> V3 standard-contract addresses.
- 0014 re-pins the standard contracts with V3 (pin-standard-build) and
  carries the regenerated address tables:
    AuthRegistry        0x2e05e8fb... -> 0x2ba87146...
    MultiCallEntrypoint 0x09b93e8e... -> 0x265552a4...
    PublicChecks        0x0468c918... -> 0x2cfebe97...
    HandshakeRegistry   0x24d2effa... -> 0x198aa5f2...
0015-0017 apply unchanged.
Adds labs-patches/0018, which updates the three pins in labs'
testnet_compatibility.test.ts to the values the v3 contract address
separator produces on v6 (taken from CI3 run 37721289208 on c320497):

  VK tree root            0x031139ab... -> 0x13eeb174...
  protocol contracts hash 0x0030cdae... -> 0x0f54271c...
  genesis archive root    0x2ef904bb... -> 0x29eb2c52...
@AztecBot
AztecBot force-pushed the cb/port-to-v6-25521 branch from 1e629c1 to dc3e900 Compare October 8, 2026 06:37
@IlyasRidhuan
IlyasRidhuan disabled auto-merge October 8, 2026 07:20
@AztecBot AztecBot added ci-full Run all master checks. and removed ci-full Run all master checks. labels Oct 8, 2026
@IlyasRidhuan
IlyasRidhuan merged commit dd4ac21 into v6 Oct 8, 2026
12 of 14 checks passed
@IlyasRidhuan
IlyasRidhuan deleted the cb/port-to-v6-25521 branch October 8, 2026 08:06
spalladino added a commit that referenced this pull request Oct 8, 2026
Brings the v6 upgrade work onto the `v6` release line: the deploy
script, the governance payload, a simulation harness, an operator
runbook, and the pinned rollup verifier and protocol constants the
deploy script uses. 11 new files; the only existing file touched is
`l1-contracts/.gitignore`, which stops ignoring the pinned
`ConstantsGen.sol`.

Supersedes #25496, which targeted `next`. This is that branch's history
plus #25598, cherry-picked onto `v6` and squashed into one commit. `v6`
already carries the AZIP-31 stack (#25570–#25573), and
`l1-contracts/src` is byte-identical between `v6` and the base the
original commits were written against, so nothing needed adapting beyond
the reward-override reconciliation described below.

## What it does

`DeployRollupForUpgradeV6.s.sol` deploys the HonkVerifier, the Rollup
and its sub-contracts, the EscapeHatch and the `V6UpgradePayload`. Every
configuration value is a literal in `_config()`, so reviewing that one
function is sufficient to review the deployment — no env-var defaults
and no `network-defaults.json` fallbacks can change what gets deployed.
Mainnet is the literal; Sepolia is a short override list underneath it,
so the only thing to check for Sepolia is that list. A chain matching
neither reverts rather than silently deploying mainnet values.
`verify(address)` reads every value back off the deployed contracts, so
a typo in the table fails loudly rather than at the next governance
vote.

## Two things worth reviewing closely

**The rollup is constructed owned by governance, not transferred
afterwards.** The owner argument also becomes the Slasher's immutable
`GOVERNANCE`, which can execute any slash payload with no vote and no
delay. Constructing with the deploy key would hand that power to the key
permanently, because `transferOwnership` moves only the `Ownable` half.
That is why the EscapeHatch is built in the script but installed by the
payload, and why no owner-gated setup happens during deployment.

**The payload acts on the outgoing rollup before registering v6.** It
draws the reservation, forwards the earmark, retunes v5's reward split,
and only then calls `Registry.addRollup` and `GSE.addRollup` before
carrying the entry-queue flush incentive to a fresh FlushRewarder. The
distributor resolves the canonical rollup live, so once v6 is canonical
the old rollup can no longer reach the pool and a retune would be
settling a chain that has already stopped.

## No sequencer reward calculator at launch

`sequencerRewardCalculator` is set to `address(0)` on both chains, so
every proposer earns the default sequencer share. Under AZIP-31,
governance can install a calculator later via
`setSequencerRewardCalculator`, which needs no redeploy.

## The verifier and genesis roots are pinned

The rollup verifier is a function of the protocol circuits, and the
circuits this branch builds differ from the v6 release build, so a
verifier built here would reject every proof the v6 nodes produce. The
deploy script therefore deploys a pinned verifier, the same mechanism
`v5-next` uses for v5:

- `l1-contracts/script/deploy/HonkVerifier.sol` is the verifier from the
v6 release build at `42fae4eb3feb5a493f2e8a2baf78b4716e323c40` (`VK_HASH
0x1fd4eb1d14be45e05dc78c448eb4f29d7f63e4de95129c4a5e1058cd9837f8a6`),
with a provenance comment naming that commit.
`DeployRollupForUpgradeV6.s.sol` imports it as `./HonkVerifier.sol`
instead of `@generated/HonkVerifier.sol`.
- `l1-contracts/src/core/libraries/ConstantsGen.sol` is committed from
the same build.
- The three genesis roots in `_config()` come from the same build:

  | Root | Value |
  | --- | --- |
| `vkTreeRoot` |
`0x22fff5de6ce590153df4468f7f0b152188a803d91b3c9c648b91d93d5913f219` |
| `protocolContractsHash` |
`0x0f54271c52865841a77aaa66036eed901aff22fdce9f08e123ec8b205c9854d7` |
| `genesisArchiveRoot` |
`0x29eb2c527f8d45276430363214e6c8d709ef3f657a3670ebac3179373d41e5c4` |

`ConstantsGen.sol` matches what `v6` itself now generates, including the
genesis root from the contract address domain separator change (#25624),
so the existing test fixtures pass against it.

These four move together: re-pin all of them if the release build moves
to a commit that changes the protocol circuits or protocol contracts.
Because the verifier is pinned, the script deploys from a clean clone
with no circuits build; the runbook's Build section has the exact steps,
including running `forge script` rather than a whole-project `forge
build`.

The pin was exercised end to end on an isolated Sepolia network:
deployed from a clean clone of this branch, the deployed verifier's
bytecode matched the pinned file exactly and not this branch's own
build, all contracts verified on Etherscan, and the payload executed
through governance and moved all validators to v6.

## Fee asset price

`initialEthPerFeeAsset` is set to `5_934_240` on mainnet (0.0000059342
ETH per AZTEC), read from the AZTEC/ETH Uniswap v4 pool
`0xce2899b16743cfd5a954d8122d5e07f410305b1aebee39fd73d9f3b9ebf10c2f` at
mainnet block 26148995 (2026-10-08). It only sets the starting point the
fee oracle moves from. No configuration values remain outstanding.

---------

Co-authored-by: Santiago Palladino <santiago@aztec-labs.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci-draft Run CI on draft PRs. ci-full Run all master checks. ci-no-fail-fast Sets NO_FAIL_FAST in the CI so the run is not aborted on the first failure claudebox Owned by claudebox. it can push to this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants