fedimint_core/net/
peers.rs

1use std::ops::{Deref, DerefMut};
2use std::sync::Arc;
3
4use async_trait::async_trait;
5use fedimint_core::PeerId;
6use serde::de::DeserializeOwned;
7use serde::Serialize;
8
9use crate::task::Cancellable;
10
11#[cfg(not(target_family = "wasm"))]
12pub mod fake;
13
14/// Owned [`PeerConnections`] trait object type
15pub struct PeerConnections<Msg>(Box<dyn IPeerConnections<Msg> + Send + Unpin + 'static>);
16
17impl<Msg> Deref for PeerConnections<Msg> {
18    type Target = dyn IPeerConnections<Msg> + Send + Unpin + 'static;
19
20    fn deref(&self) -> &Self::Target {
21        &*self.0
22    }
23}
24
25impl<Msg> DerefMut for PeerConnections<Msg> {
26    fn deref_mut(&mut self) -> &mut Self::Target {
27        &mut *self.0
28    }
29}
30
31/// Connection manager that tries to keep connections open to all peers
32///
33/// Production implementations of this trait have to ensure that:
34/// * Connections to peers are authenticated and encrypted
35/// * Messages are received exactly once and in the order they were sent
36/// * Connections are reopened when closed
37/// * Messages are cached in case of short-lived network interruptions and
38///   resent on reconnect, this avoids the need to rejoin the consensus, which
39///   is more tricky.
40///
41/// In case of longer term interruptions the message cache has to be dropped to
42/// avoid DoS attacks. The thus disconnected peer will need to rejoin the
43/// consensus at a later time.
44#[async_trait]
45pub trait IPeerConnections<Msg>
46where
47    Msg: Serialize + DeserializeOwned + Unpin + Send,
48{
49    /// Send a message to a specific peer.
50    ///
51    /// The message is sent immediately and cached if the peer is reachable and
52    /// only cached otherwise.
53    async fn send(&mut self, peers: &[PeerId], msg: Msg) -> Cancellable<()>;
54
55    /// Await receipt of a message from any connected peer.
56    async fn receive(&mut self) -> Cancellable<(PeerId, Msg)>;
57
58    /// Removes a peer connection in case of misbehavior
59    async fn ban_peer(&mut self, peer: PeerId);
60
61    /// Converts the struct to a `PeerConnection` trait object
62    fn into_dyn(self) -> PeerConnections<Msg>
63    where
64        Self: Sized + Send + Unpin + 'static,
65    {
66        PeerConnections(Box::new(self))
67    }
68}
69
70/// Owned [`MuxPeerConnections`] trait object type
71#[derive(Clone)]
72pub struct MuxPeerConnections<MuxKey, Msg>(
73    Arc<dyn IMuxPeerConnections<MuxKey, Msg> + Send + Sync + Unpin + 'static>,
74);
75
76impl<MuxKey, Msg> Deref for MuxPeerConnections<MuxKey, Msg> {
77    type Target = dyn IMuxPeerConnections<MuxKey, Msg> + Send + Sync + Unpin + 'static;
78
79    fn deref(&self) -> &Self::Target {
80        &*self.0
81    }
82}
83
84#[async_trait]
85/// Like [`IPeerConnections`] but with an ability to handle multiple
86/// destinations (like modules) per each peer-connection.
87///
88/// Notably, unlike [`IPeerConnections`] implementations need to be thread-safe,
89/// as the primary intended use should support multiple threads using
90/// multiplexed channel at the same time.
91pub trait IMuxPeerConnections<MuxKey, Msg>
92where
93    Msg: Serialize + DeserializeOwned + Unpin + Send,
94    MuxKey: Serialize + DeserializeOwned + Unpin + Send,
95{
96    /// Send a message to a specific destination at specific peer.
97    async fn send(&self, peers: &[PeerId], mux_key: MuxKey, msg: Msg) -> Cancellable<()>;
98
99    /// Await receipt of a message from any connected peer.
100    async fn receive(&self, mux_key: MuxKey) -> Cancellable<(PeerId, Msg)>;
101
102    /// Removes a peer connection in case of misbehavior
103    async fn ban_peer(&self, peer: PeerId);
104
105    /// Converts the struct to a `PeerConnection` trait object
106    fn into_dyn(self) -> MuxPeerConnections<MuxKey, Msg>
107    where
108        Self: Sized + Send + Sync + Unpin + 'static,
109    {
110        MuxPeerConnections(Arc::new(self))
111    }
112}