network.rs

 1use clock::ReplicaId;
 2
 3pub struct Network<T: Clone, R: rand::Rng> {
 4    inboxes: std::collections::BTreeMap<ReplicaId, Vec<Envelope<T>>>,
 5    all_messages: Vec<T>,
 6    rng: R,
 7}
 8
 9#[derive(Clone)]
10struct Envelope<T: Clone> {
11    message: T,
12}
13
14impl<T: Clone, R: rand::Rng> Network<T, R> {
15    pub fn new(rng: R) -> Self {
16        Network {
17            inboxes: Default::default(),
18            all_messages: Vec::new(),
19            rng,
20        }
21    }
22
23    pub fn add_peer(&mut self, id: ReplicaId) {
24        self.inboxes.insert(id, Vec::new());
25    }
26
27    pub fn replicate(&mut self, old_replica_id: ReplicaId, new_replica_id: ReplicaId) {
28        self.inboxes
29            .insert(new_replica_id, self.inboxes[&old_replica_id].clone());
30    }
31
32    pub fn is_idle(&self) -> bool {
33        self.inboxes.values().all(|i| i.is_empty())
34    }
35
36    pub fn broadcast(&mut self, sender: ReplicaId, messages: Vec<T>) {
37        for (replica, inbox) in self.inboxes.iter_mut() {
38            if *replica != sender {
39                for message in &messages {
40                    // Insert one or more duplicates of this message, potentially *before* the previous
41                    // message sent by this peer to simulate out-of-order delivery.
42                    for _ in 0..self.rng.gen_range(1..4) {
43                        let insertion_index = self.rng.gen_range(0..inbox.len() + 1);
44                        inbox.insert(
45                            insertion_index,
46                            Envelope {
47                                message: message.clone(),
48                            },
49                        );
50                    }
51                }
52            }
53        }
54        self.all_messages.extend(messages);
55    }
56
57    pub fn has_unreceived(&self, receiver: ReplicaId) -> bool {
58        !self.inboxes[&receiver].is_empty()
59    }
60
61    pub fn receive(&mut self, receiver: ReplicaId) -> Vec<T> {
62        let inbox = self.inboxes.get_mut(&receiver).unwrap();
63        let count = self.rng.gen_range(0..inbox.len() + 1);
64        inbox
65            .drain(0..count)
66            .map(|envelope| envelope.message)
67            .collect()
68    }
69}