//! Utility functions for exchanging messages with many peers. use crate::{PeerSetUpdate, Provider, TrackedPeers}; use commonware_cryptography::PublicKey; use commonware_utils::{ channel::{ fallible::FallibleExt, mpsc::{self, UnboundedReceiver, UnboundedSender}, }, ordered::Set, }; pub mod codec; pub mod limited; #[cfg(feature = "mocks")] pub mod mocks; pub mod mux; /// Primary and secondary peer memberships at one peer set index. /// /// Import as `PeerSetsAtIndexBase` (or similar) and define a local /// `type PeerSetsAtIndex

= PeerSetsAtIndexBase<...>` with the primary/secondary types you use. pub(crate) struct PeerSetsAtIndex { pub(crate) primary: Primary, pub(crate) secondary: Secondary, } /// A [Provider] over a static set of peers. #[derive(Debug, Clone)] pub struct StaticProvider { id: u64, peers: Set

, senders: Vec>>, } impl StaticProvider

{ /// Create a new [StaticProvider] with the given ID and peers. pub const fn new(id: u64, peers: Set

) -> Self { Self { id, peers, senders: vec![], } } } impl Provider for StaticProvider

{ type PublicKey = P; async fn peer_set(&mut self, id: u64) -> Option> { assert_eq!(id, self.id); Some(TrackedPeers::primary(self.peers.clone())) } async fn subscribe(&mut self) -> UnboundedReceiver> { let (sender, receiver) = mpsc::unbounded_channel(); sender.send_lossy(PeerSetUpdate { index: self.id, latest: TrackedPeers::new(self.peers.clone(), Set::default()), all: TrackedPeers::new(self.peers.clone(), Set::default()), }); self.senders.push(sender); // prevent the receiver from closing receiver } }