Release: Zakura 1.8.0


We have released Zakura 1.8.0, a security and stability release. It removes unnecessary dependencies, reducing supply chain risk and making our release downloads smaller. This builds on the reductions we already shipped in 1.7.0. We also made significant performance improvements to block announcement and validation.
NU7 activates on Mainnet in about three days, but there is no rush to update to 1.8.0 if you are already running 1.7.0. Updating early is fine too, and gets these improvements onto the network sooner.
Fewer Dependencies
Zakura's dependency lock file lists 341 packages, down from 350 in 1.7.0.
- The Prometheus metrics endpoint is now in-tree, replacing
metrics-exporter-prometheus. Metric names and the output format are unchanged. Histogram quantiles also become more accurate: they now reflect every sample from the last minute, where the previous exporter lost samples recorded before a histogram's first scrape. - Building Zakura no longer requires libclang. The RocksDB bindings are no longer generated at build time, removing a system prerequisite we introduced in 1.1.1.
- The bundled RocksDB is compiled without features Zakura never uses, such as SST file ingestion and remote compaction. This leaves out more than 500 KB of code and shortens clean builds; RocksDB's behavior and the on-disk database format are unchanged.
- The indexer gRPC server is now a build-time choice. Default and release builds still include it, and a build without the new
indexer-rpcfeature drops the gRPC dependency tree entirely.
Faster Block Announcements
New blocks are announced to peers up to about 110× faster. In a two-node benchmark measuring the time from a block mined on one node to the other node building a block template on it, the median fell from 833 ms to 7.5 ms, statistically indistinguishable from Zebra 7.0.0 on the same setup.
The old median was a worst case for a quiet node: an announcement could sit behind an unanswered block-discovery request until that request's six-second timeout, and most samples did. Announcements now go out on their own queue, adopting the announcement design Zebra uses.
The effect is already visible on Mainnet. After a mining pool upgraded its sending node to Zakura 1.8.0-rc.1, the median time from the pool submitting a block to our nodes accepting it fell by about half, and the slowest deliveries by about three quarters (16 blocks before, 13 after, across three receivers):
| Before upgrade | After upgrade | |
|---|---|---|
| Median delivery delay, across three receivers | 1.15 to 1.56 s | 0.63 to 0.69 s |
| Slowest observed delivery | 7.44 to 7.55 s | 1.35 to 1.91 s |
With NU7 tripling the block rate, these delays would have occurred three times as often. The related changes:
- Blocks no longer queue behind earlier announcements. Newly mined or received blocks previously waited for an earlier block's announcements to finish; each block's announcements now start immediately.
- Quiet connections answer immediately. When its mempool is empty, the node now replies to inventory requests with an empty list instead of letting them time out. This removes block relay delays of up to six seconds for sparsely connected nodes.
- Announced blocks download at once. Blocks announced while the node waits on a discovery reply from the same connection download immediately instead of after the full discovery round. Gossiped blocks that arrive before their parent request the missing parent right away, after a proof-of-work check, instead of waiting for the next sync round.
- Announcement peers stay current. The peers selected for legacy block announcements are refreshed while the node is idle, and announcements retry against fresh peers when a selected connection becomes unusable.
- Local transactions reach block templates sooner.
sendrawtransactionand other local submissions no longer wait an extra 50 ms per transaction before the verified transaction enters the mempool and block templates.
Faster Block Validation
Verifying new blocks and accepting mined ones is faster across every block type we benchmark; the comparison section below puts the numbers next to Zebra's. The changes:
- Accepting a block built from the node's own template takes about half as long. In our benchmarks, a 1.9 MB block drops from 375 ms to under 200 ms. The node no longer logs every transaction during the commit, reads output addresses straight from their scripts, skips the Merkle check for a template it already validated, and reuses the template's transactions instead of parsing them again. Miners start building on their own blocks sooner.
- Verifying a block the node has never seen takes up to 34% less time. In our benchmarks, a 1.9 MB transparent block drops from 2.14 to 1.41 seconds, and a mixed block from 882 to 742 ms. Transaction results are collected without being throttled by the async runtime, and Orchard proof batches are prepared on blocking threads instead of the workers that admit transactions, which makes Orchard blocks verify in about 11% less time.
- The Common libraries are updated to 5.0.0, with faster Groth16 proof and RedDSA signature batch verification and faster parsing of Sapling proofs.
- Per-block overhead falls 3 to 5% on every block. Verification no longer recomputes each transaction's ID for its signature hashes, network upgrade lookups no longer rebuild their tables, parent-input checks overlap their reads, and block commits no longer open a tracing span per transaction.
getblocktemplatealso uses about 10% less CPU. - Transactions use less memory. Sprout, Sapling, and Orchard bundles move out of every transaction's inline representation.
Comparing With Zebra Ándale
The Zcash Foundation recently released Zebra Ándale, a performance build for miners and mining pools, with benchmarks comparing it to Zakura 1.7.0. Congratulations to the Zebra team on the release.
On everyday Mainnet blocks, the two nodes are close. The Foundation's live dashboard feeds every new Mainnet block to each node and times its acceptance. Over the 24 hours to November 2 (1,154 blocks), Zakura 1.7.0 accepted a block in a median of 6.7 ms against Ándale's 5.9 ms, a difference of under a millisecond, while Zebra 7.0.0 took 119 ms.
The Zebra team's benchmarks also exercise more demanding cases, such as large synthetic blocks sent to nodes with no peers and empty mempools, where every proof is checked inside the block rather than earlier in the mempool. Those cases were a useful stress test for us, and they pointed to several improvements in this release.
The biggest one was in block announcements. The announcement of a new block could wait behind a busy connection, which slowed how quickly a peer learned about a block and built new work on it. That is fixed in 1.8.0. On the Zebra team's tip-to-template benchmark, run on our hardware, the median fell from 833 ms to 7.5 ms. Thanks to the Zebra team for publishing their benchmark harness, which made this easy to find and confirm.
Running the same harness against Ándale, block propagation is now measured in milliseconds on both nodes, and Zakura is the more predictable of the two. When a peer learns of a new block over a fresh connection, Zakura 1.8.0 builds new work on it in a median of 61 ms, and never took longer than 106 ms across 18 runs; Ándale's median was 71 ms, with its slowest run at 2 seconds. Empty solved blocks reach a peer in 14 to 103 ms on Zakura and 21 to 92 ms on Ándale. On a quiet, settled connection and on a node's own block, both nodes build new work within about 12 ms.
The propagation results below are medians of repeated runs, with the fastest and slowest run in parentheses. Both nodes were measured on the same machine in the same session for each row, and where a table marks both nodes, the difference between them was smaller than the run-to-run spread.
| Zakura 1.8.0 | Zebra Ándale | |
|---|---|---|
| New work after a peer's block, fresh connection | 61 ms (12–106) | 71 ms (13–1,998) |
| Same, settled connection | 12 ms (10–15) | 5.5 ms (4–16) |
| New work after the node's own block | 4.2 ms (3–8) | 1.6 ms (1–2) |
| Relaying an empty solved block to a peer | 62 ms (14–103) | 46 ms (21–92) |
Additionally, we replayed 32,860 consecutive Mainnet blocks, about four weeks of chain, into Zakura 1.8.0 and Zebra Ándale on the same 8-vCPU cloud server, with both nodes fully verifying and committing every block. Zakura was 2.5× faster, 461 seconds against 1,141, using under a quarter of the CPU time:
| Zakura 1.8.0 | Zebra Ándale | |
|---|---|---|
| Average time per block | 14.0 ms | 34.7 ms |
| Median time per block | 12.7 ms | 26.2 ms |
| 99th percentile time per block | 81 ms | 367 ms |
| Slowest block | 396 ms | 1,106 ms |
| Blocks verified faster | 32,368 (98.5%) | 492 (1.5%) |
| CPU time for all blocks | 1,382 s | 5,632 s |
Shielded blocks verified 2.6× faster, and Ándale's slowest 1% of blocks 5.3× faster. Each node replayed the blocks three times with no peers and empty mempools, so every proof was checked inside its block.
Zakura also leads where pools feel load most: turning a burst of incoming transactions into a block template. With 1.9 MB of transparent transactions arriving at once, Zakura 1.8.0 had them in a template in 19.0 seconds, 38% less time than Ándale's 30.9, and its slowest run beat Ándale's fastest.
| Zakura 1.8.0 | Zebra Ándale | |
|---|---|---|
| Transaction burst to block template, transparent | 19.0 s (18.3–19.2) | 30.9 s (29.9–31.1) |
We are glad to be improving Zcash alongside the Zebra team.
Coming Next
- Accepting a block built from the node's own template catches up with Ándale. The node also reuses the template's spend checks, value-pool change, and body hash: a mixed block takes 75 ms against Ándale's 76 ms, and an Orchard block 41 against 46 ms.
- Transparent signature checks take about 29% less time on transparent blocks. They stop computing data they never use, such as the v5-only digests and the transaction-wide hash for transactions with no shielded components. New transparent blocks verify in 822 ms, down from 988 ms in 1.8.0.
- Shielded blocks verify in 6 to 32% less time. Shielded transactions are dispatched to verification first, a partially filled proof batch flushes after five idle milliseconds, and Orchard batches grow to 128 actions. New 250 kB mixed blocks verify in 63 ms, down from 93 ms in 1.8.0.
With that work, relaying a mixed block takes 1,026 ms, down from 1,203 ms in 1.8.0, and a new mixed block verifies in 497 ms, down from 537 ms.
Faster Field Arithmetic on x86-64
Published x86-64 binaries previously used portable Pasta field arithmetic so they could run on any x86-64 CPU. Default and release builds now enable the faster BMI2 and ADX assembly, with no per-operation runtime detection.
zakurad checks the CPU once at startup and exits with an error naming the missing extensions, instead of crashing with an illegal instruction. Intel CPUs since 2014 and AMD CPUs since 2017 have both; older CPUs can still build with --features portable.
Security
- Decoded blocks can no longer pile up in memory. In our experimental P2Pv2 stack, a slow verifier could leave hundreds of decoded block bodies queued between download and submission. Queued bodies now count against the same 512 MiB decoded-block budget we shipped in 1.7.0; past it, blocks wait as raw bytes and are decoded when submitted. A block at the chain tip is still decoded only once.
- Recent block downloads must claim real work. As defense in depth, Mainnet block sync now refuses to download a recent block whose header claims less than a minimum proof-of-work difficulty, so floods of low-difficulty announcements cannot occupy download capacity. Historical sync is exempt only below height 3,535,411, and only while the node's committed tip is also below it: full verification from genesis still works, and old height claims cannot bypass the floor.
- The native protocol rejects more malformed traffic. Stream preludes whose frame cap cannot carry a payload are refused, a frame that does not fit its stream no longer closes the whole connection, and a handshake acknowledgment cannot accept a capability the dialer never offered.
Other Changes
zcashdcompatibility mode pins zcashd v1.3.1, fixing sidecar sync stalls after out-of-order block announcements.z_gettreestateanswers below the prune height. Pruned nodes now return the note commitment tree state for heights whose bodies pruning has dropped.getblocktemplatejudges sync by the clock. It reports "not synced" only when the chain tip's block time is more than six hours old. The threshold was a block count, which would have shrunk when NU7 shortens block spacing.getpeerinforeportsstartingheight, the best chain height each peer advertised when it connected, aszcashddoes.- Metrics are more accurate. Histogram quantiles no longer lose samples recorded across a window boundary, the metrics endpoint's
/healthresponse isOKagain, and five new gauges report block-sync memory use by stage. tracing.filterapplies only level and target directives. Span and field directives are now ignored with a warning instead of being applied, andrustlslog records no longer appear inzakuradlogs.- Our experimental P2Pv2 stack's block sync recovers from more failure modes. Stalls after resets, reorgs, and peers without latency measurements are fixed, memory accounting survives resets, and checkpoint sync recovers retained commitment-tree data at a blocked commit boundary instead of waiting for more headers. Discovery also no longer times out connections whose peers already answered.
- Custom testnets accept compatible peers using the active network upgrade's protocol version.
End of Support
Mainnet zakurad nodes running 1.8.0 support Mainnet through height 3,643,309 and halt above it (estimated 2026-12-05); upgrade warnings begin three days earlier.
Updating
You can update using our signed release binaries or by upgrading the zakura crate to 1.8.0 via Cargo. See the download page for installation and verification instructions.