Repository navigation
v5 L1 ▕░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▏ L2 24–108s
v6 L1 ▕████████▏ L2 12–30s
A Z T E C · 6 · 0 · 0
Date: 2026-10-22 · Tag: v6.0.0 · Baseline: v5.2.0 · Major release
Install: aztec-up install 6.0.0 · Docker: azteclabs/aztec:6.0.0 (note the new Docker Hub organization)
Summary
v6 is the new Aztec rollup deployment proposed in AZUP-3. It is a major protocol upgrade, and upgrading to v6.0.0 is required for everyone. The new rollup becomes canonical on Mainnet no earlier than Monday 26 October 2026, 08:00 UTC, and Testnet upgrades at the same time.
Node operators: two breaking changes. A trace-capable L1 endpoint is now required by default, and the Docker image moved to the azteclabs Docker Hub organization. See Breaking changes for node operators.
Almost everything you pull from has moved: the Docker image is now published under azteclabs (azteclabs/aztec), the npm packages are now under @aztec-labs and @aztec-foundation, and Aztec.nr is now published from aztec-labs-eng/aztec-nr.
Breaking changes for node operators
-
A trace-capable L1 endpoint is required by default (#511).
ETHEREUM_ALLOW_NO_DEBUG_HOSTSnow defaults tofalse: the node refuses to start unlessETHEREUM_DEBUG_HOSTS(orETHEREUM_HOSTS) servesdebug_traceTransactionortrace_transaction. Without traces, a node silently stops syncing at the first checkpoint published through a non-standard contract. Set the flag totrueto accept that risk. -
The Docker image moved to the
azteclabsDocker Hub organization:azteclabs/aztec(andazteclabs/aztec-prover-agent). The image name is unchanged, butaztecprotocol/aztechas no v6 releases; a compose file still pointing at it pulls v5.- image: aztecprotocol/aztec:5.2.0 + image: azteclabs/aztec:6.0.0
When to switch on Mainnet
Option 1 (recommended): standby. Start a v6 node next to your v5 node any time before the execution date. At startup it compares the canonical rollup's genesis archive root, VK tree root and protocol contracts hash with its own. While v5 is canonical they differ, so the node enters standby: it serves only a health endpoint (which reports healthy), checks L1 once a minute, and uses very few resources. When the v6 rollup becomes canonical it logs Compatible rollup found and starts normally, with nothing for you to do.
- Run it on a separate host, or give it its own container name,
AZTEC_PORTandP2P_PORT. Standby binds the HTTP port as soon as it starts, and the node binds the P2P port when it leaves standby, so reusing the v5 values makes it fail. - Use a new, empty data directory.
- Leave
ROLLUP_VERSIONunset so the node follows the canonical rollup. Pinning it to the v6 rollup's version makes the node fail at startup, because that version is not in the registry until the proposal executes. - Keep your v5 node running until the v6 node has left standby and is attesting.
Option 2: upgrade at execution time. Stop the v5 node and start v6 on Monday 26 October 2026 at 08:00 UTC, or as soon after as the proposal executes. Your sequencer is idle until the v6 node has started and synced. Slashing is disabled for the first 8,400 slots (about 7 days) after the v6 rollup becomes canonical, so the slots you miss while starting up cost you rewards but do not get you slashed.
High-availability signing on a shared PostgreSQL database: v5 nodes delete other rollups' signing records when they start (#352 fixes this in v6 only). Give your v6 replicas their own database, or do not restart v5 replicas after the switch, so the v6 replicas keep their double-signing protection.
Full operator migration guide: v6.0.0 operator changelog.
Breaking changes
Everything below applies to every project moving from v5.2.0.
Where things live
-
[Docker]The image moved to theazteclabsDocker Hub organization:azteclabs/aztec(andazteclabs/aztec-prover-agent).aztecprotocol/aztechas no v6 releases; a compose file still pointing at it pulls v5.- image: aztecprotocol/aztec:5.2.0 + image: azteclabs/aztec:6.0.0
-
[npm]Packages moved to@aztec-labs(#93), and the foundation packages (bb.js, thenoir-*packages,l1-artifacts, and others) to@aztec-foundation(#113). Subpaths are unchanged beyond the scope. The@aztecscope keeps everything already published, so v5 projects keep installing.-import { Contract } from '@aztec/aztec.js'; +import { Contract } from '@aztec-labs/aztec.js';
-
[npm]The packages depend on upstreamviem, not the@aztec/viemfork (#304). If you aliasedviemto the fork, depend on upstreamviemat the version@aztec-labs/aztec.jsuses. -
[Aztec.nr]Aztec.nr is published fromaztec-labs-eng/aztec-nr.AztecProtocol/aztec-nrhas no v6 tags, so bumping onlytagfails withRemote branch v6.x.x not found. Updategitas well (#135):-aztec = { git = "https://github.com/AztecProtocol/aztec-nr", tag = "v5.2.0", directory = "aztec" } +aztec = { git = "https://github.com/aztec-labs-eng/aztec-nr", tag = "v6.0.0", directory = "aztec" }
-
[Aztec.nr]The ECDSA note and the protocol contract interfaces ship with aztec-nr (#404). Depend on them fromaztec-labs-eng/aztec-nrat the same tag asaztec. Pulling them from the old repositories brings in a second copy ofaztecand fails withNo matching impl found.
Protocol: every address changes, every contract recompiles
- The contract address domain separator is bumped to V3, so every contract address, account addresses included, differs from v5 for the same class, salt, initialization and keys. This is deliberate: an address can never be live on two rollups at once. Anything that hard-codes an address must be updated. Protocol contracts keep their magic addresses (
1,2, ...). - Block headers commit to a per-block tx effects tree (#123). A block header alone now proves a transaction's inclusion and exact effects with a short membership proof. Every transaction hash, verification key, contract artifact and canonical address changes with it.
- The protocol nullifier is derived from the tx request's salt alone (#310). Two transactions with the same origin and salt (a fee bump or a cancellation) are mutually exclusive: at most one is mined.
tx_request_saltin the private context becomesprotocol_nullifier. Wallets must draw a fresh salt for every transaction. Contracts need only a recompile. - The standard contracts are at new addresses.
MultiCallEntrypoint,HandshakeRegistry,AuthRegistryandPublicChecksare all re-pinned. Handshakes made with the v5 registry must be re-established. - The PXE oracle interface is now version 33. Contracts must be recompiled against Aztec.nr v6.0.0 to run against a v6 PXE.
Aztec.nr
-
Fact collections are scoped by
FactScopeinstead of anAztecAddress(#426).FactScope::account(address)is the old behaviour; the newFactScope::public()is shared by all accounts.- record_retractable_fact(contract_address, recipient, type_id, collection_id, fact_type_id, payload, origin_block); + record_retractable_fact(contract_address, FactScope::account(recipient), type_id, collection_id, fact_type_id, payload, origin_block);
-
OriginBlockis replaced byaztec::oracle::block_reference::BlockReference, with the same fields (#157). -
Nullifier existence checks are batched:
get_nullifier_statuseschecks any number of nullifiers in one oracle call and reports each one's inclusion block.check_nullifier_existsstill works (#157). -
Writer::advance_offsetis removed. Serialize the skipped fields instead (#387). -
DelayedPublicMutablerejects delays below one hour, at compile time for the initial delay and at runtime inschedule_delay_change(#99). -
Nine
DOM_SEP__*constants left the protocol constants module.DOM_SEP__PARTIAL_NOTE_COMMITMENTandDOM_SEP__NOTE_COMPLETION_LOG_TAGmove toaztec::note::partial_note; the other seven are now internal. Custom account entrypoints should callcompute_tx_nullifierinstead of hashingDOM_SEP__TX_NULLIFIERthemselves (AztecProtocol/aztec-packages#25014).
Aztec.js
-
Protocol contract wrappers moved to
@aztec-labs/aztec.js/protocoland out of@aztec-labs/noir-contracts.js. They are bound to their canonical address, so they attach withwithWallet(wallet).at(wallet)still works but is deprecated (AztecProtocol/aztec-packages#24998).- import { FeeJuiceContract } from '@aztec/noir-contracts.js/FeeJuice'; + import { FeeJuiceContract } from '@aztec-labs/aztec.js/protocol'; - const feeJuice = FeeJuiceContract.at(ProtocolContractAddress.FeeJuice, wallet); + const feeJuice = FeeJuiceContract.withWallet(wallet);
-
A function's return type is a single
returnType, not areturnTypeslist.decodeFromAbitakes one type; usedecodeEachFromAbifor lists (AztecProtocol/aztec-packages#25066). -
Artifacts keep the names of
#[abi(tag)]globals, readable withgetGlobalsByTag. Artifacts compiled before this are rejected and must be recompiled (AztecProtocol/aztec-packages#25184). -
GasPriceis renamedFeesPerGasin@aztec-labs/ethereum/l1-tx-utils, with matching method and field renames (getGasPrice()→getFeesPerGas()) (AztecProtocol/aztec-packages#25152).
Node API
getBlockHashMembershipWitnessrequires a reference block the node has. v5 accepted a block number one past the tip; v6 does not. To prove against a specific archive root, including a block's own post-block archive, use the newgetBlockHashMembershipWitnessAtArchive({ archive }, blockHash)(#334).
CLI
- Removed
aztec bridge-erc20. UseL1ToL2TokenPortalManagerfrom@aztec-labs/aztec.js/ethereum. Fee juice bridging withaztec-wallet bridge-fee-juiceis unchanged (#52). - Removed
get-canonical-sponsored-fpc-address.aztec-walletnow aliases it ascontracts:SponsoredFPC(#49). - Removed
inspect-contract,compute-selector,generate-secret-and-hash,parse-parameter-structandexample-contracts. Their aztec.js equivalents are listed in the migration notes (#36).
Node operators
-
ACVM_*is renamedNOIR_EXECUTE_*, with no fallback (#116). A prover agent exits withRequested real proving but no path to bb or noir-execute binaries provided; a node not doing real proofs starts anyway but falls back to much slower WASM simulation.- ACVM_BINARY_PATH=/usr/src/labs-aztec-toolchain/bin/noir-execute - ACVM_WORKING_DIRECTORY=/usr/src/acvm + NOIR_EXECUTE_BINARY_PATH=/usr/src/labs-aztec-toolchain/bin/noir-execute + NOIR_EXECUTE_WORKING_DIRECTORY=/usr/src/noir-execute
The same rename applies to the
--sequencer.*and--proverNode.*flags. The release image sets the new variables itself.
For node operators
Attester-initiated sequencer exits (#215)
A position can now be exited by its attester, not only its withdrawer, and exits can be batched: each attester signs an authorization offline, and one relayer submits them all in one transaction. This is built for staking providers, who hold the attester keys for many delegations but not the withdrawer keys.
# 1. Each attester signs an exit authorization (offline), appended to one file
aztec sign-attester-exit --private-key $ATTESTER_KEY --attester $ATTESTER \
--rollup $ROLLUP --l1-chain-id $L1_CHAIN_ID --deadline $DEADLINE \
--output exits.json --append
# 2. Simulate, then submit from any funded key
aztec initiate-withdraw-by-attester-batch --dry-run --authorizations exits.json \
--rollup $ROLLUP --l1-chain-id $L1_CHAIN_ID --l1-rpc-urls $L1_RPC
aztec initiate-withdraw-by-attester-batch --authorizations exits.json \
--rollup $ROLLUP --l1-chain-id $L1_CHAIN_ID --l1-rpc-urls $L1_RPC \
--private-key $RELAYER_KEY
# 3. The withdrawer names the recipient (does not restart the delay)
aztec remove-l1-validator --validator $ATTESTER --recipient $RECIPIENT \
--rollup $ROLLUP --l1-rpc-urls $L1_RPC --l1-chain-id $L1_CHAIN_ID \
--private-key $WITHDRAWER_KEY
# 4. After the delay, anyone finalizes
cast send $ROLLUP "finalizeWithdraw(address)" $ATTESTER --private-key $ANY_KEY --rpc-url $L1_RPCWhat to know:
- The stake always goes to the withdrawer's chosen recipient, never to the attester. If you are a provider exiting delegated positions, your delegators must do step 3.
- Timing. On Mainnet the stake is claimable about 9.6 days after the exit starts: the rollup's 4-day exit delay and the 9.6-day governance withdrawal delay both have to pass.
- Rate limit. At most
floor((N - 1) / 20)attester-initiated exits (about 5% of the set) per rolling 9.6-day window, never taking the set below the 48-seat committee. Withdrawer exits are not limited. Check the current state withgetAttesterExitLimitState(). - Batches. By default a batch is all or nothing against the rate limit;
--up-to-limitprocesses as many as fit and leaves the rest for later. Either way, one invalid entry (expired deadline, bad signature, already exiting) reverts the whole transaction, so always--dry-runfirst. - Only on the canonical rollup. On Mainnet, attester exits work on v6 once the upgrade executes, not on v5. Until then, pass the v6 rollup to
sign-attester-exitwith--rollupexplicitly. aztec initiate-withdraw-by-attesterexits one position in a transaction sent from the attester key.aztec remove-l1-validatorandaztec sequencers removenow require--recipient(#520). Both used to make the attester's own address the recipient, which sent the stake to the hot attester key (or, for delegated stake, to the provider) and could not be changed afterwards.remove-l1-validator --recipient, run by the withdrawer, is also how you name the recipient after an attester-initiated exit.
Full guide: Exiting a sequencer.
Publishers and L1
- Nodes check that a publisher can afford its L1 transaction before doing the work (#443). A sequencer with no funded publisher skips the slot before building anything; a prover finishes the proof but holds it back, retrying every 12 seconds until a publisher is funded or the submission window closes. A dust-funded idle publisher can no longer win every proposal.
- Publisher balances are checked every minute, for every publisher (#465, #466). The node logs which publisher to fund and how much ETH it is missing. New metrics
aztec_l1_publisher_sends_affordable,aztec_l1_publisher_required_balance_ethandaztec_l1_publisher_funder_balance_eth;aztec_l1_publisher_balance_ethis now always recorded, andaztec_l1_balance_ethis deprecated. Alert onaztec_l1_publisher_sends_affordable < 1. - A clear error and metric when the L1 RPC cannot trace a propose transaction (#509).
- Proof submissions that run out of gas are resent (#491), and very early epoch proofs are resubmitted correctly (#397).
BLS keys and staking
- The upgrade raises the GSE's proof-of-possession gas cap from 250k to 300k. Since Osaka's modexp repricing, about 1 in 28,600 honestly generated BLS keys needed more than 250k gas to verify, and their deposits were refunded and dropped from the entry queue. At 300k that is about 1 in 2.5 million. The GSE is shared, so this also applies to v5 from the moment the upgrade executes.
aztec validator-keysand the staker output now check BLS keys against the live cap, so you find an expensive key before depositing it (#396, #507).
Provers
- New:
PROVER_NODE_DISABLE_FULL_EPOCH_PROVING(#436). Whentrue, the prover node stops proving complete epochs on its own and proves only the partial epochs requested through itsstartProofadmin method. Use it to serve paid partial-epoch proofs (for example, for early withdrawals) without competing for full epoch proofs. Defaultfalse. - Fault recovery. A dead batch verifier is rebuilt (#359, #354), prover agents report preemption (#475) and finish their proof on shutdown (#300), and per-block L1-to-L2 messages are capped when slicing checkpoints (#390).
Operations
- Change the log level without a restart (#497).
aztecAdmin_setConfigaccepts alogLevelin theLOG_LEVELformat (e.g."debug;trace:sequencer,p2p"), andaztecAdmin_getConfigreports it. A restart reverts toLOG_LEVEL. - The node exits when its world state database process dies, instead of running on without it, including on an idle node at genesis (#449, #460).
- HA signing keeps each rollup's signing history across restarts of replicas serving other rollups, with a 24-hour default retention set by
VALIDATOR_HA_OLD_DUTIES_MAX_AGE_H(#352). See the warning under When to switch on Mainnet. - New node RPC methods:
aztec_getTxEffectMembershipWitnessandaztec_getValidatorStatsBatch.
For wallet / PXE developers
- Draw a fresh salt for every transaction. Transactions with the same origin and salt now share a protocol nullifier, so at most one is mined. This is what makes fee bumps and cancellations possible, and it means a reused salt silently drops a transaction (#310).
- PXE databases re-initialize on first open (data schema bump), and the PXE requires contracts built against oracle interface version 33.
- Tx inclusion proofs from a block header.
TxEffect.computeTxEffectLeaf(),Body.computeTxEffectsTreeRoot()and the node'saztec_getTxEffectMembershipWitnessprove that a transaction was included in a block with exactly a given set of effects (#123). - Browser-facing packages no longer import Node.js-specific modules (#444).
Security & correctness
Most of this is in how the node treats input from peers and from L1.
- p2p: gossip messages with trailing bytes are rejected (#236); tx req/resp requests are de-duplicated, capped and bounded (#201, #202, #379); public calldata and contract class log validation are tighter (#510); a tx whose proof was evicted is dropped rather than served without it (#375); and peers are no longer penalized for conditions that are local to the receiver (#143, #235, #316, #477).
- Archiver: checkpoints that repeat a tx hash are rejected (#338); a rolled-back checkpoint range re-syncs at the same L1 head (#381); a failed batch restores the L1 sync point (#336); and a checkpoint accepted earlier in the same batch is a valid parent (#503).
- Slashing accuracy: checkpoint proposals with a forged
lastArchiveRootare slashable (#339); proposals rejected only because of a reorg during validation are not (#315); equivocation is slashed only when one key signed both checkpoints (#493); and a committee is served only once its seed is fixed on L1 (#500).
New in this release
- Attester-initiated, batched sequencer exits. See For node operators.
- Public fact collections.
FactScope::public()lets any execution of a contract read and write a collection, whichever accounts are in scope (#426). - Deployment framework: universal deploys (#16) and deployment transactions paid through a payment method you supply (#455).
getBlockHashMembershipWitnessAtArchiveproves block membership against any archive root the node knows (#334).
Protocol constants
New in v6. The Mainnet v6 rollup (0xE37A2663Cc9c119BA41572C40fAb0bbb23a5402f, rollup version 2070860440) was deployed with:
vk root 0x22fff5de6ce590153df4468f7f0b152188a803d91b3c9c648b91d93d5913f219
protocol contracts 0x0f54271c52865841a77aaa66036eed901aff22fdce9f08e123ec8b205c9854d7
genesis archive root 0x29eb2c527f8d45276430363214e6c8d709ef3f657a3670ebac3179373d41e5c4
A v6.0.0 node starts only when the canonical rollup carries exactly these values, which is what makes standby mode safe: it cannot attach to the wrong rollup. The new Testnet rollup uses the same circuits.
Reference
- v6.0.0 operator changelog: the full node operator migration guide.
- Exiting a sequencer: attester- and withdrawer-initiated exits.
- Migration notes: per-change migration reference for contract and wallet developers, with full diffs.
- v5.2.0 release notes: this release's baseline.
- Networks: v6 contract addresses for Mainnet and Testnet.