Skip to content
ZIPs.tools

ZIP 218

25-second Block Target Spacing

  • Draft
Proposal metadata
ID
218
Status
Draft
Category
Consensus
Owners
  • Dev Ojha
  • Evan Forbes
Created
2026-03-13
License
MIT
Contents
  1. Rationale for anchor selection depth
  2. Shielded sync bandwidth analysis
  3. Difficulty averaging window [difficulty-averaging-window]
  4. Deployment
  5. Reference implementation
  6. References
  7. Footnotes

Recent incidents show consensus splits can persist beyond tens of minutes: for example, Litecoin's April 2026 MWEB incident produced a 13-block invalid chain that was later reorged out, with a ~3-hour recovery window per the postmortem 28. The optimal long-term value for MAX_REORG_LENGTH likely needs to change further in the future, but that is out of scope here. Raising it to at least 600 blocks restores the ~4.2-hour wall-clock window it provided at Zcash's launch 150-second target spacing, while COINBASE_MATURITY remains 100. This is more conservative than the ~125-minute window at today's 75-second spacing. Given the incident above and that the launch 150-second-spacing value predates this line of evidence, restoring the launch wall-clock margin is the safer choice.

This deliberately means that a supported reorg may invalidate a mature coinbase output. That case is already a valid consequence of deep PoW reorgs in the abstract protocol model.

Since version 5.2.0, Zebra keeps a rollback window of 1000 blocks before and after activation (about 20.8 hours at 75-second spacing and 6.9 hours at 25-second spacing), which satisfies the floor of 600.

Rationale for anchor selection depth

This follows the same precedent set by the Blossom upgrade (ZIP 208 24), which did not update the anchor depth and therefore halved delay.

Parameter Current Post-activation Notes
Recommended anchor depth 3 blocks (~3.75 min) 3 blocks (~1.25 min) No change; follows Blossom precedent

The increased likelihood of forking due to block time reduction should not be concerning here. For an issue to occur when anchor depth is 3 blocks back, you must have a 4 block re-org. In the many years of Ethereum PoW, a 4 block re-org has never been observed 29. So we are not practically at risk of inherent randomness causing a re-org. In other POW chains, re-orgs of 4+ blocks resulted from a consensus split of some form, including the recent Litecoin attack, or an attack from a surge in hashpower. Anchor height depth is not intended to protect against those two vectors.

Shielded sync bandwidth analysis

The per-pool block space limits are chosen so that the worst-case daily bandwidth for lightweight wallet syncing does not increase relative to the current protocol. This section presents the analysis.

Parameters

Parameter Value
Block size limit 2,000,000 bytes
Block target spacing 25 seconds
Blocks per day 86,400/25=3,456 86{,}400 / 25 = 3{,}456
Compact block header size ~90 bytes

Orchard and Ironwood pools:

Parameter Value
OrchardProtocolBlockActionLimit\mathsf{OrchardProtocolBlockActionLimit} 330 actions per pool
Compact sync bandwidth per action 148 bytes
Compact bandwidth per block 330×148=48,840330 \times 148 = 48{,}840 bytes

Sapling pool:

Parameter Value
SaplingBlockIOLimit\mathsf{SaplingBlockIOLimit} 300 (inputs + outputs)
Compact sync bandwidth per spend 32 bytes
Compact sync bandwidth per output 116 bytes
Compact bandwidth per block (worst case, all outputs) 300×116=34,800300 \times 116 = 34{,}800 bytes

Daily bandwidth comparison

Metric Current (75s, no pool limits) Proposed (25s, action limits)
Blocks per day 1,152 3,456
Max Orchard + Ironwood actions/block ~617 (block-size limited) 330
Sapling IOs/block ~2,140 (simulated attack) 300 (limit)
Orchard or Ironwood compact BW/day ~105.2 MB 168.79 MB
Sapling compact BW/day ~270.38 MB 120.27 MB
Compact block headers/day ~0.10 MB 0.31 MB
Worst-case total BW/day ~270.5 MB 169.10 MB
Worst-case trial decrypts/day ~4.8M ~2.3M

The pre-activation Sapling estimates use the Shielded Sync Simulator's 8 one-spend, 64-output transaction model; IOs count both spends and outputs. They are not maxima over arbitrary input/output mixes. The simulator uses 32 compact bytes per spend and 112 per output, whereas the post-activation Sapling bound above uses 116 bytes per output.

The worst-case compact sync bandwidth is 169.10 MB/day, a reduction of 37% from today's worst case of approximately 270.5 MB/day. This is despite a 3× increase in block frequency and overall throughput capacity.

The binding constraint is Orchard or Ironwood at 330 actions per block: 330×148×3,456+90×3,456=169.10 MB/day330 \times 148 \times 3{,}456 + 90 \times 3{,}456 = 169.10\textsf{ MB/day}.

The trial decryption count also decreases significantly, since the per-block action limits more than offset the 3× increase in block count.

Note that the trial decrypt count per account is 2× the number of shielded outputs/actions, because wallets must attempt decryption with both the internal and external incoming viewing keys (IVKs). The internal IVK detects change outputs sent back to the wallet, while the external IVK detects incoming payments. In principle, wallets could avoid trial decrypts with one of their IVKs assuming other sync trade-offs are taken, but current Sapling and Orchard-protocol wallets always attempt both.

Normal transaction throughput

For standard 2-action Orchard or Ironwood transactions, the action limit of 330 allows ⌊330/2⌋=165\lfloor 330 / 2 \rfloor = 165 transactions per block, giving:

orchard_protocol_tps=165  /  25=6.6 TPS\mathsf{orchard\_protocol\_tps} = 165 \;/\; 25 = 6.6 \textsf{ TPS}

For comparison, the current protocol (75s blocks, block-size limited) supports approximately 2.9 TPS for 2-action Orchard transactions. This is a 2.3× increase in normal Orchard throughput.

Sapling throughput. For standard Sapling transactions (2 spends + 2 outputs = 4 IOs), the limit of 300 IOs allows ⌊300/4⌋=75\lfloor 300 / 4 \rfloor = 75 transactions per block, giving 75/25=3.075 / 25 = 3.0 TPS. Even with the reduced Sapling limit, the post-NU7 Sapling TPS (3.0) still exceeds the current pre-NU7 Orchard TPS (2.9).

Fee incentives and DoS resistance

A concern with per-pool limits is that a DoS attacker could fill one pool's budget to crowd out transactions in another pool. The global shielded budget prevents this from being worse than filling any single pool, but it is worth examining whether fee incentives create an asymmetry.

Under ZIP 317 30, the conventional fee is based on logical actions. Each Orchard or Ironwood action counts as one logical action, but a transaction's Sapling spends and outputs count as max⁡(nSpendsSapling,nOutputsSapling)\max(\mathit{nSpendsSapling}, \mathit{nOutputsSapling}) logical actions, whereas they consume nSpendsSapling+nOutputsSapling\mathit{nSpendsSapling} + \mathit{nOutputsSapling} units of the global shielded budget. A balanced Sapling bundle therefore buys budget units at half the Orchard or Ironwood price, while an all-output or all-spend Sapling bundle pays the same price per unit.

Furthermore, because the global shielded budget is shared, filling one pool's budget necessarily reduces the remaining budget for all other pools by the same amount. An attacker who spends their entire budget on Sapling spam at 300 IOs leaves only 30 Orchard or Ironwood actions available in that block. With 150 Sapling spends and 150 Sapling outputs, plus 30 Orchard actions, the attacker exhausts the budget for 180 logical actions, about 55% of the conventional fee for 330 Orchard or Ironwood actions. Such a block carries less compact sync data, however: 150×32+150×116+30×148=26,640150 \times 32 + 150 \times 116 + 30 \times 148 = 26{,}640 bytes, against 330×148=48,840330 \times 148 = 48{,}840 bytes. The global budget ensures that the total shielded sync cost per block is bounded to 330 units regardless of the attacker's pool choice.

The bounds this ZIP sets therefore still hold: a block contains at most 330 units in any mix of pools, and the cheapest way to exhaust the budget carries less compact sync data than an Orchard-protocol block. What the Sapling pricing changes is the cost of crowding other transactions out of a block. At the ZIP 317 marginal fee of 5,000 zatoshis, it is 0.009 ZEC per block, about 31 ZEC per day at 25-second spacing, instead of 0.0165 ZEC and about 57 ZEC. A future ZIP could remove the difference by counting nSpendsSapling+nOutputsSapling\mathit{nSpendsSapling} + \mathit{nOutputsSapling} logical actions in ZIP 317, which raises the conventional fee of a typical one-spend, two-output Sapling transaction by half, or by having block templates rank transactions by fee per unit of shielded budget rather than per logical action.

The 330-action per-pool cap also allows either Orchard or Ironwood transactions to use the full global budget when other shielded pools are not used.

Difficulty averaging window [difficulty-averaging-window]

This proposal increases PoWAveragingWindow\mathsf{PoWAveragingWindow} from 17 to 102 at NU7 activation (specified in Averaging window under Consensus changes), so that the wall-clock smoothing window is 102×25=17×150=2,550102 \times 25 = 17 \times 150 = 2{,}550 seconds — the same wall-clock window the value PoWAveragingWindow=17\mathsf{PoWAveragingWindow} = 17 was originally chosen to provide at Zcash's launch target spacing of 150 s. At today's 75 s spacing the same value covers only 1,275 s, and at NU7's proposed 25 s spacing it would cover only 425 s.

The motivations are:

  1. To preserve the wall-clock duration over which difficulty is smoothed, so that NU7 does not amplify difficulty-manipulation attacks like the one recently observed on Litecoin 28.
  2. As an additional improvement over keeping PoWAveragingWindow=17\mathsf{PoWAveragingWindow} = 17, to reduce the standard deviation of block-spacing averages over short rolling windows.

Under a Zebra difficulty-adjustment simulator 31 with a stable hash rate and with PoWAveragingWindow=17\mathsf{PoWAveragingWindow} = 17 unchanged across the transition, the expected block spacing recovers to within 5% of the new 25 s target within 62 blocks of NU7 activation:

Expected spacing Blocks after activation Wall-clock
75 s (pre-NU7 target) — —
56.8 s (activation) 0 —
≤30\leq 30 s 30 ~21 min
≤26.25\leq 26.25 s 62 ~36 min

Setting PoWAveragingWindow=102\mathsf{PoWAveragingWindow} = 102 is expected to require roughly 6× as many blocks to cross each threshold, which is the same wall-clock duration as recovery would have taken at Zcash's launch 150 s spacing with PoWAveragingWindow=17\mathsf{PoWAveragingWindow} = 17.

For a real-world reference point, the Blossom upgrade 24 made a 2× target-spacing reduction (150 s → 75 s) with PoWAveragingWindow\mathsf{PoWAveragingWindow} unchanged; mainnet block spacing (20-block rolling average) reached approximately 74 s at height 653,664 — 64 blocks after activation.

Two geographically-distributed devnets of 99 Zebra nodes across 14 regions (1 vCPU per node), one at PoWAveragingWindow=17\mathsf{PoWAveragingWindow} = 17 and one at 51, confirmed a ~1-second reduction in the standard deviation of 5- and 10-block rolling-average block spacings. The variance reduction is expected to be somewhat larger at PoWAveragingWindow=102\mathsf{PoWAveragingWindow} = 102.

Deployment

This proposal is intended to be deployed as part of NU7. ZIP 259 16 specifies the deployment details, including activation heights and the consensus branch ID.

Reference implementation

References

Footnotes

  1. Information on BCP 14 — "RFC 2119: Key words for use in RFCs to Indicate Requirement Levels" and "RFC 8174: Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words" ↩

  2. ZIP 200: Network Upgrade Mechanism ↩

  3. Zcash Protocol Specification, Version 2025.6.3. Section 7.7.3: Difficulty adjustment ↩

  4. Zcash Protocol Specification, Version 2025.6.3 or later ↩ ↩2

  5. Zcash Protocol Specification, Version 2025.6.3. Section 3.12: Mainnet and Testnet ↩

  6. On Slow and Fast Block Times ↩

  7. Shielded Sync Simulator ↩ ↩2

  8. ZIP 2003: Disallow version 4 transactions ↩

  9. Forum: Proposal — Lower Zcash Block Target Spacing to 25s ↩

  10. Forum: Zcash Block Time Reduction Appears Safe for NU7 w/ Zebra-only Devnet ↩

  11. ZIP 229: Version 6 Transaction Format ↩ ↩2

  12. Zebra worst-case block verification benchmark (worst_case_tx_verification.rs) ↩

  13. ZIP 315: Best Practices for Wallet Implementations ↩ ↩2 ↩3

  14. Zcash Protocol Specification, Version 2025.6.3. Section 5.3: Constants ↩

  15. ZIP 259: Deployment of the NU7 Network Upgrade ↩ ↩2 ↩3

  16. Zcash Protocol Specification, Version 2025.6.3. Section 7.8: Calculating Block Subsidy, Funding Streams, Lockbox Disbursement, and Founders' Reward ↩

  17. ZIP 237: Network Sustainability Mechanism: Halving-Preserving Issuance ↩

  18. ZecStats Mainnet network statistics, reporting height 3,501,422 at 2026-09-30 12:05 UTC. ↩

  19. ZIP 214: Consensus rules for a Zcash Development Fund ↩

  20. ZIP 207: Funding Streams ↩

  21. Zcash Protocol Specification, Version 2025.6.3. Section 7.1: Transaction Encoding and Consensus ↩

  22. Zcash Light Wallet Protocol v0.5.0: compact_formats.proto ↩

  23. ZIP 208: Shorter Block Target Spacing ↩ ↩2 ↩3 ↩4 ↩5 ↩6

  24. ZIP 205: Deployment of the Sapling Network Upgrade ↩

  25. ZIP 315: Best Practices for Wallet Implementations — Expiration height ↩

  26. Zcash Protocol Specification, Version 2025.6.3. Section 7.1.2: Transaction Consensus Rules ↩

  27. Litecoin MWEB Security Incident Postmortem ↩ ↩2

  28. Lovejoy, James P. (2020). An Empirical Analysis of Chain Reorganizations and Double-Spend Attacks on Proof-of-Work Cryptocurrencies. M.Eng. thesis, Massachusetts Institute of Technology, Department of Electrical Engineering and Computer Science. ↩

  29. ZIP 317: Proportional Transfer Fee Mechanism ↩

  30. Zebra difficulty-adjustment recovery simulator: benchmark_hash_rate_shock_daa_configurations in zebra-state/src/service/check/difficulty.rs. The 3× target-spacing transition is exercised by simulate_three_x_target_spacing_reduction in the same file. ↩

  31. Zebra PR 11529: feat(consensus)!: implement NU7 spacing, funding schedules, and shielded limits ↩

  32. Zakura PR 1066: feat(consensus): reduce block target spacing to 25 seconds at NU7 ↩

  33. Zakura PR 1068: fix(chain): apply NU7 spacing at activation boundary ↩

  34. Zakura PR 1221: test(chain): pin ZIP 218 rounding over every block and halving era ↩

Citation graph

Hover or tap a node to see its title and citations.
Loading citation graph…
ZIP 218: 25-second Block Target Spacing — Part 2 · ZIPs.tools