round_based/delivery.rs
1/// Incoming message
2#[derive(Debug, Clone, Copy, Eq, PartialEq)]
3pub struct Incoming<M> {
4 /// Index of a message
5 pub id: MsgId,
6 /// Index of a party who sent the message
7 pub sender: PartyIndex,
8 /// Indicates whether it's a broadcast message (meaning that this message is received by all the
9 /// parties), or p2p (private message sent by `sender`)
10 pub msg_type: MessageType,
11 /// Received message
12 pub msg: M,
13}
14
15/// Message type (broadcast or p2p)
16#[derive(Debug, Copy, Clone, Eq, PartialEq)]
17pub enum MessageType {
18 /// Message was broadcasted
19 Broadcast {
20 /// Indicates that message was reliably broadcasted, meaning that it's guaranteed (cryptographically or through
21 /// other trust assumptions) that all honest participants of the protocol received the same message
22 reliable: bool,
23 },
24 /// P2P message
25 P2P,
26}
27
28/// Index of party involved in the protocol
29pub type PartyIndex = u16;
30/// ID of received message
31///
32/// Can be used to retrieve extra information about message from delivery layer when needed.
33/// E.g. if malicious party is detected, we need a proof that received message was sent by this
34/// party, so message id should be used to retrieve signature and original message.
35pub type MsgId = u64;
36
37impl<M> Incoming<M> {
38 /// Maps `Incoming<M>` to `Incoming<T>` by applying a function to the message body
39 pub fn map<T, F>(self, f: F) -> Incoming<T>
40 where
41 F: FnOnce(M) -> T,
42 {
43 Incoming {
44 id: self.id,
45 sender: self.sender,
46 msg_type: self.msg_type,
47 msg: f(self.msg),
48 }
49 }
50
51 /// Maps `Incoming<M>` to `Result<Incoming<T>, E>` by applying a function `fn(M) -> Result<T, E>`
52 /// to the message body
53 pub fn try_map<T, E, F>(self, f: F) -> Result<Incoming<T>, E>
54 where
55 F: FnOnce(M) -> Result<T, E>,
56 {
57 Ok(Incoming {
58 id: self.id,
59 sender: self.sender,
60 msg_type: self.msg_type,
61 msg: f(self.msg)?,
62 })
63 }
64
65 /// Converts `&Incoming<M>` to `Incoming<&M>`
66 pub fn as_ref(&self) -> Incoming<&M> {
67 Incoming {
68 id: self.id,
69 sender: self.sender,
70 msg_type: self.msg_type,
71 msg: &self.msg,
72 }
73 }
74
75 /// Checks whether it's broadcast message (regardless if it's reliable or not)
76 pub fn is_broadcast(&self) -> bool {
77 matches!(self.msg_type, MessageType::Broadcast { .. })
78 }
79
80 /// Checks if message was reliably broadcasted
81 pub fn is_reliably_broadcasted(&self) -> bool {
82 matches!(self.msg_type, MessageType::Broadcast { reliable: true })
83 }
84
85 /// Checks whether it's p2p message
86 pub fn is_p2p(&self) -> bool {
87 matches!(self.msg_type, MessageType::P2P)
88 }
89}
90
91/// Outgoing message
92#[derive(Debug, Clone, Copy, PartialEq, Eq)]
93pub struct Outgoing<M> {
94 /// Message destination: either one party (p2p message) or all parties (broadcast message)
95 pub recipient: MessageDestination,
96 /// Message being sent
97 pub msg: M,
98}
99
100impl<M> Outgoing<M> {
101 /// Constructs an outgoing message addressed to all parties
102 pub fn all_parties(msg: M) -> Self {
103 Self {
104 recipient: MessageDestination::AllParties { reliable: false },
105 msg,
106 }
107 }
108
109 /// Constructs an outgoing message addressed to all parties via reliable broadcast channel
110 pub fn reliable_broadcast(msg: M) -> Self {
111 Self {
112 recipient: MessageDestination::AllParties { reliable: true },
113 msg,
114 }
115 }
116
117 /// Constructs an outgoing message addressed to one party
118 pub fn p2p(recipient: PartyIndex, msg: M) -> Self {
119 Self {
120 recipient: MessageDestination::OneParty(recipient),
121 msg,
122 }
123 }
124
125 /// Maps `Outgoing<M>` to `Outgoing<M2>` by applying a function to the message body
126 pub fn map<M2, F>(self, f: F) -> Outgoing<M2>
127 where
128 F: FnOnce(M) -> M2,
129 {
130 Outgoing {
131 recipient: self.recipient,
132 msg: f(self.msg),
133 }
134 }
135
136 /// Converts `&Outgoing<M>` to `Outgoing<&M>`
137 pub fn as_ref(&self) -> Outgoing<&M> {
138 Outgoing {
139 recipient: self.recipient,
140 msg: &self.msg,
141 }
142 }
143
144 /// Checks whether it's broadcast message
145 pub fn is_broadcast(&self) -> bool {
146 self.recipient.is_broadcast()
147 }
148
149 /// Checks whether it's p2p message
150 pub fn is_p2p(&self) -> bool {
151 self.recipient.is_p2p()
152 }
153}
154
155/// Destination of an outgoing message
156#[derive(Debug, Copy, Clone, Eq, PartialEq)]
157pub enum MessageDestination {
158 /// Broadcast message
159 AllParties {
160 /// Indicates that message needs to be reliably broadcasted, meaning that when recipient receives this message,
161 /// it must be assured (cryptographically or through other trust assumptions) that all honest participants of the
162 /// protocol received the same message
163 reliable: bool,
164 },
165 /// P2P message
166 OneParty(PartyIndex),
167}
168
169impl MessageDestination {
170 /// Returns `true` if it's p2p message
171 pub fn is_p2p(&self) -> bool {
172 matches!(self, MessageDestination::OneParty(_))
173 }
174 /// Returns `true` if it's broadcast message (regardless if it's reliable or not)
175 pub fn is_broadcast(&self) -> bool {
176 matches!(self, MessageDestination::AllParties { .. })
177 }
178 /// Returns `true` if it's reliable broadcast message
179 pub fn is_reliable_broadcast(&self) -> bool {
180 matches!(self, MessageDestination::AllParties { reliable: true })
181 }
182}