Skip to content

feat: merge-train/fairies-v5 - #24388

Merged
nchamo merged 10 commits into
v5-nextfrom
merge-train/fairies-v5
Jul 1, 2026
Merged

feat: merge-train/fairies-v5#24388
nchamo merged 10 commits into
v5-nextfrom
merge-train/fairies-v5

Conversation

@AztecBot

@AztecBot AztecBot commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator

BEGIN_COMMIT_OVERRIDE
chore(aztec-nr): add constrained delivery index nullifier test (#24366)
fix(key-store): protect all KeyStore methods with transactionAsync (#24406)
feat(pxe): add resolveCustomRequest hook for caller-defined requests (#24409)
refactor(pxe): unify the app-silo primitive for tagging and encryption (#24402)
feat!: close down access to context member fields (#24417)
feat(pxe): default unconstrained delivery to a handshake (#24387)
feat!: allow passing and retrieving privacy keys in pxe/wallet (#24416)
fix(bench): use address-derived tagging secrets for the client-flows bench; widen the PXE unfinalized tagging window (#24429)
feat(aztec-nr): let contracts choose the message tag derivation (#24432)
END_COMMIT_OVERRIDE

@ludamad ludamad left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Auto-approved

@AztecBot
AztecBot added this pull request to the merge queue Jun 30, 2026
@AztecBot

Copy link
Copy Markdown
Collaborator Author

🤖 Auto-merge enabled after 4 hours of inactivity. This PR will be merged automatically once all checks pass.

@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jun 30, 2026
mverzilli and others added 6 commits June 30, 2026 17:14
…24406)

Some of the recent changes to KeyStore made some of its methods
IndexedDB-unsafe. We are in the process of deprecating support for
IndexedDB, but until everyone is safely on SQLite we need to stick to
read/write patterns that make transaction aliveness predictable.

Note: proper regression testing for this is covered by aztec-kit, which
is how we detected this issue (eg:
aztec-labs-eng/aztec-kit#72)

Closes F-772
#24402)

## Why we are doing this

App-siloing an ECDH shared secret to a contract address (`s_app = h(S.x,
S.y, app)`) was done **two different ways**:

- **Tagging** used a bare `poseidon2Hash([S.x, S.y, app])` — no domain
separator.
- **Encryption** (and Noir's `compute_app_siloed_shared_secret`) used
`poseidon2HashWithSeparator([S.x, S.y, app],
APP_SILOED_ECDH_SHARED_SECRET)`.

So the tagging silo was the odd one out: a second, separator-less
primitive doing morally the same job as the one encryption and the
contracts already use. Two ways to app-silo the same point is exactly
the kind of "is this the same thing or not?" wart that makes the tagging
code hard to reason about.

## Our fix

Collapse both onto a single primitive,
`appSiloEcdhSharedSecretPoint(point, app)` (the separator-based silo).
The keys-input encryption path (`appSiloEcdhSharedSecret`) and the
tagging path now both go through it, and it mirrors Noir's
`compute_app_siloed_shared_secret` exactly. "The tagging secret is the
same app-silo encryption uses, then directed to the recipient" becomes a
single invariant a reviewer asserts once.

Because tagging now uses the separator, the derived tagging-secret value
changes — so this is a behavioral change, not a pure no-op refactor.

### Naming

The old names didn't say what they did, so they were renamed alongside
the unification:

- `AppTaggingSecret.compute` → `computeDirectional`: the result binds
the recipient; the name now says so.
- `AppTaggingSecret.computeUnconstrained` → `computeViaEcdh`:
"unconstrained" named the delivery mode, but **both** factories return
an unconstrained-kind secret, so it distinguished nothing — what
actually sets this one apart is the ECDH key exchange it does first.
- `deriveAppSiloedSharedSecret` → `appSiloEcdhSharedSecret` (plus the
new `appSiloEcdhSharedSecretPoint`): surfaces the
`APP_SILOED_ECDH_SHARED_SECRET` separator the helper commits to.
This just makes a bunch of `pub` fields be either private or
`pub(crate)`, adding getters when needed, to allow better local
reasoning about correctness of complex modules such as `PrivateContext`.

Closes AztecProtocol/aztec-claude#1952.
@mverzilli
mverzilli added this pull request to the merge queue Jul 1, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jul 1, 2026
nventuro and others added 2 commits July 1, 2026 14:19
This lets wallets specify the private keys of the different privacy keys
directly, instead of them all being derived from a single master secret.
The wallets get equivalent functionality.

There's also a new getter that returns these keys, only in PXE. Wallets
can use this e.g. export accounts and import in a separate device. Apps
do not get access to these keys.

Finally I got rid of some old utilities that were unused
(`account_with_single_key`).

---

Some more work will follow this (e.g. not actually storing the fallback
keys, etc.), this is the initial step in the modernization of this store
and interface.
…bench; widen the PXE unfinalized tagging window (#24429)

## Summary

- widen the PXE `UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN` to
`MAX_PRIVATE_LOGS_PER_TX` (aligning the window with the per-tx
private-log cap, which is the real bound the store is gated on)
- wire a `resolveTaggingSecretStrategy` hook on the client-flows bench
user wallet that returns `address-derived` for unconstrained delivery,
restoring the pre-#24387 tagging secret path for these benches

## Investigation

The merge-train PR #24388 was removed from the merge queue on 2026-07-01
at 13:05 UTC after CI3 failed in `bench all` on merge-group SHA
`84262a7ee42e1c391c00b55b377910ddb4308230`, in run `28515530242`. The
concrete failures:

- `client_flows/transfers`: expected 7 execution steps but got 10 for
the sponsored-FPC transfer case, matching 2 extra app executions plus
one extra kernel batch after #24387 (`feat(pxe): default unconstrained
delivery to a handshake`).
- `bench_build_block`: timed out after repeated `Highest used index 21
is further than window length from the highest finalized index 0.
Tagging window length 20 is configured too low` errors.

Both failures share a root cause: #24387 defaulted unconstrained
delivery to a non-interactive handshake for external recipients, and the
benches don't pre-establish a chain, so every timed transfer inflates a
cold-chain handshake bootstrap into the measured numbers.

## Why the hook, not just wider fudges

The bench's subject is steady-state app cost. Baking `+2 app executions
per cold handshake` into `expectedExecutionSteps` measures a
first-time-only cost every run, and re-tunes with every future
handshake-bootstrap change. Instead, the user wallet now wires a
`resolveTaggingSecretStrategy` hook that returns `{ type:
'address-derived' }` for unconstrained delivery — the same tagging
secret path this bench got before #24387. The hook only affects the
client-flows bench's user wallet, not production defaults.

Constrained delivery is unaffected: the Noir circuit rejects
`address-derived` there, so the hook falls back to
`non-interactive-handshake` for the constrained branch.

## Why the window bump stands independently

The previous doc-comment on `UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN` was
self-contradictory: the header text said the value had to be larger than
`MAX_PRIVATE_LOGS_PER_TX` "because there could be more than
MAX_PRIVATE_LOGS_PER_TX indexes consumed in case the logs are squashed,"
but the constant was set to `20` (well below `MAX_PRIVATE_LOGS_PER_TX =
64`). The real limit is one full private-tx's worth of unfinalized tag
indexes per chain; aligning the constant with that bound makes the
semantic clearer.

Refs #24388, #24387.

## Testing

- Diff verified: `client_flows/transfers.test.ts` now runs with the
pre-#24387 `expectedExecutionSteps(1 + apps + 1 + recursions)` counts.
- Local unit tests / `bench all` will re-run under CI3 on this branch's
push.
@vezenovm
vezenovm enabled auto-merge July 1, 2026 16:06
@vezenovm
vezenovm added this pull request to the merge queue Jul 1, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jul 1, 2026
@nchamo
nchamo enabled auto-merge July 1, 2026 16:58
@AztecBot

AztecBot commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator Author

Flakey Tests

🤖 says: This CI run detected 1 tests that failed, but were tolerated due to a .test_patterns.yml entry.

\033FLAKED\033 (8;;http://ci.aztec-labs.com/126bb67194e19029�126bb67194e190298;;�): yarn-project/kv-store/scripts/run_test.sh src/sqlite-opfs/internal/ordered-binary-browser.test.ts (1s) (code: 0)

@nchamo
nchamo added this pull request to the merge queue Jul 1, 2026
Merged via the queue into v5-next with commit 0df2e0d Jul 1, 2026
17 checks passed
rangozd pushed a commit to rangozd/aztec-packages that referenced this pull request Aug 5, 2026
RAW cherry-pick of public merge 0df2e0d (-m 1). Conflicts committed as git produced them.
Conflicted: migration_notes.md. Resolution in fix(port) commit.
rangozd pushed a commit to rangozd/aztec-packages that referenced this pull request Aug 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants