//! Resolve data identified by a fixed-length key. #![doc( html_logo_url = "https://commonware.xyz/imgs/rustdoc_logo.svg", html_favicon_url = "https://commonware.xyz/favicon.ico" )] commonware_macros::stability_scope!(BETA { use commonware_actor::Feedback; use commonware_cryptography::PublicKey; use commonware_utils::{channel::oneshot, vec::NonEmptyVec, Span}; pub mod delivery; mod ingress; pub mod opaque; pub mod p2p; mod subscribers; /// A key to fetch data for a subscriber. #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] pub struct Fetch { /// The peer-visible key. pub key: K, /// Subscriber attached to the key. pub subscriber: S, } impl From for Fetch { fn from(key: K) -> Self { Self { key, subscriber: S::default(), } } } /// Data delivered for a resolved fetch. #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] pub struct Delivery { /// The peer-visible key used to validate the response. pub key: K, /// Subscribers that were still retained when the response arrived. pub subscribers: NonEmptyVec, } /// Notified when data is available, and must validate it. pub trait Consumer: Clone + Send + 'static { /// Type used to key data requested from peers. type Key: Span; /// Type of data to retrieve. type Value; /// Type used to track subscribers on fetch keys. type Subscriber: Clone + Eq + Send + 'static; /// Deliver data to the consumer. /// /// Returns a receiver that resolves to `true` if the data is valid for the key. /// /// The returned receiver may be dropped before completion if the application /// cancels the fetch via [`Resolver::retain`]. When this happens, the /// resolver discards the validation result. /// /// Implementations of [`Resolver`] must only invoke `deliver` for keys that were /// previously requested via [`Resolver::fetch`] (or [`TargetedResolver`] variants). /// /// `delivery` contains the peer-visible key and the retained subscribers /// for the fetch. Subscribers decide who should observe a valid response; /// they do not define peer validity. fn deliver( &mut self, delivery: Delivery, value: Self::Value, ) -> oneshot::Receiver; } /// Responsible for fetching data and notifying a `Consumer`. pub trait Resolver: Clone + Send + 'static { /// Type used to key data requested from peers. type Key: Span; /// Type used to track subscribers on fetch keys. /// /// Implementations that also own the [`Consumer`] should supply subscribers to /// [`Consumer::deliver`] when a fetch resolves. type Subscriber: Clone + Eq + Send + 'static; /// Initiate a fetch. /// /// The resolver fetches and delivers the key. The subscriber is /// retained and supplied to [`Consumer::deliver`] when the fetch resolves. /// If multiple subscribers are attached to the same key, /// the fetch is retained as long as at least one subscriber satisfies the /// latest [`retain`](Self::retain) predicate. /// /// Passing a bare key is supported when `Subscriber: Default`. fn fetch( &mut self, key: F, ) -> Feedback where F: Into> + Send; /// Initiate fetches for a batch of keys. fn fetch_all(&mut self, keys: Vec) -> Feedback where F: Into> + Send; /// Retain only fetch subscribers satisfying the predicate. /// /// The predicate receives the peer-visible key and subscriber. /// /// Fetches not retained are canceled. If response validation is in /// progress, cancellation may drop the [`Consumer::deliver`] future /// before it reports whether the data was valid. fn retain( &mut self, predicate: impl Fn(&Self::Key, &Self::Subscriber) -> bool + Send + 'static, ) -> Feedback; } /// Extension for resolvers that accept target peer hints. pub trait TargetedResolver: Resolver { /// Type used to identify peers for targeted fetch hints. type PublicKey: PublicKey; /// Initiate a fetch with target peer hints. /// /// Implementations define whether target hints persist through retries, /// merge with existing in-progress fetches, or are discarded. fn fetch_targeted( &mut self, fetch: impl Into> + Send, targets: NonEmptyVec, ) -> Feedback; /// Initiate fetches for multiple keys, each with their own target hints. /// /// See [`fetch_targeted`](Self::fetch_targeted) for details on target behavior. fn fetch_all_targeted( &mut self, keys: Vec<(F, NonEmptyVec)>, ) -> Feedback where F: Into> + Send; } });