fedimint_hbbft/messaging.rs
1use std::collections::BTreeSet;
2use std::iter;
3
4/// Message sent by a given source.
5#[derive(Clone, Debug)]
6pub struct SourcedMessage<M, N> {
7 /// The ID of the sender.
8 pub source: N,
9 /// The content of a message.
10 pub message: M,
11}
12
13/// The intended recipient(s) of a message.
14#[derive(Clone, Debug, PartialEq, Eq)]
15pub enum Target<N> {
16 /// The message must be sent to the nodes with the given IDs.
17 /// It is _not_ automatically sent to observers.
18 Nodes(BTreeSet<N>),
19 /// The message must be sent to all remote nodes except the passed nodes.
20 /// Useful for sending messages to observer nodes that aren't
21 /// present in a node's `all_ids()` list.
22 AllExcept(BTreeSet<N>),
23}
24
25impl<N: Ord> Target<N> {
26 /// Creates a new `Target` addressing all peers, including observers.
27 pub fn all() -> Self {
28 Target::AllExcept(BTreeSet::new())
29 }
30
31 /// Creates a new `Target` addressing a single peer.
32 pub fn node(node_id: N) -> Self {
33 Target::Nodes(iter::once(node_id).collect())
34 }
35
36 /// Returns a `TargetedMessage` with this target, and the given message.
37 pub fn message<M>(self, message: M) -> TargetedMessage<M, N> {
38 TargetedMessage {
39 target: self,
40 message,
41 }
42 }
43
44 /// Returns whether `node_id` is included in this target.
45 pub fn contains(&self, node_id: &N) -> bool {
46 match self {
47 Target::Nodes(ids) => ids.contains(node_id),
48 Target::AllExcept(ids) => !ids.contains(node_id),
49 }
50 }
51}
52
53/// Message with a designated target.
54#[derive(Clone, Debug, PartialEq, Eq)]
55pub struct TargetedMessage<M, N> {
56 /// The node or nodes that this message must be delivered to.
57 pub target: Target<N>,
58 /// The content of the message that must be serialized and sent to the target.
59 pub message: M,
60}
61
62impl<M, N> TargetedMessage<M, N> {
63 /// Applies the given transformation of messages, preserving the target.
64 pub fn map<T, F: FnOnce(M) -> T>(self, f: F) -> TargetedMessage<T, N> {
65 TargetedMessage {
66 target: self.target,
67 message: f(self.message),
68 }
69 }
70}