Skip to content

Add PIR spendability support to zcash_client_sqlite#12

Closed
p0mvn wants to merge 1 commit into
sync-mainfrom
spendability-pir
Closed

Add PIR spendability support to zcash_client_sqlite#12
p0mvn wants to merge 1 commit into
sync-mainfrom
spendability-pir

Conversation

@p0mvn
Copy link
Copy Markdown

@p0mvn p0mvn commented Apr 9, 2026

Branched from maint/zcash_client_sqlite-0.19.x (post zcash_client_sqlite-0.19.5).

https://screen.studio/share/tm6q8yUz

Motivation

During normal wallet sync, Orchard notes are not spendable until the
shard-tree scanner has processed enough blocks to construct a Merkle
authentication path for each note. For wallets that are catching up after
being offline, this can mean a significant delay before funds become
available.

Nullifier PIR (Private Information Retrieval) sidesteps this by querying
an external server for two pieces of information:

  1. Nullifier inclusion — has a note been spent on-chain? This lets the
    wallet mark notes as spent before the scanner confirms it.
  2. Merkle authentication paths — the server provides the witness data
    needed to spend a note, so the wallet does not need to wait for its
    local shard to be fully scanned.

Together, these allow the wallet to display accurate spendable balances
and build transactions within seconds of startup, rather than waiting for
a full scan.

Changes

zcash_client_backend

  • WalletCommitmentTrees::get_pir_orchard_merkle_path — new trait
    method (with default no-op returning Ok(None)) for retrieving a
    PIR-provided Orchard Merkle path by commitment tree position.
  • PirOrchardWitness type alias for the witness tuple.
  • spendability-pir feature flag gating the above.
  • create_proposed_transactions gains a use_pir_witnesses parameter
    (feature-gated) that switches the Orchard witness source from the
    local ShardTree to stored PIR witnesses.

zcash_client_sqlite

  • New wallet::spendability_pir module with:
    • Nullifier gate queries (get_unspent_orchard_notes_for_pir)
    • Witness storage, retrieval, and validation (insert_pir_witness,
      get_pir_witness, validate_orchard_witness, etc.)
    • Helper types: UnspentOrchardNote, NoteNeedingWitness,
      PirWitnessRow, PirWitnessedNote, PirWitnessValidation
  • spendability_pir_tables migration creating the pir_witness_data
    table. The migration is unconditional (not feature-gated) to keep the
    migration DAG identical across all builds; the table is empty and
    unused when the feature is off.
  • get_wallet_summary treats Orchard notes with PIR witnesses as
    spendable even when their shard is not fully scanned.
  • Note selection (select_spendable_notes) accepts Orchard notes with
    PIR witnesses, bypassing the shard-scanned gate.
  • truncate_to_height unconditionally clears pir_witness_data to
    invalidate authentication paths after reorgs.
  • WalletCommitmentTrees::get_pir_orchard_merkle_path implemented for
    WalletDb, backed by the pir_witness_data table.
  • CHANGELOG updated under [Unreleased].

Nullifier PIR lets the wallet discover Orchard note spendability by
querying an external server for nullifier inclusion and Merkle
authentication paths, rather than waiting for sequential shard-tree
scanning to complete. This significantly reduces the time before notes
become spendable.

The implementation is gated behind the `spendability-pir` feature flag
and comprises:

- A `wallet::spendability_pir` module with queries for unspent notes
  eligible for PIR checking, witness storage/retrieval/validation, and
  helper types.
- A `pir_witness_data` table via the `spendability_pir_tables` migration
  (unconditional, not feature-gated, to keep the migration DAG identical
  across all builds).
- `WalletCommitmentTrees::get_pir_orchard_merkle_path` trait method
  (with default no-op) in zcash_client_backend, implemented for
  `WalletDb` backed by the `pir_witness_data` table.
- Changes to `get_wallet_summary` and note selection that treat Orchard
  notes with PIR witnesses as spendable even when their shard is not
  fully scanned.
- Unconditional `pir_witness_data` cleanup in `truncate_to_height` to
  invalidate authentication paths after reorgs.

Made-with: Cursor
@p0mvn p0mvn closed this Apr 9, 2026
greg0x pushed a commit that referenced this pull request Apr 14, 2026
…f0768ea4..dd0ea2c3c5

dd0ea2c3c5 Merge pull request #23 from zcash/2026-03-doc-fixes
93b26b7db1 v0.4.1 release - minor doc fixups
d528fa82e3 Merge pull request #22 from zcash/2025-12-doc-git-subtree
b421ef0b34 Merge pull request #22 from zcash/2025-12-doc-git-subtree
4a26e54c36 Fix git subtree command syntax in README
34bb38b606 Merge pull request #20 from zcash/doc/get_block
a507182f92 Document GetBlock transparent data behavior and clarify nullifier RPCs
fc5cc9a4b1 Merge pull request #19 from zcash/deprecate_get_nullifiers
f0ebc72cad Mark `GetBlockNullifiers` and `GetBlockRangeNullifiers` as deprecated.
9a5f7a0eec Merge pull request #16 from zcash/2026-01-remove-fullHeader
f1095897d9 revert the previous PR that added BlockID.fullHeader
99d9bf9fff Merge pull request #15 from zcash/2025-12-compactblock-doc
bbdd689d73 either CompactBlock.{hash, prevHash}, or CompactBlock.header
aa42926ed3 Merge pull request #13 from pacu/add-README
da4d3d57d8 Add rationale suggested by @LarryRuane
4edd22465b fix type
e36df314b8 clean up whitespace and line width
215cb5a3f3 Add PR suggestions. Organize Clients section
3e78d5d872 Apply suggestions from code review
96b86544db Apply suggestion from @LarryRuane
6259b97df0 Apply suggestion from @nuttycom
f2fcef3e42 Apply suggestion from @nuttycom
8cc1e66b11 Apply suggestion from @LarryRuane
99132222dd Apply suggestion from @nuttycom
207cc5e6f9 create a README file with context and instructions
7392b9706f Merge pull request #12 from zcash/release/v0.4.0

git-subtree-dir: zcash_client_backend/lightwallet-protocol
git-subtree-split: dd0ea2c3c5827a433e62c2f936b89efa2dec5a9a
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