1use std::collections::BTreeMap;
4use std::fmt::{Debug, Display};
5use std::hash::Hash;
6use std::iter::once;
7
8use failure::Fail;
9use rand::Rng;
10use serde::{de::DeserializeOwned, Serialize};
11
12use crate::fault_log::{Fault, FaultLog};
13use crate::sender_queue::SenderQueueableMessage;
14use crate::{Target, TargetedMessage};
15
16pub trait Contribution: Eq + Debug + Hash + Send + Sync {}
18impl<C> Contribution for C where C: Eq + Debug + Hash + Send + Sync {}
19
20pub trait NodeIdT: Eq + Ord + Clone + Debug + Hash + Send + Sync {}
22impl<N> NodeIdT for N where N: Eq + Ord + Clone + Debug + Hash + Send + Sync {}
23
24pub trait FaultT: Clone + Debug + Fail + PartialEq {}
26impl<N> FaultT for N where N: Clone + Debug + Fail + PartialEq {}
27
28pub trait Message: Debug + Send + Sync {}
30impl<M> Message for M where M: Debug + Send + Sync {}
31
32pub trait SessionIdT: Display + Serialize + Send + Sync + Clone + Debug {}
34impl<S> SessionIdT for S where S: Display + Serialize + Send + Sync + Clone + Debug {}
35
36pub trait EpochT: Copy + Message + Default + Eq + Ord + Serialize + DeserializeOwned {}
38impl<E> EpochT for E where E: Copy + Message + Default + Eq + Ord + Serialize + DeserializeOwned {}
39
40#[must_use = "The algorithm step result must be used."]
63#[derive(Debug)]
64pub struct Step<M, O, N, F: Fail> {
65 pub output: Vec<O>,
68 pub fault_log: FaultLog<N, F>,
71 pub messages: Vec<TargetedMessage<M, N>>,
74}
75
76impl<M, O, N, F> Default for Step<M, O, N, F>
77where
78 F: Fail,
79{
80 fn default() -> Self {
81 Step {
82 output: Vec::default(),
83 fault_log: FaultLog::default(),
84 messages: Vec::default(),
85 }
86 }
87}
88
89impl<M, O, N, F> Step<M, O, N, F>
90where
91 F: Fail,
92{
93 pub fn new(
95 output: Vec<O>,
96 fault_log: FaultLog<N, F>,
97 messages: Vec<TargetedMessage<M, N>>,
98 ) -> Self {
99 Step {
100 output,
101 fault_log,
102 messages,
103 }
104 }
105
106 pub fn with_output<T: Into<Option<O>>>(mut self, output: T) -> Self {
108 self.output.extend(output.into());
109 self
110 }
111
112 pub fn map<M2, O2, F2, FO, FF, FM>(
115 self,
116 f_out: FO,
117 f_fail: FF,
118 f_msg: FM,
119 ) -> Step<M2, O2, N, F2>
120 where
121 F2: Fail,
122 FO: Fn(O) -> O2,
123 FF: Fn(F) -> F2,
124 FM: Fn(M) -> M2,
125 {
126 Step {
127 output: self.output.into_iter().map(f_out).collect(),
128 fault_log: self.fault_log.map(f_fail),
129 messages: self.messages.into_iter().map(|tm| tm.map(&f_msg)).collect(),
130 }
131 }
132
133 #[must_use]
135 pub fn extend_with<M2, O2, F2, FF, FM>(
136 &mut self,
137 other: Step<M2, O2, N, F2>,
138 f_fail: FF,
139 f_msg: FM,
140 ) -> Vec<O2>
141 where
142 F2: Fail,
143 FF: Fn(F2) -> F,
144 FM: Fn(M2) -> M,
145 {
146 let fails = other.fault_log.map(f_fail);
147 self.fault_log.extend(fails);
148 let msgs = other.messages.into_iter().map(|tm| tm.map(&f_msg));
149 self.messages.extend(msgs);
150 other.output
151 }
152
153 pub fn extend(&mut self, other: Self) {
155 self.output.extend(other.output);
156 self.fault_log.extend(other.fault_log);
157 self.messages.extend(other.messages);
158 }
159
160 pub fn join(mut self, other: Self) -> Self {
162 self.extend(other);
163 self
164 }
165
166 pub fn is_empty(&self) -> bool {
168 self.output.is_empty() && self.fault_log.is_empty() && self.messages.is_empty()
169 }
170}
171
172impl<M, O, N, F> From<FaultLog<N, F>> for Step<M, O, N, F>
173where
174 F: Fail,
175{
176 fn from(fault_log: FaultLog<N, F>) -> Self {
177 Step {
178 fault_log,
179 ..Step::default()
180 }
181 }
182}
183
184impl<M, O, N, F> From<Fault<N, F>> for Step<M, O, N, F>
185where
186 F: Fail,
187{
188 fn from(fault: Fault<N, F>) -> Self {
189 Step {
190 fault_log: fault.into(),
191 ..Step::default()
192 }
193 }
194}
195
196impl<M, O, N, F> From<TargetedMessage<M, N>> for Step<M, O, N, F>
197where
198 F: Fail,
199{
200 fn from(msg: TargetedMessage<M, N>) -> Self {
201 Step {
202 messages: once(msg).collect(),
203 ..Step::default()
204 }
205 }
206}
207
208impl<I, M, O, N, F> From<I> for Step<M, O, N, F>
209where
210 I: IntoIterator<Item = TargetedMessage<M, N>>,
211 F: Fail,
212{
213 fn from(msgs: I) -> Self {
214 Step {
215 messages: msgs.into_iter().collect(),
216 ..Step::default()
217 }
218 }
219}
220
221pub trait Epoched {
225 type Epoch: EpochT;
227
228 fn epoch(&self) -> Self::Epoch;
230}
231
232pub type CpStep<D> = Step<
234 <D as ConsensusProtocol>::Message,
235 <D as ConsensusProtocol>::Output,
236 <D as ConsensusProtocol>::NodeId,
237 <D as ConsensusProtocol>::FaultKind,
238>;
239
240impl<'i, M, O, N, F> Step<M, O, N, F>
241where
242 N: NodeIdT,
243 M: 'i + Clone + SenderQueueableMessage,
244 F: Fail,
245{
246 pub fn defer_messages(
250 &mut self,
251 peer_epochs: &BTreeMap<N, M::Epoch>,
252 max_future_epochs: u64,
253 ) -> Vec<(N, M)> {
254 let mut deferred_msgs: Vec<(N, M)> = Vec::new();
255 let mut passed_msgs: Vec<_> = Vec::new();
256 for msg in self.messages.drain(..) {
257 match msg.target.clone() {
258 Target::Node(id) => {
259 if let Some(&them) = peer_epochs.get(&id) {
260 if msg.message.is_premature(them, max_future_epochs) {
261 deferred_msgs.push((id, msg.message));
262 } else if !msg.message.is_obsolete(them) {
263 passed_msgs.push(msg);
264 }
265 }
266 }
267 Target::All => {
268 let is_accepted = |&them| msg.message.is_accepted(them, max_future_epochs);
269 let is_premature = |&them| msg.message.is_premature(them, max_future_epochs);
270 let is_obsolete = |&them| msg.message.is_obsolete(them);
271 if peer_epochs.values().all(is_accepted) {
272 passed_msgs.push(msg);
273 } else {
274 for (id, them) in peer_epochs {
277 if is_premature(them) {
278 deferred_msgs.push((id.clone(), msg.message.clone()));
279 } else if !is_obsolete(them) {
280 passed_msgs
281 .push(Target::Node(id.clone()).message(msg.message.clone()));
282 }
283 }
284 }
285 }
286 }
287 }
288 self.messages.extend(passed_msgs);
289 deferred_msgs
290 }
291}
292
293pub trait ConsensusProtocol: Send + Sync {
298 type NodeId: NodeIdT;
300 type Input;
302 type Output;
305 type Message: Message;
307 type Error: Fail;
309 type FaultKind: FaultT;
311
312 fn handle_input<R: Rng>(
314 &mut self,
315 input: Self::Input,
316 rng: &mut R,
317 ) -> Result<CpStep<Self>, Self::Error>
318 where
319 Self: Sized;
320
321 fn handle_message<R: Rng>(
323 &mut self,
324 sender_id: &Self::NodeId,
325 message: Self::Message,
326 rng: &mut R,
327 ) -> Result<CpStep<Self>, Self::Error>
328 where
329 Self: Sized;
330
331 fn terminated(&self) -> bool;
333
334 fn our_id(&self) -> &Self::NodeId;
336}