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}