Fast and Secure P2Pv2 Through Resource Budgets


High throughput and denial-of-service (DoS) resistance both require control over a node’s resources. Every peer message can consume memory, CPU, and storage work. A simple throughput cap can limit that demand, but a low cap also prevents useful traffic from using the node’s capacity. Zakura’s P2Pv2 stack needs to sustain high throughput while preventing a peer from exhausting those resources.
We therefore require peer data to be verifiable, useful to the protocol, and covered by a resource budget. We check message validity before allowing the work it protects, authorize requested responses and check whether information remains useful, and reserve capacity before accepting work. We hold that capacity until the work ends. When a peer asks for more than the available budget, we delay processing and let QUIC backpressure reach the sender. These controls let useful traffic use available capacity without relying on a low blanket throughput cap.
Check before spending
A limit must apply before the cost it controls. The transport limits pending handshakes and incoming packet bytes. Message checks reject invalid frame types and sizes before allocating payloads. Decoding needs separate bounds because a small payload can declare a large collection. Verification precedes the state changes it protects.
Authorize responses
Before requesting data, a node records which responses it will accept and reserves capacity for them. Each response consumes that authorization. Range responses have object and byte limits and an explicit ending.
Changing the selected chain or reassigning work does not cancel a response already requested. The response still consumes its reservation. The handler decides whether to process it further.
Handlers also decide whether repeated information remains useful. An unchanged service record can renew its validity. An empty service list can clear old state. Local staleness alone does not justify a peer penalty.
Hold capacity until work ends
GetBlocks v3 bounds accepted requests, running storage operations, retained results, and queued output. Before reading a block, the serving task reserves output capacity and acquires an execution slot. Per-peer budgets contain one connection’s demands. Node-wide budgets limit their combined cost.
A disconnect cannot release a slot while its database read still runs. Otherwise, repeated disconnects could bypass the execution limit. Output likewise stays accounted for while retained or queued.
Announcements and discovery requests have a declared cadence. Block requests can run continuously within available capacity. Responses use the reservations their requester created.
Let backpressure reach the sender
Zakura’s QUIC driver reads stream data on application demand, with bounded read-ahead. When the application stops consuming, the receive buffer fills and QUIC stops extending credit. The sender must wait once it exhausts existing credit.
Application queues must stay bounded too. Moving bytes out of QUIC into an unlimited queue would defeat backpressure.
Waiting must preserve progress. A stalled request must not block responses or control messages needed to finish active work. Empty responses still consume execution capacity and must yield to other work. Capacity exhaustion causes waiting. Penalties require an unambiguous protocol violation.
Remove work within the budget
GetBlocks serves finalized blocks directly from stored bytes, avoiding decoding and re-encoding. On one 16-vCPU host, storage probes increased Mainnet single-block throughput from 23,500 to 53,000 reads per second at the same 24-job limit. This measures storage serving, not synchronization. Ready responses also bypass slower reads while preserving block order within each range.
The raw response queue caps raw-frame retention at about 20 MB per session, excluding QUIC and downstream allocations. Synthetic small-block probes lost 5–16% throughput with this bound. Production probes showed no loss or remained inconclusive. These changes are merged but not yet in a stable release. Total memory still depends on transport, application, and connection-count budgets.
Further reading
Read the regulation design and protocol specification for the full resource model.