Skip to main content

Module dht

Module dht 

Source
Expand description

Wire message types for the cdn/dht/v1 Kademlia content DHT (ADR 022).

cdn/dht/v1 is the primary content discovery mechanism: nodes publish (hash → NodeId) records to the K closest peers in keyspace, and clients iteratively look up providers in O(log N) hops. This module defines the wire surface only — routing-table, record-store, scheduler, and rate-limit logic live in decdn-node.

§Authentication model

StoreRequest has no per-record signature. The receiver instead checks that holder equals the authenticated NodeId of the inbound QUIC connection (NodeIds are 32-byte Ed25519 public keys; iroh’s QUIC handshake binds the connection to that key). This depends on records being pushed directly by the holder to the K-closest nodes and never relayed peer-to-peer — if a future scheme introduces peer relay of records, a per-record signature MUST be reintroduced together with an in-scope sender timestamp in the signed body (ADR 022 §STORE Flow).

§BatchStore wire types

BatchStoreRequest / BatchStoreAck are part of cdn/dht/v1 at DhtMessage discriminants 4 and 5, ahead of FindNode / FindNodeResponse at 6 and 7 to match ADR 022’s variant order. They carry the bandwidth optimization in which one holder publishes many hashes to one receiver in a single RPC (ADR 022 §STORE Flow Batched STORE). The receiver-side admission and two-stage rate-limit accounting live in decdn-node; every DHT node implements them, so there is no per-hash fallback or support negotiation.

§Bounded-Vec deserialization

Network responses with Vec fields are bounded at decode time via #[serde(deserialize_with = ...)] hooks that enforce the wire-level caps below. The framing layer caps the whole message at 16 MiB (crate::framing::MAX_MESSAGE_SIZE), but the per-field caps stop peers from forcing the responder to allocate up to a megabyte of 32-byte NodeIds (or up to ~16M / 8B booleans) inside one frame. Pattern mirrors ProbeResponseBody::rate_per_mb.

Structs§

BatchStoreAck
Per-hash acknowledgement for a BatchStoreRequest (ADR 022 §STORE Flow). results[i] corresponds to BatchStoreRequest.entries[i].
BatchStoreRequest
Batched publication of multiple content records from one holder to one receiver (ADR 022 §STORE Flow). A bandwidth optimization over n separate StoreRequests: the re-publish scheduler groups due hashes by receiver and sends each its set in one of these. Admission and two-stage rate-limit accounting live in the decdn-node handler.
CloserNodes
A bounded list of the K closest NodeIds a responder returns in a closer_nodes field (ADR 022 §Routing Table). Wraps Vec<NodeId> and enforces the MAX_CLOSER_NODES invariant at construction — both CloserNodes::try_new and the bounded Deserialize impl reject oversize lists, so an over-cap closer_nodes cannot exist in memory or on the wire. #[repr(transparent)] + #[serde(transparent)] keep the encoding byte-identical to a bare Vec<NodeId>.
CloserNodesError
Error returned by CloserNodes::try_new when the list exceeds MAX_CLOSER_NODES.
FindNodeRequest
Kademlia node lookup — used during routing-table bootstrap and bucket refresh (ADR 022 §Bootstrap, §Routing Table). Distinct from FindValueRequest in that the target is a NodeId, not a content hash, and no provider lookup is performed.
FindNodeResponse
Response to a FindNodeRequest (ADR 022 §Message Types).
FindValueRequest
Query for providers of a specific content hash (ADR 022 §Message Types).
FindValueResponse
Response to a FindValueRequest (ADR 022 §Message Types).
FindValueResponseExt
Optional FindValueResponse extension fields, carried as trailing bytes after the message via the two-phase pattern (ADR 013 §Tier 1; see encode_find_value_response / parse_find_value_response_ext).
Provider
A known holder of a content hash, plus which Coverage blocks it reports being able to serve (range-keyed discovery). Carried in FindValueResponse::providers.
StoreAck
Acknowledgement for a StoreRequest (ADR 022 §Message Types).
StoreRequest
Publish a content record: “I hold this hash” (ADR 022 §Message Types, §STORE Flow). Sent by the holder to each of the K+3 nodes closest to hash in keyspace.
StoreRequestExt
Optional StoreRequest extension fields, carried as trailing bytes after the message via the two-phase pattern (ADR 013 §Tier 1; see encode_store_request / parse_store_request_ext).

Enums§

DhtMessage
Top-level protocol enum for cdn/dht/v1. Variant order matches ADR 022 §Message Types and is frozen per ADR 013.

Constants§

MAX_BATCH_STORE_HASHES
Wire-level maximum number of hashes a BatchStoreRequest may carry (ADR 022 §STORE Flow — “Batch size is bounded at 256 hashes”). Applies symmetrically to BatchStoreAck::results (one bool per request hash, same cap so a malicious responder can’t reply with an oversize ack). Enforced at the wire boundary; ADR 022 spells out that oversize batches close the stream with MALFORMED_MESSAGE (0x03) — the decode-time reject here surfaces as that error code via the framing layer.
MAX_CLOSER_NODES
Wire-level maximum number of NodeIds in a closer_nodes field, equal to the Kademlia bucket size K=20 (ADR 022 §Routing Table). Applies to both FindValueResponse::closer_nodes and FindNodeResponse::closer_nodes. Enforced by the CloserNodes type — at construction (CloserNodes::try_new) and at the wire boundary (its Deserialize).
MAX_PROVIDERS_PER_HASH
Wire-level maximum number of providers a FindValueResponse may carry (ADR 022 §Content Records and TTL). Bounds the response size at the ~2.3 KB ceiling documented in ADR 022 §DHT Bandwidth Analysis.

Functions§

encode_find_value_response
Encode a DhtMessage::FindValueResponse with its optional trailing FindValueResponseExt (ADR 013 §Tier 1, two-phase).
encode_store_request
Encode a DhtMessage::Store with its optional trailing StoreRequestExt (ADR 013 §Tier 1, two-phase). Typed per variant, as above.
parse_find_value_response_ext
Parse the trailing FindValueResponseExt bytes returned as the remainder by crate::decode_message after a DhtMessage::FindValueResponse.
parse_store_request_ext
Parse the trailing StoreRequestExt bytes returned as the remainder by crate::decode_message after a DhtMessage::Store.