Skip to content

Ironwood migration-dummy blocks the helper send (create vs create-max) + engine-bump fix #86

Description

@danielgorgonha

The bug: Ironwood migration-dummy breaks the helper send path

Post-NU6.3, a single/multi-note spend from the Orchard pool creates a wallet-controlled
zero-value "migration dummy" spend. create_pczt_from_proposal (in the pinned engine 42ffd0d)
does not stamp the ZIP-32 derivation on that dummy, so an external signer (our FROST flow, and
even a seed wallet's pczt sign) skips it as "not ours" → MissingSpendAuthSig at extract → the
broadcast fails.

This blocks the Architecture-B / convergence broadcast for any vault funded in the Orchard pool.

Where create is used (all hit the bug for Orchard-funded vaults)

  • orchestrator/src/send.rs::build_unprovenPayment: pczt::create (single output).
  • same → Payroll: konclave-signer build-payroll (multi output).
  • Funding a vault (seed → vault) via the CLI also hits it (seed's own Orchard spend).

create is correct semantically (send X, change back) — the problem is only the Orchard dummy.

The two paths to fix it

(1) Workaround — create-max migration (interim, Phase-14-validated on mainnet)

zcash-devtool pczt create-max --address <self> <account> spends all notes to one output with
no dummy. Pattern:

  1. Migrate the vault's Orchard → Ironwood (a create-max self-send, once). Funds land in the
    Ironwood pool.
  2. Payments from the Ironwood pool then work with plain create (the Ironwood pool signs its
    own dummy correctly).

create-max does not fit a normal payment (spends everything to one address, no change), so it is
only for the migration step. Needs a small helper addition (a pczt::create_max wrapper + a "migrate
first" step in the send flow), gated so it can be removed once (2) lands.

(2) Proper fix — engine bump to librustzcash ≥ 51385a15 (definitive)

Commit 51385a15 ("Stamp ZIP 32 derivation on wallet-controlled zero-value spends in PCZTs", #2777,
merged 2026-07-27) makes plain create work — no create-max. But it is a major bump:
pczt 0.7 → 0.9, 406 commits past our pin, which breaks the byte-for-byte PCZT wire compat between
konclave-signer and zcash-devtool (ADR-0002). Requires rebuilding both at the new pin +
updating the signer's extract/inject to pczt 0.9. A dedicated engine-migration task.

Plan

  • This issue / branch (fix/ironwood-createmax-migration): add pczt::create_max + a migration
    step to the helper, interim, so the convergence broadcast works now on the current engine.
  • Separate issue (engine bump): move to librustzcash 51385a15 / pczt 0.9, re-align ADR-0002,
    drop the workaround.

The branch is prepared with the create_max primitive so it is ready to complete/enable when we run
the money-gated broadcast.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions