fedimint_server/consensus/aleph_bft/
network.rs1use bitcoin::hashes::{Hash, sha256};
2use fedimint_core::config::P2PMessage;
3use fedimint_core::encoding::Encodable;
4use fedimint_core::net::peers::{DynP2PConnections, Recipient};
5use parity_scale_codec::{Decode, Encode, IoReader};
6
7use super::data_provider::UnitData;
8use super::keychain::Keychain;
9
10#[derive(Debug, Clone, Eq, PartialEq)]
11pub struct Hasher;
12
13impl aleph_bft::Hasher for Hasher {
14 type Hash = [u8; 32];
15
16 fn hash(input: &[u8]) -> Self::Hash {
17 input.consensus_hash::<sha256::Hash>().to_byte_array()
18 }
19}
20
21pub type NetworkData = aleph_bft::NetworkData<
22 Hasher,
23 UnitData,
24 <Keychain as aleph_bft::Keychain>::Signature,
25 <Keychain as aleph_bft::MultiKeychain>::PartialMultisignature,
26>;
27
28pub struct Network {
29 connections: DynP2PConnections<P2PMessage>,
30}
31
32impl Network {
33 pub fn new(connections: DynP2PConnections<P2PMessage>) -> Self {
34 Self { connections }
35 }
36}
37
38#[async_trait::async_trait]
39impl aleph_bft::Network<NetworkData> for Network {
40 fn send(&self, network_data: NetworkData, recipient: aleph_bft::Recipient) {
41 let recipient = match recipient {
43 aleph_bft::Recipient::Node(node_index) => {
44 Recipient::Peer(super::to_peer_id(node_index))
45 }
46 aleph_bft::Recipient::Everyone => Recipient::Everyone,
47 };
48
49 self.connections
50 .try_send(recipient, P2PMessage::Aleph(network_data.encode()));
51 }
52
53 async fn next_event(&mut self) -> Option<NetworkData> {
54 loop {
55 if let P2PMessage::Aleph(bytes) = self.connections.receive().await?.1 {
56 if let Ok(network_data) = NetworkData::decode(&mut IoReader(bytes.as_slice())) {
57 if network_data.included_data().iter().all(UnitData::is_valid) {
60 return Some(network_data);
61 }
62 }
63 }
64 }
65 }
66}