ZF Engineering Update: 7 - 20 September 2026

Over the past two weeks, we worked on reducing delays for miners, improving Zebra’s handling of competing blocks, and supporting lower transaction fees. We also restored documentation updates, improved our testing and monitoring, and addressed security reports. The node changes below were merged into Zebra’s development branch during this period and are not yet part of a published Zebra release. The missing transaction checks described below affected development code only.

Faster mining and more reliable nodes

We merged a change that prepares block templates in the background, reducing the time miners wait for their next set of work.

We also corrected how Zebra chooses between competing blocks. When two blocks have the same height and accumulated work, Zebra now keeps the one it received first. This avoids unnecessary switches between competing versions of the chain.

For operators using the bundled zcashd compatibility helper for wallet support, we updated the helper so it can follow deep chain rollbacks alongside Zebra without shutting down.

We fixed a development-only regression in proof data returned by detailed lookups of older shielded transactions. Published releases were unaffected. A separate fix prevents a transparent address’s “total ever received” counter from wrapping around after exceptionally large cumulative payments. This corrects the reported total; it does not change the address’s funds.

Support for lower fees

@aphelionz added support for a lower conventional transaction fee: 1,000 zatoshis per logical action, down from 5,000. For a minimal transaction, that means 2,000 zatoshis instead of 10,000. The change also adjusts how miners prioritise transactions by fee.

The fee proposal remains a draft. It recommends that wallets switch at Mainnet block 3,590,000, after nodes have shipped support for relaying transactions at the lower fee. This is a wallet and relay-policy change, not a change to consensus rules.

@str4d also added shielded-pool balance metrics using the same names as zcashd, helping existing monitoring dashboards work with Zebra.

Security checks restored before release

Security reviews found that moving transaction parsing into shared Zcash libraries had left out several validation checks on Zebra’s development branch. Every published Zebra version retains these checks.

We restored checks covering mining-reward inputs and transaction expiry, value leaving the older Sprout shielded pool, and an input format reserved for mining rewards. Each now has regression tests to catch future omissions. Thanks to the Zakura security team and @ouicate for reporting these issues.

Separately, @jiehuo100net improved how Zebra penalises peers that send blocks containing duplicate transactions, making peer scoring during sync more consistent. Zebra already rejected these blocks; the change concerns the penalty applied to the peer.

Documentation, testing, and monitoring

The Zebra book is updating again after a build failure stopped publication on 8 September. We fixed the build, and readers can now ask a documentation assistant questions from any page. The assistant loads only after a reader opts in, and the browser remembers that choice.

Behind the scenes, we made testing more reliable and reduced its resource use:

We added monitoring to check that fresh nightly Mainnet snapshots actually reach the download site. We also upgraded the monitoring service.

Work in progress

We are improving how Zebra turns pending transactions into candidate blocks. This brings block-template creation and validation together and checks transactions alongside the earlier transactions they depend on. Preparing templates in advance was the first step; the remaining work is under review.

@judah-caruso opened an early implementation of a halving-preserving issuance rule proposed for NU7, the next network upgrade. It requires explicit build-time enablement and has no activation height set. It does not change the rules used by nodes today.

Thank you to our contributors

Thanks to @aphelionz, @str4d, and @jiehuo100net for the improvements highlighted above, and to @john-lawniczak for restoring the build for our automated random-input tests.

Thanks also to @ouicate, the Zakura security team, and @zmanian for their reports, and to @judah-caruso for the early NU7 work.

8 Likes

Happy to see this in the update, and glad I could help. I reported two consensus-critical regressions while they were still on Zebra’s development branch. Both are fixed there now. They never shipped in a Zebra release, so mainnet was never exposed.

In short: either one, in a published release, would have been a chain split. Zebra would have accepted transactions or blocks that the protocol requires rejecting, and that other conforming nodes reject. Nodes would have followed different chains.

The two rules were:

  • Coinbase script length. A coinbase scriptSig must be 2 to 100 bytes. On the development branch that check was no longer on the path a node actually runs. A miner could have produced a block that new Zebra nodes accepted and other nodes rejected.
  • Transaction expiry. A non-coinbase transaction’s expiry height must be at most 499,999,999. A large band of higher values was treated as “no expiry” and accepted. Anyone could have created that transaction. Once a miner included it, Zebra would have extended a chain that rule-following nodes refused.

To other researchers: report a consensus bug when you confirm it on the development branch. Waiting for a tagged release, a CVE, or a published advisory would have left these in the first release that carried them, and put Zcash at risk for no benefit. Finding them early is what kept them off the network. Credit in the issue and in this update is the right outcome.

2 Likes