Skip to content

feat(state): add the 28.1.0 sync metadata and known-hash chunk format - #11275

Draft
arya2 wants to merge 1 commit into
p2p-v2-2-wire-formatsfrom
p2p-v2-3-quic-transport
Draft

feat(state): add the 28.1.0 sync metadata and known-hash chunk format#11275
arya2 wants to merge 1 commit into
p2p-v2-2-wire-formatsfrom
p2p-v2-3-quic-transport

Conversation

@arya2

@arya2 arya2 commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Motivation

Third PR of the six-PR stack implementing the draft version 2 Zcash P2P
network protocol (zcash/zips#1344).
The protocol's synchronization requests need per-block data the state does
not index today: get-hashes serves best-chain hashes with aggregated span
metadata, and get-tree-roots serves per-block note commitment tree roots
and counts. The known-hash sync engine additionally needs a store for
verified known-hash chunks, and SwiftSync spentness hints
(zcash/zips#1346) need a global
ordinal for every transparent output.

Per the design decision in docs/design-swiftsync-hints.md (one combined
format), this PR lands all three needs as a single 28.1.0 database
format: the sync-metadata column family with a per-height cumulative
transparent-output count, and the known-hash chunk column family. The QUIC
transport and peer connection that consume this metadata follow in the next
PR.

Solution

  • sync_meta_by_height: per-block synchronization metadata — serialized
    size, transaction and note counts, per-pool transaction counts, the
    ZIP 244 authorizing data commitment, and the chain's cumulative
    transparent-output count at that block, which assigns every transparent
    output its spentness-hint ordinal. Records are written at block commit;
    a format upgrade backfills existing databases and chases the live tip,
    and commit-time writes skip ahead-of-backfill heights so the column
    family stays contiguous from genesis.
  • known_hash_chunk: verified known-hash chunk bytes by chunk index,
    stored opaquely after verification against the pinned SHA-256 constants
    (the pins stay in zebra-chain as the trust root). Not backfilled;
    written on demand.
  • Serving plumbing: ReadRequest::SyncHashes/TreeRoots answer the v2
    requests from the index — entries stop at MAX_BLOCK_REORG_HEIGHT below
    the tip and at the backfill frontier, and tree-roots is refused unless
    the anchor is in the best chain. The internal Request::SyncHashes/
    TreeRoots variants are local-only (never routed to a peer), and the
    inbound service answers them from state.

Tests

  • New state vectors: metadata written at commit with the correct
    cumulative count, upgrade backfill on an existing database, and column
    family snapshot updates.
  • Full zebra-network and zebra-state suites pass; cargo clippy --all-targets warning-free; zebrad builds.

Specifications & References

  • Draft version 2 Zcash P2P network protocol: zcash/zips#1344
  • Draft SwiftSync spentness hints: zcash/zips#1346
  • Combined-format decision: docs/design-swiftsync-hints.md (decision 5), docs/port-plan-sync-engine.md (W1)

Follow-up Work

AI Disclosure

  • No AI tools were used in this PR
  • AI tools were used: Claude Code was used to implement the format and
    serving changes, run the test/lint verification, and draft the commit
    messages and this description; the changes were reviewed by the author.

PR Checklist

  • The PR title follows conventional commits format: type(scope): description
  • The PR follows the contribution
    guidelines
    .
  • This change was discussed in an issue or with the team beforehand.
  • The solution is tested.
  • The documentation and changelogs are up to date.

@v12-auditor

v12-auditor Bot commented Aug 17, 2026

Copy link
Copy Markdown

Note

Complete: Audit complete. V12 found four issues worth reviewing.

Open the full results here.

FindingSeverityDetails
F-232241 🔵 Low
Legacy QUIC drafts bypass v1 policy

The transport declares that it uses QUIC version 1, but new_endpoint constructs its listener with quinn::Endpoint::server and never supplies a v1-only EndpointConfig. In the resolved quinn 0.11.9 / quinn-proto 0.11.16 implementation, that convenience constructor accepts QUIC v1 plus legacy draft versions 0xff00001d through 0xff000022. An unauthenticated client can select one of those drafts, offer the expected network ALPN, complete TLS 1.3, and pass accept because the post-handshake validation checks only ALPN. Outbound Zebra connections still default to v1, so the bypass affects inbound sessions. The defect is currently latent because the v2 transport is test-only until the follow-up peer-set integration.

F-232243 🟡 Medium
Custom testnets share one ALPN domain

alpn_protocol maps every non-Regtest Network::Testnet(_) to the same zcash/test ALPN, even though configured testnets can have distinct network magic and consensus parameters. Both TLS configurations advertise only that collapsed identifier, and both post-handshake checks compare only against the same mapping. Two incompatible custom testnets therefore complete QUIC/TLS negotiation and can exchange stream data despite the module's claim that different networks fail before application data. The stated genesis-hash fallback is absent from the v2 init record and cannot distinguish two custom networks that intentionally share the default Testnet genesis while using different magic values. This defect is latent because v2 is not yet connected to the production peer set.

F-232244 🟡 Medium
Handshake PINGs pin connection slots indefinitely

connect and accept await Quinn's connection future directly and configure only a 120-second activity-based idle timeout, not an absolute handshake deadline. A peer can derive QUIC Handshake keys, withhold its TLS Finished message, and periodically send authenticated Handshake packets containing legal PING frames. Quinn resets the idle timer on each authenticated packet before frame processing, so the TLS state remains unfinished while either future stays pending indefinitely. Quinn and rustls impose no separate absolute establishment deadline, and Zebra's existing three-second HANDSHAKE_TIMEOUT is not applied by these helpers. This is currently latent because the v2 helpers are test-only; it becomes reachable if the follow-up integration does not add an external deadline.

F-232245 🔵 Low
Shared server name leaks cross-peer identifiers

The endpoint installs one reusable client configuration, and every outbound dial uses the same dummy server name zcash regardless of the peer address. Quinn's default validation-token cache and rustls's default TLS 1.3 resumption cache both use that name as their origin key. After connecting, peer A can issue a unique QUIC NEW_TOKEN or TLS NewSessionTicket; the victim stores it under zcash and offers the same opaque identifier in its next first flight to unrelated peer B. A colluding peer B can compare the identifier with A's value and link the two outbound sessions even though the TLS client presents no certificate. One-use cache semantics do not prevent correlation because a single transmission to B is sufficient, and disabling 0-RTT does not suppress PSK identity offers.

And one more auto-invalidated finding.

Analyzed two files, diff 13a8c79...8cf4212.

@mergify

mergify Bot commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Merge Protections

🔴 1 of 1 protections blocking · waiting on ⛓️ dependency

Protection Waiting on
🔴 ⛓️ Depends-On Requirements ⛓️ dependency

🔴 ⛓️ Depends-On Requirements

Waiting for

This rule is failing.

Requirement based on the presence of Depends-On in the body of the pull request

Indexes per-block sync metadata (sizes, tx and note counts, ZIP 221/244
commitments) with a cumulative transparent-output count, adds the
known-hash chunk column family, and serves sync metadata to v2 peers.
The upgrade backfills existing databases and chases the live tip, and
commit-time writes skip ahead-of-backfill heights to keep the column
family contiguous from genesis.
@arya2
arya2 force-pushed the p2p-v2-3-quic-transport branch from bcd06a4 to 8350f30 Compare August 17, 2026 23:33
@arya2 arya2 changed the title feat(network): QUIC transport for the v2 P2P protocol feat(state): add the 28.1.0 sync metadata and known-hash chunk format Aug 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Tracking: v2 P2P protocol (QUIC) and known-hash sync with spentness hints

1 participant