Skip to main content

Module probe_cache

Module probe_cache 

Source
Expand description

Requester-side POSITIVE probe cache (ADR 001 §Probe cache).

The mirror of super::negative_cache: where that one remembers which (NodeId, hash) pairs answered has_blob: false (or refused a pull), this one remembers which nodes answered has_blob: true — so a second miss for the same hash inside the TTL skips the DHT lookup AND the probe fanout entirely and goes straight to selection. Per ADR 001 §Probe cache the cache:

  • is keyed by hash;
  • holds at most 1024 hashes with LRU eviction;
  • retains at most 10 providers per hash (top 10 by selection score);
  • retains entries for PROBE_SLASH_WINDOW / 2 = 15s (ADR 005 §Derived constants), anchored at insertion;
  • stores the ADR triple (NodeId, rate_per_mb, rtt) plus the probe’s UNSIGNED range-keyed Coverage (#1506) — never the signed ProbeResponse.

That last point is #1165’s “no evidence retention” requirement, and it is not a memory optimisation. A ProbeResponse carries slash_sig: a peer’s signed has_blob: true. Paired with a stream response it is on-chain rate-manipulation evidence for PROBE_SLASH_WINDOW, and it can also corroborate a blacklist violation — which is bounded by MAX_EVIDENCE_AGE_US (5 days), not by the 30s window (ADR 014 §Evidence staleness). So the 15s TTL does not make retention harmless by expiry alone; the point is simply that a structure surviving one request to speed up the next has no business holding another node’s slashable statements — retaining them turns an availability cache into an evidence locker.

Coverage is exempt from that concern, not an exception to it: it is UNSIGNED (ProbeResponseExt, outside the slash_sig set), so it carries no author to slash and is not evidence of anything. It rides the entry so a cache-hit candidate can still be range-planned (plan_covered_runs) against its ≤15s-fresh coverage; without it a real partial holder would read as covering nothing on the hit path and be excluded from range assignment.

reputation is likewise NOT stored, for a different reason: it is a local, live value that moves on every pull outcome. Freezing it for the TTL would let a node that just failed three pulls keep the rank it held before them. node_origin::cached_candidates recomputes reputation and region on read and re-runs rank_candidates — ADR 001’s “goes straight to selection” means skipping discovery and probing, not skipping the selection algorithm.

Structs§

Hash
32-byte content hash. Re-exported from the protocol crate’s decdn_protocol::ContentHash newtype — distinct from NodeId at the type level, identical ([u8; 32]) on the wire. A 32-byte content address (BLAKE3 hash).
PositiveProbeCache
Bounded LRU cache of hash → Vec<(NodeId, rate_per_mb, rtt)>.
ProbedProvider
One probed provider — ADR 001 §Probe cache’s entry triple (hash → Vec<(NodeId, rate_per_mb, rtt)>) plus the probe’s unsigned range-keyed Coverage (#1506), and nothing more.