1use std::{
2 cmp,
3 sync::mpsc::{channel, Receiver, Sender},
4 thread::sleep,
5 time::{Duration, Instant},
6 vec::IntoIter,
7};
8
9use queues::{IsQueue, Queue};
10
11pub trait NetworkDescription {
13 fn instantiate(&self, n_parties: usize) -> Vec<Channels>;
15}
16
17#[derive(Default)]
18pub struct FullMesh {
20 latency: Duration,
21 seconds_per_byte: Duration,
22}
23
24impl FullMesh {
25 pub fn new() -> Self {
27 FullMesh {
28 latency: Duration::ZERO,
29 seconds_per_byte: Duration::ZERO,
30 }
31 }
32
33 pub fn new_with_overhead(latency: Duration, bytes_per_second: f64) -> Self {
35 FullMesh {
36 latency,
37 seconds_per_byte: Duration::from_secs_f64(1. / bytes_per_second),
38 }
39 }
40}
41
42impl NetworkDescription for FullMesh {
43 fn instantiate(&self, n_parties: usize) -> Vec<Channels> {
44 let mut receivers = vec![];
45 let mut senders: Vec<Vec<Sender<_>>> = (0..n_parties).map(|_| vec![]).collect();
46
47 for _ in 0..n_parties {
48 let (sender, receiver) = channel();
49
50 receivers.push(receiver);
51
52 for sender_vec in senders.iter_mut() {
53 sender_vec.push(sender.clone());
54 }
55 }
56
57 receivers
58 .into_iter()
59 .enumerate()
60 .zip(senders)
61 .map(|((id, r), s)| Channels::new(id, s, r, self.latency, self.seconds_per_byte))
62 .collect()
63 }
64}
65
66pub struct Message {
68 arrival_time: Instant,
69 from_id: usize,
70 contents: Vec<u8>,
71}
72
73pub struct DelayedByteIterator {
75 wake_time: Instant,
76 bytes: IntoIter<u8>,
77 seconds_per_byte: Duration,
78}
79
80impl DelayedByteIterator {
81 pub fn new(bytes: Vec<u8>, start_time: Instant, seconds_per_byte: Duration) -> Self {
83 DelayedByteIterator {
84 wake_time: start_time + seconds_per_byte,
85 bytes: bytes.into_iter(),
86 seconds_per_byte,
87 }
88 }
89}
90
91impl Iterator for DelayedByteIterator {
92 type Item = u8;
93
94 fn next(&mut self) -> Option<Self::Item> {
95 self.bytes.next().map(|byte| {
96 let dur = self.wake_time - Instant::now();
98 sleep(dur);
99
100 self.wake_time += self.seconds_per_byte;
101 byte
102 })
103 }
104}
105
106pub struct Channels {
108 id: usize,
109 senders: Vec<Sender<Message>>,
110 receiver: Receiver<Message>,
111 buffer: Vec<Queue<(Instant, Vec<u8>)>>,
112 sent_bytes: Vec<usize>,
113 latency: Duration,
114 seconds_per_byte: Duration,
115 next_vacancy: Instant,
116}
117
118impl Channels {
119 pub fn new(
121 id: usize,
122 senders: Vec<Sender<Message>>,
123 receiver: Receiver<Message>,
124 latency: Duration,
125 seconds_per_byte: Duration,
126 ) -> Self {
127 let sender_count = senders.len();
128
129 Channels {
130 id,
131 senders,
132 receiver,
133 buffer: (0..sender_count - 1).map(|_| Queue::new()).collect(),
134 sent_bytes: vec![0; sender_count],
135 latency,
136 seconds_per_byte,
137 next_vacancy: Instant::now(),
138 }
139 }
140
141 fn add_sent_bytes(&mut self, byte_count: usize, to_id: &usize) {
142 self.sent_bytes[*to_id] += byte_count;
143 }
144
145 pub fn receive(&mut self, from_id: &usize) -> DelayedByteIterator {
149 debug_assert_ne!(
150 *from_id, self.id,
151 "`from_id = {}` may not be the same as `self.id = {}`",
152 from_id, self.id
153 );
154
155 let reduced_id = if *from_id < self.id {
156 *from_id
157 } else {
158 *from_id - 1
159 };
160
161 let (arrival_time, bytes) = match self.buffer[reduced_id].size() {
162 0 => loop {
163 let message = self.receiver.recv().unwrap();
164
165 if message.from_id == *from_id {
166 break (message.arrival_time, message.contents);
167 }
168
169 let message_reduced_id = if message.from_id < self.id {
170 message.from_id
171 } else {
172 message.from_id - 1
173 };
174 self.buffer[message_reduced_id]
175 .add((message.arrival_time, message.contents))
176 .unwrap();
177 },
178 _ => self.buffer[reduced_id].remove().unwrap(),
179 };
180
181 sleep(self.next_vacancy - Instant::now());
183
184 sleep(arrival_time - Instant::now());
186
187 let start_time = cmp::max(self.next_vacancy, arrival_time);
189
190 self.next_vacancy = start_time + self.seconds_per_byte * bytes.len() as u32;
192
193 DelayedByteIterator::new(bytes, start_time, self.seconds_per_byte)
195 }
196
197 pub fn send(&mut self, message: &[u8], to_id: &usize) {
200 let byte_count = message.len();
201
202 self.senders[*to_id]
203 .send(Message {
204 arrival_time: Instant::now() + self.latency,
205 from_id: self.id,
206 contents: message.to_vec(),
207 })
208 .unwrap();
209
210 self.add_sent_bytes(byte_count, to_id);
211 }
212
213 pub fn broadcast(&mut self, message: &[u8]) {
216 let byte_count = message.len();
217
218 for sender in &self.senders {
219 sender
220 .send(Message {
221 arrival_time: Instant::now() + self.latency,
222 from_id: self.id,
223 contents: message.to_vec(),
224 })
225 .unwrap();
226 }
227
228 for i in 0..self.senders.len() {
229 self.add_sent_bytes(byte_count, &i);
230 }
231 }
232}