TxGuard: Zcash v5 Consensus Branch‑ID Preflight (CLI + GitHub Action)

Project Summary

TxGuard is a small CLI and GitHub Action that checks a Zcash v5 transaction’s embedded consensus branch ID against what a target node expects in the current upgrade context, and fails CI (or pre-broadcast) on mismatch. It prevents a recurring “can’t send” failure mode seen across wallets during 2024–2025 upgrade events by catching branch-ID mistakes before release.

Project Description

TxGuard is a small, focused developer tool meant to reduce a specific and recurring class of Zcash send failures: broadcasting a Zcash v5 transaction with an incorrect embedded consensus branch ID, which can cause the transaction to be rejected, particularly around network upgrade boundaries. When this happens, wallet/service teams typically need to ship a fix before users can send again.

The project will deliver an open-source command-line tool and a GitHub Action that external wallet and service teams can run in CI or as a pre-broadcast check. TxGuard takes a raw v5 transaction hex produced by the team’s code and verifies branch-ID alignment in one of two ways:

  • Online mode (recommended): TxGuard queries a target node via RPC and derives the expected branch ID from the node’s reported upgrade context. If the required fields are missing or ambiguous, it fails closed with an “insufficient context” error rather than guessing.

  • Offline mode: Teams can supply an explicit expected branch ID when CI cannot reach a node, and TxGuard performs the same comparison deterministically.

TxGuard is CI-friendly: it returns stable exit codes and can emit a machine-readable JSON report so teams can gate releases and diagnose mismatches quickly. An optional wrapper mode is included for broadcast services: it runs the same check before calling sendrawtransaction, so mismatched transactions can be blocked before a broadcast attempt.

The goals of the project are:

  1. Reduce the chance of user-facing send failures caused by branch-ID mismatches by catching them before release or broadcast.

  2. Make the check easy to adopt by shipping a standalone CLI, a copy/paste GitHub Action example, clear documentation, and deterministic outputs.

  3. Avoid false confidence by keeping scope narrow (branch-ID alignment only), failing closed on unknowns, and clearly stating what the tool does not validate.

  4. Make the work reusable by including a minimal vector pack (good/bad fixtures) and an optional upstream-ready patch bundle, without depending on any upstream merge for TxGuard itself to be useful.

Proposed Problem

A recurring and user-blocking problem in the Zcash ecosystem is wallets and services producing Zcash v5 transactions with an incorrect embedded consensus branch ID, especially around network upgrade boundaries. When this happens, the transaction is rejected at broadcast time and users cannot send funds until the wallet/service software is updated and redeployed. This is not a theoretical edge case; it has surfaced repeatedly across different wallet contexts and implementations.

In practice, this failure mode is painful for both users and developers:

  • Users experience “can’t send” failures with confusing errors (for example, branch ID mismatch) and often assume Zcash itself is broken.

  • Wallet and service teams face urgent support load and must ship fixes quickly, because the issue blocks normal funds movement.

  • The same class of failure repeats at upgrades because branch ID correctness is an upgrade-edge requirement, and it is easy for external stacks (especially those built on custom or forked transaction logic) to miss an update.

This recurring breakage is visible in public 2024–2025 reports and upstream work:

Even though documentation exists, these incidents show that documentation alone does not reliably prevent implementations from shipping the wrong branch ID. What is missing is a small, CI-friendly enforcement step that checks the actual transaction bytes produced by a wallet/service before release or broadcast. This proposal directly targets that gap.

Proposed Solution

This project will deliver TxGuard, a small CI-first tool that helps wallet and service teams catch a specific upgrade-edge mistake before release or broadcast: producing a Zcash v5 transaction with an incorrect embedded consensus branch ID, which can cause the node to reject the transaction.

TxGuard performs one narrow check:

Does the transaction’s embedded consensus branch ID match the expected branch ID for the target node’s current upgrade state?

What TxGuard provides (v1)

1) Standalone CLI (runs locally or in CI)
TxGuard takes a raw v5 transaction hex produced by the team’s code and compares the transaction’s embedded branch ID against an expected value:

  • Online mode (recommended):
    txguard check --rawtx <hex> --rpc <node_rpc_url>
    TxGuard queries the target node via RPC and derives an expected branch ID from the node’s reported upgrade context. If the node response does not provide enough information to derive an expected value, TxGuard fails with an “insufficient context” error rather than guessing.

  • Offline mode:
    txguard check --rawtx <hex> --expected-branchid <hex>
    For environments where CI cannot reach a node, teams can supply the expected branch ID explicitly and the check remains deterministic.

TxGuard outputs:

  • a clear pass/fail result,

  • an optional machine-readable JSON report (--json report.json), and

  • a CI-friendly exit code (0 pass

Solution Format

  • A small command-line tool (TxGuard) distributed as release binaries (and optionally a container image).

  • A GitHub Action wrapper that runs TxGuard in CI and can upload a JSON report artifact on failure.

  • A machine-readable JSON report format plus stable exit codes so teams can gate releases and troubleshoot mismatches quickly.

  • A minimal fixture/vector pack (good/bad examples) used for TxGuard’s own tests, plus an optional upstream-ready patch bundle (not required for TxGuard to work).

  • Documentation: quickstart, CI integration snippet, wrap/broadcast usage, and a short troubleshooting guide.

Dependencies

Technical dependencies

  • A standard development environment for building a small CLI tool (open-source toolchain and libraries for parsing hex/bytes and producing JSON output).

  • For online mode, access to a Zcash node RPC endpoint (in test/staging) that supports getblockchaininfo. TxGuard also supports an offline mode where the expected branch ID is provided explicitly.

  • Release tooling for security hygiene: signing for release tags/artifacts, SBOM generation, and reproducible build steps (verified in CI).

Resources

  • Developer time for implementation, tests (including basic fuzz/property tests), documentation, release packaging, and a 90-day maintenance window.

  • CI to run tests and publish artifacts (e.g., GitHub Actions or equivalent).

Collaborations

  • No formal collaborations is required.

  • Optional community feedback via public issues/threads.

Technical Approach

1) Implementation and packaging

  • Implement TxGuard as a single CLI (Rust is a good fit for safe, deterministic parsing and distributing stable binaries).

  • Publish versioned release binaries. A minimal container image is optional and only for easier CI usage (the tool must work without Docker).

**2) v5 transaction parsing **

  • Parse only what is required from the raw transaction bytes to:

    • confirm the transaction is v5, and

    • extract the embedded consensus branch ID field.

  • Use bounded parsing with explicit error returns (no panics on malformed inputs).

3)Expected branch ID derivation

  • Online mode: call a target node RPC endpoint and derive an expected branch ID from the node’s reported upgrade context. If the expected value cannot be derived from the RPC response, TxGuard returns a clear “insufficient context” failure rather than guessing.

  • Offline mode: accept --expected-branchid <hex> so teams can run the check deterministically in CI environments where RPC access is not available.

Note: TxGuard does not depend on any deprecated node stack. Online mode works with any node implementation that exposes the required RPC fields; offline mode works even without node access.

4)Check + reporting

  • txguard check compares:

    • tx embedded branch ID, vs

    • expected branch ID ,
      and returns:

    • stable exit codes,

    • a short human-readable summary, and

    • optional JSON output (--json) for CI artifacts.

  • txguard inspect prints only the parsed tx version and embedded branch ID to support debugging.

5) Testing and correctness safeguards

  • Unit tests for parsing and mismatch detection using a minimal fixture pack (good/bad examples).

  • Mocked-RPC tests for online mode, so behavior is reproducible and does not rely on live infrastructure.

  • Basic fuzz/property tests focused on parser safety and report serialization (ensuring malformed inputs cannot crash the tool).

6) Release hygiene

  • Signed tags and/or signed release artifacts.

  • SBOM generation for releases.

  • Documented build steps that CI can reproduce (pinned toolchain/dependencies and repeatable release workflow).

Upstream Merge Opportunities

TxGuard does not fork or modify any upstream Zcash repositories. It will ship as a standalone tool and does not depend on upstream merges.

Hardware/Software Costs (USD)

0

Hardware/Software Justification

n/a

Service Costs (USD)

0

Service Costs Justification

n/a

Compensation Costs (USD)

$21,000

Compensation Costs Justification

  • Core development, tests, docs, CI/Action, and release hygiene: ~175 hours × $100/hr = $17,500

  • 90-day light maintenance (bug fixes, minor compatibility adjustments, support): ~40 hours × $100/hr = $4,000

Total: 215 hours × $100/hr = $21,500

Total Budget (USD)

$21,000

Previous Funding

No

Previous Funding Details

No response

Other Funding Sources

No

Other Funding Sources Details

No response

Implementation Risks

  • RPC field variability: Online mode relies on extracting the expected branch ID from getblockchaininfo. If required fields are missing or differ across nodes, TxGuard must fail closed and direct users to offline mode.

  • Scope control: There is a risk of expanding beyond the intended v1 (v5 branch-ID alignment). v1 must stay limited to that single check to remain feasible.

  • Input handling: TxGuard must handle malformed tx hex or missing parameters safely, returning clear errors without crashing.

  • Maintenance: If relevant RPC response fields change, the online extraction logic may need small updates during the 90-day maintenance window.

Potential Side Effects

  • False sense of full validity: Teams might treat a “pass” as meaning the transaction is fully valid. TxGuard will mitigate this by clearly stating in output and documentation that it only checks branch-ID alignment, not full transaction validity.

  • Extra CI friction: Adding a new CI step can block releases if the tool can’t verify (e.g., RPC unavailable) or detects mismatches. This is intentional for safety, but it may require teams to adjust workflows (using offline mode where needed).

  • Misconfiguration risk: If a team supplies the wrong expected branch ID in offline mode, TxGuard will still behave deterministically, but they could block themselves unnecessarily. Documentation will emphasize correct parameter handling and when to prefer online mode.

Success Metrics

Adoption in real projects:

  • Within ~90 days of v1.0, at least 10 external repositories (not owned by us) using TxGuard in CI (via the Action or CLI).

    • Within ~180 days, at least 25 external repositories using it.
  • Evidence it prevents real failures:

    • At least 2 public examples (issue/PR/forum post) within 180 days where TxGuard output is referenced as catching a branch-ID mismatch before release or broadcast.
  • Basic usage volume:

    • At least 300 downloads/pulls (release binaries and/or container pulls) within 90 days, and 1,000 within 180 days.
  • Maintenance performance:

    • During the 90-day maintenance window, confirmed bugs reported by users are either fixed in a patch release or documented with a workaround within the window.

Startup Funding (USD)

n/a

Startup Funding Justification

n/a

Milestone Details

  • Milestone: M1 — Core CLI (v5 parse + inspect + offline check)
    Amount (USD): 5,500
    Expected Completion Date: 2026-01-20
    User Stories:

    • “As a wallet/service developer, I want to inspect a raw Zcash v5 transaction and see its embedded consensus branch ID, so that I can debug branch-ID mismatch failures faster.”
    • “As a CI engineer, I want an offline branch-ID check with stable exit codes, so that I can run the check even when CI cannot reach a node RPC endpoint.”
      Deliverables:
    • txguard inspect --rawtx <hex> [--json] (prints tx version and embedded branch ID)
    • txguard check --rawtx <hex> --expected-branchid <hex> [--json report.json] (offline mode)
    • Minimal fixtures for TxGuard self-tests: good_v5.hex and bad_wrong_branchid.hex
    • Unit tests for v5 parsing and mismatch detection
      Acceptance Criteria:
    • Running txguard inspect on good_v5.hex prints tx_version=5 and a branch ID value.
    • Running txguard check passes on good_v5.hex and fails on bad_wrong_branchid.hex with a non-zero exit code and a mismatch message.
    • All unit tests pass in CI.
  • Milestone: M2 — Online mode (RPC-derived expected branch ID, fail-closed)
    Amount (USD): 6,000
    Expected Completion Date: 2026-02-03
    User Stories:

    • “As a developer, I want TxGuard to derive an expected branch ID from my target node’s RPC output, so that I don’t have to hardcode upgrade constants.”
    • “As a release engineer, I want the tool to fail when it cannot determine an expected value from RPC, so that CI does not report a false pass.”
      Deliverables:
    • txguard check --rawtx <hex> --rpc <node_rpc_url> [--json report.json] (online mode)
    • Mocked-RPC fixtures and tests covering: pass, mismatch fail, and “insufficient context” fail
    • JSON report includes tx_branch_id, expected_branch_id (when available), and verification_mode (online/offline)
      Acceptance Criteria:
    • With mocked RPC fixtures, txguard check returns the expected exit codes for pass/mismatch/insufficient-context cases.
    • If required RPC fields are missing/ambiguous, TxGuard fails with “insufficient context” and a non-zero exit code.
  • Milestone: M3 — GitHub Action + optional wrap-sendrawtransaction mode
    Amount (USD): 5,000
    Expected Completion Date: 2026-02-17
    User Stories:

    • “As a CI engineer, I want a copy/paste GitHub Action step, so that I can add TxGuard to CI quickly.”
    • “As a service operator, I want an optional pre-broadcast wrapper, so that I can block branch-ID mismatched transactions before attempting to broadcast.”
      Deliverables:
    • GitHub Action wrapper that runs txguard check and can upload the JSON report artifact on failure
    • Example workflow in the TxGuard repo demonstrating both a passing and failing fixture
    • Optional txguard wrap-sendrawtransaction --rpc <url> --rawtx <hex> command with documented behavior
    • Short documentation: “Add to CI” and “Use wrap mode”
      Acceptance Criteria:
    • The example workflow fails on bad_wrong_branchid.hex, passes on good_v5.hex, and uploads report.json on failure.
    • Wrap mode blocks a mismatch and returns a clear error without broadcasting (validated via a stubbed RPC test).
  • Milestone: M4 — Release hardening + vector pack + upstream-ready patch bundle
    Amount (USD): 3,000
    Expected Completion Date: 2026-03-03
    User Stories:

    • “As an integrator, I want verifiable releases (signing + SBOM), so that I can trust TxGuard in CI.”
    • “As a maintainer, I want a small fixture/vector pack that can be proposed upstream, so that this failure class is easier to test elsewhere if maintainers choose.”
      Deliverables:
    • Signed release tag and/or signed artifacts for v1.0.0
    • SBOM generated and published with the release
    • Reproducible build instructions verified in CI
    • Minimal vector pack under vectors/branchid/ and an optional format-patch/ bundle
    • Basic fuzz/property tests for parser safety (bounded runtime in CI)
      Acceptance Criteria:
    • v1.0.0 release exists with verification instructions and an SBOM artifact.
    • CI includes a documented build path that produces the release artifacts.
    • Fuzz/property tests run in CI for a bounded duration without crashes.
  • Milestone: M5 — 90-day maintenance window
    Amount (USD): 2,500
    Expected Completion Date: 2026-06-03
    User Stories:

    • “As an adopter, I want early bugs addressed promptly, so that the tool remains usable during initial adoption.”
      Deliverables:
    • Up to ~40 hours of maintenance: bug fixes, minor compatibility adjustments (e.g., RPC-shape handling), documentation clarifications
    • One patch release if needed during the window
      Acceptance Criteria:
    • Issues filed during the window receive an initial response within 7 days.
    • Confirmed bugs are fixed in a patch release or documented with a workaround during the maintenance period.
2 Likes

The ‘can’t send’ failures during recent upgrades were a significant hurdle for user trust. Providing a tool that ‘fails closed’ is absolutely the right approach for financial privacy software.

Further Recommendation (if you don’t mind):
To drive the ‘Adoption’ success metric you mentioned, it might be worth creating a ‘TxGuard Verified’ badge for READMEs. It’s a small addition, but it highlights to users that a wallet/service is actively testing against consensus branch-ID mismatches.

I’m currently looking into how we can improve developer onboarding, and would be interested in discussing how TxGuard could be integrated as a standard check in future Zcash RFP templates.

Overall, great work identifying this gap,
GGs!

1 Like

Thank you. We agree that failing closed is the right default for anything finance-adjacent. The “TxGuard Verified” badge is a good idea too; we’ll include it as an optional README badge that links to a short page explaining exactly what TxGuard checks (branch-ID alignment for v5) and what it does not. Also happy to share a copy-paste CI snippet that could fit future onboarding/RFP templates.

1 Like

Glad it helped. Sharing the snippet is also fine if you wish to.

Anything else is welcome, as long as it helps contribute.
All the best.

1 Like