Skip to main content

Module chain_origin_directory

Module chain_origin_directory 

Source
Expand description

Chain-backed OriginDirectory implementation.

Resolves a request’s namespace to the set of currently-active operator NodeIds authorised as origins for it. The resolution chain (ADR 022 § FIND_VALUE Flow “Origin discovery”, ADR 011 § Origin Assignment Authority) is:

OriginAssignment.getOrigins(namespaceId) → [operator...] → drop operators the local ContentDenylist denies (the origin ∪ operator blacklist union the watcher syncs from ContentBlacklist, plus the operator’s own [content] denied_origins) → capacity-bond reverse projection (operator → NodeId, binding only) → keep operators the shared StakerSet reports active

The blacklist drop is this node protecting itself: getOrigins is a routing hint the contract does not filter (ADR 011 § Interaction with ContentBlacklist), so the consumer applies the same deny-set its delivery gate already holds rather than trusting the seat set to be blacklist-clean.

The bare hash carries no origin information (ADR 002 § Retrieval by namespace): the request supplies the namespace its content is published under. namespaceId == 0 has no authorized origins, so it resolves to no origins here and is never fetched or cached.

Namespace creation is permissionless and free, so this directory does not mirror the whole chain-side namespace set up front: it resolves each namespace lazily, on first request, and caches the result (positive or negative) behind a split TTL (crate::dht::lazy_origin_cache). A live cache hit — including a cached “no origins” — resolves with no RPC; a cold miss issues one getOrigins(namespace) call. Chain reads therefore scale with the namespaces this node is actually asked to serve, not the permissionless global namespace count.

The cache stores only the raw operator address set; it never stores resolved NodeIds or liveness. Both the operator → NodeId binding (the shared capacity-bond reverse projection) and staker liveness (the shared StakerSet) are read live at resolution time, so a TTL-anchored cache entry never goes stale on the parts of the answer that can change without a new getOrigins call.

A getOrigins RPC failure fails closed: the lookup resolves no origins for that request, and — because a transient RPC failure must not be frozen for a TTL — the result is not cached, so the next request retries.

Structs§

ChainOriginDirectory
Chain-backed origin directory: a lazy TTL cache over getOrigins, resolving operators to active NodeIds against the shared capacity-bond reverse projection. No background watcher and no whole-directory mirror — a single getOrigins(ns) RPC fires only on a cold-namespace miss, and chain reads therefore scale with the namespaces this node is actually asked to serve, not the permissionless global namespace count.