Skip to main content

commonware_resolver/
lib.rs

1//! Resolve data identified by a fixed-length key.
2
3#![doc(
4    html_logo_url = "https://commonware.xyz/imgs/rustdoc_logo.svg",
5    html_favicon_url = "https://commonware.xyz/favicon.ico"
6)]
7
8commonware_macros::stability_scope!(BETA {
9    use commonware_actor::Feedback;
10    use commonware_cryptography::PublicKey;
11    use commonware_utils::{channel::oneshot, vec::NonEmptyVec, Span};
12
13    pub mod delivery;
14    mod ingress;
15    pub mod opaque;
16    pub mod p2p;
17    mod subscribers;
18
19    /// A key to fetch data for a subscriber.
20    #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
21    pub struct Fetch<K, S = ()> {
22        /// The peer-visible key.
23        pub key: K,
24        /// Subscriber attached to the key.
25        pub subscriber: S,
26    }
27
28    impl<K, S: Default> From<K> for Fetch<K, S> {
29        fn from(key: K) -> Self {
30            Self {
31                key,
32                subscriber: S::default(),
33            }
34        }
35    }
36
37    /// Data delivered for a resolved fetch.
38    #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
39    pub struct Delivery<K, S> {
40        /// The peer-visible key used to validate the response.
41        pub key: K,
42        /// Subscribers that were still retained when the response arrived.
43        pub subscribers: NonEmptyVec<S>,
44    }
45
46    /// Notified when data is available, and must validate it.
47    pub trait Consumer: Clone + Send + 'static {
48        /// Type used to key data requested from peers.
49        type Key: Span;
50
51        /// Type of data to retrieve.
52        type Value;
53
54        /// Type used to track subscribers on fetch keys.
55        type Subscriber: Clone + Eq + Send + 'static;
56
57        /// Deliver data to the consumer.
58        ///
59        /// Returns a receiver that resolves to `true` if the data is valid for the key.
60        ///
61        /// The returned receiver may be dropped before completion if the application
62        /// cancels the fetch via [`Resolver::retain`]. When this happens, the
63        /// resolver discards the validation result.
64        ///
65        /// Implementations of [`Resolver`] must only invoke `deliver` for keys that were
66        /// previously requested via [`Resolver::fetch`] (or [`TargetedResolver`] variants).
67        ///
68        /// `delivery` contains the peer-visible key and the retained subscribers
69        /// for the fetch. Subscribers decide who should observe a valid response;
70        /// they do not define peer validity.
71        fn deliver(
72            &mut self,
73            delivery: Delivery<Self::Key, Self::Subscriber>,
74            value: Self::Value,
75        ) -> oneshot::Receiver<bool>;
76    }
77
78    /// Responsible for fetching data and notifying a `Consumer`.
79    pub trait Resolver: Clone + Send + 'static {
80        /// Type used to key data requested from peers.
81        type Key: Span;
82
83        /// Type used to track subscribers on fetch keys.
84        ///
85        /// Implementations that also own the [`Consumer`] should supply subscribers to
86        /// [`Consumer::deliver`] when a fetch resolves.
87        type Subscriber: Clone + Eq + Send + 'static;
88
89        /// Initiate a fetch.
90        ///
91        /// The resolver fetches and delivers the key. The subscriber is
92        /// retained and supplied to [`Consumer::deliver`] when the fetch resolves.
93        /// If multiple subscribers are attached to the same key,
94        /// the fetch is retained as long as at least one subscriber satisfies the
95        /// latest [`retain`](Self::retain) predicate.
96        ///
97        /// Passing a bare key is supported when `Subscriber: Default`.
98        fn fetch<F>(
99            &mut self,
100            key: F,
101        ) -> Feedback
102        where
103            F: Into<Fetch<Self::Key, Self::Subscriber>> + Send;
104
105        /// Initiate fetches for a batch of keys.
106        fn fetch_all<F>(&mut self, keys: Vec<F>) -> Feedback
107        where
108            F: Into<Fetch<Self::Key, Self::Subscriber>> + Send;
109
110        /// Retain only fetch subscribers satisfying the predicate.
111        ///
112        /// The predicate receives the peer-visible key and subscriber.
113        ///
114        /// Fetches not retained are canceled. If response validation is in
115        /// progress, cancellation may drop the [`Consumer::deliver`] future
116        /// before it reports whether the data was valid.
117        fn retain(
118            &mut self,
119            predicate: impl Fn(&Self::Key, &Self::Subscriber) -> bool + Send + 'static,
120        ) -> Feedback;
121    }
122
123    /// Extension for resolvers that accept target peer hints.
124    pub trait TargetedResolver: Resolver {
125        /// Type used to identify peers for targeted fetch hints.
126        type PublicKey: PublicKey;
127
128        /// Initiate a fetch with target peer hints.
129        ///
130        /// Implementations define whether target hints persist through retries,
131        /// merge with existing in-progress fetches, or are discarded.
132        fn fetch_targeted(
133            &mut self,
134            fetch: impl Into<Fetch<Self::Key, Self::Subscriber>> + Send,
135            targets: NonEmptyVec<Self::PublicKey>,
136        ) -> Feedback;
137
138        /// Initiate fetches for multiple keys, each with their own target hints.
139        ///
140        /// See [`fetch_targeted`](Self::fetch_targeted) for details on target behavior.
141        fn fetch_all_targeted<F>(
142            &mut self,
143            keys: Vec<(F, NonEmptyVec<Self::PublicKey>)>,
144        ) -> Feedback
145        where
146            F: Into<Fetch<Self::Key, Self::Subscriber>> + Send;
147    }
148});