Skip to content

Ironwood Compatibility - #1

Merged
USCMig merged 10 commits into
mainfrom
spike/ironwood-published
Aug 2, 2026
Merged

USCMig merged 10 commits into
mainfrom
spike/ironwood-published

Conversation

@USCMig

@USCMig USCMig commented Aug 2, 2026

Copy link
Copy Markdown
Collaborator

This PR incorporates updating the required crates to support the Ironwood NU, that is enabled for both mainnet and testnet networks. There are additional UI/UX improvements to help differentiate Orchard vs Ironwood ZEC/TAZ.

USCMig and others added 10 commits July 11, 2026 08:08
Syncing panicked in a tokio worker at shardtree prunable.rs:
'Tree state inconsistent with checkpoints.' scan_cached_blocks runs on the
sync critical path, so this aborted the sync -- the wallet could not finish
scanning.

Root cause is upstream: the fork pinned incrementalmerkletree at decefc4
(2026-07-06), which panics in clear_flags when it reaches a folded leaf.
Commit a59d6ce (2026-07-08), 'shardtree: clear flags across a folded leaf
instead of panicking', fixes exactly this. Move the [patch.crates-io] pin to
a59d6ce -- the last 0.6.x commit before the shardtree 0.7.0 release, so it
carries the fix without the version bump that would break the fork's ^0.6
requirement. Verified the bare panic is gone from the fetched source and the
workspace still resolves shardtree 0.6.2 / incrementalmerkletree 0.8.2.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Move the whole zcash_* cohort off the zecrocks git fork onto published crates,
and enable Ironwood/V6 shielded sends now that the upstream PCZT gate is fixed.

Dependencies (src-tauri):
- orchard 0.15.4, zcash_protocol 0.10.3, zcash_primitives 0.30.0,
  zcash_keys 0.16.1, zcash_address 0.13, pczt 0.9.1 (all stable);
  zcash_client_backend 0.24.0-rc.6, zcash_client_sqlite 0.22.0-rc.6 (RCs).
- Delete the [patch.crates-io] incrementalmerkletree hack: shardtree 0.7.1 is
  published and carries the folded-leaf panic fix.

Send path (create_pczt_from_proposal now builds V6 with an Ironwood bundle from
NU6.3 onward, per zcash_client_backend 0.24.0-rc.2):
- Pass proposed_version=None so the backend picks V5/V6 by target height; this
  is what unblocks shielded sends. Add the new lock_inputs (None) and
  orchard_pool_padding (BundlePadding::DEFAULT) args. Drop the now-dead
  ProposalNotSupported / OrchardReceiverRequiresIronwood handling.

Pool-aware signing (a post-NU6.3 send can carry both bundles at once — spends in
Orchard, payment via Ironwood — so signing can no longer assume one pool):
- SpendToSign gains a SpendPool tag; spends_to_sign walks both the Orchard and
  Ironwood bundles (sign_orchard_with + sign_ironwood_with).
- apply_signatures splits signatures by pool and applies each to its bundle.
- broadcast_signed proves each present bundle (create_orchard_proof and/or
  create_ironwood_proof), gated on bundle_presence so an empty bundle's anchor
  check can't fail the send. Both pools share the PostNu6_3 circuit, so one
  proving/verifying key serves both (as the extractor already assumes).
- Thread the pool tag through the multi-note ceremony and the frontend
  SpendToSign type.

All 30 core tests pass; frontend builds; backend compiles warning-free.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
# Conflicts:
#	src-tauri/core/src/wallet.rs
…nfigurable

The core auto-substituted a 3,800,000 birthday for every new testnet wallet,
forcing ~350k blocks of pre-creation trial-decryption before reaching the tip —
the dominant cause of slow first syncs. A brand-new group holds no funds mined
before it existed, so it now starts at the chain tip and syncs in seconds.

- default_birthday_height returns None (tip) on both networks; new wallets no
  longer scan empty history. Wiped-wallet recovery is unaffected: it uses the
  birthday persisted in settings (wallet_birthdays), supplied by the command
  layer. DEFAULT_TESTNET_BIRTHDAY (3.8M) is retained and made pub as an explicit
  opt-in deep-rescan floor for the rare double-loss case.
- sync_group takes a batch_size (None -> DEFAULT_SYNC_BATCH_SIZE = 5000, clamped
  to [500, 25000]); bigger batches amortize per-batch gRPC round-trip and DB
  transaction overhead. Exposed as a per-install setting (sync_batch_size).

Spend-before-sync early-balance surfacing already works (upstream scans
priority-ordered ranges, UI polls balance every 5s) and needs no change.

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

A post-Ironwood turnstile-out pads the Orchard bundle with a split note — a
zero-value note derived from the group's own spending key (orchard uses these
instead of random dummies so the real spend count doesn't leak). A split note
carries no dummy_sk, so the IO Finalizer never signs it, and it has zero value,
so spends_to_sign's `value != 0` filter treated it as a dummy and skipped it. It
therefore needed the group's spend-auth signature but received none, and the
TransactionExtractor rejected the transaction with Orchard(Extract(
MissingSpendAuthSig)) — reproduced on a live send.

Enumerate a spend for FROST signing by whether it still lacks a spend_auth_sig
after create_pczt_from_proposal's IO Finalizer has run (which already signs every
dummy from its dummy_sk), rather than by value. That selects exactly the wallet's
own notes — real and zero-value split notes alike — and excludes the already-
signed dummies. Sends with a split note now authorize both actions (one FROST
ceremony each). The completeness guard added in the prior commit backstops this.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Post-NU6.3 a group's funds split between the sealed Orchard pool and the new
Ironwood pool, but the wallet only ever read/showed the Orchard pool — so funds
moved across the turnstile were invisible in the balance summary AND treated as
unspendable by the send form (it gated on orchard.spendable_zatoshis). The
account total already includes Ironwood; only the app's surfacing lagged.

Balance:
- WalletStatus/group_status gain an `ironwood: PoolBalance` (from
  AccountBalance::ironwood_balance); the stale "total == Orchard pool" comment is
  corrected (total/spendable already sum every pool).
- The balance summary now shows total/spendable across all pools as the headline,
  with an "Orchard (sealed) · Ironwood" per-pool breakdown line.
- The send form gates on the account-wide spendable/pending, so migrated Ironwood
  funds are spendable and visible.

Migration:
- A "Migrate Orchard → Ironwood" action self-sends the spendable Orchard balance
  to the group's own address; because every post-NU6.3 shielded output lands in
  Ironwood, this sweeps the sealed pool across the turnstile. It reuses the
  self-send review + ceremony path, with distinct migration labelling.
- A prompt appears whenever a group still holds a spendable Orchard balance,
  since that pool can never receive again.

cargo test (32 core) + tsc + vite build + full backend build all green.

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

- ZNS: human-readable names for groups/wallets (name.zcash -> shielded receive
  address). Resolve-first (low effort, high value; show resolved address before
  send), register/claim second (threshold on-chain action via FROST send+memo).
- Tailscale serve: carry the feasibility/impact verdict alongside the item.

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

Several read paths still assumed an Orchard-only wallet, so after receiving into
or migrating to Ironwood, funds were correct on-chain but misrepresented in the
UI:

- wallet_notes queried only orchard_received_notes → Ironwood notes were absent
  from Review Notes (and undercounted the FROST rounds a full-balance send needs).
  Now queries both pools' (identical) tables and merges, largest-first.
- wallet_history's received query was Orchard-only → Ironwood receipts were
  missing from history. Now unions both note tables before grouping per tx. (The
  sent path already uses pool-agnostic v_transactions, so it needed no change.)
- count_orchard_received_notes (drives receive-address rotation on new activity)
  counted only Orchard, so a post-NU6.3 receive — which lands in Ironwood — would
  never rotate the address, silently reusing it across payments. Renamed to
  count_received_notes and now counts both pools.
- Receive card + Review Notes copy updated: funds land in Ironwood post-NU6.3.

cargo test (32 core) + tsc + full backend build green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@USCMig
USCMig merged commit 8519c98 into main Aug 2, 2026
2 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.

1 participant