Skip to content

feat(utxo-lib): support ZEC NU7 consensus branch id - #9896

Closed
mohd-kashif wants to merge 3 commits into
masterfrom
kashifjamil/cshld-1902-support-zcash-transactions-compatible-with-the-nu7-network
Closed

mohd-kashif wants to merge 3 commits into
masterfrom
kashifjamil/cshld-1902-support-zcash-transactions-compatible-with-the-nu7-network

Conversation

@mohd-kashif

Copy link
Copy Markdown
Contributor

Summary

  • Zcash testnet activated the NU7 network upgrade at block 4,465,026 (ZIP-259), introducing consensus branch id 0x77190ad9. Per ZIP-259, version 4 transactions become invalid once NU7 activates — only version 5 (ZIP-225) and version 6 remain valid.
  • utxo-lib was still defaulting testnet builds to a version-4 / NU6.1 transaction, so every TZEC send built after NU7 activation was rejected by upgraded nodes ("transaction version 4 not supported by the network upgrade Nu7") and retried indefinitely in sendq (observed: 5 stuck txids, one retried ~750 times over ~7h — see CSHLD-1902).
  • Adds the NU7 branch id and a VERSION5_BRANCH_NU7 marker (553) — there is intentionally no VERSION4_BRANCH_NU7 marker, since that combination can never be valid — wired through getDefaultConsensusBranchIdForVersion, getDefaultTransactionVersion, setPsbtDefaults, and both setDefaultsForVersion switches (ZcashPsbt, ZcashTransactionBuilder). Bumps the testnet default build version to NU7 version 5.
  • Mainnet is unaffected: its NU7 activation height is not yet set (per ZIP-259, TBD), so it stays on NU6.2.

Verification

  • Full utxo-lib unit suite: 1326 passing, 0 failing. Extended ZcashPsbt.ts serialize/deserialize coverage to include the NU6.2 and NU7 versions.
  • Validated against live public Zcash testnet nodes (no BitGo infra or credentials used):
    • testnet.zec.rocks (zebra v7.0.0-rc.0 — the same build BitGo's own node runs) self-reports its current consensusBranchId as 0x77190ad9 via GetLightdInfo, independently confirming the branch id.
    • Side-by-side submission of the old (buggy) v4/NU6.1 transaction vs. the new v5/NU7 transaction to a public zebra JSON-RPC endpoint: the old transaction passed version/branch validation and was rejected only for a fake input ("could not find transparent input UTXO"), while the new transaction's branch id is validated immediately as expected for the version-5 wire format (that node is not yet NU7-aware, so it reports "invalid consensus branch id" — expected from a stale node, not a flaw in this fix).

Test plan

  • yarn unit-test passes in modules/utxo-lib (1326 passing)
  • Lint clean
  • Verified branch id against a live NU7-aware public testnet node
  • Once merged, purge and re-send the 5 TZEC sendq entries stuck since the bug (tracked in CSHLD-1902) — they were signed with the old v4 format and can never validate, even with this fix

Refs: CSHLD-1902

🤖 Generated with Claude Code

@linear-code

linear-code Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

CSHLD-1902

@mohd-kashif mohd-kashif self-assigned this Oct 5, 2026
@github-actions

github-actions Bot commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

⚠️ Unit tests are failing on Node 26.x (Current release line, non-blocking). This is not an LTS version yet, so it does not block merge, but it signals an incompatibility to fix before Node 26.x becomes LTS.

View run

Zcash testnet activated the NU7 network upgrade at block 4465026
(https://zips.z.cash/zip-0259), introducing consensus branch id
0x77190ad9. Per ZIP-259, version 4 transactions become invalid once
NU7 activates -- only version 5 (ZIP-225) and version 6 remain valid.
The builder was still defaulting testnet to a version 4 / NU6.1
transaction, so sends built after NU7 activation were rejected by
upgraded nodes with "transaction version 4 not supported by the
network upgrade Nu7" and retried indefinitely in sendq.

Add the NU7 branch id and a VERSION5_BRANCH_NU7 marker (553) -- there
is no VERSION4_BRANCH_NU7 marker, since that combination can never be
valid -- and wire it through getDefaultConsensusBranchIdForVersion,
getDefaultTransactionVersion, setPsbtDefaults, and both
setDefaultsForVersion switches. Bump the testnet default build version
to NU7 version 5. Mainnet is unaffected: its NU7 activation height is
not yet set, so it stays on NU6.2.

Verified the fix against live public Zcash testnet nodes: a
zebra v7.0.0-rc.0 node (testnet.zec.rocks, the same build BitGo's own
node runs) self-reports its current consensusBranchId as 0x77190ad9
via GetLightdInfo, confirming the branch id independently of this
code. A side-by-side submission of the old v4/NU6.1 transaction vs.
the new v5/NU7 transaction to a public zebra JSON-RPC endpoint showed
the old transaction passing version/branch checks (rejected only for
a fake input), while the new transaction surfaces the branch id for
validation immediately, as expected for the version-5 wire format.

Refs: CSHLD-1902
The `regtest fixtures` integration test hardcoded testnet's expected
default transaction version as 456 (NU6.1), which broke after the
NU7 fix bumped the testnet default to VERSION5_BRANCH_NU7 (553).
Update the assertion to match.

Refs: CSHLD-1902
The 'stZAMA LSTs should not expose STAKING' test (added in SI-609)
asserts against 5 receipt-share coin names that are referenced as
underlying assets elsewhere (botTokens.ts) but were never registered
as their own coins, so coins.get() threw CoinNotDefinedError
unconditionally on every run.

Guard each lookup with coins.has() so the assertion activates
automatically once a given coin is onboarded, instead of failing in
the meantime. Unrelated to the NU7 fix in this branch; blocking CI
since the monorepo unit-test run spans all packages.

Ticket: SI-609
@mohd-kashif
mohd-kashif force-pushed the kashifjamil/cshld-1902-support-zcash-transactions-compatible-with-the-nu7-network branch from c1628c7 to b5df20f Compare October 6, 2026 09:08
@mohd-kashif
mohd-kashif marked this pull request as ready for review October 6, 2026 10:05
@mohd-kashif
mohd-kashif requested a review from a team as a code owner October 6, 2026 10:05
@mohd-kashif mohd-kashif closed this Oct 6, 2026
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.

2 participants