Skip to main content

bb_runtime/contracts/
peer_selector.rs

1//! `bb::PeerSelector` — Contract trait for peer-selection protocols.
2//!
3//! Every method takes `ctx: &mut RuntimeResourceRef<'_>` as the first
4//! parameter after `&mut self` (the uniform shape shared by every
5//! Contract trait) plus a [`CompletionHandle`] AND returns
6//! [`ContractResponse`]. See [`crate::contracts::index`] for the
7//! sync (Now) vs async (Later) semantics.
8//!
9//! Selector impls read `ctx.peers.addresses` to walk the local
10//! `AddressBook`, write through it for membership updates from the
11//! `dispatch_atomic` arm (`Announce` / `Forget`), and reach the
12//! shared `Scheduler` via `ctx.time` when they need to plan a delayed
13//! probe. Declared dependencies are reached via
14//! `ctx.dependency::<T>(slot)`.
15
16use crate::completion::{CompletionHandle, ContractResponse};
17use crate::runtime::RuntimeResourceRef;
18use bb_ir::ids::PeerId;
19
20/// Parameters describing what peer set to select. Different
21/// concrete selectors handle the variants they support and return
22/// an error variant for the ones they don't (e.g. `GlobalRegistry`
23/// supports `Random` + `All`; `DhtView` supports `NearKey`).
24///
25/// Open enum - new variants are additive; concrete impls match
26/// the ones they handle + return an unsupported-params error for
27/// the rest.
28#[derive(Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
29pub enum SelectParams {
30    /// Sample `n` peers uniformly at random from the current view.
31    Random {
32        /// Number of peers requested.
33        n: u32,
34    },
35    /// Sample up to `n` peers whose identifier is closest to `key`
36    /// under whatever metric the selector uses (Kademlia XOR, etc.).
37    NearKey {
38        /// Routing key the selector matches against.
39        key: Vec<u8>,
40        /// Maximum peers to return.
41        n: u32,
42    },
43    /// Return every peer in the current view. Useful for tiny
44    /// fixed-size deployments + tests.
45    All,
46}
47
48/// User-facing Contract trait for a peer-selection protocol.
49pub trait PeerSelector: Send + Sync {
50    /// Library-maker-defined error type.
51    type Error: std::error::Error + std::fmt::Display + Send + Sync + 'static;
52
53    /// Generic selection — `params` carries selector-specific
54    /// config. Concrete impls handle the variants they support
55    /// and fail the unsupported ones via `ContractResponse::Now`
56    /// carrying an error. `ctx` exposes `ctx.peers.addresses`
57    /// (the framework's `AddressBook`), the engine's per-op
58    /// runtime surface, and `ctx.dependency::<T>(slot)` for
59    /// reaching any concrete bound via `#[depends(...)]`.
60    fn select(
61        &mut self,
62        ctx: &mut RuntimeResourceRef<'_>,
63        params: SelectParams,
64        completion: CompletionHandle<Vec<PeerId>, Self::Error>,
65    ) -> ContractResponse<Vec<PeerId>, Self::Error>;
66
67    /// Sample `n` peers from the current view. Calls
68    /// land on `select(SelectParams::Random { n })` by default.
69    /// Concrete impls may override to keep an optimized fast path.
70    fn sample(
71        &mut self,
72        ctx: &mut RuntimeResourceRef<'_>,
73        n: u32,
74        completion: CompletionHandle<Vec<PeerId>, Self::Error>,
75    ) -> ContractResponse<Vec<PeerId>, Self::Error> {
76        self.select(ctx, SelectParams::Random { n }, completion)
77    }
78
79    /// Snapshot the current view of known peers (owned snapshot —
80    /// async serialization needs owned values).
81    fn current_view(
82        &mut self,
83        ctx: &mut RuntimeResourceRef<'_>,
84        completion: CompletionHandle<Vec<PeerId>, Self::Error>,
85    ) -> ContractResponse<Vec<PeerId>, Self::Error>;
86}