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}