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
//! This module implements a trusted broadcast relay.
//!
//! It must be stressed that this acts as a trusted third party in the protocol
//! and does not implement secure point-to-point broadcast among the parties.
use std::sync::mpsc::{Receiver, Sender};
use crate::messages::{Message, MessagePayload};
/// A broadcast relay functionality.
///
/// Accepts openings to broadcasted committed values and faithfully relays them to all
/// parties.
pub struct BroadcastRelay {
num_parties: usize,
pub(crate) listen: Receiver<Message>,
pub(crate) parties: Vec<Sender<Message>>,
}
impl BroadcastRelay {
/// Create a new broadcast relay.
pub fn new(listen: Receiver<Message>, parties: Vec<Sender<Message>>) -> Self {
Self {
num_parties: parties.len(),
listen,
parties,
}
}
/// Continuously await broadcast communication rounds.
///
/// A broadcast round starts with all parties sending commitment opening
/// information to the broadcast relay. Once openings have been received by
/// all parties, the relay starts distributing openings to all parties,
/// sending every opening to every party, except the party where the opening
/// came from.
///
/// If the receiving channel errors this must mean that all parties have
/// shut down and dropped their copies of the sender. In this case the
/// broadcast relay also shuts down.
pub fn run(&self) {
loop {
let mut openings = Vec::new();
for _i in 0..self.num_parties {
let opening_msg = self.listen.recv();
if let Ok(Message {
from,
to,
payload: MessagePayload::BroadcastOpening(_),
}) = opening_msg
{
debug_assert_eq!(from, to, "malformed broadcast opening");
openings.push(opening_msg.expect("already confirmed it's ok"))
} else {
// One of the parties was dropped, time to shut down.
return;
}
}
for opening in openings {
for i in 0..self.num_parties {
if i == opening.from {
continue;
}
if let MessagePayload::BroadcastOpening(ref inner_opening) = opening.payload {
let franked_opening = Message {
from: opening.from,
to: i,
payload: MessagePayload::BroadcastOpening(inner_opening.clone()),
};
self.parties[i].send(franked_opening).expect(
"all parties should still be online, waiting to receive the opening",
);
}
}
}
}
}
}