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