Expand description
Resolve data identified by a fixed-length key by using the P2P network.
§Overview
The p2p module enables resolving data by fixed-length keys in a P2P network. Central to the
module is the peer actor which manages the fetch lifecycle. Its mailbox allows
initiation and pruning of fetches via the Resolver interface.
The peer handles an arbitrarily large number of concurrent fetches by sending requests
to other peers and processing their responses. It selects peers based on performance, retrying
with another peer if one fails or provides invalid data. Blocked peers are learned from the
network through Blocker::blocked, so a peer becomes eligible
again when its block expires. Fetches persist until pruned, fulfilled, or reported as no longer
needed by the Consumer.
The Consumer returns a crate::Outcome, checking data integrity and authenticity unless it
no longer needs the key. A complete response retires its delivered subscribers, an ambiguous
response retries without penalizing the peer, an invalid response retries after blocking the
peer, and an ignored response retires the key without scoring its peer. A verdict the consumer
drops without answering hands the response to the remaining subscribers, or retires the key
when none remain. Pruning a fetch with in-progress response validation aborts that validation;
an invalid outcome produced after cancellation does not block the peer.
The peer also serves data to other peers, forwarding network requests to the Producer. The
Producer provides data asynchronously (e.g., from storage). If it fails, the peer sends an
empty response, prompting the requester to retry elsewhere. Each message between peers contains
an ID. Each request is sent with a unique ID, and each response includes the ID of the request
it responds to.
§Targeting
Callers can restrict fetches to specific target peers using
TargetedResolver::fetch_targeted.
Only target peers are tried, there is no automatic fallback to other peers. Targets persist through
transient failures (timeout, “no data” response, send failure) since the peer might be slow or
receive the data later.
While a fetch is in progress, callers can modify targeting:
TargetedResolver::fetch_targetedadds peers to the existing target set (only if the fetch already has targets, an “all” fetch remains unrestricted)Resolver::fetchclears all targets, allowing fallback to any peer
These modifications only apply to in-progress fetches. Once a fetch succeeds, is pruned, or is ignored by the consumer, the targets for that key are cleared automatically. A blocked peer is skipped until the network unblocks it, so a fetch whose every target is blocked stays outstanding and resumes when one of them is unblocked, new targets are added, or targeting is cleared.
§Subscribers
Resolver::fetch accepts a peer-visible key and a
subscriber. This is useful when several subscribers can share the same peer-visible
fetch. A fetch remains active while at least one attached subscriber satisfies the latest
Resolver::retain predicate. When the fetch resolves, the
key and currently retained subscribers are supplied to
Consumer::deliver. Subscribers added while response validation
is in progress are delivered the same response locally, once it is accepted or when the
consumer drops its verdict without judging it.
While a response is being validated, its key remains in flight, so no further request is sent. New fetches for the key only attach subscribers or targets. A complete outcome retires the delivered subscribers, an ambiguous outcome retries the key, an invalid outcome retries the key after blocking the serving peer, and an ignored outcome retires the entire key without scoring the serving peer. When a peer-visible key admits multiple valid responses, a consumer should return an ambiguous outcome if the delivered response does not satisfy every subscriber, allowing the resolver to try another response.
§Scheduling
All pending fresh keys are attempted before any pending retries. Fresh keys and retries are each ordered by their next attempt time.
§Peer Selection
Outbound fetches are only sent to peers in latest.primary (see commonware_p2p::Provider) but inbound
requests are handled for all connected peers. Thus, callers that still expect a key to be fetchable after
a peer set update must ensure the latest primary set can serve it.
TargetedResolver::fetch_targeted can narrow the current primary set
further, but it does not bypass that latest-primary filter. Explicit targets that are no longer
in the latest primary set are ignored until they become primary again.
§Performance Considerations
The peer supports arbitrarily many concurrent fetches, but resource usage generally depends on the rate-limiting configuration of the underlying P2P network.
Structs§
- Config
- Configuration for the peer actor.
- Engine
- Manages incoming and outgoing P2P requests, coordinating fetch and serve operations.
- Mailbox
- A way to send messages to the peer actor.
Traits§
- Producer
- Serves data requested by the network.