github AztecProtocol/aztec-packages v4.4.0

one hour ago

Date: 2026-06-27
Tag: v4.4.0
Base: v4.3.1
Range: v4.3.1..v4.4.0


Summary

v4.4.0 is a strongly recommended upgrade on top of v4.3.1. It contains important security fixes that harden the node against crash and sync-stall vectors, plus a new auto-shutdown feature designed to support zero-downtime rollup upgrades.

All node operators should upgrade as soon as possible.

No migration steps required.


⚠ Breaking Changes

  • ENABLE_VERSION_CHECK (CLI: --enable-version-check) has been removed and replaced with ENABLE_AUTO_SHUTDOWN (CLI: --enable-auto-shutdown). The default has also changed from true to false. If you had ENABLE_VERSION_CHECK set in your config, it will be silently ignored — remove it and set ENABLE_AUTO_SHUTDOWN=true if you want the new auto-shutdown behavior. Note that the old version checker was effectively non-functional (its node-version check never fired), so this removal has no practical impact beyond the config key change.

Security fixes

  • P2p node crash via malformed ENR (#24215, A-1255): A single discovery peer advertising a malformed TCP field in its ENR could crash any p2p-enabled node via an unhandled RangeError. This affected both regular nodes and bootnodes. The fix guards all ENR address parsing sites, drops unparseable ENRs, and adds validation in validateEnr.

  • Sync stall from zero-field public logs (#24212, A-1253): A public log with zero fields (reachable via any tx using the raw EMITPUBLICLOG AVM opcode with logSize = 0) would throw inside the archiver's addLogs transaction, aborting the entire block/checkpoint update. A single such tx in an accepted block would permanently stall L1 sync for every node. The fix indexes zero-field logs under an empty tag.

  • Sync stall from protocol contract re-publish (#24227, A-1257): If a bundled protocol contract class was published on-chain (a valid L1 operation), the archiver would throw on the pre-existing block-0 key, aborting the block store transaction and stalling L1 sync indefinitely. The fix makes protocol-preloaded entries idempotent at the store layer.

  • L2 tips cache corruption (#24237): A race condition in the archiver could cause L2 tips cache refreshes to be corrupted by concurrent writer transactions, leading to inconsistent block-stream state. The fix moves cache refreshes out of writer transactions and assembles cached tips through a single atomic snapshot.

Additionally:

  • World-state archive root guard (#24240): Backports archive-root verification in native world-state sync_block, rejecting blocks with divergent archive roots before they can corrupt local state.

Auto-shutdown for zero-downtime rollup upgrades (new, opt-in)

v4.4.0 introduces ENABLE_AUTO_SHUTDOWN (CLI: --enable-auto-shutdown), a new opt-in feature for nodes following the canonical rollup. When enabled, the node polls the on-chain rollup's protocol constants (genesis archive root, VK tree root, protocol contracts hash) every 10 minutes. If the canonical rollup becomes incompatible — e.g. after a v4 to v5 upgrade — the node soft-shuts-down its subsystems (sequencer, p2p, archiver, etc.) while leaving the HTTP health server running so liveness/readiness probes keep passing.

This is the inverse of standby mode (waitForCompatibleRollup), which blocks startup until the rollup is compatible.

Intended usage — zero-downtime upgrades:

Auto-shutdown and standby mode together enable Ethereum-style hardfork upgrades: operators install the new software ahead of time, and it automatically switches over when the protocol upgrade activates on L1 — no manual intervention required at upgrade time.

To set this up, run two containers side-by-side on different ports. Your v4 container should set ENABLE_AUTO_SHUTDOWN=true — it polls the on-chain rollup's protocol constants every 10 minutes and soft-shuts-down its subsystems when they diverge, while keeping the health server alive. Your v5 container (once available) starts in standby mode by default, blocking on startup until the new rollup is compatible. When the upgrade lands on L1, the v4 container winds down and the v5 container activates. Both containers may briefly be online at the same time depending on polling intervals, but because they follow different rollup versions they cannot equivocate.

After soft-shutdown, the process stays alive (health server only). When it eventually receives a termination signal — whether from K8s pod deletion, docker stop, systemd, or Ctrl-C — it exits with code 78 (ROLLUP_UPGRADE), so your process manager can distinguish an upgrade-driven shutdown from a crash or normal stop.

We would love feedback from operators on whether this two-container approach works for your deployment setup.

Default: false (opt-in). Only applies to nodes following the canonical rollup.


What node operators should care about

  • All node operators should upgrade to v4.4.0 as soon as possible. This release fixes remotely triggerable crash and sync-stall bugs that affect every node on the network.
  • Try auto-shutdown if you want to prepare for zero-downtime upgrades: set ENABLE_AUTO_SHUTDOWN=true on your current node and run a v5 image in standby alongside it once v5 is available.

What contract developers should care about

No contract-facing changes in this release.


What changed since v4.3.1

  • #24237 — fix(archiver): harden v4 L2 tips cache refresh
  • #24240 — fix(world-state): backport archive root guard from #24229
  • #24227 — fix(archiver): treat re-publish of preloaded protocol contracts as idempotent
  • #24215 — fix(p2p): guard ENR address parsing against malformed TCP fields (A-1255)
  • #24212 — fix(archiver): index zero-field logs under empty tag instead of throwing (A-1253)
  • #24269 — feat(node): auto-shutdown node on incompatible canonical rollup upgrade

Reference

Don't miss a new aztec-packages release

NewReleases is sending notifications on new releases.