Skip to content

chore(release): v5.0.1 - #24737

Merged
PhilWindle merged 42 commits into
v5from
release/v5.0.1
Jul 15, 2026
Merged

chore(release): v5.0.1#24737
PhilWindle merged 42 commits into
v5from
release/v5.0.1

Conversation

@aminsammara

Copy link
Copy Markdown
Contributor

Merges the current v5-next tree (c11bc68) back into v5 and bumps the release-please manifest to 5.0.1 to cut the v5.0.1 patch release.

  • .release-please-manifest.json: 5.0.05.0.1
  • Brings all commits on v5-next since v5.0.0 onto v5 (companion change: v5-next manifest bumped to 5.1.0 in ee3716277a).

Merge strategy: this is a release-branch sync — merge so v5 remains a true superset of the history (merge commit or fast-forward). A squash merge would collapse the whole tree into a single commit and rewrite the SHAs, so avoid it here.

Tagging v5.0.1 on the resulting release commit is a follow-up step.

mverzilli and others added 30 commits July 10, 2026 09:33
Adds a new `getTxEffects` oracle to fetch tx effects in batch.
)

Changes store management so that changes in rollup addresses and schema
versions cause different stores to be used. Previously we only supported
one store to be present at a time, which meant any version or rollup
change wiped pre-existing stores (note this includes network changes).

An underlying design decision in this PR is to strip the kv-store
package from responsibility over location on disk, knowledge about
rollup addresses, etc, at least as as regards PXE and wallet storage.
Other users of LMDB-v2 should not be impacted by this change.

In consonance, IndexedDB and SQLite backends drop their `createStore`
functions, which shoehorned wallet and PXE store creation to an
homogeneous interface that made it hard to let them independently
evolve.

Since we're changing this, I decided to also include the chain id as a
component of the store id, in addition to the already present schema
version and rollup address. It's not clear that we'll ever work on a
testnet or a different L1, but doing so is trivial and removes the need
to deal with this in the future.

Closes F-809
The fee payer should only be set in the non-revertible phase, but we
were not asserting this.
Fixes a flake on the SQLite db management browser tests.
BEGIN_COMMIT_OVERRIDE
feat: getTxEffects oracle (#24636)
feat: preserve stores on schema version or rollup address change
(#24631)
feat: assert non revertible phase when setting fee payer (#24479)
fix: release OPFS handles before sqlite worker close/delete ack (#24647)
END_COMMIT_OVERRIDE
…down (#24579)

v5 version of #24562 (based on `merge-train/spartan-v5`). Stacked on
#24578 — review/merge that first.

Note: this is a fresh implementation, not a port — the v5 prover-node
architecture differs from `next` (it uses `EpochSession` / `TopTreeJob`
rather than `EpochProvingJob` / `ProvingOrchestrator`), which is the
structure actually running on testnet.

## Problem

On a clean shutdown, `SessionManager.stop()` cancels every live session
with reason `'prover-node stopping'`. That flows `EpochSession.cancel` →
`TopTreeJob.cancel()` → `topTree.cancel({ abortJobs: true })` — the
`abortJobs: true` was **hardcoded**, so a deploy/restart aborted the
in-flight top-tree broker jobs. Aborting on a clean restart is wasteful:
the proofs are still valid, agents are mid-flight, and a restarted node
re-orchestrating the same epoch produces the same
deterministically-hashed job ids, so it re-proves from scratch.

## Fix

Thread an `abortJobs` decision from the cancel reason down to the
broker:

- `SessionManager.stop()` cancels with `{ abortJobs: false }` — a clean
shutdown preserves the jobs.
- `EpochSession.cancel(reason, { abortJobs })` forwards it to
`TopTreeJob.cancel(abortJobs)` → `topTree.cancel({ abortJobs })`.
- All other cancels (reorg / supersede / deadline) keep the default
`abortJobs: true`, since their inputs are stale.

Composes with #24578: a clean redeploy mid-epoch neither cancels the
in-flight jobs nor (if one ever were aborted) poisons them, so the epoch
keeps proving across the restart.

## Tests

- `session-manager.test.ts`: `stop()` cancels every session with
`abortJobs: false`.
- `epoch-session.test.ts`: a normal cancel forwards `abortJobs: true` to
the top-tree orchestrator; a clean-shutdown cancel forwards `abortJobs:
false`.

Note: not run locally in this session — the prover-node suite needs a
full noir/wasm bootstrap that wasn't available here — so relied on CI.

---
*Created by
[claudebox](https://claudebox.work/v2/sessions/6fa5e242ed9ceae7) ·
group: `slackbot`*

---------

Co-authored-by: Phil Windle <philip.windle@gmail.com>
Some stores were being accessed without checking if the associated
accounts were in scope or not. For logs I added this to the service, but
we're not yet consistent in how we use services (call-lived, tx-lived?)
so in other cases it is just inlined in the oracle.
I added a sanity check to avoid having messages implausibly far into the
future, which would lead to them not getting evicted etc., but more
importantly which would signal some inconsistency somewhere.
BEGIN_COMMIT_OVERRIDE
fix(prover-node): do not abort in-flight proving jobs on a clean
shutdown (#24579)
END_COMMIT_OVERRIDE
This fixes an issue in which the note validation checks were not using
the note's contract address to do the nhsk app siloing, but instead the
_executing_ contract's address. This is because app siloing kernel
requests can only be done for the current contract, but the helpers did
not prevent usage on external contracts.

They now contain an assertion preventing this, and have been renamed to
reflect it.
Wire the --funding-account option through the validator-keys new and add
commands so operators can generate a keystore with a top-level funding
account instead of hand-editing the JSON. The value may be a private key
or, together with --remote-signer, an address. With --password the
plaintext funder key is encrypted to a JSON V3 file like other accounts.

The funding account is written at the keystore top level, matching the
only field KeystoreManager.createFundingSigner consumes at runtime.
…bcommand

Review feedback: --funding-account on add read as per-validator but mutated
the keystore-level account. Keep it on new, drop it from add, and add a
dedicated set-funding-account subcommand for existing keystores.
…ress form

An address funding account no longer requires --remote-signer when the keystore
already defines a top-level remote signer. In that case the funder is stored as a
bare address, which the keystore manager resolves against the keystore-level signer
at runtime, so operators don't declare the signer URL twice.
The base now rejects empty keystore passwords on validator-keys new, so the
funding-account encryption test must supply a real password.
Additions to the README on gas and fees
…-account (#24476)

## Summary

Wires a real `--funding-account` option into `aztec validator-keys new`
(previously commented out with a TODO, so operators had to hand-edit the
keystore JSON), and adds a dedicated `set-funding-account` subcommand
for existing keystores.

Per review feedback, `add` does **not** take `--funding-account`: the
funding account is a keystore-level field (the only one
`KeystoreManager.createFundingSigner` reads), so setting it from `add`
would be a global mutation disguised as a per-validator flag. Use
`set-funding-account` instead:

```
aztec validator-keys set-funding-account <keystore.json> <privateKey|address> [--remote-signer <url>] [--password <str>]
```

## Behavior

- The funding account value accepts either a 32-byte private key or a
20-byte address.
- An address requires `--remote-signer` (a local funder needs its
private key to sign funding txs); it is stored as `{ address,
remoteSignerUrl }`.
- With `--password`, a plaintext funder key is encrypted to a JSON V3
file and replaced with a `{ path, password }` reference, mirroring how
attester/publisher keys are handled.
- The value is written at the keystore top level
(`keystore.fundingAccount`). Validator-level funding exists in the
schema but is never consumed at runtime, so it is intentionally not
emitted.
- `set-funding-account` replaces an existing funding account with a
warning.

## Changes

- `index.ts` — real `--funding-account` option on `new`; new
`set-funding-account` subcommand.
- `set_funding_account.ts` — new command: validate, resolve, optionally
encrypt, write `keystore.fundingAccount`.
- `utils.ts` — `validateFundingAccountOptions` (normalize + validate
key/address, require remote-signer for address form).
- `shared.ts` — `resolveFundingAccount` and
`encryptFundingAccountToFile`; extracted the ETH JSON V3 encryption
helper for reuse.
- `new.ts` — validate, resolve, optionally encrypt, set
`keystore.fundingAccount`.
- `valkeys.test.ts` — 17 new tests covering validation,
private-key/address/password paths on `new`, and set/replace on
`set-funding-account`.

## Testing

- `yarn workspace @aztec/cli test
src/cmds/validator_keys/valkeys.test.ts` — 60 passed.
- `yarn build`, `yarn format cli`, `yarn lint cli` — all clean.
…-account (#24476)

## Summary

Wires a real `--funding-account` option into `aztec validator-keys new`
(previously commented out with a TODO, so operators had to hand-edit the
keystore JSON), and adds a dedicated `set-funding-account` subcommand
for existing keystores.

Per review feedback, `add` does **not** take `--funding-account`: the
funding account is a keystore-level field (the only one
`KeystoreManager.createFundingSigner` reads), so setting it from `add`
would be a global mutation disguised as a per-validator flag. Use
`set-funding-account` instead:

```
aztec validator-keys set-funding-account <keystore.json> <privateKey|address> [--remote-signer <url>] [--password <str>]
```

## Behavior

- The funding account value accepts either a 32-byte private key or a
20-byte address.
- An address requires `--remote-signer` (a local funder needs its
private key to sign funding txs); it is stored as `{ address,
remoteSignerUrl }`.
- With `--password`, a plaintext funder key is encrypted to a JSON V3
file and replaced with a `{ path, password }` reference, mirroring how
attester/publisher keys are handled.
- The value is written at the keystore top level
(`keystore.fundingAccount`). Validator-level funding exists in the
schema but is never consumed at runtime, so it is intentionally not
emitted.
- `set-funding-account` replaces an existing funding account with a
warning.

## Changes

- `index.ts` — real `--funding-account` option on `new`; new
`set-funding-account` subcommand.
- `set_funding_account.ts` — new command: validate, resolve, optionally
encrypt, write `keystore.fundingAccount`.
- `utils.ts` — `validateFundingAccountOptions` (normalize + validate
key/address, require remote-signer for address form).
- `shared.ts` — `resolveFundingAccount` and
`encryptFundingAccountToFile`; extracted the ETH JSON V3 encryption
helper for reuse.
- `new.ts` — validate, resolve, optionally encrypt, set
`keystore.fundingAccount`.
- `valkeys.test.ts` — 17 new tests covering validation,
private-key/address/password paths on `new`, and set/replace on
`set-funding-account`.

## Testing

- `yarn workspace @aztec/cli test
src/cmds/validator_keys/valkeys.test.ts` — 60 passed.
- `yarn build`, `yarn format cli`, `yarn lint cli` — all clean.
BEGIN_COMMIT_OVERRIDE
fix: prevent access to secrets not in scope (#24616)
fix: prevent reception of messages too far into the future (#24645)
fix(aztec-nr): prevent recipient forging a colliding handshake (#24403)
feat!: forbid external note validation checks (#24644)
feat(txe): add option to authorize all utility call targets (#24662)
END_COMMIT_OVERRIDE
…24665)

## Problem

When encrypting a message, the ephemeral secret key comes from an
unconstrained routine, so a malicious sender can substitute any value
while proving. Substituting `eph_sk = 0` yields the point at infinity as
the ephemeral public key, which passed the y-sign check: its
y-coordinate is 0, which counts as positive. Its x-coordinate (0) is
then broadcast, but 0 is not a valid x-coordinate on the curve, so the
recipient can never reconstruct the key and the message is permanently
undecryptable. This breaks the constrained-delivery guarantee that a
note delivered by an untrusted sender remains decryptable by the
recipient.

## Fix

`generate_positive_ephemeral_key_pair` now asserts the ephemeral public
key is not the point at infinity, alongside the existing sign check. A
test emulates the substitution by mocking the randomness oracle to
return 0.

Fixes F-799
BEGIN_COMMIT_OVERRIDE
docs: fee readme improvements (#24666)
feat(cli): support funding accounts in validator-keys
new/set-funding-account (#24476)
END_COMMIT_OVERRIDE
BEGIN_COMMIT_OVERRIDE
feat(cli): support funding accounts in validator-keys
new/set-funding-account (#24476)
END_COMMIT_OVERRIDE
BEGIN_COMMIT_OVERRIDE
fix(aztec-nr): reject infinity ephemeral key in message encryption
(#24665)
END_COMMIT_OVERRIDE
## What

Fixes a low-frequency (~1 in 140) startup-race flake in the
`proof_boundary` multi-node e2e suite (CI hash `c06563e7d2b7e067`, group
`e2e-p2p-epoch-flakes`). All five scenarios time out in the shared
`computeBoundarySlot()` helper at `waitUntilCheckpointNumber(1)` — the
3-validator committee never produces its first checkpoint.

## Why

`setupTest` created the three validator nodes sequentially (`asyncMap`)
and started each sequencer at node construction. A node subscribes to
the gossip topics when its P2P client starts (unconditionally, at node
creation), but the in-memory mock gossip bus has no message replay. So
when the first-created validator happened to draw the first slot's
proposer, it broadcast the inaugural block proposal before the other two
committee members had been created and subscribed — the proposal was
lost, the 3-of-3 quorum was missed, and the chain forked onto genesis
and never produced checkpoint 1. It's randao-dependent (fatal only when
the first-created node is the first proposer), hence the low frequency.

## Fix

Create the validator nodes with `dontStartSequencer: true`, then
`startSequencers(nodes)` once all three exist. All peers subscribe to
gossip at creation, so no proposal is broadcast before the whole
committee is on the bus. This matches the pattern already used by the
non-flaky sibling tests `first_slot.test.ts` and
`block-production/setup.ts`.

## Scope

Test-only change. Related to A-1419, which tracks the underlying
product-level recovery race (competing block-1 re-executions surfacing
as `BlockNumberNotSequentialError`). This PR implements that issue's
"keep the test startup barrier" acceptance criterion but does **not**
resolve A-1419 — the product-side race is unchanged.
AztecBot and others added 12 commits July 14, 2026 13:30
Upstreaming the utilities build for `aztec-kit` so external projects can
benefit from our e2e scaffolding. Essentially the same thing we already
use, but pure ts rather than the unpublishable .sh script. Verified with
`ci-full-no-test-cache`
…evidence (#24655)

Fixes the sender tag sync conflict from
https://gist.github.com/nventuro/0aa690736b1d2865e27197723a814e9d,
including the "Window straddle" residual edge.

Discovery could re-derive a different index range for an already tracked
(secret, txHash) pair and hit the `Conflicting range` throw in
`storePendingIndexes`, permanently wedging the secret. Two triggers:

- A same-PXE tx partially reverts: the chain only shows the surviving
non-revertible sub-range of the prove-time entry, and the throw fired
before the finalized receipt step could resolve it.
- A tx straddles a sync window boundary: the window loop assembles its
range piecewise, so window 2 stores a different range than window 1
(latent regardless of reverts).

Fix: discovery passes `mergeExisting` to `storePendingIndexes`, which
widens the stored entry to the union of both ranges (grow-only, driven
by onchain evidence). The finalized receipt step still resolves partial
reverts. The only other writer of pending ranges,
`persistSenderTaggingIndexRangesForTx` (records the indexes a tx sent
from this PXE used, at prove time), does not pass the flag and still
throws on a mismatch: there it indicates a bug, not partial onchain
evidence.

Red-green (all fail on the base with the `Conflicting range` throw):
- partial revert repro: finalizes the surviving index, frees the
squashed ones, repeat sync is a no-op
- cross-sync widen: an entry tracked from an earlier sync grows when
discovery evidences further indexes
- window straddle: drives the actual window advance loop, asserts per
window queried tags and that the widened entry later finalizes cleanly

Store-level tests pin the union semantics: a sub-range keeps the entry,
a range beyond it widens it, an untracked tx still stores.
BEGIN_COMMIT_OVERRIDE
feat: exported in-process testing network (#24629)
fix(pxe): widen tracked sender tagging ranges with onchain discovery
evidence (#24655)
END_COMMIT_OVERRIDE
# Conflicts:
#	noir-projects/aztec-nr/aztec/src/standard_addresses.nr
#	noir-projects/noir-contracts/pinned-standard-contracts.tar.gz
#	yarn-project/standard-contracts/src/standard_contract_data.ts
#	yarn-project/txe/esbuild/plugins/size_guard.mjs
Resolves the 4 conflicts from merging origin/v5 into v5-next:

- yarn-project/txe/esbuild/plugins/size_guard.mjs: keep the higher
  totalLimitMiB = 15 (v5), since merging v5's larger bundle content in
  needs the bigger cap; merged both bump-log lines chronologically.

- Generated standard-contract artifacts (kept at the v5-next baseline,
  REGEN REQUIRED before merge):
    - noir-projects/aztec-nr/aztec/src/standard_addresses.nr
    - yarn-project/standard-contracts/src/standard_contract_data.ts
    - noir-projects/noir-contracts/pinned-standard-contracts.tar.gz
  These are generated by 'bootstrap.sh pin-standard-build' + 'yarn
  workspace @aztec/standard-contracts run generate'. The merged tree
  combines v5-next's standard-contract source changes (handshake
  forgery-protection) with v5's aztec-nr + protocol-constants changes,
  so the deterministic addresses match NEITHER committed side and must
  be re-pinned/regenerated from the merged tree. Left at v5-next's
  values as a consistent placeholder; bootstrap drift-check will flag
  this until regenerated.
## Problem

Partial-note discovery has four crash points on the completion path,
each reachable by a malicious sender and each firing before the pending
note advances — so every subsequent sync re-hits it and permanently
freezes note sync for that contract:

- a matched completion log yields no note (`panic`),
- a pending note resolves to more than one completion log (`assert`),
- the delivered private half plus the log's public content exceed the
packed-note capacity (`BoundedVec` overflow in the append), or
- the completion log payload is empty, so reading the storage slot is
out of bounds.

The first three are reachable on the canonical token (mismatched content
over the unconstrained delivery channel, completing the same partial
note twice which the token does not prevent, and an over-length
delivered private half); the last needs an attacker-controlled contract
emitting a tag-only log.

## Fix

Make each non-fatal: warn and advance the FSM rather than panicking, so
one bad message cannot break sync. A completion log that cannot yield a
note (empty, over-length, or matching none) is skipped; more than one
completion log completes with the first.

Fixes F-798
Merges public `v5` into public `v5-next` so ongoing development can
continue on `v5-next` while `v5` stays the release line. Requested in
#engineering.

`v5` was ~887 commits ahead of the merge base and `v5-next` ~31, and the
merge is **not** clean — 4 conflicts. Structured as three commits for
review:

### Commit 1 — raw merge (conflict markers committed)
`Merge remote-tracking branch 'origin/v5'` — the merge commit with the
conflict markers left in place, so you can see exactly what git couldn't
auto-resolve:

- `yarn-project/txe/esbuild/plugins/size_guard.mjs`
- `noir-projects/aztec-nr/aztec/src/standard_addresses.nr` *(generated)*
- `yarn-project/standard-contracts/src/standard_contract_data.ts`
*(generated)*
- `noir-projects/noir-contracts/pinned-standard-contracts.tar.gz`
*(generated, binary)*

### Commit 2 — hand resolution
- **`size_guard.mjs`** — resolved by hand. Kept the higher
`totalLimitMiB = 15` (from `v5`): merging `v5`'s larger bundle content
into `v5-next` needs the bigger cap. Merged both bump-log lines
chronologically.
- The 3 generated standard-contract artifacts were left at the `v5-next`
baseline as a placeholder (correctly flagged by CI: `BBApiException:
verification key has wrong size: expected 5216, got 4576` — the old
pinned VKs don't match `v5`'s bb).

### Commit 3 — regenerated standard-contract artifacts
Ran the real regeneration on the merged tree:
`noir-projects/noir-contracts/bootstrap.sh pin-standard-build` + `yarn
workspace @aztec/standard-contracts run generate`, iterated to a
fixpoint (3 rounds — the standard contracts embed each other's address
stamps via aztec-nr, so re-pinning shifts addresses until they
stabilize). All four standard-contract addresses changed, as expected:
the merged tree combines **v5-next's** handshake forgery-protection
changes with **v5's** `aztec-nr` + protocol-constants + bb (VK format)
changes, so the addresses match neither committed side.

Verified locally on the merged tree: full `noir-contracts` build and
full `yarn-project` build (the CI job that failed) both pass, including
the standard-contracts drift check.

Everything else auto-merged (including `constants.gen.ts` /
`constants.nr` and the handshake contract/aztec-nr source). Opened as a
draft for review per the usual conflict-PR flow.

---
*Created by
[claudebox](https://claudebox.work/v2/sessions/97f178a58b3b68fb) ·
group: `slackbot`*
@aminsammara
aminsammara requested a review from a team July 15, 2026 18:01
@PhilWindle
PhilWindle merged commit 72666f8 into v5 Jul 15, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants