Skip to content

test: re-derive the remaining pinned addresses for the v3 separator - #25623

Closed
AztecBot wants to merge 15 commits into
nextfrom
cb/v3-separator-stale-address-fixtures
Closed

AztecBot wants to merge 15 commits into
nextfrom
cb/v3-separator-stale-address-fixtures

Conversation

@AztecBot

@AztecBot AztecBot commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator

Into #25521. Carries @spalladino's two commits from #25622 unchanged and adds the one failure they don't cover, so merging this lands everything and closes that PR.

The pattern

Each is a test pinning an address derived from inputs the separator doesn't change, so the pin — and only the pin — moves. Four so far, in the order CI surfaced them:

labs patch what pinned a v5 address author
0015 protocol-contracts/fixtures/ContractInstancePublishedEventData.hex + its event snapshot spalladino
0016 key-store/src/key_store.test.ts inline snapshots; PXE AddressStore.json + KeyStore.json spalladino
0017 handshake_registry_contract's recipient_signature fixture claudebox

0017 — the remaining failure

RecipientSignature::verify opens by binding the returned keys to the address:

assert_eq(
    recipient,
    AztecAddress::compute(self.public_keys, self.partial_address),
    "handshake public keys do not match recipient",
);

The fixture's recipient was derived under the old separator, so seven of the eight recipient_signature tests fail on that line — every one that gets past it. interactive_signature_rejects_wrong_recipient passes, because it is the one that expects this mismatch. The schnorr signature is over [chain_id, version, registry, eph_pk_x] and never commits to the address, so only the one constant moves:

0x1b94108a…d15b → 0x1866b3a2…f2c4

Cross-check of 0016

Rather than take the new values on trust I re-derived all three from the fixtures' own fields, with an independent Poseidon2-BN254 + Grumpkin implementation built from barretenberg's parameters and self-tested against poseidon2.test.cpp::HashConsistencyCheck. The check that matters is the backwards one — recomputing with the old separator has to reproduce each pinned value exactly, which is what proves the derivation inputs are right:

pin V2 recompute V3 →
key-store snapshot reproduces 0x0a3120bd…3940 0x085dc217…a7b3 ✓ matches 0016
PXE complete_addresses[0] reproduces 0x2369ead0…ce44 0x20c1641e…493a ✓ matches 0016
PXE complete_addresses[1] reproduces 0x1fc97e4d…ba63 0x23210e69…05aa ✓ matches 0016
handshake recipient reproduces 0x1b94108a…d15b 0x1866b3a2…f2c4 (this PR)

The complete_address_index reordering in 0016 is also right: the map is keyed by the address string, and under v3 0x20c1641e… sorts before 0x23210e69…, so the num:0/num:1 values swap against the keys. For the record the serialized CompleteAddress layout is address, npk_m_hash, ivpk.x, ivpk.y, ovpk, tpk, mspk, fbpk, partial_address.

I had pushed a narrower version of the PXE fix before picking up 0016; it was wrong — it replaced only complete_addresses[0]'s address, leaving [1] stale and the index map mis-sorted. 0016 is the correct one and this branch now carries it verbatim.

Not verified locally

No test was run here. nargo is not present in this container and rebuilding it is blocked by cargo-binstall failing to reach index.crates.io (403 on api.github.com/graphql through the proxy), and the labs jest workspace needs the labs-use-local marker commit that rebuild would produce. labs-patches/bootstrap.sh check passes on all 17 patches; the rest is CI's.


Created by claudebox · group: slackbot · requested by Mike (@iAmMichaelConnor) · Slack thread

iAmMichaelConnor and others added 13 commits September 21, 2026 21:50
Every protocol version rotates the contract address domain separator so an
address can never exist on two rollup instances. v4 shipped V1 and v5 shipped
V2; next (v6) still carried V2, so v6 addresses could collide with v5 ones.

Replace DOM_SEP__CONTRACT_ADDRESS_V2 (4099338721) with
DOM_SEP__CONTRACT_ADDRESS_V3 = 993442748 = hash_to_u32("az_dom_sep",
"contract_address_v3"), as checked by constants_tests.nr, and propagate it:
the AVM address-derivation PIL and its generated relation, the C++ AVM
simulation/tracegen/constraining sources, the constants-codegen selections,
the protocol circuit test vectors and contract fixtures, and the labs consumers
(a new labs-patches entry: derivation.ts, aztec-nr's separator list, address
snapshots and the standard-contract address tables). The protocol contracts'
derived addresses move with the separator, so the genesis roots and the C++
genesis seed vector were regenerated with regenerate_genesis_constants.sh; the
six L1 checkpoint fixtures still need the --fixtures pass.
Labs patch recording, in the unversioned developer migration notes, that every contract address on v6 differs from v5 (the address domain separator is rotated per protocol version) and the standard contracts' canonical addresses old to new.
jest's inline snapshot writer mangled derivation.test.ts (a comment line was spliced into the preceding statement, breaking compilation) and dropped blank lines in contract_address.test.ts. Restore both files to their upstream content with only the three new snapshot values applied.
…parator

The protocol contracts' derived addresses move with the separator, so the genesis archive root the checkpoint fixtures start from changed. Regenerated with noir-projects/fnd/scripts/regenerate_genesis_constants.sh --fixtures; --check reports the genesis constants up to date.
Resolutions:
- constants.nr: next's GENESIS_* values, V3 rename re-applied. All three
  genesis roots still need re-measuring on this tree.
- genesis_protocol_nullifiers.hpp: now native-packages/wsdb/cpp, new
  namespace. Took next's seed vector; needs re-measuring.
- l1-contracts checkpoint fixtures: took next's; need regenerating.
- labs-patches: next upstreamed the two patches this branch renumbered;
  the separator and migration-note patches move to 0011/0012 on the tail
  of next's series.
- native-packages/wsdb/scripts/constants-codegen/cpp.json: next's second
  copy of the C++ selection list also selects the separator.
The separator patch carried the pre-bump blob id for derivation.test.ts, so
`git am --3way` needed a preimage that a --depth 1 submodule clone does not
have: apply failed on a fresh checkout. Re-exported against the gitlink, so a
straight apply works.
Measured with regenerate_genesis_constants.sh --fixtures against a build of
this tree; --check afterwards reports up to date. Exactly one of the six
protocol registration nullifiers moves with the separator: the class
nullifier of ContractInstanceRegistry, whose bytecode embeds
AztecAddress::compute. The other five, including all three instance
nullifiers (siloed by the magic addresses 1/2/3), are unchanged.

wsdb's constants selection stays on V2: native-packages/wsdb builds against
the published release in foundation.pin, whose constants.nr has no V3, and
no wsdb source reads the separator.
next added labs-patches/0011 for the Glamsterdam L1 gas constants, so the
separator and migration-note patches move to 0012/0013.
Re-run after the Glamsterdam L1 gas constants landed on next; the genesis
roots and the seed vector are unchanged by that, only the fixtures' gas
fees move. regenerate_genesis_constants.sh --check: up to date.
HandshakeRegistry reaches get_public_keys, which asserts
account == AztecAddress::compute(public_keys, partial_address), so the address
domain separator is compiled into its bytecode. Its pinned artifact has to be
refreshed with the separator or it derives v5 addresses inside a v6 tree and
rejects every account; the e2e prover run fails on exactly that assertion.

Re-pinning recompiles all four standard contracts, so MultiCallEntrypoint's
artifact hash and private functions root move too - unrelated to the
separator, and a consequence of the pinned build predating the current
toolchain. Its canonical address moves with them, and the migration note
carries both new addresses.
Written by the e2e prover dump
(AZTEC_GENERATE_TEST_DATA=1 FAKE_PROOFS=1 yarn test:e2e single-node/prover/server/full.test).
The init and inner fixtures pinned addresses derived under the old separator,
so the two circuits CI executes aborted in validate_contract_address; all
sixteen circuits in the bootstrap's circuits_to_execute list now execute.
world_state.test.cpp seeds a tree from genesis_protocol_nullifiers() and
asserts the roots it produces. Those expectations came from the GENESIS_*
macros in common/aztec_constants.hpp, which is generated from the release named
in foundation.pin rather than from this tree, so the seeds and the roots they
are compared against have different sources and disagree whenever the genesis
moves here first - which it cannot avoid doing, since the pin can only advance
to a release that already contains the new values.

regenerate_genesis_constants.sh now writes the three roots alongside the seeds
it measures them from, --check holds them to the measurement, and the test
reads them from there. constants.nr stays the protocol's source of truth.
@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 7, 2026
spalladino and others added 2 commits October 7, 2026 20:03
The last failure in 25623's run that spalladino's 0016 does not cover: seven of
the eight handshake_registry_contract recipient_signature tests fail on
verify()'s opening assert_eq(recipient, AztecAddress::compute(...)).

Independently cross-checked against 0016: recomputing both PXE AddressStore
addresses and the key-store address with the old separator reproduces each
pinned value exactly, and under v3 they give exactly the values in 0016,
including the complete_address_index reordering that follows from the new
addresses' sort order.
@AztecBot
AztecBot force-pushed the cb/v3-separator-stale-address-fixtures branch from 2f4fa81 to 8db4a1e Compare October 7, 2026 23:39
Base automatically changed from mc/bump-contract-address-domain-separator-v3 to next October 8, 2026 01:22
@AztecBot

AztecBot commented Oct 8, 2026

Copy link
Copy Markdown
Collaborator Author

Closing as redundant. Everything on this branch is on next: #25521 was squash-merged as a36ddcc1c4c carrying labs patches 0015–0017, including the handshake-registry fixture (0x1866b3a2…f2c4) that this PR added on top of @spalladino's #25622. The change is also on v6 via #25624.


Created by claudebox · group: slackbot · requested by Mike (@iAmMichaelConnor) · Slack thread

@AztecBot AztecBot closed this Oct 8, 2026
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-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