1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
use crateIncoming;
/// Stores messages received at particular round
///
/// In MPC protocol, party at every round usually needs to receive up to `n` messages. `MessagesStore`
/// is a container that stores messages, it knows how many messages are expected to be received,
/// and should implement extra measures against malicious parties (e.g. prohibit message overwrite).
///
/// ## Procedure
/// `MessagesStore` stores received messages. Once enough messages are received, it outputs [`MessagesStore::Output`].
/// In order to save received messages, [`.add_message(msg)`] is called. Then, [`.wants_more()`] tells whether more
/// messages are needed to be received. If it returned `false`, then output can be retrieved by calling [`.output()`].
///
/// [`.add_message(msg)`]: Self::add_message
/// [`.wants_more()`]: Self::wants_more
/// [`.output()`]: Self::output
///
/// ## Example
/// [`RoundInput`](super::simple_store::RoundInput) is an simple messages store. Refer to its docs to see usage examples.
/// Message of MPC protocol
///
/// MPC protocols typically consist of several rounds, each round has differently typed message.
/// `ProtocolMessage` and [`RoundMessage`] traits are used to examine received message: `ProtocolMessage::round`
/// determines which round message belongs to, and then `RoundMessage` trait can be used to retrieve
/// actual round-specific message.
///
/// You should derive these traits using proc macro (requires `derive` feature):
/// ```rust
/// use round_based::ProtocolMessage;
///
/// #[derive(ProtocolMessage)]
/// pub enum Message {
/// Round1(Msg1),
/// Round2(Msg2),
/// // ...
/// }
///
/// pub struct Msg1 { /* ... */ }
/// pub struct Msg2 { /* ... */ }
/// ```
///
/// This desugars into:
///
/// ```rust
/// use round_based::rounds_router::{ProtocolMessage, RoundMessage};
///
/// pub enum Message {
/// Round1(Msg1),
/// Round2(Msg2),
/// // ...
/// }
///
/// pub struct Msg1 { /* ... */ }
/// pub struct Msg2 { /* ... */ }
///
/// impl ProtocolMessage for Message {
/// fn round(&self) -> u16 {
/// match self {
/// Message::Round1(_) => 1,
/// Message::Round2(_) => 2,
/// // ...
/// }
/// }
/// }
/// impl RoundMessage<Msg1> for Message {
/// const ROUND: u16 = 1;
/// fn to_protocol_message(round_message: Msg1) -> Self {
/// Message::Round1(round_message)
/// }
/// fn from_protocol_message(protocol_message: Self) -> Result<Msg1, Self> {
/// match protocol_message {
/// Message::Round1(msg) => Ok(msg),
/// msg => Err(msg),
/// }
/// }
/// }
/// impl RoundMessage<Msg2> for Message {
/// const ROUND: u16 = 2;
/// fn to_protocol_message(round_message: Msg2) -> Self {
/// Message::Round2(round_message)
/// }
/// fn from_protocol_message(protocol_message: Self) -> Result<Msg2, Self> {
/// match protocol_message {
/// Message::Round2(msg) => Ok(msg),
/// msg => Err(msg),
/// }
/// }
/// }
/// ```
/// Round message
///
/// See [`ProtocolMessage`] trait documentation.