use std::io::Write;
use bitcoin_hashes_12::{sha256, Hash};
use fedimint_core::net::peers::IPeerConnections;
use parity_scale_codec::{Decode, Encode, IoReader};
use super::data_provider::UnitData;
use super::keychain::Keychain;
use super::{Message, Recipient};
use crate::net::peers::ReconnectPeerConnections;
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Hasher;
impl aleph_bft::Hasher for Hasher {
type Hash = [u8; 32];
fn hash(input: &[u8]) -> Self::Hash {
let mut engine = sha256::HashEngine::default();
engine
.write_all(input)
.expect("Writing to a hash engine cannot fail");
sha256::Hash::from_engine(engine).to_byte_array()
}
}
pub type NetworkData = aleph_bft::NetworkData<
Hasher,
UnitData,
<Keychain as aleph_bft::Keychain>::Signature,
<Keychain as aleph_bft::MultiKeychain>::PartialMultisignature,
>;
pub struct Network {
connections: ReconnectPeerConnections<Message>,
}
impl Network {
pub fn new(connections: ReconnectPeerConnections<Message>) -> Self {
Self { connections }
}
}
#[async_trait::async_trait]
impl aleph_bft::Network<NetworkData> for Network {
fn send(&self, network_data: NetworkData, recipient: aleph_bft::Recipient) {
let recipient = match recipient {
aleph_bft::Recipient::Node(node_index) => {
Recipient::Peer(super::to_peer_id(node_index))
}
aleph_bft::Recipient::Everyone => Recipient::Everyone,
};
self.connections
.send_sync(Message(network_data.encode()), recipient);
}
async fn next_event(&mut self) -> Option<NetworkData> {
while let Ok(message) = self.connections.receive().await {
if let Ok(network_data) = NetworkData::decode(&mut IoReader(message.1 .0.as_slice())) {
if network_data.included_data().iter().all(UnitData::is_valid) {
return Some(network_data);
}
}
}
std::future::pending::<Option<NetworkData>>().await
}
}