Alpha Upgrade for node operators (v4 from v2)

Now that the governance vote for Alpha is likely to pass, we want to make sure you’re aware of the changes in the v4 client and Alpha in general.

Headline changes

  • Double Signing Slashing: new slashing offenses for duplicate proposals and attestations (penalties currently disabled)
  • Increased L1 Gas Usage: heavier checkpoints and more blobs increase L1 costs
  • Blobs: transaction data is now published via EIP-4844 blobs (up to 6 per checkpoint)
  • Multiple Blocks Per Slot: the sequencer now builds multiple L2 blocks per slot, grouped into checkpoints

How rollup upgrades work

Aztec network upgrades are rollup cutovers: a new rollup instance is deployed with fresh state, new circuits, and new block validation rules, then registered as canonical through a governance vote. The old rollup is not forked. It remains accessible so users can bridge assets out, but all active operators are expected to cut over to the new rollup. Sequencers who registered with moveWithLatestRollup = true have their stake automatically migrated.

Alpha is the first rollup cutover. The governance vote is expected to pass, and the execution delay ends on Monday March 30th at roughly 2:30 AM UTC. After that point, anyone can call execute() on the Governance contract to make the new rollup canonical.

The Alpha payload executes six actions in a single governance execution:

  1. Register a new rollup in the Registry (making it canonical)
  2. Register the new rollup in the GSE (so stake-following sequencers auto-migrate)
  3. Enable rewards claiming on the new rollup
  4. Update the escape hatch to a new contract
  5. Migrate rewards from the old FlushRewarder to the new one
  6. Increase the governance executionDelay to 30 days for future upgrades

The old rollup remains accessible. Users can always bridge assets out of historical rollup instances.

Impact of the increased execution delay on staker withdrawals

The governance executionDelay feeds into the withdrawal delay formula used by the Governance contract: votingDelay/5 + votingDuration + executionDelay. When a staker withdraws from the GSE, the withdrawal goes through this same Governance delay. Increasing executionDelay from 7 days to 30 days increases the withdrawal period from roughly 15 days to 38 days (calculated as 3d/5 + 7d + 30d).

Standby mode for rollup upgrades

v4 introduces standby mode. You can start your v4 node before the governance vote executes, even while the old rollup is still canonical. On startup, the node checks its local genesis archive root, verification key tree root, and protocol contracts hash against the canonical rollup. If any of these don’t match, the node enters standby: it starts a lightweight HTTP server for K8s liveness probes and polls every 10 minutes for a compatible rollup. Once a compatible rollup becomes canonical, the node exits standby and starts normally.

This means you can deploy your v4 nodes ahead of time and have them start participating automatically once execute() is called.

After your v4 node is running, you should shut down your v2 node. Sequencers who have moveWithLatestRollup = false can choose to keep the old rollup alive by continuing to run their v2 node.

For full details on governance, see the Governance Participation Guide.

Upgrade timeline and slashing protection

How quickly do you need to upgrade? There are several layers of protection:

  • The new rollup’s slashing has a built-in execution delay of 28 rounds (~3 days). Even if inactivity is observed immediately on the new rollup, no slash can actually execute for about 3 days.
  • The slashing grace period on mainnet is 8,400 L2 slots (~7 days). This is how long the slasher waits before considering an offense actionable.

In practice, the grace period gives you roughly 7 days after the upgrade executes before inactivity slashing becomes a concern. However, the new rollup needs a quorum of sequencers to start producing blocks. The more sequencers that are online when execute() is called, the faster the network comes up.

If you have moveWithLatestRollup = true (the default), you should either start a separate v4 node in standby mode before March 30th, or upgrade your existing node to v4 as soon as possible after the upgrade executes.


Action required

These items require you to take specific steps before or during the upgrade.

Upgrade your node software to v4

Your v4 node can be started before the upgrade executes thanks to standby mode (see above). By default, all sequencers were registered with moveWithLatestRollup = true, which means your stake auto-migrates to the new rollup. If you explicitly set it to false, you must manually exit and re-enter on the new rollup.

Capture your admin API key

The admin RPC endpoint (port 8880) now requires API key authentication by default. On first start, a random key is generated and printed to stdout once. It is never shown again. Only the SHA-256 hash is persisted.

All admin API calls require an x-api-key: <key> or Authorization: Bearer <key> header. Any automation or monitoring scripts that call admin endpoints will get 401 errors unless updated.

If you miss the key in the startup logs, use AZTEC_RESET_ADMIN_API_KEY=true to regenerate it on the next restart.

AZTEC_ADMIN_API_KEY_HASH=<sha256-hex>    # Pre-configure a known key hash
AZTEC_DISABLE_ADMIN_API_KEY=true         # Disable auth entirely (not recommended)

The /status health check endpoint is exempt from auth, so K8s liveness probes still work.

Set up HA signing if you run redundant sequencer nodes

If you run redundant sequencer nodes for the same key, you must use the new HA signing system. Without it, your redundant nodes will produce duplicate proposals and attestations, which are now slashable offenses.

The HA signer uses PostgreSQL as a distributed lock. For each signing duty (proposal, attestation, governance vote, slashing vote), only the first node to acquire the lock signs. All other nodes skip the duty. The system is fail-closed: if PostgreSQL is unreachable, no node signs anything. There is no risk of double-signing, but you will miss duties until the DB recovers.

VALIDATOR_HA_SIGNING_ENABLED=true
VALIDATOR_HA_DATABASE_URL=postgresql://user:pass@host:port/db
VALIDATOR_HA_NODE_ID=<must-be-unique-per-node>
VALIDATOR_HA_SIGNING_TIMEOUT_MS=3000     # How long losers wait before giving up
VALIDATOR_HA_POLLING_INTERVAL_MS=100     # Poll interval while waiting

Before starting any HA nodes, run the database migration:

aztec migrate-ha-db up --database-url postgresql://user:pass@host:port/db

Failure modes to be aware of:

  • PostgreSQL outage = sequencer stops signing entirely. Plan for DB high availability if you need uptime.
  • Duplicate VALIDATOR_HA_NODE_ID across nodes can cause one node’s cleanup to delete another’s in-progress duties. Each node must have a unique ID.
  • Stuck duties from crashes. If a node crashes mid-sign, the duty row stays locked until the cleanup task runs (default: 2x slot duration). The duty for that slot may be missed.

The HA signer integrates with Web3Signer for remote key management. The architecture is: Sequencer Node → HAKeyStore (PostgreSQL lock) → Web3SignerKeyStore (HTTP signing) → Web3Signer.

Update renamed sequencer environment variables

Several sequencer config variables have been renamed or removed. If you set any of these explicitly, update them:

Old (v2.1.11) New (v4)
SEQ_TX_POLLING_INTERVAL_MS SEQ_POLLING_INTERVAL_MS
SEQ_MAX_TX_PER_BLOCK SEQ_MAX_TX_PER_CHECKPOINT
SEQ_MAX_L1_TX_INCLUSION_TIME_INTO_SLOT SEQ_L1_PUBLISHING_TIME_ALLOWANCE_IN_SLOT
SEQ_MAX_BLOCK_SIZE_IN_BYTES Removed

Run your consensus client as a supernode or semi-supernode

We recommend running your Ethereum consensus client (beacon node) as a supernode or semi-supernode (if your client supports it). After PeerDAS (Fusaka), a regular beacon node only downloads 8 of 128 erasure-coded columns and cannot reconstruct complete blob data. Since Aztec relies on blobs for all transaction data, having full blob availability from your own infrastructure is important.

L1_CONSENSUS_HOST_URLS=<beacon node URLs>

Blob file stores should be seen as a backup, not a primary source. If you use the default blob storage provided by the network config (via --network), blob file store URLs are auto-configured as a fallback. But your primary blob source should be your own consensus client running as a supernode or semi-supernode.

If you want to configure additional backup blob storage:

BLOB_FILE_STORE_URLS=<comma-separated read URLs>    # GCS, S3, R2, HTTPS, file://
BLOB_FILE_STORE_UPLOAD_URL=<upload URL>
BLOB_ARCHIVE_API_URL=<archive API>                   # e.g., Blobscan for historical blobs

Awareness (no action required)

These are changes in behavior you should be aware of, but they do not require configuration changes.

Double signing slashing

Two new slashing offense types detect equivocation:

  • Duplicate proposal slashing: if a sequencer sends multiple proposals for the same position with different content, it is detected and reported.
  • Duplicate attestation slashing: if a sequencer signs attestations for different proposals at the same slot, it is detected and propagated across the P2P network.

Both offenses follow the existing tally-based voting flow. Offenses are detected at the P2P layer, block proposers encode slash votes into their checkpoint, and sequencers reaching quorum are slashed.

Penalties for these two new offenses are currently set to 0 on mainnet. The detection infrastructure is active and offenses are tracked, but no stake is slashed for these offenses yet. The existing inactivity and invalid block penalties remain active at 2000e18 each.

For the full list of slashing configuration options, see the Slashing Configuration Guide.

Increased L1 gas usage

Each checkpoint can use up to 6 EIP-4844 blobs. The L1 cost per checkpoint is calculated as:

ethUsed = (300,000 * baseFee) + (3 * 131,072 * blobFee)

Where 300,000 is the calldata gas for the propose transaction, 3 is the number of blobs used for fee calculation, and 131,072 is the blob gas per blob (EIP-4844).

Gas model changes:

Parameter v2.1.11 v4
DA gas per byte 16 1
Fixed DA gas n/a 512
L2 gas per note hash 2,700 9,200
L2 gas per nullifier 16,000 16,000 (unchanged)

L1 gas configuration for operators:

L1_GAS_LIMIT_BUFFER_PERCENTAGE=20        # Extra headroom on gas estimates
L1_GAS_PRICE_MAX=2000000000000           # Max gas price (2000 gwei)
L1_BLOB_FEE_PER_GAS_MAX=3000000000000   # Max blob fee (3000 gwei)
L1_TX_MONITOR_TX_TIMEOUT_MS=120000       # Tx timeout before cancellation
L1_TX_MONITOR_CANCEL_TX_ON_TIMEOUT=true  # Auto-cancel on timeout

A new blob-aware priority fee strategy analyzes blob transactions in the mempool to set competitive priority fees, since blob transactions compete in a separate fee market.

L2 gas (mana) changes

The rollup now uses an EIP-4844-style congestion pricing mechanism for L2 gas (mana). When mana usage exceeds the target (AZTEC_MANA_TARGET), the congestion multiplier increases exponentially. This affects the minimum fee charged to users and the cost economics for sequencers.

Transactions exceeding the rollup mana limit are now rejected at the entry point (gossip, RPC, pending pool) rather than being silently dropped during block building.

Blobs

Transaction data is now published entirely via EIP-4844 blobs. There is no calldata fallback. All block effect data goes through blobs. Calldata is only used for the propose function arguments (header, attestations, blob commitments).

Blobs are pruned from Ethereum after roughly 18 days. For historical blob access, you need dedicated blob storage or an archive API. See the action required section above for configuration.

Multiple blocks per slot (checkpoints)

This is the most significant architectural change. Previously, the sequencer produced one block per slot submitted directly to L1. Now:

  • The sequencer builds multiple L2 blocks per slot, grouped into a checkpoint.
  • The checkpoint is the unit that gets proposed, attested, and published to L1.
  • Checkpoints are grouped into epochs for proving.
  • Maximum 32 checkpoints per epoch.

All monitoring and tooling that references “blocks” in the context of L1 submissions should now reference “checkpoints.” The getL2Tips() API response now includes checkpoint information alongside block information.

New sequencer environment variables:

SEQ_MAX_TX_PER_CHECKPOINT=<value>             # Max txs across all blocks in a checkpoint
SEQ_BLOCK_DURATION_MS=<value>                 # Duration target per block within a slot
SEQ_BUILD_CHECKPOINT_IF_EMPTY=<true|false>    # Build checkpoint even with no txs
SEQ_L1_PUBLISHING_TIME_ALLOWANCE_IN_SLOT=<value>  # L1 publishing time budget

Sequencers can now set their own limits for accepting proposals:

VALIDATOR_MAX_L2_BLOCK_GAS=<value>
VALIDATOR_MAX_DA_BLOCK_GAS=<value>
VALIDATOR_MAX_TX_PER_BLOCK=<value>
VALIDATOR_MAX_TX_PER_CHECKPOINT=<value>

Prover node is now a subsystem of the Aztec node

The prover no longer runs as a standalone process with its own archiver, P2P, and world-state. Instead, it runs as a subsystem within the regular Aztec node process. Start it with --prover-node alongside --node.

Keystore hot reload

A new reloadKeystore admin RPC endpoint allows adding, removing, or rotating sequencer keys without restarting the node. This enables:

  • Adding sequencers on the fly: drop a new keystore JSON file into KEY_STORE_DIRECTORY and call reloadKeystore.
  • Removing sequencers gracefully: remove the key from the keystore file and reload. The sequencer stops signing immediately.
  • Key rotation: replace an attester private key and reload. The old key is discarded in memory.
  • Kubernetes automation: mount keystore ConfigMaps/Secrets and trigger reloads via the admin API.

Constraints to be aware of:

  • You must use file-based keystore mode (KEY_STORE_DIRECTORY). The reload does not work with VALIDATOR_PRIVATE_KEY env var mode.
  • Publisher (L1 gas-paying) keys cannot be hot-reloaded. New sequencers must use a publisher key that was already configured at node startup. If you need a new publisher key, you must restart.
  • If any remote signer is temporarily unreachable, the entire reload fails (all-or-nothing). The old keystore stays in effect.

Escape hatch

A new fallback mechanism allows block production to continue when the sequencer committee cannot produce blocks. During escape hatch windows, normal sequencers stop producing blocks and do not attest. This is expected behavior, not a bug. Slashing is automatically disabled during escape hatch periods.

Standby mode can look healthy while doing nothing

When the node enters standby mode (genesis root mismatch), it serves HTTP 200 on /status but does not process blocks or participate in consensus. If you rely on liveness probes for monitoring, make sure you also monitor actual block production metrics.

Peer scoring is now aggressive

v4 implements comprehensive gossipsub peer scoring. Nodes with clock skew, wrong software versions, or poor connectivity will be pruned from gossip meshes faster than before. Previously, even banned peers could still receive gossip due to overly lax thresholds. This is no longer the case.

Web3Signer support

Full support for remote signing via Web3Signer. Private keys stay entirely off the sequencer nodes.

WEB3_SIGNER_URL=<url>
VALIDATOR_ADDRESSES=<comma-separated addresses>

Network config endpoint

Nodes can now read contract addresses and network parameters from a centralized config endpoint rather than requiring all addresses as environment variables:

USE_NETWORK_CONFIG=true

Testnet already runs with these changes. You can use it to test your setup ahead of Alpha going live on mainnet.

The exact v4 release version will be announced soon. The docs website will also be updated with more detailed documentation for all of these changes soon. In the meantime, if you have questions or need help with the upgrade, join the Aztec Discord or reply to this forum post.

3 Likes