Skip to main content

bytesandbrains_core/
overlay.rs

1use crate::{address::Address, index::OpRef, peer::Peer, peer_id::PeerId};
2
3/// The result of a protocol step: events emitted and messages to send.
4///
5/// Callers must process the returned `Step` — it contains outbound messages
6/// that must be delivered and events that must be handled by the application.
7#[must_use = "the returned Step contains messages and events that must be processed"]
8pub struct Step<P: OverlayProtocol + ?Sized> {
9    pub events: Vec<P::Event>,
10    pub messages: Vec<OutMessage<P>>,
11}
12
13impl<P: OverlayProtocol + ?Sized> Step<P> {
14    pub fn new() -> Self {
15        Step {
16            events: Vec::new(),
17            messages: Vec::new(),
18        }
19    }
20
21    pub fn with_event(mut self, event: P::Event) -> Self {
22        self.events.push(event);
23        self
24    }
25
26    pub fn with_message(mut self, message: OutMessage<P>) -> Self {
27        self.messages.push(message);
28        self
29    }
30
31    pub fn is_empty(&self) -> bool {
32        self.events.is_empty() && self.messages.is_empty()
33    }
34
35    /// Extend this step with events and messages from another step.
36    pub fn extend(&mut self, other: Step<P>) {
37        self.events.extend(other.events);
38        self.messages.extend(other.messages);
39    }
40}
41
42impl<P: OverlayProtocol + ?Sized> Default for Step<P> {
43    fn default() -> Self {
44        Self::new()
45    }
46}
47
48/// An outgoing protocol message addressed to a specific peer.
49pub struct OutMessage<P: OverlayProtocol + ?Sized> {
50    pub destination: Peer<P::Address>,
51    pub message: P::Message,
52}
53
54/// The core behavior trait for overlay protocols.
55///
56/// Generalizes the poll()/message() -> Step pattern. Applicable to any
57/// overlay protocol (gossip peer sampling, etc.).
58pub trait OverlayProtocol {
59    type Address: Address;
60    type Message;
61    type Event;
62    /// The peer type managed by this overlay.
63    type Peer: Clone;
64    /// Configuration for bootstrap operations.
65    type BootstrapConfig;
66    /// Handle to an in-flight bootstrap operation.
67    type BootstrapRef<'a>: OpRef
68    where
69        Self: 'a;
70
71    /// Unique protocol identifier for message dispatch (e.g., "/bb/gossip/1.0.0")
72    const PROTOCOL_ID: &'static str;
73
74    /// Advance internal timers, check liveness, progress queries.
75    fn poll(&mut self) -> Step<Self>;
76
77    /// Handle an incoming protocol message from another peer.
78    fn on_message(&mut self, from: Peer<Self::Address>, msg: Self::Message) -> Step<Self>;
79
80    /// The local peer identity.
81    fn local_peer_id(&self) -> &PeerId;
82
83    /// Bootstrap the overlay by discovering peers in the network.
84    ///
85    /// Returns an [`OpRef`] handle to track the bootstrap operation. The caller
86    /// should poll [`is_finished`](OpRef::is_finished) or wait for events via
87    /// [`poll`](OverlayProtocol::poll), then call [`finish`](OpRef::finish) to
88    /// retrieve the result.
89    fn bootstrap(&mut self, config: Self::BootstrapConfig) -> Self::BootstrapRef<'_>;
90
91    /// Called when a connection to a peer fails or is lost.
92    ///
93    /// The overlay should fail all pending requests to this peer and clean up state.
94    /// Returns a Step with any resulting events (e.g., peer removal, query failures).
95    fn on_connection_failed(&mut self, peer_id: &PeerId) -> Step<Self>;
96
97    /// Add a peer to the overlay's view.
98    fn add_peer(&mut self, peer: Self::Peer) -> Step<Self>;
99
100    /// Remove a peer from the overlay's view by ID.
101    fn remove_peer(&mut self, peer_id: &PeerId) -> Option<Self::Peer>;
102
103    /// Associate an address with a known peer.
104    fn add_address(&mut self, peer_id: &PeerId, address: Self::Address);
105
106    /// Remove an address from a peer.
107    ///
108    /// If this was the peer's last address, removes the peer entirely and returns it.
109    fn remove_address(&mut self, peer_id: &PeerId, address: &Self::Address) -> Option<Self::Peer>;
110}