, api: Arc) -> Self {
ConsensusNetwork { network, api }
}
}
impl
Clone for ConsensusNetwork
{
fn clone(&self) -> Self {
ConsensusNetwork {
network: self.network.clone(),
api: self.api.clone(),
}
}
}
/// A long-lived network which can create parachain statement and BFT message routing processes on demand.
impl Network for ConsensusNetwork {
/// The input stream of BFT messages. Should never logically conclude.
type Input = InputAdapter;
/// The output sink of BFT messages. Messages sent here should eventually pass to all
/// current validators.
type Output = BftSink<::node_consensus::Error>;
type Block = Block;
/// Get input and output streams of BFT messages.
fn communication_for(
&self, validators: &[SessionKey],
local_id: SessionKey,
parent_hash: Hash,
mut task_executor: TaskExecutor
) -> (Self::Input, Self::Output)
{
let sink = BftSink {
network: self.network.clone(),
parent_hash,
_marker: Default::default(),
};
let (bft_send, bft_recv) = mpsc::unbounded();
// spin up a task in the background that processes all incoming statements
// TODO: propagate statements on a timer?
let process_task = self.network.with_spec(|spec, _ctx| {
spec.consensus_gossip.new_session(parent_hash);
MessageProcessTask {
inner_stream: spec.consensus_gossip.messages_for(parent_hash),
bft_messages: bft_send,
validators: validators.to_vec(),
local_id,
}
});
if let Err(e) = Executor::spawn(&mut task_executor, Box::new(process_task)) {
debug!(target: "node-network", "Cannot spawn message processing: {:?}", e)
}
(InputAdapter { input: bft_recv }, sink)
}
}