# ZIP 218: 25-second Block Target Spacing

Status: Draft

Owners: Dev Ojha, Evan Forbes

Snapshot: a34cfc091434275120ff017c92c3b50d3cef623a

Source date: 2026-10-16T02:56:04+01:00

[Source revision](https://github.com/zcash/zips/commit/a34cfc091434275120ff017c92c3b50d3cef623a)

[Official source](https://zips.z.cash/zip-0218) · [Source file](https://github.com/zcash/zips/blob/a34cfc091434275120ff017c92c3b50d3cef623a/zips/zip-0218.md) · [Discussion](https://forum.zcashcommunity.com/t/proposal-lower-zcash-block-target-spacing-to-25s/54577)

## Document parts

[Part 1](https://zips.tools/zip/218) · [Part 2](https://zips.tools/zip/218?part=2)

Reading part 1 of 2. Follow all parts for the complete proposal.

Preamble

**ZIP**: 218

**Title**: 25-second Block Target Spacing

**Owners**: 

- [Dev Ojha](mailto:dev@valargroup.dev)
- [Evan Forbes](mailto:evan@valargroup.dev)

**Status**: Draft

**Category**: Consensus

**Created**: 2026-03-13

**License**: MIT

**Discussions-To**: [https://forum.zcashcommunity.com/t/proposal-lower-zcash-block-target-spacing-to-25s/54577](https://forum.zcashcommunity.com/t/proposal-lower-zcash-block-target-spacing-to-25s/54577)

<a id="terminology"></a>

## Terminology

The key words "MUST", "MUST NOT", "SHOULD", and "SHOULD NOT" in this document
are to be interpreted as described in BCP 14 <a id="user-content-fnref-bcp14"></a>
[1](/zip/218?part=2#user-content-fn-bcp14) when, and only
when, they appear in all capitals.

The terms "block chain", "consensus rule change", "consensus branch",
and "network upgrade" are to be interpreted as defined in ZIP 200.
<a id="user-content-fnref-zip-0200"></a>
[2](/zip/218?part=2#user-content-fn-zip-0200)

The term "block target spacing" means the time interval between blocks
targeted by the difficulty adjustment algorithm in a given consensus
branch. It is normally measured in seconds. (This is also sometimes
called the "target block time", but "block target spacing" is the term
used in the Zcash Protocol Specification <a id="user-content-fnref-protocol-diffadjustment"></a>
[3](/zip/218?part=2#user-content-fn-protocol-diffadjustment).)

The term "TPS" refers to the maximum number of transactions per second
supported by a Zcash subprotocol, assuming the target block spacing.

The character § is used when referring to sections of the Zcash Protocol
Specification. <a id="user-content-fnref-protocol"></a>
[4](/zip/218?part=2#user-content-fn-protocol)

The terms "Mainnet" and "Testnet" are to be interpreted as described in
§ 3.12 'Mainnet and Testnet'. <a id="user-content-fnref-protocol-networks"></a>
[5](/zip/218?part=2#user-content-fn-protocol-networks)

<a id="abstract"></a>

## Abstract

This proposal specifies a change in the block target spacing from 75
seconds to 25 seconds in NU7, and introduces per-pool action limits for
the Sapling, Orchard, and Ironwood shielded pools.

This solves three problems.

- Significantly improves the UX for actors who need 1 or 2 confirmations,
  such as Near Intents, and for small payments. The user-visible latency
  goes down 3x.

- Increases consensus bandwidth, which would amplify the scaling impact
  of any future shielded pools that do not require shielded sync.

- Introduces action limits. These provide limits on the number of actions that
  can go into a block. There is a *global shielded budget* across all
  shielded pools, as well as per-pool limits. These limits are configured to more
  than double Orchard-protocol TPS (2.9 → 6.6 TPS), while lowering the impact
  a DoS attacker can impose on wallets; for example, maximum shielded sync
  bandwidth for light clients is reduced by 37% (271 → 169 MB/day).

The action limits significantly decrease the number of Sprout and Sapling pool
outputs available per block, to lower the maximum shielded sync burden under
attempted DoS.

The emission schedule of mined ZEC will be the same in terms of ZEC/day,
but this requires the emission per block to be adjusted
to take account of the changed block target spacing.

<a id="motivation"></a>

## Motivation

The motivations for decreasing the block target spacing are:

- **Reduced transaction latency.** Currently, users must wait
  75 seconds on average for even a single confirmation, regardless
  of network utilization. This creates friction for point-of-sale
  payments, exchange deposits, and cross-chain bridge operations. A
  25-second target spacing reduces the expected wait for a first
  confirmation to 25 seconds on average.

- **Greater throughput.** With 3× as many blocks per day and the same
  2 MB block size limit, we will have allocated higher consensus bandwidth
  capacity. In the short term, when paired with the action limits, we will more than
  double the Ironwood TPS for 2-action transactions. In the longer term, when
  we get a shielded pool with no shielded sync burden, we will have 3x higher
  throughput.

The throughput goal on its own could be achieved via a block size increase.
However the goal of this proposal is foremost to improve the transaction
latency.

This proposal is complementary to, and does not compete with, finality
mechanisms such as Crosslink <a id="user-content-fnref-crosslink"></a>
[6](/zip/218?part=2#user-content-fn-crosslink). Faster block times improve the
responsiveness of the base layer regardless of whether an additional finality
gadget is also deployed. Rollback-risk analysis depends on the threat model.
For models that bound an attacker by a fixed fraction of total hash power,
reducing the block target spacing can reduce confirmation latency by nearly the
same factor, provided that block validation and propagation times remain small
relative to the target spacing. Given that is maintained here, this proposal is
expected to improve confirmation latency by slightly less than 3x for users
applying the same rollback-risk tolerance as today. See 'On Slow and Fast Block
Times' <a id="user-content-fnref-slowfastblocks"></a>
[7](/zip/218?part=2#user-content-fn-slowfastblocks) for analysis under several attack models.

Economic rollback models give a different result. For recipients who wait until
the block rewards built on top of their payment exceed the payment value, then
shorter block times significantly reduce the variance of their waiting time,
while the mean stays roughly the same. Recall that proof-of-work block times
have high variance, so variance reduction is a substantial benefit.
This ZIP does not argue for clients reducing confirmation counts, but it does
expect many users to see a lower expected time until receipt under confirmation
policies comparable to those they use today.

<a id="security"></a>

### Security

Scaling and block time reductions in Zcash impose three security costs, one on
full nodes' and miners' ability to verify blocks, a second on clients for
shielded sync, and a third on the whole network for the uncle rate and fork
rate. Action limits are introduced in this ZIP to limit the block processing
costs, and client shielded sync costs. The proposed parameterization lowers the
worst case for shielded sync and node processing times relative to today, while
yielding far higher Ironwood TPS. We benchmark
[block verification](#block-processing-time), and the uncle-rate post-proposal
on networks more distributed than mainnet at maximum load is far lower than
ETH-PoW was, leading to conclusion that it is safe.

Today the worst-case DoS attack can induce 271 MB of wallet sync download to
clients per day, and 4.8M trial decryptions per day <a id="user-content-fnref-syncsimulator"></a>
[8](/zip/218?part=2#user-content-fn-syncsimulator). This is
achieved by fully utilizing block space with Sapling transactions that have
few inputs and many outputs. The worst-case DoS for node verification time
uses many Sapling inputs and a single transparent output, totaling 5,600
Sapling inputs and zero-knowledge proofs. This takes 3.2 seconds on a modern
AMD laptop CPU with 4 pinned threads. Regular user flows impose far lower
costs on the network than this DoS model.

We propose introducing a global shielded budget and per-pool action limits as follows:

- A global shielded budget of 330 across all pools

- A maximum of 330 Orchard actions per block

- A maximum of 330 Ironwood actions per block

- A maximum of 300 Sapling inputs + outputs. (Total inputs + outputs <= 300)

- No Sprout JoinSplits (achieved by deploying this ZIP in conjunction with
  ZIP 2003 <a id="user-content-fnref-zip-2003"></a>
  [9](/zip/218?part=2#user-content-fn-zip-2003) which disables v4 transactions).

With these limits, the worst case client load becomes 169 MB bandwidth and 2.3M
trial decrypts per day. This is a 37% improvement in worst case wallet sync
bandwidth despite 3× more blocks. This yields a 2.3× increase in Ironwood TPS,
and keeps Sapling TPS at a higher level than today's Ironwood TPS.

However, every wallet does have to download every compact block header, which
is 90 bytes. This leads to an extra 200 kB of wallet bandwidth per day in
exchange for the improved UX.

The reduced Sapling per-block limit and disabling of Sprout are justified by
the current distribution of shielded funds across pools (other motivations for
disabling Sprout are discussed in ZIP 2003). As of May 2026:

| Pool | Balance | Share of shielded supply |
| --- | --- | --- |
| Orchard | 4,534,914 ZEC | 87.9% |
| Sapling | 597,910 ZEC | 11.6% |
| Sprout | 25,409 ZEC | 0.5% |

The vast majority of shielded activity is already in Orchard, and this
trend is expected to continue. The Sapling limit is set generously relative
to current usage while substantially reducing the potential for DoS.
Furthermore, this ZIP is proposed to activate together with disabling v4
transactions in NU7, which would prevent any Sprout transactions from being
included in blocks.

<a id="stale-block-rate-stale-block-rate"></a>

### Stale block rate [stale-block-rate]

The stale rate is the percentage of blocks that get orphaned, which relates to
mining centralization risk, block propagation delay, and block verification
times. Today the stale rate is 0.4%, but this may be lower than what pure block
propagation delay may imply due to hash-power centralization in mining pools.

At 25-second block target spacing, the theoretical stale block rate is
approximately 3.26%, derived from measured Zcash network propagation
delays. A devnet experiment with 99 geographically-distributed Zebra
nodes producing 2MB blocks at 25-second target spacing measured a stale
block rate of 4.86% and a fork rate of 0.37%. Both observed figures are
below the 5.4% safety threshold set by Ethereum's historical proof-of-work
stale rate. <a id="user-content-fnref-forum-proposal"></a>
[10](/zip/218?part=2#user-content-fn-forum-proposal) The only modification required to achieve
these rates was tuning TCP configuration (more details in the linked
footnote). The devnet's node distribution was significantly more
decentralized than today's mainnet, so these figures represent a
near worst-case scenario. <a id="user-content-fnref-devnet-blocktime-test"></a>
[11](/zip/218?part=2#user-content-fn-devnet-blocktime-test)

<a id="block-processing-time-block-processing-time"></a>

### Block processing time [block-processing-time]

A prerequisite for reducing the target block spacing is that block validation
and propagation remain small relative to the target spacing. The per-pool
action limits introduced by this proposal ensure that worst-case
*per-block* processing time is lower than today's. The fact that there
are three times as many blocks in unit time does mean that the *overall*
worst-case proportion of time taken for processing, and the worst cost of
sync after a given time offline for full nodes will increase. We accept this
trade-off. These computational limits parallelize well. At the 2,000,000-byte block size limit and 25-second target spacing, the raw block payload rate is 640 kbps, so a 10 Mbps connection has about 15 times that rate, before transport overhead.

**Current worst case:** A full 2 MB block today can contain up to ~617
Orchard or Ironwood actions, or ~2,107 Sapling outputs, with no per-pool
limits. A fully packed Orchard-protocol block requires verifying all action
proofs, spend authorization, and binding signatures, and checking validity
of curve point encodings, for those ~617 actions.

**Proposed worst case:** With the action limits, a block contains at
most 330 actions across pools. There are also separate per-pool limits:

- 330 Orchard actions

- 330 Ironwood actions

- 300 Sapling inputs+outputs.

This means the new worst case block processing time, if Orchard- or
Ironwood-dominant, would be 14% of today's worst case, and Sapling's would be
less than one tenth. The worst case per-block verification work is therefore
substantially reduced.

**Batch verification.** Ironwood transaction verification benefits from
batch validation, where proof and signature verification is amortized across
multiple transactions. Ironwood uses the same Action encoding and proof system
as Orchard. <a id="user-content-fnref-zip-0229"></a>
[12](/zip/218?part=2#user-content-fn-zip-0229) In current node software, Orchard transactions are
batch-verified in groups of up to 64 transactions (each worst case being a
single action). Zebra has performed batch verification during live network
syncing since version 3.0.0. With the action limits, the Orchard-protocol
bundles in a worst-case block can be fully batch-verified in a small number of
batches.

**Measured timing.** We benchmarked worst-case block verification with
Zebra on a modern AMD laptop CPU with 4 pinned threads.<a id="user-content-fnref-verification-benchmark"></a>
[13](/zip/218?part=2#user-content-fn-verification-benchmark)
The figures report wall-clock time for verifying the zero-knowledge proofs
and signatures in a single block, without any mempool pre-verification.

| Case | Block composition | Mean ± stddev |
| --- | --- | --- |
| Full Orchard limit (proposed) | 330 Orchard actions | 432.11 ± 11.03 ms |
| Full Sapling limit (proposed) | 300 Sapling spends, 0 outputs | 271.51 ± 5.03 ms |
| Today's Orchard worst case | ~617 actions in dense multi-action txs in a 2 MB block | 769.85 ± 16.18 ms |
| Today's Sapling worst case | ~5,600 spends in dense multi-spend txs in a 2 MB block | 3,174.90 ± 144.04 ms |

- **Full Orchard limit (proposed)** — binding post-NU7 verification worst case.

- **Full Sapling limit (proposed)** — verification worst case is all-spends;
  the bandwidth worst case (all-outputs) is in [Rationale](#rationale).

- **Today's Orchard worst case** — dense multi-action (single-action would
  understate the byte bound).

- **Today's Sapling worst case** — analogous, dense multi-spend.

When transactions have already been pre-verified upon entering the mempool,
block validation reduces to checking signatures and state updates, which is even
cheaper. This is the typical case for a node that has been online under normal
usage of the network, but under DoS attack it cannot be assumed, because the
adversary can send blocks with transactions that were never in the mempool.

<a id="privacy-implications"></a>

## Privacy Implications

Reducing the target spacing does not change the information revealed by an
individual shielded transaction. It does, however, change the wall-clock timing
of transaction creation, inclusion, and confirmation. More frequent blocks give
observers finer timing information, which may be combined with network-layer or
application-layer observations. The action limits can also delay transactions
under sustained demand for a particular shielded pool, making transaction timing
and pool-specific congestion relevant to privacy-sensitive applications.

A fixed anchor depth measured in blocks becomes three times shorter in wall-clock
time. If a wallet continues to select the final treestate three blocks behind
the chain tip, the nominal distance falls from about 3.75 minutes to about
1.25 minutes. If the chain rolls back past a transaction's anchor, the
transaction becomes invalid. If it was already broadcast, its shielded
nullifiers have nevertheless been revealed; a later transaction spending the
same notes can then be linked to the invalidated transaction. This reliability
and privacy trade-off is described in ZIP 315 <a id="user-content-fnref-zip-0315"></a>
[14](/zip/218?part=2#user-content-fn-zip-0315).

The stale-rate measurements in [Stale block rate](#stale-block-rate) provide
evidence about ordinary forks in the tested conditions, but do not bound the
depth of a rollback caused by a consensus split, an implementation defect, an
attack, or a large change in hash power. They therefore do not establish that
any particular anchor depth is safe for every wallet threat model.

The shielded action limits reduce the maximum compact-block data and trial
decryption work that an adversary can impose on a syncing wallet per day. They
do not prevent traffic analysis or eliminate denial-of-service risk, and the
per-pool limits reveal no information beyond the already-public transaction
components and block composition.

<a id="specification"></a>

## Specification

The changes described in this section are to be made in the Zcash
Protocol Specification <a id="user-content-fnref-protocol-2"></a>
[4](/zip/218?part=2#user-content-fn-protocol), relative to the specification as of
the activation of this proposal.

<a id="consensus-changes"></a>

### Consensus changes

#### Block target spacing

In § 2 'Notation', add $\mathsf{NU7ActivationHeight}$ and
$\mathsf{PostNU7PoWTargetSpacing}$ to the list of integer constants.

In § 5.3 'Constants' <a id="user-content-fnref-protocol-constants"></a>
[15](/zip/218?part=2#user-content-fn-protocol-constants), define:

$\mathsf{NU7ActivationHeight} : \mathbb{N}$
$\mathsf{PostNU7PoWTargetSpacing} : \mathbb{N} := 25 \textsf{ seconds}$

For each network, $\mathsf{NU7ActivationHeight}$ is the height at which
this network upgrade activates, as specified in ZIP 259 <a id="user-content-fnref-zip-0259"></a>
[16](/zip/218?part=2#user-content-fn-zip-0259).

On Testnet, the minimum-difficulty threshold remains 450 seconds after
NU7 activation; see
[Minimum difficulty blocks on Testnet](#minimum-difficulty-blocks-on-testnet).

In § 7.7.3 'Difficulty adjustment', define:

$\mathsf{NU7PoWTargetSpacingRatio} : \mathbb{N} := \mathsf{PostBlossomPoWTargetSpacing} \;/\; \mathsf{PostNU7PoWTargetSpacing} = 3$
$\mathsf{IsNU7Activated} : \mathbb{N} \to \{\mathsf{false}, \mathsf{true}\}$
$\mathsf{IsNU7Activated}(\mathsf{height}) := (\mathsf{height} \geq \mathsf{NU7ActivationHeight})$

Redefine $\mathsf{PoWTargetSpacing}$ as a function of type
$\mathbb{N} \to \mathbb{N}$:

$\mathsf{PoWTargetSpacing}(\mathsf{height}) :=
  \begin{cases}
    \mathsf{PreBlossomPoWTargetSpacing},  &\textsf{if not } \mathsf{IsBlossomActivated}(\mathsf{height}) \\\\
    \mathsf{PostBlossomPoWTargetSpacing}, &\textsf{if } \mathsf{IsBlossomActivated}(\mathsf{height}) \textsf{ and not } \mathsf{IsNU7Activated}(\mathsf{height}) \\\\
    \mathsf{PostNU7PoWTargetSpacing}      &\textsf{otherwise}
  \end{cases}$

#### Averaging window [averaging-window]

In § 2 'Notation', replace the integer constant
$\mathsf{PoWAveragingWindow}$ with the integer constants
$\mathsf{PreNU7PoWAveragingWindow}$ and
$\mathsf{PostNU7PoWAveragingWindow}$.

In § 5.3 'Constants', replace the definition of the former constant with:

$\mathsf{PreNU7PoWAveragingWindow} : \mathbb{N} := 17$
$\mathsf{PostNU7PoWAveragingWindow} : \mathbb{N} := 102$

In § 7.7.3 'Difficulty adjustment', define $\mathsf{PoWAveragingWindow}$ as a function of type
$\mathbb{N} \to \mathbb{N}$:

$\mathsf{PoWAveragingWindow}(\mathsf{height}) :=
  \begin{cases}
    \mathsf{PreNU7PoWAveragingWindow},  &\textsf{if not } \mathsf{IsNU7Activated}(\mathsf{height}) \\\\
    \mathsf{PostNU7PoWAveragingWindow} &\textsf{otherwise}
  \end{cases}$

For the block under consideration at $\mathsf{height}$, replace the three
formulae in that section that use the former constant with:

$\mathsf{AveragingWindowTimespan} : \mathbb{N} \to \mathbb{N}$
$\mathsf{AveragingWindowTimespan}(\mathsf{height}) := \mathsf{PoWAveragingWindow}(\mathsf{height}) \cdot \mathsf{PoWTargetSpacing}(\mathsf{height})$
$\mathsf{ActualTimespan} : \mathbb{N} \to \mathbb{Z}$
$\mathsf{ActualTimespan}(\mathsf{height}) := \mathsf{MedianTime}(\mathsf{height}) - \mathsf{MedianTime}(\mathsf{height} - \mathsf{PoWAveragingWindow}(\mathsf{height}))$
$\mathsf{MeanTarget} : \mathbb{N} \to \mathbb{Q}$
$\mathsf{MeanTarget}(\mathsf{height}) :=
  \begin{cases}
    \mathsf{PoWLimit}, &\textsf{if } \mathsf{height} \leq \mathsf{PoWAveragingWindow}(\mathsf{height}) \\\\
    \mathsf{mean}\left(\left[\mathsf{ToTarget}(\mathsf{nBits}(i))\;\middle|\;i \in \{\mathsf{height} - \mathsf{PoWAveragingWindow}(\mathsf{height}), \ldots, \mathsf{height} - 1\}\right]\right), &\textsf{otherwise.}
  \end{cases}$

All other mentions in § 7.7.3 of the former constant, including the note
about the first averaging-window blocks of the chain, are replaced by a call
to $\mathsf{PoWAveragingWindow}(\mathsf{height})$ for the block under
consideration.

#### Halving interval and block subsidy

Define:

$\mathsf{PostNU7HalvingInterval} : \mathbb{N} := \lfloor \mathsf{PostBlossomHalvingInterval} \cdot \mathsf{NU7PoWTargetSpacingRatio} \rfloor = 5{,}040{,}000$

Redefine $\mathsf{Halving}$ as a function of type $\mathbb{N} \to \mathbb{N}$:

$\mathsf{Halving}(\mathsf{height}) :=
  \begin{cases}
    0, &\textsf{if } \mathsf{height} < \mathsf{SlowStartShift} \\\\[1.5ex]
    \left\lfloor \dfrac{\mathsf{height} - \mathsf{SlowStartShift}}{\mathsf{PreBlossomHalvingInterval}} \right\rfloor,
      &\textsf{if not } \mathsf{IsBlossomActivated}(\mathsf{height}) \\\\[1.5ex]
    \left\lfloor \dfrac{\mathsf{BlossomActivationHeight} - \mathsf{SlowStartShift}}{\mathsf{PreBlossomHalvingInterval}}
      + \dfrac{\mathsf{height} - \mathsf{BlossomActivationHeight}}{\mathsf{PostBlossomHalvingInterval}} \right\rfloor,
      &\textsf{if } \mathsf{IsBlossomActivated}(\mathsf{height}) \textsf{ and not } \mathsf{IsNU7Activated}(\mathsf{height}) \\\\[1.5ex]
    \left\lfloor \dfrac{\mathsf{BlossomActivationHeight} - \mathsf{SlowStartShift}}{\mathsf{PreBlossomHalvingInterval}}
      + \dfrac{\mathsf{NU7ActivationHeight} - \mathsf{BlossomActivationHeight}}{\mathsf{PostBlossomHalvingInterval}}
      + \dfrac{\mathsf{height} - \mathsf{NU7ActivationHeight}}{\mathsf{PostNU7HalvingInterval}} \right\rfloor,
      &\textsf{otherwise}
  \end{cases}$

Redefine $\mathsf{BlockSubsidy} : \mathbb{N} \to \mathbb{N}$ to add a case for
post-activation heights. The prior Blossom case in § 7.8 'Calculating Block
Subsidy, Funding Streams, Lockbox Disbursement, and Founders' Reward'
<a id="user-content-fnref-protocol-subsidies"></a>
[17](/zip/218?part=2#user-content-fn-protocol-subsidies), currently written as "otherwise", must be
amended to "if $\mathsf{IsBlossomActivated}(\mathsf{height})$ and not
$\mathsf{IsNU7Activated}(\mathsf{height})$":

$\mathsf{BlockSubsidy}(\mathsf{height}) :=
  \begin{cases}
    \ldots &\text{(prior cases, with the Blossom case amended as above)} \\\\[1ex]
    \mathsf{floor}\left(\dfrac{\mathsf{MaxBlockSubsidy}}{\mathsf{BlossomPoWTargetSpacingRatio} \cdot \mathsf{NU7PoWTargetSpacingRatio} \cdot 2^{\mathsf{Halving}(\mathsf{height})}}\right),
      &\textsf{if } \mathsf{IsNU7Activated}(\mathsf{height})
  \end{cases}$

This divides the per-block subsidy by an additional factor of 3 relative
to the post-Blossom subsidy, so that the total issuance per unit of wall
clock time remains the same.

Note: during the second halving period, the post-Blossom block subsidy is
1.5625 ZEC. At 25-second spacing it becomes
$\mathsf{floor}(156250000 / 3) = 52083333$ zatoshi (0.52083333 ZEC),
so three post-NU7 blocks issue one zatoshi less than one pre-NU7 block.
After the third halving, the subsidy is
$\mathsf{floor}(78125000 / 3) = 26041666$ zatoshi (0.26041666 ZEC),
so three post-NU7 blocks issue two zatoshi less than one pre-NU7 block.

Let $A$ be the NU7 activation height, and let $H_3$ be the third-halving
height under the 75-second schedule on the relevant network. If NU7
activates between the second and third halvings, the additional shortfall
in scheduled issuance relative to keeping 75-second blocks is
$0.4872 + (H_3 - A)/10^8$ ZEC. The first term is the combined rounding
shortfall from the third and later halving periods: 0.0336 ZEC from two
zatoshi per 75-second interval during the third period, and 0.4536 ZEC
from later periods. The second term is the one-zatoshi shortfall per
remaining 75-second block in the second period.
The existing 75-second schedule falls short of $\mathsf{MAX\_MONEY}$ by
0.1848 ZEC, so the post-NU7 scheduled shortfall is
$0.6720 + (H_3 - A)/10^8$ ZEC. These figures exclude any reissuance
under the Network Sustainability Mechanism specified in ZIP 237 <a id="user-content-fnref-zip-0237"></a>
[18](/zip/218?part=2#user-content-fn-zip-0237),
which renames this $\mathsf{BlockSubsidy}$ to $\mathsf{ScheduledBlockSubsidy}$
and adds $\mathsf{AdditionalBlockSubsidy}$.

For a dated Mainnet illustration, the observed chain tip on 2026-09-30
at 12:05 UTC was height 3,501,422. <a id="user-content-fnref-mainnet-height-20260930"></a>
[19](/zip/218?part=2#user-content-fn-mainnet-height-20260930) The first
subsequent height divisible by 3, as required for NU7 activation by
ZIP 259 <a id="user-content-fnref-zip-0259-2"></a>
[16](/zip/218?part=2#user-content-fn-zip-0259), is $A = 3{,}501{,}423$. Then
$H_3 - A = 4{,}406{,}400 - 3{,}501{,}423 = 904{,}977$.
The additional terminal shortfall relative to the 75-second schedule
is $0.4872 + 0.00904977 = 0.49624977$ ZEC. The total scheduled
shortfall from $\mathsf{MAX\_MONEY}$ is
$0.1848 + 0.49624977 = 0.68104977$ ZEC. Any later NU7 activation
before the third halving has a smaller additional shortfall under this
formula.

Revision 3 of ZIP 214 <a id="user-content-fnref-zip-0214"></a>
[20](/zip/218?part=2#user-content-fn-zip-0214) extends the two funding streams to the
post-NU7 third halving. At 75-second spacing, each remaining pre-halving
block pays 12,500,000 and 18,750,000 zatoshi to the 8% and 12% streams.
The corresponding three 25-second blocks pay $3 \times 4{,}166{,}666$
and $3 \times 6{,}249{,}999$ zatoshi. The streams therefore receive two
and three zatoshi less, respectively, while the miner receives four
zatoshi more. In this second halving period, only one fewer zatoshi is
issued in total. Across the $H_3 - A$ remaining 75-second intervals,
the streams receive $5(H_3 - A)$ zatoshi less, but total scheduled
issuance falls by only $H_3 - A$ zatoshi. This is already included in
the terminal shortfall above; funding-stream rounding does not create
a separate shortfall in total issuance.

Revision 2 of ZIP 207 <a id="user-content-fnref-zip-0207"></a>
[21](/zip/218?part=2#user-content-fn-zip-0207) extends the remaining funding-stream address
period at NU7 activation, and subsequent address periods, in proportion to the
change in block target spacing.

#### Shielded pool action limits

Define the following constants in § 5.3 'Constants':

$\mathsf{GlobalShieldedBudget} : \mathbb{N} := 330$
$\mathsf{OrchardProtocolBlockActionLimit} : \mathbb{N} := 330$
$\mathsf{SaplingBlockIOLimit} : \mathbb{N} := 300$
$\mathsf{SproutBlockJoinSplitLimit} : \mathbb{N} := 0$

In § 2 'Notation', add $\mathsf{GlobalShieldedBudget}$,
$\mathsf{OrchardProtocolBlockActionLimit}$, $\mathsf{SaplingBlockIOLimit}$,
and $\mathsf{SproutBlockJoinSplitLimit}$ to the list of integer constants.

In the limits below, $\mathit{nActionsOrchard}$, $\mathit{nSpendsSapling}$,
$\mathit{nOutputsSapling}$, and $\mathit{nJoinSplit}$ are the transaction
fields specified in § 7.1 'Transaction Encoding and Consensus'
<a id="user-content-fnref-protocol-txnencoding"></a>
[22](/zip/218?part=2#user-content-fn-protocol-txnencoding), and $\mathit{nActionsIronwood}$ is the field added
by ZIP 229 <a id="user-content-fnref-zip-0229-2"></a>
[12](/zip/218?part=2#user-content-fn-zip-0229). Each is taken as 0 for a transaction version that
does not have the field.

For each block at height $\mathsf{height}$ where
$\mathsf{IsNU7Activated}(\mathsf{height})$, the following limits MUST
be satisfied:

**Per-pool limits:**

- The total number of Orchard actions across all transactions in the
  block MUST NOT exceed $\mathsf{OrchardProtocolBlockActionLimit}$. That is,
  $\sum_{\mathit{tx} \in \mathit{block}} \mathit{nActionsOrchard}(\mathit{tx}) \leq \mathsf{OrchardProtocolBlockActionLimit}$.

- The total number of Ironwood actions across all transactions in the
  block MUST NOT exceed $\mathsf{OrchardProtocolBlockActionLimit}$. That is,
  $\sum_{\mathit{tx} \in \mathit{block}} \mathit{nActionsIronwood}(\mathit{tx}) \leq \mathsf{OrchardProtocolBlockActionLimit}$.

- The total number of Sapling inputs and outputs across all
  transactions in the block MUST NOT exceed
  $\mathsf{SaplingBlockIOLimit}$. That is,
  $\sum_{\mathit{tx} \in \mathit{block}} (\mathit{nSpendsSapling}(\mathit{tx}) + \mathit{nOutputsSapling}(\mathit{tx})) \leq \mathsf{SaplingBlockIOLimit}$.

- The total number of Sprout JoinSplits across all transactions in
  the block MUST NOT exceed $\mathsf{SproutBlockJoinSplitLimit}$. That
  is,
  $\sum_{\mathit{tx} \in \mathit{block}} \mathit{nJoinSplit}(\mathit{tx}) \leq \mathsf{SproutBlockJoinSplitLimit}$.

**Global shielded budget:**

In addition to the per-pool limits, the total shielded cost across all
pools in a block MUST NOT exceed $\mathsf{GlobalShieldedBudget}$, where
the shielded cost of a block is defined as:

$\sum_{\mathit{tx}} \left(\mathit{nActionsOrchard}(\mathit{tx}) + \mathit{nActionsIronwood}(\mathit{tx})\right) \;+\; \sum_{\mathit{tx}} (\mathit{nSpendsSapling}(\mathit{tx}) + \mathit{nOutputsSapling}(\mathit{tx})) \;+\; 2 \times \sum_{\mathit{tx}} \mathit{nJoinSplit}(\mathit{tx})$

Thus, Orchard and Ironwood do not receive separate 330-unit global
budgets: every action in either pool consumes one unit of the same global
budget.

The factor of 2 for Sprout JoinSplits reflects that each
JoinSplit produces 2 shielded outputs. While
$\mathsf{SproutBlockJoinSplitLimit} = 0$, this term is always zero.

This global budget ensures that the worst-case shielded sync bandwidth
per block is bounded regardless of which combination of pools is used.

These limits do not apply to the transparent components of
transactions. The overall 2 MB block size limit continues to apply as
before.

##### Rationale: Compact sync bandwidth per action

The limits above are chosen to bound the worst-case bandwidth that
lightweight wallets must download for shielded sync. The Light Wallet
Protocol represents both Orchard and Ironwood actions using
`CompactOrchardAction`. <a id="user-content-fnref-lightwallet-protocol"></a>
[23](/zip/218?part=2#user-content-fn-lightwallet-protocol) The per-action field payload
has the following costs:

**Orchard and Ironwood:** 148 bytes per action, consisting of:

| Field | Size |
| --- | --- |
| cmx (note commitment) | 32 bytes |
| nullifier | 32 bytes |
| ephemeral public key | 32 bytes |
| truncated note plaintext | 52 bytes |
| **Total** | **148 bytes** |

**Sapling:** 32 bytes per spend (input) and 116 bytes per output,
consisting of:

| Field | Size |
| --- | --- |
| *Per spend:* nullifier | 32 bytes |
| *Per output:* cmu (note commitment) | 32 bytes |
| *Per output:* ephemeral public key | 32 bytes |
| *Per output:* truncated note plaintext | 52 bytes |
| **Per spend total** | **32 bytes** |
| **Per output total** | **116 bytes** |

With these limits, the worst-case compact sync bandwidth per block is:

- **Orchard or Ironwood:** $330 \times 148 = 48{,}840$ bytes

- **Sapling:** at most $300 \times 116 = 34{,}800$ bytes (all-output
  pathological case)

Due to the global shielded budget, these cannot stack: a block that
uses 330 Orchard and/or Ironwood actions has zero budget remaining for
Sapling. The worst-case compact sync bandwidth per block is
therefore always bounded by the Orchard-protocol case at 48,840 bytes.

See the [Rationale](#rationale) section for the full daily bandwidth
analysis.

<a id="effect-on-difficulty-adjustment"></a>

### Effect on difficulty adjustment

As with the Blossom activation <a id="user-content-fnref-zip-0208"></a>
[24](/zip/218?part=2#user-content-fn-zip-0208), the difficulty adjustment
parameter $\mathsf{PoWMedianBlockSpan}$ refers to a number of blocks
and does not change at activation. The change in the effective value
of $\mathsf{PoWTargetSpacing}$ will cause the block spacing to adjust
to the new target at the normal rate for a difficulty adjustment. See
[Difficulty averaging window](#difficulty-averaging-window) in the
Rationale for analysis of the $\mathsf{PoWAveragingWindow}$ change.

It is likely that the difficulty adjustment for the first few blocks
after activation will be limited by $\mathsf{PoWMaxAdjustDown}$. This
is not anticipated to cause any problem.

<a id="minimum-difficulty-blocks-on-testnet-minimum-difficulty-blocks-on-testnet"></a>

### Minimum difficulty blocks on Testnet [minimum-difficulty-blocks-on-testnet]

On Testnet, the minimum-difficulty block threshold defined in ZIP 205
<a id="user-content-fnref-zip-0205"></a>
[25](/zip/218?part=2#user-content-fn-zip-0205) and modified by ZIP 208 <a id="user-content-fnref-zip-0208-2"></a>
[24](/zip/218?part=2#user-content-fn-zip-0208) is changed at the
Testnet NU7 activation height. For a block at height
$\mathsf{height} \geq 299188$, the threshold is
$6 \cdot \mathsf{PoWTargetSpacing}(\mathsf{height})$ seconds before NU7
activation and $18 \cdot \mathsf{PoWTargetSpacing}(\mathsf{height})$
seconds from NU7 activation onward. The latter is $18 \times 25 = 450$
seconds. A block is a minimum-difficulty block only if its block time is
*strictly greater* than this threshold after the preceding block's time.
Thus, at and after Testnet NU7 activation, a gap of 450 seconds does not
qualify, while a gap of 451 seconds does. In that case, the block's
`nBits` field MUST be set to $\mathsf{ToCompact}(\mathsf{PoWLimit})$ as
specified by ZIP 208. This change does not affect Mainnet.

<a id="non-consensus-node-behaviour"></a>

### Non-consensus node behaviour

#### Default expiry delta

The default expiry delta of 40 blocks (approximately 50 minutes at 75-second
spacing) is tripled from NU7 activation, to keep that expiry time. In
"Expiration height" <a id="user-content-fnref-zip-0315-expiration-height"></a>
[26](/zip/218?part=2#user-content-fn-zip-0315-expiration-height), replace:

> ```
> A wallet SHOULD create transactions using the default expiration height of
> 40 blocks from the current height, as specified in [#zip-0203]_.
> ```

with:

> ```
> A wallet SHOULD create transactions using a default expiration height of
> 40 blocks after the target height (the height of the next block after the
> chain tip) before NU7 activation, and of 120 blocks after the target height
> from NU7 activation, as specified in [#zip-0203]_ and [#zip-0218]_. If the
> user has configured an expiry delta, the configured value SHOULD be used both
> before and after NU7 activation.
> ```

In "References" <a id="user-content-fnref-zip-0315-2"></a>
[14](/zip/218?part=2#user-content-fn-zip-0315), add:

> ```
> .. [#zip-0218] `ZIP 218: 25-second Block Target Spacing <zip-0218.md>`_
> ```

#### Block-count-based constants

The following constants, measured in number of blocks, were reviewed.
They are named as in the 'Other block-related constants' section of
ZIP 208 <a id="user-content-fnref-zip-0208-3"></a>
[24](/zip/218?part=2#user-content-fn-zip-0208), which quotes their `zcashd` definitions; the
"Current" column gives the values listed there.

Implementations SHOULD scale by $\mathsf{NU7PoWTargetSpacingRatio}$
those constants that represent a time duration (marked "Scale by 3"
below), and SHOULD NOT scale those marked "No change". Implementations
SHOULD support rolling back at least 600 blocks after activation (marked
"At least 600"); a larger rollback window conforms.

| Constant | Current | Post-activation | Notes |
| --- | --- | --- | --- |
| `COINBASE_MATURITY` | 100 | 100 | Consensus rule; not changed |
| `MAX_REORG_LENGTH` | 99 | At least 600 | Wall-clock target, not a ratio scaling; decoupled from `COINBASE_MATURITY` |
| `TX_EXPIRING_SOON_THRESHOLD` | 3 | 3 | No change; |
| `MAX_BLOCKS_IN_TRANSIT_PER_PEER` | 16 | 48 | Scale by 3 |
| `BLOCK_DOWNLOAD_WINDOW` | 1024 | 3072 | Scale by 3 |
| `MIN_BLOCKS_TO_KEEP` | 288 | 864 | Scale by 3; keep 6 hours worth of blocks |
| `NETWORK_UPGRADE_PEER_PREFERENCE_BLOCK_PERIOD` | 1728 | 1728 | No change; a duration, not scaled (see Rationale) |

#### Anchor selection depth

ZIP 315 <a id="user-content-fnref-zip-0315-3"></a>
[14](/zip/218?part=2#user-content-fn-zip-0315), recommends selecting an anchor 3 blocks back from
the chain tip when constructing shielded transactions. The recommended
anchor depth SHOULD remain at 3 blocks after activation, reducing the average
wall-clock anchor delay from ~3.75 minutes to ~1.25 minutes.

#### Transactions exceeding a block limit

A transaction that would by itself violate any of the per-pool limits or
the global shielded budget specified above cannot be included in any block
at a height where NU7 is active. For example, a transaction with 200
Orchard actions and 200 Ironwood actions satisfies both per-pool limits but
exceeds $\mathsf{GlobalShieldedBudget}$.

Nodes SHOULD NOT admit such a transaction to their mempool, or relay it, if
NU7 is active at the height of the candidate next block. Wallets SHOULD NOT
create such a transaction for a target height at or after NU7 activation.

<a id="rationale"></a>

## Rationale

<a id="rationale-for-block-count-based-constants"></a>

### Rationale for block-count-based constants

The constant `COINBASE_MATURITY` is listed for completeness. Its value is
fixed by a consensus rule in § 7.1.2 'Transaction Consensus Rules'
<a id="user-content-fnref-protocol-txnconsensus"></a>
[27](/zip/218?part=2#user-content-fn-protocol-txnconsensus), which this ZIP does not change.

The constant `NETWORK_UPGRADE_PEER_PREFERENCE_BLOCK_PERIOD` represents a
duration, but is deliberately not scaled, as with Blossom <a id="user-content-fnref-zip-0208-4"></a>
[24](/zip/218?part=2#user-content-fn-zip-0208). Its
window therefore shrinks from 1.5 days at 75-second spacing to 12 hours at
25-second spacing.

This proposal is fundamentally about decreasing the target
spacing, which makes the wall-clock margin shorter for any given
`MAX_REORG_LENGTH`. Zebra's `MAX_REORG_LENGTH` was previously 99, set
just below `COINBASE_MATURITY` (= 100) by Bitcoin-inherited
convention. At Zcash's launch 150-second spacing it covered about
4.2 hours, at the current 75-second spacing about 125 minutes, and
at NU7's proposed 25-second spacing only about 42 minutes.

## Citation relationships

Cites: [ZIP 200](https://zips.tools/zip/200), [ZIP 203](https://zips.tools/zip/203), [ZIP 205](https://zips.tools/zip/205), [ZIP 207](https://zips.tools/zip/207), [ZIP 208](https://zips.tools/zip/208), [ZIP 214](https://zips.tools/zip/214), [ZIP 229](https://zips.tools/zip/229), [ZIP 237](https://zips.tools/zip/237), [ZIP 259](https://zips.tools/zip/259), [ZIP 315](https://zips.tools/zip/315), [ZIP 317](https://zips.tools/zip/317), [ZIP 2003](https://zips.tools/zip/2003)

Cited by: [ZIP 203](https://zips.tools/zip/203), [ZIP 207](https://zips.tools/zip/207), [ZIP 208](https://zips.tools/zip/208), [ZIP 214](https://zips.tools/zip/214), [ZIP 237](https://zips.tools/zip/237), [ZIP 259](https://zips.tools/zip/259), [ZIP 271](https://zips.tools/zip/271), [ZIP 401](https://zips.tools/zip/401), [ZIP 1016](https://zips.tools/zip/1016), [ZIP 2008](https://zips.tools/zip/2008)