P2Pv2

Zakura’s P2Pv2 combines high-throughput networking, resource controls, and a property-tested consensus engine with permissionless services for Zcash’s future needs.

Glowing mesh of pink nodes and edges forming a five-petal zakura blossom on a night-black field, with luminous data strands streaming horizontally through it, and P2Pv2 lettered in the lower left.

50,000 transactions per second requires about 100MB/s of block data arriving at every full node on Zcash's network. NU7's 25-second blocks carry at most 2MB each, leaving the network more than a thousand times short of that rate. Tachyon helps by shrinking proofs once they appear in blocks, but the network must still propagate a firehose of individual transactions.

This is why we are building a new networking layer for Zcash. As we've mentioned in every release of Zakura, we've made steady progress on a new architecture that replaces the inefficient protocol Zcash inherited from Bitcoin. P2Pv2 starts over. We are building a high-throughput stack with security enforced through resource budgets and a consensus engine checked by property tests. Developers can add services without permission, so the network can adapt to whatever Zcash needs next.

Testnet runs P2Pv2 alongside the legacy stack by default. Soon, it will be ready for Mainnet.

Zcash's next-generation networking

P2Pv2 replaces the decade-old stack with independent protocols that can optimize for latency, throughput, or robustness.

An authenticated QUIC connection carries independent bounded streams into a service registry. The registry routes each stream to discovery, header sync, block sync, compatibility, or a custom service.SERVICESDiscoveryrobustnessHeader synclow latencyBlock synchigh throughputCompatibilitygradual rolloutCustompermissionlessROUTINGService registrynegotiate stream types · route accepted streamsTRANSPORTAuthenticated QUIC · zakura-quicbounded streambounded streambounded streamAn authenticated QUIC connection carries independent bounded streams into a service registry. The registry routes each stream to discovery, header sync, block sync, compatibility, or a custom service.SERVICESDiscoveryrobustnessHeader synclow latencyBlock synchigh throughputCompatibilitygradual rolloutCustompermissionlessROUTINGService registrynegotiate stream typesroute accepted streamsTRANSPORTAuthenticated QUIC · zakura-quicbounded streambounded streambounded stream
One secure connection carries independent services. Each service can optimize for its traffic without forcing the same tradeoff on the rest of the network.

Zakura uses its own zakura-quic transport, built on upstream quinn-proto. QUIC provides secure connections and independent streams. Zakura owns the asynchronous driver and UDP socket layer. TLS 1.3 authenticates each peer with its Ed25519 node identity. Zakura defines the service handshake, stream types, bounds, services, and schedulers above that transport.

The transport change removes Iroh from the dependency graph. Zakura now controls socket buffers, flow-control windows, timers, and connection admission before the TLS handshake through [network.zakura.quic]. The transport connects directly to peer addresses without relays, external address lookup, or automatic router port mapping. It no longer supports QUIC NAT traversal.

This split keeps Zcash policy in code that Zcash developers can inspect and change. It also lets a bulk transfer and a control message make progress on separate streams.

One network, different tradeoffs

A network protocol rarely gets the lowest latency, the highest throughput, and the strongest resistance to abusive peers from one policy. P2Pv2 isolates those decisions. Each service spends resources according to its traffic and cannot hold unrelated work behind it.

A triangle whose corners are latency, throughput, and robustness. Header sync sits near latency, block sync near throughput, peer discovery near robustness, and mempool in the middle as a future design.Latencyrespond quicklyRobustnessreject bad dataThroughputmove more dataHeader syncDiscoveryBlock syncMempoolplanned after TachyonA triangle whose corners are latency, robustness, and throughput. Header sync sits near latency, discovery near robustness, block sync near throughput, and mempool in the middle as a future design.Latencyrespond quicklyRobustnessreject bad dataThroughputmove more dataHeader syncDiscoveryBlock syncMempoolplanned
Header sync needs quick responses. Block sync needs to move lots of data. Discovery needs to reject bad peer records. Each service gets its own protocol and controls.

Permissionless service discovery

Each node signs a record that names its identity, addresses, protocol range, and service IDs. Peers gossip bounded records and reject invalid signatures, expired records, incompatible networks, and oversized fields. A client can ask for peers that advertise one exact service instead of connecting first and guessing what they support.

A provider signs a node record that advertises a custom service. A client asks discovery for that service. Discovery returns matching peers, and the client opens the service stream it needs.1 · ADVERTISESigned node recordidentity · addressesprotocol rangewallet.pir.v12 · DISCOVERFind this servicewallet.pir.v1bounded matching recordsfrom the signed discovery book3 · CONNECTMatching peeropen only theneeded streamindependent serviceNo central service assignment · peers choose what to offer and useA provider signs a node record that advertises a custom service. A client asks discovery for that service. Discovery returns matching peers, and the client opens the service stream it needs.1 · ADVERTISESigned node recordidentity · addresses · protocol rangewallet.pir.v12 · DISCOVERFind wallet.pir.v1return matching signed recordsbounded by local policy3 · CONNECTOpen the service streamindependent from other protocolsPeers choose what to offer and use
A service provider advertises a bounded service ID. Other nodes can discover matching peers and open only that service.

The custom-service API already lets an application declare the services it provides and seeks, then attach its own stream handler. Developers do not need a central party to assign a service ID or add their messages to header sync. Peers choose what they offer and what they use. Evan Forbes shows the basic service model and two prototype ideas.

Header sync: a light-client-first consensus engine

The standalone zakura-header-chain crate validates headers, retains competing branches in a DAG, and selects the best eligible chain. A headers-only deployment can run the engine without downloading block bodies. An integrated full node runs the same engine and lets verified bodies advance its verified path and finality.

Peers provide headers, full state provides body results, RPC calls exclude or reconsider branches, and finality advances. One planner applies all four inputs to a header DAG. The selected header path can run ahead on one branch while the body-verified path remains behind.EVIDENCEPeer headersuntrusted inputBody resultsfull-state evidenceRPC decisionsexclude · reconsiderFinalityadvance the rootOne fork-choice plannervalidate · stage · select · publish after commitHEADER DAGfinalizedverified tipselected tipselected headers can run ahead of verified bodiesPeers provide headers, full state provides body results, RPC calls exclude or reconsider branches, and finality advances. One planner applies all four inputs to a header DAG. The selected header path can run ahead on one branch while the body-verified path remains behind.EVIDENCEPeer headersuntrusted inputBody resultsfull-state evidenceRPC decisionsexclude · reconsiderFinalityadvance the rootOne fork-choice plannervalidate · stage · select · publishHEADER DAGfinalizedverifiedselectedheader selection can run ahead of body verification
One planner turns every source of evidence into one deterministic header-chain decision. The network schedules work but cannot choose the chain.

One planner handles new headers, body-validation results, explicit block exclusions, and finality changes. It stages every transition before one durable write, then updates memory and publishes the result. Branch and generation IDs prevent late work from an old fork from changing the new one.

Headers-only mode uses a local 1,000-block finality depth because it has no body evidence. That choice supports light clients, but it does not provide the same assurance as a full node and remains vulnerable to eclipse attacks. Read the production implementation guide or follow one request through the layers in PR #641.

Block sync: high-throughput catch-up

Block sync requests bodies from several peers and applies the contiguous chain in order. A byte-based BBR controller measures each peer's delivery rate, base round-trip time, and reliability. It sizes that peer's in-flight work around the measured bandwidth-delay product instead of using one fixed request count. This application-level controller schedules block requests independently of QUIC's congestion control, which uses CUBIC by default.

Three peers receive different byte windows based on their delivery rate, round-trip time, and reliability. Their block bodies enter a bounded reorder buffer and commit in chain order. In a second path, header-carried commitment roots are authenticated and let checkpoint sync skip local note-tree rebuilds.NETWORK CAPACITYHigh-capacity peerModerate peerDropping peerlarger byte windowmeasured windowdiscounted windowBBR per peerdelivery ratebase round-tripreliabilityresize outstanding bytesBounded body bufferout-of-order arrivalsContiguous commitrescue the lowest gapCHECKPOINT CPUHeader-carried rootssmall auxiliary dataAuthenticatecheck header commitmentSkip tree rebuildresume above checkpointThree peers receive different byte windows based on their delivery rate, round-trip time, and reliability. Their block bodies enter a bounded reorder buffer and commit in chain order. Header-carried commitment roots are authenticated and let checkpoint sync skip local note-tree rebuilds.NETWORK CAPACITYHigh-capacity peerModerate peerDropping peerBBR per peerrate · round-trip · reliabilityresize outstanding bytesBounded bufferout-of-order bodiesContiguous commitrescue lowest gapCHECKPOINT CPUHeader-carried commitment rootssmall auxiliary dataAuthenticateheader commitmentSkip rebuildabove checkpointnetwork and CPU bottlenecks handled separately
Block sync adapts outstanding bytes to each peer, buffers within explicit limits, and commits in chain order. VCT separately removes the main note-tree rebuild below checkpoints.

The controller keeps queues shallow, reduces work assigned to peers that drop requests, and gives the lowest missing block a short rescue path. Global byte, request-count, and resident-buffer limits keep memory bounded.

Verified commitment trees (VCT) remove a different bottleneck. During checkpoint sync, peers send small note-commitment roots with headers. Zakura authenticates each root against the chain's header commitments, folds it into state, and skips rebuilding the Sapling, Orchard, and Ironwood trees for every block. Missing or invalid roots stop the fast path without writing guessed state.

Read the BBR specification, the VCT design, and our published full-sync benchmark.

What comes next

Faster block propagation

Catch-up sync and live block relay need different protocols. We are exploring subscriptions that keep a relay stream open, block parts that let a node start forwarding before the full body arrives, and erasure encoding that can recover a block from any sufficient set of parts. A miner mesh could connect producers directly and relay blocks across several independent paths.

Mempool aggregation after Tachyon

Project Tachyon proposes a new shielded pool built around proof-carrying data and shielded aggregation. That work changes the data a mempool service must move and the work a miner must assemble. We plan to design native mempool aggregation after Tachyon's transaction and payment protocols settle, rather than encode today's transaction-by-transaction gossip into the new stack.

A network others can build on

Service discovery makes the P2P layer useful beyond full-node sync. Possible services include:

  • light wallets that verify the header chain themselves;
  • private information retrieval (PIR) for note delivery without trial decrypting every candidate transaction;
  • micropayments for independently operated PIR or recovery servers;
  • encrypted off-chain wallet recovery;
  • wallet connections to intent solvers; and
  • direct wallet-to-miner submission and miner-to-wallet responses.

These examples are not roadmap commitments. The stack supplies authenticated identity, discovery, bounded streams, and independent protocol lifecycles. Developers supply the service. P2Pv2 lets them add it without changing header sync, block sync, or one shared gossip protocol.

Status

Experimental. Mainnet uses the legacy P2P stack by default. Testnet and Regtest use dual-stack operation by default. P2Pv2 still has known denial-of-service risks and is not yet a hardened trust boundary.

The native protocol now uses p2p-v2/3. Node identities, key files, and bootstrap entries carry over from the previous transport. Nodes running the new transport communicate with older releases through the legacy Zcash protocol in dual-stack mode. Operators must remove nat_traversal = true from [network.zakura] or set it to false before upgrading. The new transport rejects that setting at startup.

Available today: zakura-quic transport on quinn-proto, signed peer and service discovery, custom service registration, the fork-aware header-chain engine, adaptive block sync with BBR, VCT fast sync, compatibility services, and dual-stack rollout.

Working toward: production hardening, message-specific resource controls, enforceable priority between services, native mempool aggregation, and new block-relay protocols.

Follow P2Pv2 on GitHub.