Skip to content

Parse NU7 transactions and size scanner catch-up for 25 s blocks - #7

Merged
Kenbak merged 1 commit into
mainfrom
new/cipherpay-nu7-backend-6b9bca
Nov 5, 2026
Merged

Kenbak merged 1 commit into
mainfrom
new/cipherpay-nu7-backend-6b9bca

Conversation

@Kenbak

@Kenbak Kenbak commented Nov 5, 2026

Copy link
Copy Markdown
Collaborator

Problem

Production (b902f50) locks zcash_protocol 0.10.5, which maps NU7 to the placeholder branch id 0xFFFFFFFF. Real NU7 transactions carry 0x77190AD9, so:

  • scan_blocks fails on the first NU7 block (invalid consensus branch id) before saving its checkpoint, so it retries that block forever. Mainnet activates at 3,543,405; testnet activated at 4,465,026.
  • The mempool, x402 verification and session-deposit paths treated a parse failure as "no outputs", so payments would be missed silently.
  • Catch-up after downtime assumed 75 s blocks; NU7 targets 25 s, so the start height came out too late.

Changes

  • Move all Zcash crates to the Zakura 5.2.0 family (zakura-primitives, -orchard, -protocol, -address, -note-encryption). They must all stay on one release so the types line up. Orchard needs backend-halo2 and zip32-addresses.
  • decrypt.rs: a single parse_transaction helper; parse failures are now Err, not Ok(vec![]).
  • scanner/mod.rs: earliest_relevant_height uses 25 s spacing plus a 300-block margin.

Tests

  • Real testnet fixtures from just before activation, at activation (v5/v6) and later (7 Orchard + 2 Ironwood actions). The parser recomputes their exact on-chain txids, and trial decryption runs for every caller path.
  • scan_blocks over activation block 4,465,026 with a pending invoice advances scanner_state. The same test fails on production dependencies.
  • Golden UIVK, receiver and UA values at indices 0/1/7/1000 (mainnet and testnet), taken from the b902f50 build, are byte-identical, so existing invoices still match.
  • Locally: cargo test --locked gives 130 passed, 3 ignored (pre-existing). cargo build --release --locked, scripts/check-dependency-exposure.py and cargo audit all pass.

Polling (15 s blocks / 5 s mempool) and the 1-confirmation rule need no change for 25 s blocks.

Not done

  • No release or deployment yet.
  • Live NU7 testnet qualification is still needed: Orchard and Ironwood payments through detection, confirmation, checkout and webhook, plus x402 and session deposits.
  • After the mainnet rollout, confirm the scanner passes 3,543,405.

🤖 Generated with Claude Code

The locked zcash_protocol 0.10.5 maps NU7 to a placeholder branch id, so
every transaction from the NU7 activation block on failed to parse with
"invalid consensus branch id". The block scanner retried that block forever,
and the mempool, x402 and session-deposit paths silently returned no outputs.

- Move every Zcash crate to the Zakura 5.2.0 family, which knows NU7
  (0x77190AD9) and its mainnet/testnet activation heights.
- Route all parsing through one helper and return parse failures as errors
  instead of empty output lists.
- Compute the catch-up start height from the 25 s NU7 target spacing plus a
  300-block margin instead of 75 s plus 100 blocks.
- Add real NU7 testnet fixtures (Orchard and Ironwood bundles), a scan_blocks
  test across the activation block, and golden address/UIVK checks against the
  pre-NU7 production build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Kenbak
Kenbak merged commit 0a87c6f into main Nov 5, 2026
4 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