# Draft: Version 2 Zcash P2P Network Protocol

Status: Draft

Owners: Arya, Janito

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/draft-arya-jvff-p2p-quic-transport) · [Source file](https://github.com/zcash/zips/blob/a34cfc091434275120ff017c92c3b50d3cef623a/zips/draft-arya-jvff-p2p-quic-transport.md) · [Discussion](https://github.com/zcash/zips/issues/352)

## Document parts

[Part 1](https://zip-tools-web.harpocrates.workers.dev/draft/draft-arya-jvff-p2p-quic-transport) · [Part 2](https://zip-tools-web.harpocrates.workers.dev/draft/draft-arya-jvff-p2p-quic-transport?part=2) · [Part 3](https://zip-tools-web.harpocrates.workers.dev/draft/draft-arya-jvff-p2p-quic-transport?part=3)

Reading part 3 of 3. Follow all parts for the complete proposal.

<a id="block-relay"></a>

### Block Relay

#### Divided Block Relay

This protocol divides block headers and block transactions, rather than
transferring monolithic `block` messages as the legacy protocol did:

- Block headers are gossiped directly on block announcement streams, as in
  BIP 130 <a id="user-content-fnref-bip-0130-2"></a>
  [30](#user-content-fn-bip-0130).

- Block transactions are relayed separately from headers using compact block
  relay (adapted from BIP 152 <a id="user-content-fnref-bip-0152"></a>
  [31](#user-content-fn-bip-0152)): a block is transferred as its
  header plus identifiers of its transactions, and only the transactions the
  receiver is missing are requested and transferred, using `get-tx` requests.

Both mechanisms are unconditional; the per-connection preferences are carried
in the `announce` and `full_ids` fields of the `init` record (see
[Init Record](#initrecord)).

#### Compact Block Relay

Compact block relay is adapted from BIP 152 <a id="user-content-fnref-bip-0152-2"></a>
[31](#user-content-fn-bip-0152). This section
specifies the protocol flows and the Zcash-specific differences from BIP 152;
BIP 152 provides the design rationale.

The differences from BIP 152 are:

- There is no `sendcmpct` message. Compact block relay is unconditional, and
  the high-bandwidth announcement preference is carried in the `announce`
  field of the `init` record (see [Init Record](#initrecord)). (A future
  change to the compact block encoding would be deployed under a new protocol
  version.)

- A compact block cannot be requested: BIP 152's `getdata` with
  `MSG_CMPCT_BLOCK` has no equivalent, and compact blocks occur only as
  high-bandwidth announcements. A peer announced to in low-bandwidth mode
  instead requests the block's coinbase transaction and transaction IDs via
  `get-headers` with `tx_ids = 1` (see [Relay Protocol](#relayprotocol)).

- A compact block can identify the block's transactions either by short
  transaction IDs or by full transaction IDs, at the receiver's option (the
  `full_ids` field of the `init` record; see
  [Full Transaction IDs](#fulltransactionids)). BIP 152 supports only short
  transaction IDs.

- There are no `getblocktxn` and `blocktxn` messages. Missing transactions are
  requested with `get-tx` requests (using `SHORTID`, `TXID`, or `WTXID`
  references) and delivered in the corresponding responses; see
  [Requesting Missing Transactions](#requestingmissingtransactions).

- The `header` field of a compact block uses the Zcash block header encoding
  <a id="user-content-fnref-protocol-blockheader-7"></a>
  [12](#user-content-fn-protocol-blockheader), including the Equihash solution, rather than the
  80-byte Bitcoin header.

- The input to the short transaction ID computation is based on the wtxid as
  defined in ZIP 239 <a id="user-content-fnref-zip-0239-3"></a>
  [23](#user-content-fn-zip-0239) for version 5 transactions, rather than on
  either the txid (BIP 152 version 1) or the BIP 141 wtxid (BIP 152
  version 2); see [Short Transaction IDs](#shorttransactionids).

##### Compact Block Encoding

A compact block relays a block as its header plus a compact representation of
its transactions:

| Size | Field | Description |
| --- | --- | --- |
| varies | `header` | The block header, encoded as a CompactSize length prefix followed by the serialized header <a id="user-content-fnref-protocol-blockheader-8"></a> [12](#user-content-fn-protocol-blockheader) (including the Equihash solution). |
| 8 | `nonce` | Nonce for short transaction ID computation (`uint64`, little-endian). If `ids_kind` is 1, this field SHOULD be 0 and MUST be ignored. |
| 1 | `ids_kind` | 0 if `ids` contains short transaction IDs; 1 if it contains full transaction IDs (`uint8`). |
| varies | `ids_count` | Number of transaction IDs (CompactSize). |
| varies | `ids` | If `ids_kind` is 0: short transaction IDs, 6 bytes each, little-endian (see [Short Transaction IDs](#shorttransactionids)). If `ids_kind` is 1: full transaction IDs, 64 bytes each (see [Full Transaction IDs](#fulltransactionids)). |
| varies | `prefilled_count` | Number of prefilled transactions (CompactSize). |
| varies | `prefilled_txns` | Prefilled transactions (see below). |

Each transaction in the block, in block order, is represented either by a
transaction ID in `ids` (short or full, according to `ids_kind`) or by a full
serialized transaction in `prefilled_txns`; the total number of transactions
in the block is `ids_count + prefilled_count`. Each of `ids_count` and
`prefilled_count` MUST NOT exceed 65,536, and their sum MUST NOT exceed
65,536; a compact block violating any of these is a connection error of type
`FLOOD`. Bounding the two counts individually is required as well as
bounding the sum: each is an independent CompactSize that may be as large as
2^64 − 1 on the wire, and a sum of two such values can wrap to a small
number that satisfies a bound the addends do not.

A node MUST set `ids_kind` to 1 in compact blocks sent to a peer that set
`full_ids = 1` in its `init` record, and SHOULD set `ids_kind` to 0 otherwise.
A compact block with an `ids_kind` value other than 0 or 1 is a
nonconforming record (see [Announcement Streams](#announcementstreams)).

Each entry of `prefilled_txns` has the following format:

| Size | Field | Description |
| --- | --- | --- |
| varies | `index` | Differentially encoded index of this transaction within the block (CompactSize; see below). |
| varies | `tx` | A full serialized transaction, encoded as a CompactSize length prefix followed by the serialized transaction <a id="user-content-fnref-protocol-txnencoding-5"></a> [11](#user-content-fn-protocol-txnencoding). |

Prefilled transaction indexes are differentially encoded as in BIP 152
<a id="user-content-fnref-bip-0152-3"></a>
[31](#user-content-fn-bip-0152). A compact block in which any absolute index is
greater than or equal to `ids_count + prefilled_count`, or in which indexes
overflow or are not strictly increasing, is a nonconforming record (see
[Announcement Streams](#announcementstreams)). The bound is the block's own
transaction count, not the protocol maximum: an index below 65,536 can
still lie outside a small block, and a reconstructor sized to the block's
actual transaction count would then write out of bounds.

The coinbase transaction MUST be prefilled. A sender SHOULD additionally
prefill any transaction that it predicts the receiver does not have.

##### Short Transaction IDs

The short transaction ID of a transaction, relative to a given compact block,
is computed as specified in BIP 152 <a id="user-content-fnref-bip-0152-4"></a>
[31](#user-content-fn-bip-0152), with two substitutions:

1. The input to SipHash-2-4 is the transaction identifier used for relay of
   the transaction: for a transaction with version ≥ 5, its 64-byte wtxid as
   defined in ZIP 239 <a id="user-content-fnref-zip-0239-4"></a>
   [23](#user-content-fn-zip-0239) (the txid followed by the `auth_digest`);
   for a transaction with version ≤ 4, its 32-byte txid.

2. The header hashed together with the `nonce` field to derive the SipHash
   keys is the serialized Zcash block header <a id="user-content-fnref-protocol-blockheader-9"></a>
   [12](#user-content-fn-protocol-blockheader) (as it
   appears in the `header` field, without the length prefix).

The `nonce` SHOULD be chosen uniformly at random by the sender of a compact
block, so that short ID collisions between blocks and senders are independent.

##### Full Transaction IDs

The full transaction ID of a transaction is the 64-byte value consisting of
the transaction's txid followed by its `auth_digest`. For a transaction with
version ≥ 5, this is the wtxid used for relay, as defined in ZIP 239
<a id="user-content-fnref-zip-0239-5"></a>
[23](#user-content-fn-zip-0239). For a transaction with version ≤ 4, the `auth_digest` is the
placeholder value consisting of 32 bytes of `0xFF` defined in ZIP 244
<a id="user-content-fnref-zip-0244-5"></a>
[28](#user-content-fn-zip-0244).

Matching against full transaction IDs is exact — they are not subject to
collisions and involve no `nonce`. A node unable to do short-ID matching (for
example, a pruned node) requests full transaction IDs by setting
`full_ids = 1` in its `init` record, at the cost of larger compact blocks.

##### Requesting Missing Transactions

Transactions that could not be matched while reconstructing a block from a
compact block are requested with `get-tx` requests, rather than with dedicated
messages as in BIP 152 (`getblocktxn` and `blocktxn`, which identify
transactions by index within the block):

- If the compact block had `ids_kind = 0`, each unmatched short transaction ID
  is requested as a `SHORTID` transaction reference containing the block hash
  and the short transaction ID copied from the compact block. Because short
  transaction IDs depend on the `nonce` of the compact block they appeared in,
  the responding node interprets them using the `nonce` of the compact block
  it most recently sent to the requesting peer for the identified block. A
  node receiving a `SHORTID` reference for a block for which it has not
  recently sent that peer a compact block, or whose short transaction ID
  matches no transaction — or more than one transaction — in the identified
  block, SHOULD answer that reference with a not-found result.

- If the compact block had `ids_kind = 1` — and likewise for each unmatched
  full transaction ID from a `get-headers` response with `tx_ids = 1` (see
  [`get-headers`](#get-headers)) — each unmatched full transaction ID is
  requested as an ordinary transaction reference: a `TXID` reference
  containing the txid if the `auth_digest` half of the full transaction ID is
  the 32-byte `0xFF` placeholder (indicating a pre-v5 transaction), or a
  `WTXID` reference containing the full transaction ID otherwise.

A node that has sent a peer a compact block, or a `get-headers` entry carrying
transaction IDs, MUST be able, for a reasonable implementation-defined time
thereafter, to serve that block's transactions to the same peer via `get-tx` —
including by `SHORTID` references in the compact block case, and irrespective
of whether those transactions remain in its mempool.

##### Relay Protocol

A node follows the BIP 152 <a id="user-content-fnref-bip-0152-5"></a>
[31](#user-content-fn-bip-0152) protocol flows:

- **High-bandwidth mode** (the receiver's `init` record had `announce = 1`):
  the sender announces a new block by sending a compact block announcement
  directly. To minimize propagation latency, the sender MAY do so as soon as
  it has validated the block header (checking proof of work and difficulty),
  before fully validating the block. Because a high-bandwidth announcement may
  legitimately precede full validation by the announcing peer, a node MUST NOT
  assign a misbehavior penalty for a high-bandwidth announcement — a compact
  block announcement, or a header announcement substituted for one (see
  [Block Announcements](#blockannouncements)) — of a block that fails full
  validation, provided the block's header is valid (including its proof of
  work); the same exemption covers the block's transactions served under
  [Requesting Missing Transactions](#requestingmissingtransactions). A node
  SHOULD request high-bandwidth
  announcements from at most 3 peers, preferring the peers that most recently
  announced blocks to it first; changing the selection requires a new
  connection (see [Init Record](#initrecord)).

- **Low-bandwidth mode** (the receiver's `init` record had `announce = 0`):
  blocks are announced to the receiver with header announcements (see
  [Block Announcements](#blockannouncements)). The receiver MAY then request
  the block's coinbase transaction and transaction IDs — a `get-headers`
  request with `tx_ids = 1` whose `hash_stop` is the announced block hash —
  and reconstruct the block, fetching the transactions it is missing with
  `get-tx`; or it MAY request the full block via `get-blocks`. The receiver
  SHOULD use the transaction-ID form only for blocks close to its chain tip
  (BIP 152 <a id="user-content-fnref-bip-0152-6"></a>
  [31](#user-content-fn-bip-0152) recommends within 5 blocks), and request full blocks
  otherwise.

Upon receiving a compact block — or the equivalent header, coinbase
transaction, and transaction IDs from a `get-headers` response with
`tx_ids = 1` — a node attempts to reconstruct the block by matching each
transaction ID against the transactions it already holds (in its mempool or
otherwise) — computing short transaction IDs for the held transactions if the
IDs are short (`ids_kind = 0`), or comparing full transaction IDs directly
otherwise:

- If all transactions are available, the node reconstructs and validates the
  block as if it had been received as a full block.

- If one or more transactions are missing, or (for short transaction IDs) if
  two or more held transactions collide on the same short ID, the node
  requests the unresolved transactions with a `get-tx` request (see
  [Requesting Missing Transactions](#requestingmissingtransactions)), and
  completes reconstruction as the response arrives.

- If any requested transaction is answered with a not-found result, or if
  reconstruction fails after the responses arrive (for example, because a
  short ID collision caused a wrong match and the reconstructed block is
  invalid), the node SHOULD fall back to requesting the full block via
  `get-blocks`, and MUST NOT assign a misbehavior penalty solely because
  reconstruction failed.

An incorrectly reconstructed block fails validation of the block's merkle
root and authorizing data commitment, so short ID matching does not weaken
consensus enforcement.

##### Compact Block Relay Example (non-normative)

A new block reaches peer B (high-bandwidth mode) and peer C (low-bandwidth
mode) from peer A:

```
A ── block announcements ────▶ B : compact block (header, short
                                   IDs, prefilled coinbase)
     B matches the short IDs against transactions it
     holds; two are unknown
B ── get-tx ─────────────────▶ A : [SHORTID, SHORTID]
A ── response ───────────────▶ B : the two transactions
     B reconstructs the block and validates it

A ── block announcements ────▶ C : header announcement
C ── get-headers ────────────▶ A : locator, hash_stop = block
                                   hash, tx_ids = 1
A ── response ───────────────▶ C : header, coinbase, full
                                   transaction IDs
     C matches the IDs, fetches missing transactions
     via get-tx, reconstructs, and validates
```

<a id="synchronization"></a>

### Synchronization

#### Headers-First Synchronization

Nodes synchronize the block chain using a headers-first approach; it is the
baseline synchronization method of this protocol, which every node supports.
It is the *full-validation* method: it assumes no trusted data beyond the
consensus rules and the genesis block. (An alternative method for nodes
with trusted checkpoint data is specified in
[Checkpointed Synchronization](#checkpointedsynchronization); recommended
concrete synchronization strategies are specified in <a id="user-content-fnref-draft-sync-15"></a>
[13](#user-content-fn-draft-sync).)

1. The synchronizing node sends a `get-headers` request with a block locator
   (typically with `tx_ids = 0`; see [`get-headers`](#get-headers)).

2. The remote peer responds with up to 160 headers.

3. The synchronizing node validates the headers and requests full blocks via
   `get-blocks` requests.

4. Steps 1–3 repeat until the node is synchronized with the network.

The following rules apply to headers-first synchronization:

- A node MUST validate each received header — including its proof of work
  and its difficulty adjustment — before requesting the corresponding block
  and before extending its header chain with it.

- Received headers, even with valid proof of work, establish only that work
  was expended: a node MUST NOT treat a block as part of its best chain
  until the block itself has been validated under the consensus rules.
  Until then, headers serve to select and schedule block downloads.

- A node MUST NOT assign a misbehavior penalty solely because a peer's
  headers do not connect to its known chain or reflect a different best
  chain (see [Block Announcements](#blockannouncements)); penalties apply
  to provably invalid headers and blocks, per
  [Misbehavior and Banning](#misbehaviorandbanning).

#### Checkpointed Synchronization

A node MAY synchronize spans of the historical chain against *trusted
commitments*: checkpoint data — bindings of block heights to block hashes —
obtained through a channel the node already trusts, such as its own binary
or local configuration. The bulk primitives of this protocol —
`get-hashes`, `get-block-range` (whose descending delivery authenticates
every block against a committed anchor on arrival), `get-tree-roots`, and
`get-object` — exist to serve such procedures; a recommended concrete
strategy is specified in <a id="user-content-fnref-draft-sync-16"></a>
[13](#user-content-fn-draft-sync). Any checkpoint-based
synchronization procedure MUST obey the following rules.

- **Validated advancement.** A node MUST NOT advance its validated chain
  except through blocks that it has either validated under the consensus
  rules, or authenticated by an unbroken hash chain terminating in a
  checkpoint bound by a trusted commitment. The extent to which consensus
  checks may be abbreviated for checkpoint-authenticated blocks is a matter
  of local policy.

- **Untrusted inputs.** Peer-supplied data — hashes, headers, blocks — MUST
  NOT be relied upon for any security-relevant purpose until verified under
  the previous rule; until then it MAY be used only to select and schedule
  downloads. Data received from peers MUST NOT be incorporated into a
  node's trusted commitments.

- **Tolerance of divergent views.** A node MUST NOT assign a misbehavior
  penalty to a peer solely because the peer's `get-hashes` responses fail
  verification against the node's commitments, or reflect a different best
  chain; such responses are discarded and MAY be retried with other peers.

- **Reorganization margin.** Commitment-based authentication MUST NOT be
  applied within 100 blocks of the node's view of the network chain tip; the
  chain near the tip is synchronized headers-first. The responder-side
  margin of [`get-hashes`](#get-hashes) is the same depth, measured the same
  way, so that a responder's hints and a requester's authentication agree
  about which blocks are near enough to the tip to be unsettled.

- **Headers-first fallback.** A node MUST be capable of completing
  synchronization using headers-first synchronization alone, and MUST fall
  back to it where its commitments end or where too few peers serve
  `get-hashes`.

The commitment scheme itself — checkpoint spacing, any chunking, and the
hash or signature scheme binding it — is local to the node and out of scope
for this protocol.

#### Block Download Parameters

For headers-first synchronization and near-tip block fetching via
`get-blocks`, the block download parameters of ZIP 204
<a id="user-content-fnref-zip-0204-blockdownload"></a>
[32](#user-content-fn-zip-0204-blockdownload) — the download window, the per-peer in-transit
limit, and the stalling timeout — apply unchanged. On a stall, the node MAY
re-request the block from an alternative peer, cancelling the original
request stream with `CANCELLED`.

Bulk transfer via `get-block-range` and `get-object` is not governed by
those parameters: in-flight volume is bounded in bytes by transport flow
control and by the synchronizing node's scheduling policy, for which
<a id="user-content-fnref-draft-sync-17"></a>
[13](#user-content-fn-draft-sync) gives recommendations (work unit sizing, per-peer budgets,
and stall detection).

<a id="transaction-relay"></a>

### Transaction Relay

#### Announcement-Based Relay

Transaction relay follows an announcement-based protocol:

1. A node with a new transaction sends a transaction reference on its
   transaction announcement stream to each peer (subject to trickling).

2. Peers that want the transaction request it with a `get-tx` request.

3. The originating node serves the transaction in the `get-tx` response.

Announcements use `TXID` and `WTXID` references according to transaction
version, as specified in
[Transaction References](#transactionreferences).

#### Trickling

To impede network topology inference, transaction announcements SHOULD NOT be
sent immediately but SHOULD instead be "trickled" at random intervals. The
specific parameters are implementation-defined; for the reference values used
by legacy implementations, see ZIP 204 <a id="user-content-fnref-zip-0204-txrelay"></a>
[33](#user-content-fn-zip-0204-txrelay).

#### Transaction Expiry

The avoidance of relaying transactions that are about to expire
(`TX_EXPIRING_SOON_THRESHOLD`) is unchanged from the legacy protocol; see
ZIP 204 <a id="user-content-fnref-zip-0204-txrelay-2"></a>
[33](#user-content-fn-zip-0204-txrelay).

#### Mempool Policy

Orphan transaction handling and the minimum relay fee are local mempool
policy, unchanged from the legacy protocol; see ZIP 204 <a id="user-content-fnref-zip-0204-txrelay-3"></a>
[33](#user-content-fn-zip-0204-txrelay).

<a id="address-relay"></a>

### Address Relay

Address relay allows nodes to discover peers by propagating network address
records through the network, via address announcement streams and `get-addr`
requests.

#### Rate Limiting

Address records SHOULD be subject to rate limiting to prevent address
flooding. The specific mechanism is implementation-defined; for the
token-bucket reference values used by zcashd, see ZIP 204
<a id="user-content-fnref-zip-0204-addressrelay"></a>
[34](#user-content-fn-zip-0204-addressrelay).

A node MAY additionally apply backpressure on the peer's address announcement
stream to bound the rate at which it receives address records.

#### Address Book Management

Relayed addresses are unauthenticated, attacker-suppliable data; an address
book that one source can fill leads to eclipse <a id="user-content-fnref-eclipse-2"></a>
[22](#user-content-fn-eclipse). A node SHOULD
segment its address book by IP range, in the manner of the Bitcoin Core
address manager design:

- Define an address's *group* as an IP-range prefix of its address — for
  reference, Bitcoin Core and zcashd use the /16 prefix for IPv4 and the /32
  prefix for IPv6 — and, for a relayed address, its *source group* as the
  group of the peer that relayed it.

- Partition the address book into a bounded number of bounded-size buckets,
  and assign each address to a bucket determined by its group and its source
  group (keyed with a node-local secret), so that addresses from any one
  source group can occupy only a bounded fraction of the buckets. When a
  bucket is full, evict within the bucket; do not let insertions grow the
  book or displace addresses in other buckets.

- Keep addresses learned from independently trusted mechanisms (DNS seeding,
  local configuration) distinguishable from relayed addresses, and do not let
  relayed addresses evict them.

A node SHOULD also diversify its outbound connections across groups: for
reference, Bitcoin Core and zcashd make at most one outbound connection per
group. Outbound peer selection SHOULD NOT be biased toward the addresses most
recently received, since those are the easiest for an attacker to have
planted.

Addresses of overlay networks (`TORV3`, `I2P`) have no IP-range structure and
are free to generate, so bucketing cannot bound an attacker's share of them.
A node SHOULD treat each overlay network as a separate bounded segment of its
address book, and a node supporting both IP-based and overlay transports
SHOULD retain a minimum number of outbound connections on IP-based
transports.

#### Address Broadcasting

The specific broadcast intervals are implementation-defined; for the
reference values used by zcashd, see ZIP 204 <a id="user-content-fnref-zip-0204-addressrelay-2"></a>
[34](#user-content-fn-zip-0204-addressrelay).

How a node determines its own externally reachable addresses is out of scope
for this ZIP; the legacy `addr_recv`-based self-discovery is removed (see
[Init Record](#initrecord)).

<a id="misbehavior-and-banning"></a>

### Misbehavior and Banning

Peer misbehavior is handled by two mechanisms, split by severity. Unambiguous
violations of "MUST"-level requirements — malformed records, invalid stream
usage, exceeded hard limits — are *connection errors*: the node closes the
connection immediately with the indicated error code (`PROTOCOL_ERROR` or
`FLOOD` unless otherwise specified), with no score kept. Violations for which
immediate disconnection would be disproportionate, or which an
honest-but-buggy peer or a peer on a different chain could commit, instead
accumulate a per-peer *misbehavior score* that leads to disconnection and
banning only when it crosses a threshold.

Every misbehavior penalty — including any implementation-defined penalty
assigned under the final row of the table below — is constrained by the
following principle: a node MUST NOT assign a misbehavior penalty unless
the violation is provable from the received data together with data the
node has independently authenticated, does not depend on the node's own
chain view, mempool contents, clock, or local policy, and could not be
committed by a conformant peer acting on honest but divergent state.
Behavior that fails this test — however suspicious — is instead handled by
discarding the data, refusing or cancelling streams, rate limits and
backpressure, or disconnection without a ban. Penalties assigned on
weaker evidence are worse than none: they let an attacker who can arrange
the appearance of misbehavior induce honest nodes to ban one another,
narrowing each victim's peer set toward the attacker's own nodes.

The misbehavior score works as follows:

- A node SHOULD maintain a misbehavior score for each peer. Scores SHOULD
  be keyed by network address and persist across connections for a period
  on the order of the ban duration: several penalties in this protocol are
  detected only after a delay (sync-cost metadata is checked once the
  corresponding block has been downloaded; tree-root entries verify one block
  behind), so a purely per-connection score would let a peer shed its
  score — or escape a deferred penalty entirely — by reconnecting. A
  penalty detected after the offending connection has closed SHOULD be
  applied to the address's score.

- When the node detects one of the violations listed below, it adds the
  listed number of points to the peer's score:

| Points | Violation |
| --- | --- |
| 20 | `get-headers` response with more than 160 headers. |
| 20 | Non-contiguous headers in a `get-headers` response. |
| 20 | `get-addr` response with more than 1000 address records. |
| 20 | `get-hashes` metadata (`txs` or `notes`) that does not match the downloaded block (see [`get-hashes`](#get-hashes)). |
| 100 | A `get-tree-roots` entry that fails verification against authenticated header commitments (see [`get-tree-roots`](#get-tree-roots)). |
| 100 | A block delivered by `get-block-range` whose authorizing data commitment fails verification against its header (see [`get-block-range`](#get-block-range)). |
| 100 | A `get-object` object, delivered entirely by the peer, that fails verification against the requested content hash (see [`get-object`](#get-object)). |
| 100 | Announcing a v5 transaction with a `TXID` reference, or a v4-or-earlier transaction with a `WTXID` reference, in an announcement stream record or a `get-mempool` response record (see [Transaction References](#transactionreferences) and ZIP 239 <a id="user-content-fnref-zip-0239-6"></a> [23](#user-content-fn-zip-0239)). Wrong-typed references in `get-tx` requests are exempt. |
| varies | Transaction, block, or header validation failure that is provable under the principle above: an invalid signature or proof, malformed structure, invalid proof of work, or a commitment mismatch, established with full context. The penalty is determined by the severity of the validation error, subject to the exemptions below. |

Validation-failure penalties apply only where the invalidity proves that
*this* peer misbehaved. In particular, a node MUST NOT assign a
misbehavior penalty for:

- **Expiry.** A transaction that is expired, or expires too soon, relative
  to the receiver's chain tip: relay and trickling delays make expiry
  races possible between honest peers (see
  [Transaction Expiry](#transactionexpiry)).

- **Local policy.** Rejection under local mempool policy — fee
  requirements, orphan handling, conflicts with mempool contents, or
  resource limits (see [Mempool Policy](#mempoolpolicy)).

- **Missing or moved state.** A transaction whose inputs are unknown to
  the receiver or already spent in its current view, or any object the
  receiver lacks the context to validate.

- **Content of requested objects.** Consensus invalidity of a block,
  transaction, or artifact that the node itself requested by hash or
  reference (`get-blocks`, `get-block-range`, `get-tx`, `get-object`):
  the responder served exactly the bytes the identifier names, and blame
  for the object's existence lies with the peer that announced it, under
  the rules above. (Delivered data that does *not* match the requested
  identifier is covered by each stream type's own rules.)

- **Block reconstruction service.** Transactions served in fulfilment of
  the serving obligation of
  [Requesting Missing Transactions](#requestingmissingtransactions) (see
  the exemption in [Relay Protocol](#relayprotocol)).

Score thresholds and banning work as follows:

- When a peer's score reaches or exceeds the node's ban threshold, the node
  SHOULD close the connection with the `MISBEHAVIOR` error code and ban the
  peer's network address.

- While an address is banned, the node SHOULD NOT initiate connections to it,
  SHOULD refuse inbound connections from it, and SHOULD NOT include it in
  `get-addr` responses or address announcements.

- The ban threshold and ban duration are implementation-defined; for the
  reference values used by legacy implementations, see ZIP 204
  <a id="user-content-fnref-zip-0204-misbehavior"></a>
  [35](#user-content-fn-zip-0204-misbehavior).

- Whitelisted peers accumulate misbehavior scores but are exempt from
  banning and from the threshold-triggered disconnection.

Bans are keyed by network address, and are only as strong as the cost of
acquiring a new address. Banning is a meaningful deterrent for IP-based
transports; for overlay networks whose addresses are free to generate (such
as Tor onion services), it excludes only the banned address, and inbound
connection limits — not ban lists — bound the node's exposure (see
[Address Book Management](#addressbookmanagement)).

Address granularity cuts both ways even on IP transports. A single IPv6
operator typically controls at least a /64, so per-address IPv6 bans are
nearly free to evade; a node MAY key IPv6 bans and scores by prefix (a
/64 is a reasonable default). Conversely, a single IPv4 address behind
carrier-grade NAT may be shared by many independent users, so a ban can
exclude bystanders — a reason to keep ban durations bounded rather than
to widen their scope.

<a id="security-and-privacy-considerations"></a>

## Security and Privacy Considerations

**Scope of transport encryption.** Transport encryption protects the
confidentiality and integrity of each connection against passive network
observers. Peers are deliberately not authenticated (see
[Certificates](#certificates)), so an active attacker in a position to
intercept a connection can terminate the encryption with its own certificate
and read or modify that connection's traffic. The structural defense against
an active attacker seeking to control a node's view of the network is
redundancy: connections to multiple, independently discovered peers.

**Denial of service.** QUIC's address validation and amplification limits,
including Retry packets, bound the cost that spoofed-source floods can impose
(see [QUIC Transport](#quictransport)). At the application layer, resource
consumption is bounded by the record payload limit (see [Records](#records)),
the stream concurrency limits (see
[Transport Requirements](#transportrequirements)), the per-request count
limits of each request stream type, and address rate limiting (see
[Address Relay](#addressrelay)); exceeding a hard size or rate limit is a
connection error of type `FLOOD`.

A count limit is not by itself a bound on work, because the per-item size
varies by orders of magnitude: `get-block-range` and `get-object` are
therefore bounded in bytes as well (`max_bytes` and `length`), and for
`get-blocks`, `get-tx`, and `get-headers` the responder applies its own byte
budget and may finish early, with the requester re-requesting the remainder.
The general shape of the defense is that a responder is never obliged to
spend unbounded bandwidth, disk reads, or memory on one cheap request, and
that every peer-supplied count or length is checked against its bound before
it is used to size an allocation (see [Data Types and Encoding](#datatypesandencoding)).

**Fingerprinting and linkability.** A persistent TLS key would allow a node
to be recognized across connections and network locations; a node concerned
about this uses per-connection ephemeral keys (see
[Certificates](#certificates)). Connection migration links a node's traffic
across network paths (see [QUIC Transport](#quictransport)). The `user_agent`
field of the `init` record is a fingerprinting vector; a node MAY advertise a
generic user agent string. The `get-addr` policy (see [`get-addr`](#get-addr))
impedes fingerprinting of a node's address book, and trickling (see
[Trickling](#trickling)) impedes inference of the network topology and of the
origin of a transaction from announcement timing.

**Traffic analysis.** QUIC encrypts payloads but conceals neither packet
timing and volume nor the IP addresses of the communicating peers. In
particular, an adversary observing a node's traffic may still be able to
identify it as the originator of a transaction. The Tor transport (see
[Tor Transport](#tortransport)) defends against this adversary when it is
local — an observer of the node's network, or the remote peer itself, learns
neither the node's IP address nor which peers it communicates with — but not
against a global adversary correlating traffic timing across the Tor network.
The anticipated Nym mixnet transport (see [Deployment](#deployment)) is
directed at that stronger adversary.

**Length leakage.** Encryption conceals the content of application data but
not its length: neither TLS over TCP nor QUIC pads application data by
default, so encrypted packet sizes leak plaintext lengths. (QUIC defines
PADDING frames <a id="user-content-fnref-rfc9000-6"></a>
[6](#user-content-fn-rfc9000), but an implementation must use them explicitly.)
The Tor transport is coarser — Tor pads relay cells to a 509-byte body —
so leakage there is granular rather than byte-exact. To remove the
sharpest instance of this channel, every request format in this protocol
whose fields are position-fixed (`get-hashes`, `get-block-range`,
`get-tree-roots`, `get-object`, and the empty `get-addr` and `get-mempool`
requests) uses fixed-length integer encodings: every request of a given
type has a single wire length, smaller than a Tor cell body, so its
encrypted size reveals at most the stream type and never the field values,
and there is no way to misimplement the encoding so that it leaks lengths
but still interoperates. Requests that carry variable-length lists
(`get-headers`, `get-blocks`, `get-tx`) and responses necessarily reveal
their gross size; a node MAY additionally use QUIC PADDING frames to
obscure those lengths, at a bandwidth cost this specification does not
mandate.

**Tor.** On a Tor transport connection the initiator is anonymous — it
reveals no network address to the responder or to network observers — so a
node SHOULD prefer the Tor transport (where available) for the traffic most
sensitive to linkage, above all announcing transactions it originated. The
responder's onion address is a stable, linkable identifier, and onion
addresses are free to generate, which weakens address-based banning and
address book protections for `TORV3` addresses (see
[Misbehavior and Banning](#misbehaviorandbanning) and
[Address Book Management](#addressbookmanagement)).

**Mixnets.** The two kinds of traffic most sensitive to linkage are mempool
transaction propagation — announcing a transaction links the announcing
node to it, and a `get-mempool` subscription reveals interest in the
mempool's contents — and address book queries, whose `get-addr`
request/response pattern is a fingerprinting and mapping primitive. A node
implementer SHOULD carry both over a mixnet transport once one is
available (the anticipated Nym transport; see [Deployment](#deployment)),
and in the interim SHOULD carry them over the Tor transport where
available, per the preference above. Mixnet delay and cover traffic
address the timing correlation that onion routing alone does not.

**Synchronization.** Headers-first synchronization trusts proof of work:
forging a history requires outspending the honest chain's accumulated work
over the forged span, which an eclipsing attacker with sufficient hash power
can in principle do. Checkpointed synchronization trusts the node's
commitment, which shares a trust base with its binary: below its
checkpoints, an attacker who cannot break the block hash function cannot
cause acceptance of a false history. Under either method, an attacker
controlling a node's connections can withhold data and stall
synchronization; the mitigations are redundancy and re-requesting from
alternative peers (see
[Block Download Parameters](#blockdownloadparameters)).

**Eclipse attacks.** An attacker that controls all of a node's connections
controls its view of the block chain and mempool. The structural defenses are
segmentation of the address book by IP range and diversity in outbound peer
selection (see [Address Book Management](#addressbookmanagement) and
<a id="user-content-fnref-eclipse-3"></a>
[22](#user-content-fn-eclipse)), persisted addresses (see [Peer Discovery](#peerdiscovery)), and
rate-limited, validated address relay (see [Address Relay](#addressrelay)).
Overlay addresses such as onion services deserve particular caution here,
since an attacker can generate them without limit (see
[Address Book Management](#addressbookmanagement)).

<a id="deployment"></a>

## Deployment

This ZIP replaces the legacy protocol without a compatibility bridge: nodes
implementing this protocol do not interoperate with nodes implementing the
legacy protocol. Deployment is coordinated through the network upgrade
mechanism <a id="user-content-fnref-zip-0200-3"></a>
[3](#user-content-fn-zip-0200): the protocol version from which this protocol is in
effect will be assigned to a network upgrade, and the epoch enforcement of
ZIP 201 <a id="user-content-fnref-zip-0201-2"></a>
[27](#user-content-fn-zip-0201) retires legacy-protocol peers at activation, as with any
other network upgrade.

Because there is no compatibility bridge, an implementation deploying this
protocol is expected to also implement the legacy protocol during the
transition: before activation, a node participates in the network over the
legacy protocol while also listening on the QUIC transport, so that DNS
seeders and upgraded peers can discover and exercise QUIC endpoints ahead of
activation. The QUIC transport uses UDP where the legacy transport uses TCP,
so both can be served concurrently on the same port number and address. At
activation, epoch enforcement retires legacy-protocol connections, and the
node continues on this protocol alone.

DNS seeders are expected to probe and serve the QUIC endpoints of nodes
implementing this ZIP.

The protocol semantics are specified against the abstract stream layer of
[Stream Layer](#streamlayer); QUIC and Tor are the transports defined by this
ZIP. Future revisions are expected to define additional transports to be used
simultaneously with them; in particular, a transport carrying the stream layer
over the Nym mixnet <a id="user-content-fnref-nym"></a>
[36](#user-content-fn-nym) is anticipated, providing network-level metadata
protection (resistance to traffic analysis of which peers are communicating)
stronger than onion routing provides.

*Note:* The transports are complementary rather than alternatives: a node is
expected to use QUIC for latency-critical bulk relay and synchronization, and
Tor (eventually Nym) where anonymity matters more than latency, selected per
connection according to the traffic it will carry.

<a id="formal-model"></a>

## Formal Model

A TLA+ formal specification of the legacy protocol's connection lifecycle is
available at <a id="user-content-fnref-formal-model"></a>
[37](#user-content-fn-formal-model); it has not yet been updated for the protocol
specified here.

<a id="references"></a>

## References

<a id="footnote-label"></a>

### 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"](https://www.rfc-editor.org/info/bcp14) [↩](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-bcp14)

2. [Zcash Protocol Specification, Version 2026.8.0 [NU6.3]. Section 3.12: Mainnet and Testnet](protocol/protocol.pdf#networks) [↩](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-protocol-networks)

3. [ZIP 200: Network Upgrade Mechanism](/zip/200) [↩](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-zip-0200) [↩2](/draft/draft-arya-jvff-p2p-quic-transport?part=2#user-content-fnref-zip-0200-2) [↩3](#user-content-fnref-zip-0200-3)

4. [Zcash Protocol Specification, Version 2026.8.0 [NU6.3]. Section 3.3: The Block Chain](protocol/protocol.pdf#blockchain) [↩](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-protocol-blockchain)

5. [ZIP 204: Zcash P2P Network Protocol](/zip/204) [↩](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-zip-0204) [↩2](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-zip-0204-2) [↩3](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-zip-0204-3) [↩4](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-zip-0204-4) [↩5](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-zip-0204-5)

6. [RFC 9000: QUIC: A UDP-Based Multiplexed and Secure Transport](https://www.rfc-editor.org/rfc/rfc9000.html) [↩](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-rfc9000) [↩2](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-rfc9000-2) [↩3](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-rfc9000-3) [↩4](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-rfc9000-4) [↩5](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-rfc9000-5) [↩6](#user-content-fnref-rfc9000-6)

7. [Tor Rendezvous Specification — Version 3 Onion Services](https://spec.torproject.org/rend-spec/index.html) [↩](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-tor-rend-spec) [↩2](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-tor-rend-spec-2) [↩3](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-tor-rend-spec-3)

8. [RFC 8446: The Transport Layer Security (TLS) Protocol Version 1.3](https://www.rfc-editor.org/rfc/rfc8446.html) [↩](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-rfc8446) [↩2](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-rfc8446-2)

9. [RFC 9001: Using TLS to Secure QUIC](https://www.rfc-editor.org/rfc/rfc9001.html) [↩](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-rfc9001) [↩2](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-rfc9001-2)

10. [BIP 324: Version 2 P2P Encrypted Transport Protocol](https://github.com/bitcoin/bips/blob/master/bip-0324.mediawiki) [↩](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-bip-0324)

11. [Zcash Protocol Specification, Version 2026.8.0 [NU6.3]. Section 7.1: Transaction Encoding and Consensus](protocol/protocol.pdf#txnencoding) [↩](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-protocol-txnencoding) [↩2](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-protocol-txnencoding-2) [↩3](/draft/draft-arya-jvff-p2p-quic-transport?part=2#user-content-fnref-protocol-txnencoding-3) [↩4](/draft/draft-arya-jvff-p2p-quic-transport?part=2#user-content-fnref-protocol-txnencoding-4) [↩5](#user-content-fnref-protocol-txnencoding-5)

12. [Zcash Protocol Specification, Version 2026.8.0 [NU6.3]. Section 7.6: Block Header Encoding and Consensus](protocol/protocol.pdf#blockheader) [↩](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-protocol-blockheader) [↩2](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-protocol-blockheader-2) [↩3](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-protocol-blockheader-3) [↩4](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-protocol-blockheader-4) [↩5](/draft/draft-arya-jvff-p2p-quic-transport?part=2#user-content-fnref-protocol-blockheader-5) [↩6](/draft/draft-arya-jvff-p2p-quic-transport?part=2#user-content-fnref-protocol-blockheader-6) [↩7](#user-content-fnref-protocol-blockheader-7) [↩8](#user-content-fnref-protocol-blockheader-8) [↩9](#user-content-fnref-protocol-blockheader-9)

13. [Draft ZIP: Block Chain Synchronization](/draft/draft-arya-block-chain-sync) [↩](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-draft-sync) [↩2](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-draft-sync-2) [↩3](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-draft-sync-3) [↩4](/draft/draft-arya-jvff-p2p-quic-transport?part=2#user-content-fnref-draft-sync-4) [↩5](/draft/draft-arya-jvff-p2p-quic-transport?part=2#user-content-fnref-draft-sync-5) [↩6](/draft/draft-arya-jvff-p2p-quic-transport?part=2#user-content-fnref-draft-sync-6) [↩7](/draft/draft-arya-jvff-p2p-quic-transport?part=2#user-content-fnref-draft-sync-7) [↩8](/draft/draft-arya-jvff-p2p-quic-transport?part=2#user-content-fnref-draft-sync-8) [↩9](/draft/draft-arya-jvff-p2p-quic-transport?part=2#user-content-fnref-draft-sync-9) [↩10](/draft/draft-arya-jvff-p2p-quic-transport?part=2#user-content-fnref-draft-sync-10) [↩11](/draft/draft-arya-jvff-p2p-quic-transport?part=2#user-content-fnref-draft-sync-11) [↩12](/draft/draft-arya-jvff-p2p-quic-transport?part=2#user-content-fnref-draft-sync-12) [↩13](/draft/draft-arya-jvff-p2p-quic-transport?part=2#user-content-fnref-draft-sync-13) [↩14](/draft/draft-arya-jvff-p2p-quic-transport?part=2#user-content-fnref-draft-sync-14) [↩15](#user-content-fnref-draft-sync-15) [↩16](#user-content-fnref-draft-sync-16) [↩17](#user-content-fnref-draft-sync-17)

14. [ZIP 155: addrv2 message](/zip/155) [↩](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-zip-0155) [↩2](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-zip-0155-2)

15. [ZIP 204: Zcash P2P Network Protocol — DNS Seeds](/zip/204#dns-seeds) [↩](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-zip-0204-dnsseeds)

16. [RFC 9221: An Unreliable Datagram Extension to QUIC](https://www.rfc-editor.org/rfc/rfc9221.html) [↩](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-rfc9221)

17. [RFC 7301: Transport Layer Security (TLS) Application-Layer Protocol Negotiation Extension](https://www.rfc-editor.org/rfc/rfc7301.html) [↩](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-rfc7301)

18. [ZIP 204: Zcash P2P Network Protocol — Default Ports](/zip/204#default-ports) [↩](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-zip-0204-ports)

19. [RFC 7250: Using Raw Public Keys in Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS)](https://www.rfc-editor.org/rfc/rfc7250.html) [↩](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-rfc7250)

20. [The Tor Project](https://www.torproject.org/) [↩](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-tor)

21. [ZIP 204: Zcash P2P Network Protocol — Data Types and Encoding](/zip/204#data-types-and-encoding) [↩](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-zip-0204-datatypes)

22. [Ethan Heilman, Alison Kendler, Aviv Zohar, Sharon Goldberg. Eclipse Attacks on Bitcoin's Peer-to-Peer Network. 24th USENIX Security Symposium, 2015.](https://eprint.iacr.org/2015/263) [↩](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-eclipse) [↩2](#user-content-fnref-eclipse-2) [↩3](#user-content-fnref-eclipse-3)

23. [ZIP 239: Relay of Version 5 Transactions](/zip/239) [↩](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-zip-0239) [↩2](/draft/draft-arya-jvff-p2p-quic-transport#user-content-fnref-zip-0239-2) [↩3](#user-content-fnref-zip-0239-3) [↩4](#user-content-fnref-zip-0239-4) [↩5](#user-content-fnref-zip-0239-5) [↩6](#user-content-fnref-zip-0239-6)

24. bit $k$ is the bit with numeric weight $2^k$. [↩](/draft/draft-arya-jvff-p2p-quic-transport?part=2#user-content-fnref-zip-0204-serviceflags)

25. [ZIP 204: Zcash P2P Network Protocol — Assigning Protocol Versions to Network Upgrades](/zip/204#assigning-protocol-versions-to-network-upgrades) [↩](/draft/draft-arya-jvff-p2p-quic-transport?part=2#user-content-fnref-zip-0204-assignment) [↩2](/draft/draft-arya-jvff-p2p-quic-transport?part=2#user-content-fnref-zip-0204-assignment-2)

26. [ZIP 204: Zcash P2P Network Protocol — Network Upgrade Epoch Enforcement](/zip/204#network-upgrade-epoch-enforcement) [↩](/draft/draft-arya-jvff-p2p-quic-transport?part=2#user-content-fnref-zip-0204-epochs)

27. [ZIP 201: Network Peer Management for Overwinter](/zip/201) [↩](/draft/draft-arya-jvff-p2p-quic-transport?part=2#user-content-fnref-zip-0201) [↩2](#user-content-fnref-zip-0201-2)

28. [ZIP 244: Transaction Identifier Non-Malleability](/zip/244) [↩](/draft/draft-arya-jvff-p2p-quic-transport?part=2#user-content-fnref-zip-0244) [↩2](/draft/draft-arya-jvff-p2p-quic-transport?part=2#user-content-fnref-zip-0244-2) [↩3](/draft/draft-arya-jvff-p2p-quic-transport?part=2#user-content-fnref-zip-0244-3) [↩4](/draft/draft-arya-jvff-p2p-quic-transport?part=2#user-content-fnref-zip-0244-4) [↩5](#user-content-fnref-zip-0244-5)

29. [ZIP 221: FlyClient - Consensus-Layer Changes](/zip/221) [↩](/draft/draft-arya-jvff-p2p-quic-transport?part=2#user-content-fnref-zip-0221) [↩2](/draft/draft-arya-jvff-p2p-quic-transport?part=2#user-content-fnref-zip-0221-2)

30. [BIP 130: sendheaders message](https://github.com/bitcoin/bips/blob/master/bip-0130.mediawiki) [↩](/draft/draft-arya-jvff-p2p-quic-transport?part=2#user-content-fnref-bip-0130) [↩2](#user-content-fnref-bip-0130-2)

31. [BIP 152: Compact Block Relay](https://github.com/bitcoin/bips/blob/master/bip-0152.mediawiki) [↩](#user-content-fnref-bip-0152) [↩2](#user-content-fnref-bip-0152-2) [↩3](#user-content-fnref-bip-0152-3) [↩4](#user-content-fnref-bip-0152-4) [↩5](#user-content-fnref-bip-0152-5) [↩6](#user-content-fnref-bip-0152-6)

32. [ZIP 204: Zcash P2P Network Protocol — Block Download Parameters](/zip/204#block-download-parameters) [↩](#user-content-fnref-zip-0204-blockdownload)

33. [ZIP 204: Zcash P2P Network Protocol — Transaction Relay](/zip/204#transaction-relay) [↩](#user-content-fnref-zip-0204-txrelay) [↩2](#user-content-fnref-zip-0204-txrelay-2) [↩3](#user-content-fnref-zip-0204-txrelay-3)

34. [ZIP 204: Zcash P2P Network Protocol — Address Relay](/zip/204#address-relay) [↩](#user-content-fnref-zip-0204-addressrelay) [↩2](#user-content-fnref-zip-0204-addressrelay-2)

35. [ZIP 204: Zcash P2P Network Protocol — Misbehavior and Banning](/zip/204#misbehavior-and-banning) [↩](#user-content-fnref-zip-0204-misbehavior)

36. [The Nym Mixnet](https://nymtech.net/) [↩](#user-content-fnref-nym)

37. [Zcash P2P Protocol TLA+ Specification](https://github.com/oxarbitrage/zcash-p2p-spec) [↩](#user-content-fnref-formal-model)

## Citation relationships

Cites: [ZIP 155](https://zip-tools-web.harpocrates.workers.dev/zip/155), [ZIP 200](https://zip-tools-web.harpocrates.workers.dev/zip/200), [ZIP 201](https://zip-tools-web.harpocrates.workers.dev/zip/201), [ZIP 204](https://zip-tools-web.harpocrates.workers.dev/zip/204), [ZIP 221](https://zip-tools-web.harpocrates.workers.dev/zip/221), [ZIP 239](https://zip-tools-web.harpocrates.workers.dev/zip/239), [ZIP 244](https://zip-tools-web.harpocrates.workers.dev/zip/244)

Cited by: None