v4.0.0 (from v3.0.0)
Overview
Migration difficulty: TODO
Breaking changes
Node.js upgraded to v24
Node.js minimum version changed from v22 to v24.12.0.
Bot fee padding configuration renamed
The bot configuration for fee padding has been renamed from "base fee" to "min fee".
v3.x:
--bot.baseFeePadding <value> ($BOT_BASE_FEE_PADDING)
v4.0.0:
--bot.minFeePadding <value> ($BOT_MIN_FEE_PADDING)
Migration: Update your configuration to use the new flag name and environment variable.
L2Tips API restructured with checkpoint information
The getL2Tips() RPC endpoint now returns a restructured response with additional checkpoint tracking.
v3.x response:
{
"latest": { "number": 100, "hash": "0x..." },
"proven": { "number": 98, "hash": "0x..." },
"finalized": { "number": 95, "hash": "0x..." }
}
v4.0.0 response:
{
"proposed": { "number": 100, "hash": "0x..." },
"checkpointed": {
"block": { "number": 99, "hash": "0x..." },
"checkpoint": { "number": 10, "hash": "0x..." }
},
"proven": {
"block": { "number": 98, "hash": "0x..." },
"checkpoint": { "number": 9, "hash": "0x..." }
},
"finalized": {
"block": { "number": 95, "hash": "0x..." },
"checkpoint": { "number": 8, "hash": "0x..." }
}
}
Migration:
- Replace
tips.latestwithtips.proposed - For
checkpointed,proven, andfinalizedtips, access block info via.block(e.g.,tips.proven.block.number)
Block gas limits reworked
The byte-based block size limit has been removed and replaced with field-based blob limits and automatic gas budget computation from L1 rollup limits.
Removed:
--maxBlockSizeInBytes <value> ($SEQ_MAX_BLOCK_SIZE_IN_BYTES)
Changed to optional (now auto-computed from L1 if not set):
--maxL2BlockGas <value> ($SEQ_MAX_L2_BLOCK_GAS)
--maxDABlockGas <value> ($SEQ_MAX_DA_BLOCK_GAS)
New (proposer):
--perBlockAllocationMultiplier <value> ($SEQ_PER_BLOCK_ALLOCATION_MULTIPLIER)
--maxTxsPerCheckpoint <value> ($SEQ_MAX_TX_PER_CHECKPOINT)
New (validator):
--validateMaxL2BlockGas <value> ($VALIDATOR_MAX_L2_BLOCK_GAS)
--validateMaxDABlockGas <value> ($VALIDATOR_MAX_DA_BLOCK_GAS)
--validateMaxTxsPerBlock <value> ($VALIDATOR_MAX_TX_PER_BLOCK)
--validateMaxTxsPerCheckpoint <value> ($VALIDATOR_MAX_TX_PER_CHECKPOINT)
Migration: Remove SEQ_MAX_BLOCK_SIZE_IN_BYTES from your configuration. Per-block L2 and DA gas budgets are now derived automatically as (checkpointLimit / maxBlocks) * multiplier, where the multiplier defaults to 2. You can still override SEQ_MAX_L2_BLOCK_GAS and SEQ_MAX_DA_BLOCK_GAS explicitly, but they will be capped at the checkpoint-level limits. Validators can now set independent per-block and per-checkpoint limits via the VALIDATOR_ env vars; when not set, only checkpoint-level protocol limits are enforced.
Setup phase allow list requires function selectors
The transaction setup phase allow list now enforces function selectors, restricting which specific functions can run during setup on whitelisted contracts. Previously, any public function on a whitelisted contract or class was permitted.
The semantics of the environment variable TX_PUBLIC_SETUP_ALLOWLIST have changed:
v3.x:
--txPublicSetupAllowList <value> ($TX_PUBLIC_SETUP_ALLOWLIST)
The variable fully replaced the hardcoded defaults. Format allowed entries without selectors: I:address, C:classId.
v4.0.0:
--txPublicSetupAllowListExtend <value> ($TX_PUBLIC_SETUP_ALLOWLIST)
The variable now extends the hardcoded defaults (which are always present). Selectors are now mandatory. An optional flags segment can be appended for additional validation:
I:address:selector[:flags]
C:classId:selector[:flags]
Where flags is a +-separated list of:
os—onlySelf: only allow calls where msg_sender == contract addressrn—rejectNullMsgSender: reject calls with a null msg_sendercl=N—calldataLength: enforce exact calldata length of N fields
Example: C:0xabc:0x1234:os+cl=4
Migration: If you were using TX_PUBLIC_SETUP_ALLOWLIST, ensure all entries include function selectors. Note the variable now adds to defaults rather than replacing them. If you were not setting this variable, no action is needed — the hardcoded defaults now include the correct selectors automatically.
Token removed from default setup allowlist
Token class-based entries (_increase_public_balance and transfer_in_public) have been removed from the default public setup allowlist. FPC-based fee payments using custom tokens no longer work out of the box.
This change was made because Token class IDs change with aztec-nr releases, making the allowlist impossible to keep up to date with new library releases. In addition, transfer_in_public requires complex additional logic to be built into the node to prevent mass transaction invalidation attacks. FPC-based fee payment with custom tokens won't work on mainnet alpha.
Migration: Node operators who need FPC support must manually add Token entries via TX_PUBLIC_SETUP_ALLOWLIST. Example:
TX_PUBLIC_SETUP_ALLOWLIST="C:<tokenClassId>:<increaseBalanceSelector>:os+cl=3,C:<tokenClassId>:<transferInPublicSelector>:cl=5"
Replace <tokenClassId> with the deployed Token contract class ID and <increaseBalanceSelector>/<transferInPublicSelector> with the respective function selectors. Keep in mind that this will only work on local network setups, since even if you as an operator add these entries, other nodes will not have them and will not pick up these transactions.
Removed features
New features
Initial ETH per fee asset configuration
A new environment variable AZTEC_INITIAL_ETH_PER_FEE_ASSET has been added to configure the initial exchange rate between ETH and the fee asset (AZTEC) at contract deployment. This value uses 1e12 precision.
Default: 10000000 (0.00001 ETH per AZTEC)
Configuration:
--initialEthPerFeeAsset <value> ($AZTEC_INITIAL_ETH_PER_FEE_ASSET)
This replaces the previous hardcoded default and allows network operators to set the starting price point for the fee asset.
reloadKeystore admin RPC endpoint
Node operators can now update validator attester keys, coinbase, and fee recipient without restarting the node by calling the new reloadKeystore admin RPC endpoint.
What is updated on reload:
- Validator attester keys (add, remove, or replace)
- Coinbase and fee recipient per validator
- Publisher-to-validator mapping
What is NOT updated (requires restart):
- L1 publisher signers
- Prover keys
- HA signer connections
New validators must use a publisher key already initialized at startup. Reload is rejected with a clear error if validation fails.
Admin API key authentication
The admin JSON-RPC endpoint now supports auto-generated API key authentication.
Behavior:
- A cryptographically secure API key is auto-generated at first startup and displayed once via stdout
- Only the SHA-256 hash is persisted to
<dataDirectory>/admin/api_key_hash - The key is reused across restarts when
--data-directoryis set - Supports both
x-api-keyandAuthorization: Bearer <key>headers - Health check endpoint (
GET /status) is excluded from auth (for k8s probes)
Configuration:
--admin-api-key-hash <hex> ($AZTEC_ADMIN_API_KEY_HASH) # Use a pre-generated SHA-256 key hash
--disable-admin-api-key ($AZTEC_DISABLE_ADMIN_API_KEY) # Disable auth entirely
--reset-admin-api-key ($AZTEC_RESET_ADMIN_API_KEY) # Force key regeneration
Helm charts: Admin API key auth is disabled by default (disableAdminApiKey: true). Set to false in production values to enable.
Migration: No action required — auth is opt-out. To enable, ensure --disable-admin-api-key is not set and note the key printed at startup.
Transaction pool error codes for RPC callers
Transaction submission via RPC now returns structured rejection codes when a transaction is rejected by the mempool:
LOW_PRIORITY_FEE— tx priority fee is too lowINSUFFICIENT_FEE_PAYER_BALANCE— fee payer doesn't have enough balanceNULLIFIER_CONFLICT— conflicting nullifier already in pool
Impact: Improved developer experience — callers can now programmatically handle specific rejection reasons.
RPC transaction replacement price bump
Transactions submitted via RPC that clash on nullifiers with existing pool transactions must now pay at least X% more in priority fee to replace them. The same bump applies when the pool is full and the incoming tx needs to evict the lowest-priority tx. P2P gossip behavior is unchanged.
Configuration:
P2P_RPC_PRICE_BUMP_PERCENTAGE=10 # default: 10 (percent)
Set to 0 to disable the percentage-based bump (still requires strictly higher fee).
Validator-specific block limits
Validators can now enforce per-block and per-checkpoint limits independently from the sequencer (proposer) limits. This allows operators to accept proposals that exceed their own proposer settings, or to reject proposals that are too large even if the proposer's limits allow them.
Configuration:
VALIDATOR_MAX_L2_BLOCK_GAS=<value> # Max L2 gas per block for validation
VALIDATOR_MAX_DA_BLOCK_GAS=<value> # Max DA gas per block for validation
VALIDATOR_MAX_TX_PER_BLOCK=<value> # Max txs per block for validation
VALIDATOR_MAX_TX_PER_CHECKPOINT=<value> # Max txs per checkpoint for validation
When not set, no per-block limit is enforced for that dimension — only checkpoint-level protocol limits apply. These do not fall back to the SEQ_ values.
Setup allow list extendable via network config
The setup phase allow list can now be extended via the network configuration JSON (txPublicSetupAllowListExtend field). This allows network operators to distribute additional allowed setup functions to all nodes without requiring code changes. The local environment variable takes precedence over the network-json value.
Changed defaults
Troubleshooting
Next steps
- How to Run a Sequencer Node - Updated setup instructions
- Advanced Keystore Usage - Keystore configuration
- Ethereum RPC Calls Reference - Infrastructure requirements
- Aztec Discord - Upgrade support