Skip to content

Releases: ZcashFoundation/zebra

Zebra 6.0.0-rc.0

Choose a tag to compare

@upbqdn upbqdn released this 02 Jul 22:46
15d5783

Added

  • Support for the NU6.3 "Ironwood" shielded pool and v6 transaction format,
    activating on Testnet at height 4,134,000. The consensus parameters (v6 version
    group ID, consensus branch ID, and Testnet activation height) match
    zcash_protocol. No Mainnet activation height is set yet.
  • The z_gettreestate, z_getsubtreesbyindex, and verbose getblock RPCs expose the
    Ironwood note commitment tree and its subtree roots from NU6.3 activation
    (#10888).
  • Zebra now tags the coinbase input of every block it mines with a 🦓. The
    mining.extra_coinbase_data option is now limited to 86 bytes (was 94); Zebra
    refuses to start if it is exceeded.
  • Pre-built zebrad binaries are attached to each GitHub release for Linux on
    x86_64 and aarch64, so operators can run a node without Docker or a source
    build, also installable with cargo binstall zebrad. Each .tar.gz carries a
    SHA-256 checksum, a Sigstore build-provenance attestation, and a Cosign signature
    over the checksum manifest (#10799)
  • Added a Regtest configuration option, should_allow_unshielded_coinbase_spends,
    to forbid spending coinbase outputs into transparent outputs (the inverse of
    zcashd's -regtestshieldcoinbase). It defaults to allowing such spends, preserving
    existing Regtest behavior (#10698)
  • When the indexer RPC is enabled, a co-located read-state consumer can follow the
    node more efficiently: the non-finalized block subscription resumes from the
    consumer's known chain tips instead of re-streaming the whole non-finalized state,
    and a new GetBlock indexer method lets the consumer fetch blocks it is missing
    while its finalized state catches up.
  • New zebra-state read request ReadRequest::FindForkPoint (with response
    ReadResponse::ForkPoint) that returns the most recent block in a caller-supplied
    locator that is on the best chain — the fork point — for clients tracking chain
    reorganizations through a read-only state service.
  • Added a [notify] block_notify_command option that runs a command on each best-chain-tip
    change, with %s replaced by the new block hash — Zebra's equivalent of zcashd's
    -blocknotify.

Changed

  • The state database format is bumped to 28.0.0 for the NU6.3 "Ironwood" shielded
    pool. This is a major-version bump that is restorable in place from the previous
    major format version (no resync): an in-place migration backfills the genesis
    Ironwood note commitment tree and anchor, four new (initially empty) ironwood_*
    column families are created, and the chain value pool record is widened to include
    the Ironwood pool. The getblockchaininfo and getblock valuePools now include
    the (zero, until NU6.3 activates) ironwood pool.
  • Opening a Zebra state read-only (for example, as a secondary instance over a
    running node's database) now fails with a clear error instead of panicking when
    the cache directory is missing or unreadable, when no database exists at the
    configured path, or when an ephemeral database is also configured (a read-only
    secondary must not delete the primary's files). The read-write open path is
    unchanged.
  • Upgraded the librustzcash crate cohort to the NU6.3 pre-release wave (orchard
    0.15.0-pre.1, zcash_address 0.13.0-pre.0, zcash_history 0.5.0-pre.0, zcash_keys
    0.15.0-pre.0, zcash_primitives 0.29.0-pre.0, zcash_proofs 0.29.0-pre.0,
    zcash_protocol 0.10.0-pre.0, zcash_transparent 0.9.0-pre.0) for v6 transaction
    and Ironwood support (#10762).
  • Bumped anyhow to 1.0.103, clearing RUSTSEC-2026-0190
    (#10849).

Fixed

  • getblocktemplate now caches the built coinbase transaction per block, so repeated short-poll
    requests within the same block no longer rebuild it. This prevents CPU saturation and multi-second
    template latency when mining to a shielded (Sapling or Orchard) address
    (#10847)
  • Released zebrad binaries report their source commit in zebrad version
    (#10798)
  • Handle invalidateblock and reconsiderblock edge cases (chain-root and
    same-height sibling-tip invalidation, repeated reconsideration) without panicking
    (#10586)
  • A timeout waiting for a transparent input UTXO during transaction verification is
    now treated as a missing input instead of an internal error, preventing a sync
    stall near the chain tip (#10810)
  • The co-located read-state syncer (used by indexers like Zaino) no longer drops and
    re-creates its non-finalized block subscription every second while its view of the
    finalized state lags the node's
    (#10818)

Security

  • Use constant-time comparison for RPC cookie authentication (#10567)
  • Zebra's release Docker images are now reproducible: an independent rebuild of a
    published zebrad from the same commit produces the same binary. The Rust
    toolchain and the Rust and Debian base images are pinned by exact version and
    digest, and build paths and file timestamps are normalized, so two independent
    builds of the same commit produce the same binary. Release images are also built
    without the shared build cache, so a published image cannot inherit a layer from
    a lower-trust build
    (#10798)
  • Release Docker images are signed and carry build provenance and a signed SBOM.
    Each production release gets a Cosign keyless signature, a signed SLSA provenance
    attestation, and a signed SBOM, so anyone can confirm an image came from Zebra's CI
    with cosign verify or gh attestation verify
    (#10798)
  • Route directly pushed transactions (tx messages) through the same per-peer
    mempool admission accounting as advertised transaction IDs, so a single inbound
    peer cannot bypass the per-peer download cap by pushing full transactions
    instead of advertising them
    (GHSA-m9xx-8rcj-vmgp).
    This is the direct-push counterpart of the advertisement-path fix in
    GHSA-4fc2-h7jh-287c. Thanks to @SuplabsYi for reporting the issue.
  • Fixed a panic in the getblock RPC at verbosity 2 for blocks not in the best
    chain: their transactions' confirmations are negative and were cast to an
    unsigned type
    (GHSA-x6v8-c2xp-928m).

Contributors

Thank you to everyone who contributed to this release, we couldn't make Zebra without you:
@andres-pcg, @conradoplg, @dannywillems, @emersonian, @gustavovalverde, @nuttycom, @syszery, @upbqdn and @zmanian.

Zebra 5.2.0

Choose a tag to compare

@github-actions github-actions released this 18 Jun 16:31
62e4a43

Zebra 5.2.0 - 2026-06-18

This release increases Zebra's local rollback window as a defence-in-depth measure
against sustained consensus splits.

Changed

  • Increased Zebra's local rollback window (MAX_BLOCK_REORG_HEIGHT) from 99 to
    1000 blocks as a defence-in-depth measure against sustained consensus splits
    (#10650)

Zebra 5.1.1

Choose a tag to compare

@github-actions github-actions released this 12 Jun 15:02
5126cfa

Zebra 5.1.1 - 2026-06-11

This release reduces Zebra's end-of-support window ahead of the NU7 network upgrade
expected at the end of July 2026, so that nodes running outdated versions stop before
the upgrade activates.

Changed

  • Reduced the end-of-support period from 105 to 44 days, and updated the estimated
    release height, ahead of the NU7 network upgrade
    (#10710)

Zebra 5.1.0

Choose a tag to compare

@oxarbitrage oxarbitrage released this 11 Jun 01:02
80709f0

Zebra 5.1.0 - 2026-06-10

This release fixes a genesis-to-tip sync stall that could cause new nodes to hang
during initial block download, bumps the minimum network protocol version to NU6.2,
extends the getpeerinfo RPC, and includes several performance and correctness fixes.

Breaking Changes

  • The minimum network protocol version is now NU6.2 (170150). Peers running protocol
    versions below NU6.2 will be disconnected. Update to Zebra 5.0.0 or later to remain
    compatible (#10692).

Added

  • Extended getpeerinfo RPC with subver, version, services, lastrecv,
    banscore, and connection_state fields (#10443)

Fixed

  • Fixed genesis-to-tip sync stall that could cause new nodes to hang during initial
    block download (#10679)
  • Fixed mempool index being unnecessarily rebuilt per transaction in getrawmempool
    (#10599)
  • Fixed dequeue_children by-height index handling in the state service
    (#10604)

Contributors

Thank you to everyone who contributed to this release:
@andres-pcg, @conradoplg, @gustavovalverde, @judah-caruso, @oxarbitrage, @syszery and @upbqdn

Zebra 5.0.0 (NU6.2)

Choose a tag to compare

@arya2 arya2 released this 03 Jun 07:22
1e6519e

Zebra 5.0.0 - 2026-06-02

This release activates the NU6.2 network upgrade. NU6.2 re-enables Orchard
actions (temporarily disabled by the 4.5.3 soft fork) using the fixed Orchard
Action circuit, which fixes a critical bug in the Orchard pool. NU6.2
activates at block height 3,364,600 on Mainnet and 4,052,000 on Testnet. We
recommend node operators update before the activation height.

If the activation height has passed and your node followed a fork, you will need
to sync from scratch. If you have a backed-up state before the activation
height, you can sync from that.

Added

  • Activate the NU6.2 network upgrade (consensus branch id 0x5437f330) at height 3,364,600
    on Mainnet and 4,052,000 on Testnet. NU6.2 re-enables Orchard actions with the fixed
    Orchard Action circuit and routes Orchard proofs to a per-circuit verifying key
    (InsecurePreNu6_2 / FixedPostNu6_2).
  • Advertise network protocol version 170150 for NU6.2 on Mainnet, Testnet, and Regtest.

Changed

  • Set the default Testnet temporary Orchard-disabling soft-fork height to 4,048,500; the
    disable window runs until NU6.2 re-enables Orchard actions at height 4,052,000.

Security

  • Add a consensus rule that rejects Orchard bundles whose proof has a non-canonical size,
    effective from the NU6.2 network upgrade (GHSA-jfw5-j458-pfv6).

Zebra 4.5.3

Choose a tag to compare

@arya2 arya2 released this 02 Jun 06:25

This hotfix release adds a soft fork that temporarily disables Orchard actions in
transactions, to mitigate a security issue. We recommend node operators update to
4.5.3 as soon as possible.

Security

  • Add a soft fork that temporarily rejects transactions containing Orchard actions.
    It activates at a fixed height on Mainnet and at a configurable height on Testnet
    (temporary_orchard_disabling_soft_fork_height in the network config), and the
    mempool is revalidated at the activation height to drop any Orchard transactions
    accepted beforehand
    (GHSA-jfw5-j458-pfv6).

Zebra 4.5.1

Choose a tag to compare

@github-actions github-actions released this 29 May 21:34
76c440e

This hotfix release fixes a critical security issues that was not correctly
addressed in 4.5.0. We recommend node operators update to 4.5.1 as soon as
possible.

Security

Zebra 4.5.0

Choose a tag to compare

@github-actions github-actions released this 29 May 01:25
1440b43

This release fixes several critical security issues. We recommend node operators update to
4.5.0 as soon as possible.

The release also adds support for mining to a shielded address.

Security

  • Remove rejected block hashes from SentHashes so honest re-deliveries are
    not short-circuited as duplicates
    (GHSA-4m69-67m6-prqp).
    Thanks to @ipwning and @x15-eth for reporting the issue.
  • Cap the upfront Vec::with_capacity reservation in
    zcash_deserialize_external_count so a peer-supplied CompactSize
    cannot force a large allocation before any element bytes are read. The
    Vec grows naturally via push() as real data arrives. Complements
    the per-type max_allocation() caps from PR #10494
    (GHSA-xr93-pcq3-pxf8,
    #10563). CWE-770.
  • Cap block::Hash::max_allocation at MAX_BLOCK_LOCATOR_LENGTH = 101
    (matching Bitcoin Core's MAX_LOCATOR_SZ in net_processing.cpp) and
    CountedHeader::max_allocation at the existing
    MAX_HEADERS_PER_MESSAGE = 160 constant (already enforced on the
    sending side and at the codec level for read_headers). The previous
    values were derived from MAX_PROTOCOL_MESSAGE_LEN and returned 65,535
    and ~1,409 respectively, allowing a post-handshake peer to force ~2 MiB
    of upfront Vec preallocation per getblocks/getheaders message
    before any payload bytes were read. Same fix shape as
    GHSA-xr93-pcq3-pxf8 for AddrV1/AddrV2 (PR #10494)
    (#10570). CWE-770.
  • Reject non-ASCII longpollid values in the getblocktemplate RPC
    (GHSA-qv2r-v3mx-f4pf).
    Thanks to @sangsoo-osec for reporting the issue.
  • Return error for malformed Sapling receiver in z_listunifiedreceivers RPC
    (GHSA-c8w6-x74f-vmg3).
    Thanks to @robustfengbin for reporting the issue.
  • Prevent sync restart from poisoning the peer inventory registry, and score
    peers that send consensus-invalid blocks
    (GHSA-gvjc-3w7c-92jx,
    GHSA-rj6c-83wx-jxf2,
    GHSA-hwxr-r2v4-9f2p).
    Thanks to @ipwning and @sangsoo-osec for reporting the issues.
  • Avoid panic in address-balance computation on same-address self-spend chains
    by applying transparent debits before credits per transaction
    (GHSA-w834-cf6p-9m9w).
    Thanks to @sangsoo-osec for reporting the issue.
  • Reject repeated shielded transactions cleanly before the defence-in-depth
    tx_loc_by_hash assertion, avoiding a panic
    (GHSA-hhm7-qrv5-h4r6).
    Thanks to @Haxatron for reporting the issue.
  • Cap pre-handshake message body length in Codec to 1 KB; the cap is raised
    to MAX_PROTOCOL_MESSAGE_LEN after handshake completion
    (GHSA-h72h-ppcx-998p).
    Thanks to @ouicate for reporting the issue.
  • Fix sigop undercount in P2SH inputs by routing through the
    legacy_sigop_count_script FFI to match zcashd's
    CScript::GetSigOpCount(true) exactly, preventing a consensus split on
    attacker-chosen redeem scripts
    (GHSA-gf9r-m956-97qx).
    Thanks to @samsulselfut for reporting the issue.
  • Cap the inbound mempool download queue per advertising peer so a single
    peer cannot monopolize verification capacity
    (GHSA-4fc2-h7jh-287c).
    Thanks to @dingledropper for reporting the issue.
  • Canonicalize IPv4-mapped addresses on the misbehavior path so a peer cannot
    evade scoring by alternating between IPv4 and IPv4-mapped-IPv6 forms of the
    same address
    (GHSA-63wg-wjjj-7cp8).
    Thanks to @Haxatron for reporting the issue.
  • Drain the mempool downloader's cancel_handles entry when the outer
    verification timeout fires, so the queued Gossip::Tx(UnminedTx) is not
    retained until the process runs out of memory. Without the fix, a single peer
    that gets each pushed transaction to hit RATE_LIMIT_DELAY could leak up to
    ~2 MB per transaction monotonically
    (GHSA-65jj-fmw8-468q).
    Thanks to @AnticsDecoded for reporting the issue.
  • Pop Sapling/Orchard subtrees when popping non-finalized tip
    (GHSA-2gf8-q9rr-jq3h).
    Thanks to @dingledropper for reporting the issue.

Added

  • Startup warning on Linux when net.ipv4.tcp_slow_start_after_idle is enabled (which resets TCP congestion windows between block requests and significantly reduces single-peer block-propagation throughput on long-haul links), with a "Linux TCP tuning for block propagation" troubleshooting section (#10513)
  • Support for ZIP-213 (Shielded Coinbase) (#10048)

Changed

  • Renamed testnet_parameters in the network config; use [network.params]
    instead (#10051). The
    old format is still accepted.

Fixed

  • Avoid panicking in the address-book ban path when network.max_connections_per_ip > 1. Guard the optional most_recent_by_ip cache instead of unwrapping it, so a ban-threshold misbehavior update no longer crashes the address-book updater and poisons the shared mutex (#10589)
  • Propagate transaction-level value-balance errors from Block::chain_value_pool_change() instead of silently dropping them. The previous flat_map(Result) aggregation relied on Result<T, E>: IntoIterator and yielded zero items on Err, so a failing transaction was omitted from the block sum rather than surfacing as a ValueBalanceError (#10590)
  • Solve Rust 1.97 beta clippy lints (#10644)

Contributors

Thank you to everyone who contributed to this release, we couldn't make Zebra without you:
@ValarDragon, @andres-pcg, @conradoplg, @dingledropper, @evan-forbes, @gustavovalverde, @oxarbitrage, @syszery, @upbqdn, @zmanian.

Zebra 4.4.1

Choose a tag to compare

@github-actions github-actions released this 04 May 20:14
1ec1078

This release fixes one critical security issue. We recommend node operators update to 4.4.1.

Security

  • Reject V5 transparent inputs signed with SIGHASH_SINGLE (or SIGHASH_SINGLE|ANYONECANPAY) when the input has no transparent output at the same index (GHSA-pvmv-cwg8-v6c8). Follow-up to GHSA-cwfq-rfcr-8hmp.

Thanks to @sangsoo-osec, @zmanian, and @fivelittleducks for reporting the issue.

Zebra 4.4.0

Choose a tag to compare

@github-actions github-actions released this 01 May 21:59
589d64b

This release includes several security and bug fixes. We recommend node operators update to 4.4.0.

Security

  • Fix sigops counting (GHSA-jv4h-j224-23cc).
  • Consensus-divergence defense-in-depth follow-up to GHSA-8m29-fpq5-89jj: the V5 sighash callback now substitutes a per-call CSPRNG-derived sighash when rejecting undefined ZIP 244 hash-type bytes, so any peer-supplied signature fails to verify and the block is rejected in agreement with zcashd (GHSA-gq4h-3grw-2rhv, #10524).
  • Allocation amplification in inbound network deserializers: validate coinbase Sapling spend count, coinbase data size, and Equihash solution size before allocating, and enforce the 160-entry cap in read_headers (GHSA-438q-jx8f-cccv, #10525, #10526, #10527, #10528).
  • Validate transparent input/output alignment before script verification, so malformed verifier requests return an error instead of panicking or verifying against a misaligned previous output (#10510).
  • RPC hardening (#10523):
    • Cookie file is now written with explicit 0600 permissions on Unix; symlinks at the cookie path are rejected (GHSA-jg86-rwhm-fhg4).
    • HTTP request bodies are bounded before allocation, with the limit derived from MAX_BLOCK_BYTES to accommodate submitblock (GHSA-8r29-5wjm-jgvx).
    • gRPC indexer streams use try_send to drop slow subscribers instead of backpressuring the server; the buffer was reduced from 4000 to 64. Well-behaved clients are unaffected (GHSA-826r-gfq8-x79q).
    • getrawtransaction reuses the caller-provided block hash and best-chain flag from the initial query, fixing a TOCTOU race against a third state lookup (GHSA-w23c-6rpp-ff87).
  • Disconnect peers that persistently return empty or bad FindBlocks / FindHeaders responses, freeing fanout slots for useful peers. Stall classification happens inside PeerSet::route_p2c, so coverage spans both request types without a separate per-IP guard.

Added

  • nTx (per-block transaction count) field in the verbose getblock RPC response (#10498).
  • Public benchmark dashboard at zebra.zfnd.org/dev/bench covering Groth16, Halo2, Sapling, RedPallas, block, and transaction benchmarks (#10444).

Changed

  • Refreshed the Sentry/OpenTelemetry observability stack (#10490): Sentry SDK upgraded to 0.47 (transport switched from reqwest to ureq); Sentry events now carry SENTRY_ENVIRONMENT, git.ref, git.sha, and CI context (CI_PR_NUMBER, CI_TEST_ID, GITHUB_*) when present; opentelemetry is now part of the default-release-binaries feature set, with export still gated on OTEL_EXPORTER_OTLP_ENDPOINT (or the tracing config); and zebrad::sentry is now crate-private.
  • Upgraded the librustzcash crate cohort (equihash 0.3, orchard 0.13, sapling-crypto 0.7, zcash_address 0.11, zcash_encoding 0.4, zcash_keys 0.13, zcash_primitives 0.27, zcash_proofs 0.27, zcash_protocol 0.8, zcash_transparent 0.7) to the 2026-04 release wave, which migrates off the yanked core2 crate to corez 0.1.1 and clears RUSTSEC-2026-0105 (#10522).
  • Bumped workspace MSRV from 1.85.0 to 1.85.1, required by the new librustzcash releases. Also bumped zebrad MSRV from 1.89 to 1.91, required by cargo-platform 0.3.3 (transitively via vergen-git2).

Fixed

  • getrawtransaction now reports correct confirmations (#10507).

Contributors

Thank you to everyone who contributed to this release, we couldn't make Zebra without you:
@alchemydc, @arya2, @daira, @dependabot[bot], @gustavovalverde, @oxarbitrage, @schell and @upbqdn