Add draft ZIP: Version 2 Zcash P2P Network Protocol - #1344
Conversation
| The QUIC transport uses QUIC version 1 [^rfc9000] over UDP, secured with | ||
| TLS 1.3 [^rfc8446] as specified by RFC 9001 [^rfc9001]. | ||
|
|
||
| - A node MUST NOT use 0-RTT (early data). Requests carried in 0-RTT data are |
There was a problem hiding this comment.
What SHOULD/MUST you do if your peer tries to use 0-RTT? Suggestion: MUST drop the connection.
arya2
left a comment
There was a problem hiding this comment.
This draft should also include a Tor profile
| | Size | Field | Description | | ||
| |--------|-----------|-----------------------------------------------------------------------------------------------------------------| | ||
| | varies | `count` | Number of entries (CompactSize). | | ||
| | varies | `entries` | `count` entries, each a 1-byte requested format (`0x00` full block, `0x01` compact block) followed by a 32-byte block hash. | |
There was a problem hiding this comment.
we don't need to decide between full or compact blocks here, always return full blocks, add coinbase transaction and transaction ids to getheaders response instead
| Requests references to the contents of the peer's transaction memory pool; | ||
| the requester may then fetch transactions of interest with `get-tx`. A node | ||
| MAY decline to serve `get-mempool` by resetting its sending direction of the |
There was a problem hiding this comment.
Unclear if this is meant to be a snapshot or a subscription, but it should be a subscription
| ### Address Announcements | ||
|
|
||
| Stream type: `0x12` | ||
|
|
||
| Each record payload on an address announcement stream is a single network | ||
| address record (see [Network Address Record](#networkaddressrecord)). |
There was a problem hiding this comment.
This may pose a address book takeover risk (look at IP segmentation)
| mechanisms. | ||
|
|
||
|
|
||
| ## Misbehavior and Banning |
There was a problem hiding this comment.
This needs to be re-written, it can be more concise in describing the concept and more verbose in explaining how it should work.
| | Size | Field | Description | | ||
| |--------|-------------|--------------------------------------------------------------------------| | ||
| | varies | `count` | Number of address records (CompactSize). | | ||
| | varies | `addresses` | `count` network address records (see [Network Address Record](#networkaddressrecord)). | |
There was a problem hiding this comment.
add information about peer services to the response format
| | varies | `network` | Network identifier string (CompactSize-prefixed; see below). | | ||
| | varies | `initial_max_data` | Initial connection-level flow control credit in bytes (CompactSize). | | ||
| | varies | `initial_max_stream_data` | Initial per-stream flow control credit in bytes (CompactSize). | | ||
| | varies | `initial_max_streams_bidi` | Initial limit on the peer's concurrent bidirectional streams (CompactSize). | | ||
| | varies | `initial_max_streams_uni` | Initial limit on the peer's concurrent unidirectional streams (CompactSize). | |
There was a problem hiding this comment.
General comments about length leakage attacks — that is, attacks that infer information about plaintext from encrypted packet sizes.
QUIC
QUIC doesn't pad application data by default. It has PADDING frames which are one-byte frames (QUIC uses a prefix-free lengthless frame encoding) that can be used to extend any packet to a fixed length. However, an application would need to use that mechanism explicitly. If it doesn't, then it leaks the total length of the variable-length integer encodings. If it does, then any bandwidth benefit of using variable-length encodings is lost.
So what I would suggest is to look at all of the small application message types (requests without any attached data), and make all of those message formats a fixed length, so that they become indistinguishable once encrypted. For compatibility with Tor, that length should be at most the Tor cell body length, i.e. ≤ 509 bytes. The easiest way to do this is to use fixed-length integer encodings — that way the number of padding bytes is fixed for each message type, and there will be no way to misimplement it so that it leaks length information for those types but still interoperates. Optionally you could allow several small messages to be encoded within a larger fixed-size cell, but I'm not sure that's worth the hassle.
Note that this doesn't address information leakage from the lengths of larger messages; you could add padding for those but I'm not sure it would help as much.
Tor
Tor pads application data to the cell body length of 509 bytes. So the leakage in that case is granular, and would only be visible to an adversary if several messages are concatenated to a size that either fits or does not fit in a cell body. In any case, what I suggested above would be harmless for Tor and could reduce that remaining leakage.
There was a problem hiding this comment.
daira
left a comment
There was a problem hiding this comment.
Consider whether to address the short-message length leakage issue. Otherwise ACK.
A successor to the protocol specified in ZIP 204, replacing the Bitcoin-inherited TCP message-passing architecture with a transport-neutral stream layer realized by QUIC, anticipating a Nym mixnet transport used in parallel (QUIC for latency-critical relay and sync, Nym for anonymity-critical traffic such as transaction origination). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Convert draft-arya-jvff-p2p-quic-transport from reStructuredText to MultiMarkdown, and improve the specification: - Define a stream "refuse" operation so rejecting unidirectional streams is expressible (a receiver cannot reset a peer's stream). - Exempt compact block announcements with valid headers from misbehavior penalties, since high-bandwidth mode permits relay before full validation. - Permit header announcements regardless of the announce preference, and fall back to them when a compact block exceeds the record size limit. - Bound compact block transaction counts (ids_count + prefilled_count <= 65,536, matching the prefill index space). - Specify get-headers behavior for empty and unmatched locators, and allow empty responses. - Define "connection error", reserve stream type ranges, and make malformed requests/responses and unknown result values explicit PROTOCOL_ERRORs. - Allow the responder to send its init record immediately, and responders to serve requests before the requester's FIN. - Require accepting both certificate encodings and key types; note the linkability cost of connection migration. - Restrict get-addr requests to outbound connections, matching the answering rule. - Prefer persisted addresses over DNS seeding in peer discovery; note that address self-discovery is out of scope. - Ignore and preserve unrecognized service bits. - Add a Security and Privacy Considerations section and a dual-stack transition paragraph to Deployment. - Add a Serialized Blocks section: the protocol spec deliberately leaves whole-block encoding to the P2P protocol, and the previously cited "Section 7.6: Block Encoding" (#blockencoding) never existed in any spec release. - Update protocol spec citations to Version 2026.8.0 [NU6.3], including the renumbered Section 7.6: Block Header Encoding and Consensus. - Add requester/responder terminology and clarify the legacy protocol version number. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Frame the protocol over an arbitrary transport providing a secure channel and peer/network identification, per review discussion. - Add a Tor transport: v3 onion services, in-band network preamble, and a QUIC-modeled stream framing layer over the Tor bytestream. - 0-RTT: responders MUST NOT accept early data; attempted use MUST close the connection. - Clarify that a retried request starts a new stream whose first byte is again the stream type. - Deduplicate protocol version tables and assignment procedure against ZIP 204; state that protocol versions share the legacy numbering space. - get-blocks always returns full blocks; get-headers optionally carries each block's coinbase transaction and full transaction IDs (tx_ids=1), replacing requestable compact blocks in low-bandwidth relay. - Make get-mempool a subscription (snapshot plus ongoing updates). - Add Address Book Management: IP-range bucketing, source-group segmentation, and overlay-address caution against address book takeover. - Rewrite Misbehavior and Banning: concise concept, detailed mechanics, and ban semantics per transport. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C36xn69yRXtupScMCYarca
Moves the wire-level get-hashes primitive (best-chain block hashes at a requested height stride) into the protocol ZIP, supporting the checkpoint-based synchronization strategies recommended by the companion block chain synchronization draft. Headers-first becomes the baseline (rather than only) synchronization method. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C36xn69yRXtupScMCYarca
Adds normative rules and security considerations for synchronization: headers-first (eager header/PoW validation, headers as scheduling inputs only, cross-peer chain comparison, no penalties for divergent views) and checkpointed synchronization (validated advancement, untrusted-input handling, reorganization margin, headers-first fallback), with trusted commitments defined but their scheme left local to the node. Concrete strategies remain in the companion block chain synchronization draft. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C36xn69yRXtupScMCYarca
…ning Extends the review pattern of citing ZIP 204 by section: DNS seed lists, connection limits, block download parameters, trickling/mempool policy, address relay reference values, ban thresholds, and ZIP 201 peer preference are now references instead of copies. The addrv2 record encoding collapses to a ZIP 155 citation, keeping only the per-transport port interpretation and reachability notes. Also removes internal duplication (Motivation vs Changes list, the transport complementarity story, ZIP 239 relay rule stated four times, Network Upgrade Peer Management vs Epoch Enforcement) and trims rationale prose from normative sections. Net -239 lines with no normative wire format removed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C36xn69yRXtupScMCYarca
- Add a bottom-up roadmap paragraph at the top of the Specification. - Promote synchronization (headers-first, checkpointed rules, download parameters) out of Block Relay into its own top-level section, so block propagation and chain synchronization are separate concerns. - Link the stream types table entries to their sections, making it an index. - Add short non-normative example flows: connection establishment, and block relay in high- and low-bandwidth modes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C36xn69yRXtupScMCYarca
Each entry now carries span metadata alongside the block hash: a quantized size (unit ceil(MAX_BLOCK_SIZE/255) = 7,844 bytes, matching the deployed Zebra known-hash asset hint format), transaction count, and note-commitment count, aggregated over the stride-long span ending at the entry. Stride 1 gives per-block values; checkpoint-spaced strides give per-chunk totals for byte- and cost-balanced download scheduling. Hints are deterministic functions of the identified blocks, so post-download mismatches are provable and penalized. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C36xn69yRXtupScMCYarca
Brings in the security-review fixes, misbehavior-attribution hardening, and deduplication pass applied on agent/checkpointed-sync-zip, so this PR reflects the current text of the draft. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Per review: state directly that a peer attempting 0-RTT MUST have its connection closed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Drops the 7,844-byte size-value unit in favor of plain byte counts. The unit existed to compress checkpoint data distributed through crates.io, which is not a constraint on the P2P protocol, and tying the encoding to the maximum block size was a forward-compatibility footgun for a future block size change. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Per review: stride is unneeded. Each entry now describes a single block (hash, size, txs, notes); a requester needing coarser granularity aggregates the per-block values itself. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Per review: make explicit that each address record carries last-known service flags, how a responder populates them, and that they are an unauthenticated selection hint until confirmed by the peer's own init record. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Per review: requests whose fields are position-fixed (get-hashes, get-block-range, get-tree-roots, get-object) now use fixed-length integer encodings instead of CompactSize, so each request type has a single wire length below the Tor cell body size and its encrypted size reveals at most the stream type. Adds a Length Leakage discussion to the security considerations covering QUIC PADDING, Tor cell granularity, and the remaining leakage from list-carrying requests and responses. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Node implementers SHOULD carry mempool transaction propagation and address book queries over a mixnet transport once available, and over Tor in the interim. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
c4ab11e to
155d838
Compare
|
@daira I think this is ready to merge as a first draft |
Verified against a trusted commitment, cumulative txouts values give each block's bit offsets within the spentness-hint bitmap of the sync draft, letting a synchronizing node check the bitmap's length before downloading bodies and letting parallel work units index the bitmap without processing the blocks below them. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
This is still a CompactSize.
…eams Phase 1 of the TLA+ model of the draft "Version 2 Zcash P2P Network Protocol" (zcash/zips#1344, pinned at a3f4fa2a), which cites this repo as its formal model. Lives in v2/; the legacy ZIP-204 model is unchanged. - v2/streams.tla: one FIFO per stream instead of one inbox per connection, so QUIC's "streams are mutually independent" is modeled as free reordering across streams; FIN is a queue sentinel, RESET_STREAM/STOP_SENDING are flags that can overtake data; slots are reused once both sides close. - v2/records.tla: init and header-announcement records. - v2/protocol.tla: connection setup, init handshake with min-version negotiation and OBSOLETE, block announcement streams with the one-per-type rule and sender-initiated replacement. Two switches select the receiver's reading of the draft: StrictSingleton, RefusePreHandshake. Finding: under the literal reading of "Announcement Streams", a sender that finishes or resets its announcement stream and opens the replacement the draft allows is disconnected with PROTOCOL_ERROR whenever the receiver consumes the replacement's type byte before the old stream's FIN or reset. protocol_strict.cfg reproduces it as a 12-state violation of NoHonestProtocolError; protocol.cfg / protocol_refuse.cfg / protocol_obsolete.cfg verify completely under the tolerant reading. Zebra's draft implementation applies the strict check on receive. CI runs the four 2-peer configs (strict as a must-fail) and a bounded 3-peer symmetry run; the PDF workflow now also covers sync_scheduler.tla and the v2 modules. Write-up in documents/v2-modeling.md, proposed draft wording in documents/v2-spec-feedback.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A successor to the protocol specified in ZIP 204, replacing the Bitcoin-inherited TCP message-passing architecture with a transport-neutral stream layer realized by QUIC, anticipating a Nym mixnet transport used in parallel (QUIC for latency-critical relay and sync, Nym for anonymity-critical traffic such as transaction origination).
Adds
zips/draft-arya-jvff-p2p-quic-transport.rst(new draft ZIP, 1714 lines).