Skip to content

Most of the rest of the NU6.3 owl#1319

Merged
daira merged 29 commits into
zcash:mainfrom
daira:ironwood-zips-followup
Jul 9, 2026
Merged

Most of the rest of the NU6.3 owl#1319
daira merged 29 commits into
zcash:mainfrom
daira:ironwood-zips-followup

Conversation

@daira

@daira daira commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator

Follow-up to #1301 (NU6.3 deployment + v6 transaction format), plus a new wallet-facing ZIP 326. This does not include ZIP 318 which is in #1317 (draft).

The last commit is currently WIP and not factored nicely.

Contents

Protocol Specification v2026.8.0 [NU6.3]

  • Apply changes from ZIPs 2005 and 258.
  • Additional consensus rules extending Orchard rules to Ironwood.

Follow-ups to the merged NU6.3 ZIPs:

  • ZIP 2005: complete the updates for Ironwood-only deployment.
  • ZIP 229: consolidate deployment-ZIP references onto ZIP 258.
  • Move the "Changes to ZIP 221" section from ZIP 229 into ZIP 258 (keeping all cross-ZIP deployment/spec edits in the deployment ZIP).
  • ZIP 246 / 230: mark ZIP 246 as digests for the withdrawn v6 transaction format, removing overlap with the live format.

New ZIPs:

  • ZIP 326: NU6.3 Consequences for Wallets (previously draft-dairaemma-nu6.3-consequences-for-wallets.md, Discussions-To [ZIP 326] NU6.3 Consequences for Wallets #1318) — collects the wallet consequences of NU6.3 that are outside the Orchard-to-Ironwood migration strategy ([ZIP 318] Orchard to Ironwood migration #1317) and are not consensus rules: scanning for Ironwood-pool and Orchard-pool notes under the use_qsk key distinction (key-generation restrictions, scan-range rules, the first-funds optimization, and the restore-from-seed case); receiving funds into the Ironwood pool; and randomizing the note ciphertext of the fabricated same-address output required when spending in the Orchard pool under its post-NU6.3 same-address restriction.
  • Stub for now: ZIP 2006: Restricting Transfers into the Orchard Pool.

🤖 Claude Opus 4.8

Comment thread zips/zip-0326.md Outdated
against *four* incoming viewing keys: the external and the internal, each for
$\mathsf{use\_qsk} \in \{\textsf{false}, \textsf{true}\}$.

A wallet that created its own seed always knows which $\mathsf{use\_qsk}$ value is used, but

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
A wallet that created its own seed always knows which $\mathsf{use\_qsk}$ value is used, but
A wallet that performed its own key derivation always knows which $\mathsf{use\_qsk}$ value is used, but

Comment thread zips/zip-0326.md Outdated
Comment on lines +119 to +120
* A wallet MUST NOT send funds to an external receiver in the *Orchard pool* after NU6.3
activation.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
* A wallet MUST NOT send funds to an external receiver in the *Orchard pool* after NU6.3
activation.
* A wallet MUST NOT send funds to any external receiver (including its own) in the
Orchard pool* after NU6.3 activation.

Comment thread zips/zip-0326.md Outdated
The following restrictions make the scanning optimizations below sound. They concern only how a
wallet generates and uses keys; they are not consensus rules.

* For each account, a wallet MUST generate keys with the same value of $\mathsf{use\_qsk}$ —

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
* For each account, a wallet MUST generate keys with the same value of $\mathsf{use\_qsk}$ —
* For each ZIP 32 account, a wallet MUST generate keys with the same value of $\mathsf{use\_qsk}$ —

Comment thread zips/zip-0326.md Outdated
* Any wallet that generates $\mathsf{use\_qsk} = \textsf{true}$ keys:
* MUST NOT send *Orchard-pool* funds to them at any point; and
* MUST NOT expose the corresponding Orchard-protocol receivers or viewing keys before NU6.3
activation.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
activation.
activation, to avoid contamination of the Orchard pool.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I would avoid the word "contamination" and say something more precise.

Comment thread zips/zip-0326.md
either the internal or the external $\mathsf{ivk}$.

* For an account with birthday height before NU6.3 activation, *Orchard-pool* note ciphertexts
SHOULD NOT be scanned with the *external* $\mathsf{use\_qsk} = \textsf{false}$ $\mathsf{ivk}$

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Note that this doesn't work for wallets that send change back to the originating address (i.e. those that never adopted internal IVKs)

Comment thread zips/zip-0326.md
Comment on lines +220 to +226
block being scanned, it only needs to use the *external* incoming viewing keys, with one exception: if
the transaction's `valueBalanceIronwood` is negative (value is entering the *Ironwood pool*), then
the transaction has an input to the pool via the value balance, which might go to an
*Ironwood-pool* note at an *internal* receiver of this wallet. (No other party can address an
internal receiver, so before the account has received *Ironwood-pool* funds, an internal note for
it can only arise from the account's own transaction, which must be funded either by spending
existing *Ironwood-pool* funds — of which there are none yet — or by such an inflow.)

@ValarDragon ValarDragon Jun 30, 2026

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.

We should be doing this in scanning logic anyway! We were running with this in github.com/valargroup/librustzcash , until Ironwood. (There was one bug remaining, that we decided its easier to refactor post-Ironwood. So we removed that sync optimization for now)

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.

So we are still doubling load for use_qsk in scanning, relative to what always should be the case. Its just that we have a 2x on the table for improvements within the pool for everyone

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.

agreed, need to tighten up the different rules / preconditions being made here (that wallets can rely on without missing funds).

Comment thread zips/zip-0326.md
\textsf{true}$ incoming viewing keys. However, because a conservatively early birthday height has
traditionally been safe, such an optimization would *not* be safe — a $\mathsf{use\_qsk} =
\textsf{true}$ account whose recorded birthday height was set too early would have its
$\mathsf{use\_qsk} = \textsf{true}$ *Ironwood-pool* notes skipped — and so it is not specified.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

A scenario where this incorrect optimization would bite is that if a user restored a wallet and mistakenly set the birthday height too early, they could fail to find their funds.

@TalDerei
TalDerei self-requested a review June 30, 2026 21:21
@daira daira changed the title NU6.3 ZIPs follow-up + draft "NU6.3 Consequences for Wallets" NU6.3 ZIPs follow-up + [ZIP 326] NU6.3 Consequences for Wallets Jul 1, 2026

@TalDerei TalDerei 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.

flagging that basically all my feedback in #1301 is still unaddressed or only partially addressed (if that's intentional for this draft round, disregard).

Comment thread zips/zip-2005.md
Comment thread zips/zip-0326.md
Comment thread zips/zip-0326.md Outdated
Comment thread zips/zip-0326.md
Comment on lines +220 to +226
block being scanned, it only needs to use the *external* incoming viewing keys, with one exception: if
the transaction's `valueBalanceIronwood` is negative (value is entering the *Ironwood pool*), then
the transaction has an input to the pool via the value balance, which might go to an
*Ironwood-pool* note at an *internal* receiver of this wallet. (No other party can address an
internal receiver, so before the account has received *Ironwood-pool* funds, an internal note for
it can only arise from the account's own transaction, which must be funded either by spending
existing *Ironwood-pool* funds — of which there are none yet — or by such an inflow.)

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.

agreed, need to tighten up the different rules / preconditions being made here (that wallets can rely on without missing funds).

@daira

daira commented Jul 5, 2026

Copy link
Copy Markdown
Collaborator Author

@TalDerei wrote:

flagging that basically all my feedback in #1301 is still unaddressed or only partially addressed (if that's intentional for this draft round, disregard).

I'm systematically going through that with Claude.

Previously `rendered/` and its copied `static/*` assets were created
only by the `.Makefile.uptodate` stamp target, which reruns only when
`Makefile`, `render.sh`, or `static/*` change. So if `rendered/` was
removed while the stamp stayed current (e.g. by `make discard`), or a
render target won a parallel-make race against the stamp's `mkdir`,
rendering failed with a shell "No such file or directory" on
`rendered/index.html` and a downstream docutils `BrokenPipeError`.

Give the render rules an order-only prerequisite on a dedicated
`rendered` target, as the `rendered/test` rule already does, and have
`render.sh` create its own output directory, so it always exists before
anything is written — independent of the stamp file and safe under `-j`.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@daira
daira force-pushed the ironwood-zips-followup branch 2 times, most recently from af91d31 to e74b56c Compare July 6, 2026 13:22
@daira
daira marked this pull request as ready for review July 6, 2026 15:11
@daira daira changed the title NU6.3 ZIPs follow-up + [ZIP 326] NU6.3 Consequences for Wallets Remainder of the NU6.3 specification Jul 6, 2026
@daira daira changed the title Remainder of the NU6.3 specification Most of the rest of the NU6.3 owl Jul 6, 2026
Comment thread zips/zip-2005.md
is the ZIP 209 turnstile mechanism [^zip-0209]. If there were evidence of
balance violation having occurred, confidence in Zcash as a whole could
potentially be undermined despite the turnstile constraints (especially if the
violation was in the largest pool, currently the *Orchard pool*). Therefore,

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I guess it is expected that Ironwood will quickly become the largest pool, so I'll rewrite this. (It was written before Ironwood was proposed.)

daira and others added 5 commits July 9, 2026 11:09
bash 3.2 (the /bin/bash that macOS still ships, and which the `#!/bin/bash`
shebang selects even inside `nix develop`) mis-parses a single-quote in a
comment inside a `cat <(...)` process substitution as an opening quote. It
then scans to end-of-file looking for the close, aborting with a baffling
"process substitution: line N: unexpected EOF while looking for matching '"
where N is past the end of the file. Newer bash (4+/5+, as on Linux) parses
the comment correctly.

The `won't` / `span's` / `another's` apostrophes in the Markdown sed caveat
tripped this, breaking `make` on macOS. Reword them away and add a note so
the constraint does not silently regress.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The sed programs embed non-ASCII UTF-8 (em-dash, the 💲 sentinel) and the
input ZIPs are UTF-8, so running under a non-UTF-8 locale silently produces
mojibake rather than failing. Check `locale charmap` up front and exit with
an actionable message otherwise.

`locale charmap` reports the *effective* character map, which is what
matters: it is UTF-8 on a UTF-8 locale and US-ASCII / ANSI_X3.4-1968 under
C / POSIX. This also correctly rejects macOS's C.UTF-8 (which has no real
UTF-8 locale, so `locale charmap` reports US-ASCII there) while accepting
Linux's C.UTF-8 (genuinely UTF-8). The suggested fix locale is derived from
LANG so it names the user's own language, falling back to en_US.

The usage/help path runs before the check, so it still works in any locale.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… fix references.

ZIP 229: Drop the `^protocol-chainvalue` footnote, orphaned when the
ZIP 209 / § 4.17 changes moved to ZIP 258 in zcash#1301.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Daira-Emma Hopwood <daira@jacaranda.org>
The NU6.3 deployment ZIP (258) already absorbed the "Changes to ZIP 209"
and the corresponding § 4.17 protocol-spec changes in zcash#1301; move the
"Changes to ZIP 221" (Ironwood history-tree metadata) there too, so that
all of the cross-ZIP consensus/spec edits live in the deployment ZIP
rather than the transaction-format ZIP.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Daira-Emma Hopwood <daira@jacaranda.org>
ZIP 246 ("Digests for the Version 6 Transaction Format") was written for the
withdrawn v6 format (ZIP 230), not the active ZIP 229 v6 format. Retitle it to
"Digests for the Withdrawn Version 6 Transaction Format" so it is clear it does
not apply to ZIP 229.

In ZIP 230, update the obsoletion warning to reference ZIP 229 (which now defines
transaction version 6) instead of the unmerged ZIP 248 — fixing a dangling
reference — add the `[#zip-0229]` definition, and update the
`[#zip-0246-sighash-info]` title to match.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Daira-Emma Hopwood <daira@jacaranda.org>
daira and others added 23 commits July 9, 2026 11:09
Collects the consequences for wallets of NU6.3 that are outside the
Orchard-to-Ironwood migration strategy and are not consensus rules:

- scanning for Ironwood-pool and Orchard-pool notes under the use_qsk key
  distinction (key-generation restrictions, scan-range rules, the first-funds
  optimization, and the restore-from-seed case);
- receiving funds into the Ironwood pool via protocol-scoped receivers; and
- randomizing the note ciphertext of the fabricated same-address output
  required when spending in the Orchard pool under its post-NU6.3 same-address
  restriction.

Assigned ZIP number 326 (Discussions-To: zcash#1318).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…pository

Signed-off-by: Daira-Emma Hopwood <daira@jacaranda.org>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…7.1.2, not a ZIP

The v5 (ZIP 225) and v6 (ZIP 229) transaction-format ZIPs now reference § 7.1.2 for the
nVersionGroupId / nConsensusBranchId constraints, and the NU6.3 deployment ZIP (258) no
longer restates the v6 version group ID as a deployment constant. Version group IDs are
canonically defined in Zcash Protocol Specification § 7.1.2.

Not pinning the version group ID in a format or deployment ZIP is deliberate: it keeps the
ID doing its disambiguation job (ZIP 202), so a Zcash fork —or a competing definition of
the same tx version within Zcash (there have been three v6 attempts: ZIP 230, ZIP 248,
ZIP 229)— must choose a distinct value rather than silently inherit this one.

Signed-off-by: Daira-Emma Hopwood <daira@jacaranda.org>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Cite the protocol specification at the version appropriate to each ZIP's
upgrade. ZIP 2005 specifies changes to the spec, so it references two
versions: the base being changed (2026.7.0 [NU6.2], protocol.pdf) and the
version the changes are applied in (2026.8.0 [NU6.3], nu6_3.pdf). References
in the Changes sections cite the base version; Terminology and analysis
references cite the updated one. The footnotes are named
`protocol-base[-*]` / `protocol-updated[-*]` so the anchor names stay stable
when the versions bump.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Daira-Emma Hopwood <daira@jacaranda.org>
Signed-off-by: Daira-Emma Hopwood <daira@jacaranda.org>
Signed-off-by: Daira-Emma Hopwood <daira@jacaranda.org>
Signed-off-by: Daira-Emma Hopwood <daira@jacaranda.org>
…ocol

spec (7.1.2), not ZIP 224.

Signed-off-by: Daira-Emma Hopwood <daira@jacaranda.org>
Signed-off-by: Daira-Emma Hopwood <daira@jacaranda.org>
Signed-off-by: Daira-Emma Hopwood <daira@jacaranda.org>
…nwood-pool notes

Replace the note that making funds recoverable "does not depend on support from
other wallets" (via wallet-internal addresses) with a statement that other
wallets are REQUIRED, as part of supporting NU6.3, to be able to receive these
notes.

Signed-off-by: Daira-Emma Hopwood <daira@jacaranda.org>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ironwood pool specifically is meant; drop some uses of OrchardZSA.

Signed-off-by: Daira-Emma Hopwood <daira@jacaranda.org>
Signed-off-by: Daira-Emma Hopwood <daira@jacaranda.org>
…onstant.

Signed-off-by: Daira-Emma Hopwood <daira@jacaranda.org>
Signed-off-by: Daira-Emma Hopwood <daira@jacaranda.org>
Signed-off-by: Daira-Emma Hopwood <daira@jacaranda.org>
…macros.

A Sapling-like pool is Sapling, Orchard, or Ironwood, and an Orchard-like
pool is Orchard or Ironwood. This makes a lot of the spec boilerplate a
lot less verbose.

Signed-off-by: Daira-Emma Hopwood <daira@jacaranda.org>
and v6 transactions.

Signed-off-by: Daira-Emma Hopwood <daira@jacaranda.org>
Signed-off-by: Daira-Emma Hopwood <daira@jacaranda.org>
Signed-off-by: Daira-Emma Hopwood <daira@jacaranda.org>
Changes to protocol.tex and the bibliography, plus updates across the
affected ZIPs (notably ZIP 209 and ZIP 258).
- "created its own seed" -> "performed its own key derivation" for the
  use_qsk-known case.
- "each account" -> "each ZIP 32 account" in the same-use_qsk restriction.
- external-receiver restriction: "an external receiver" -> "any external
  receiver (including its own)".
- pre-activation receiver/viewing-key exposure restriction: state the actual
  disadvantage (Orchard-pool funds could reach a use_qsk=true account,
  incurring extra scanning cost or risk of lost funds), rather than an
  undefined "contamination" metaphor.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- protocol/protocol.tex: apply the ZIP 2005 § 4.7.3/4.8.3 note-derivation
  changes (ψ derived before rcm, so Derive_rcm's inputs are available), and
  use g⋆_d / pk⋆_d in the Orchard NoteCommit inputs under NU6.3.
- zips/zip-2005.md: matching § 4.7.3/4.8.3 derivation ordering and references.
- README.rst: ZIP listing updates.
- zips/zip-0256.md: minor update.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@daira
daira force-pushed the ironwood-zips-followup branch from e74b56c to 662dc87 Compare July 9, 2026 10:15
@daira
daira merged commit 6961098 into zcash:main Jul 9, 2026
3 checks passed
@daira
daira deleted the ironwood-zips-followup branch July 18, 2026 14:44
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.

Protocol spec version 2026.8.0

4 participants