use crate::{
error::Error,
id::{Proof, PublicId},
network_event::NetworkEvent,
observation::Observation,
vote::Vote,
DkgResult, DkgResultWrapper,
};
use std::{
collections::{vec_deque, BTreeMap, BTreeSet, VecDeque},
ops::{Deref, DerefMut},
};
#[serde(bound = "")]
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, Debug)]
pub struct Block<T: NetworkEvent, P: PublicId> {
payload: Observation<T, P>,
proofs: BTreeSet<Proof<P>>,
}
impl<T: NetworkEvent, P: PublicId> Block<T, P> {
pub fn new_dkg_block((participants, dkg_result): (BTreeSet<P>, DkgResult)) -> Self {
Self {
payload: Observation::DkgResult {
participants,
dkg_result: DkgResultWrapper(dkg_result),
},
proofs: BTreeSet::new(),
}
}
pub fn new(votes: &BTreeMap<P, Vote<T, P>>) -> Result<Self, Error> {
let payload = if let Some(vote) = votes.values().next() {
vote.payload().clone()
} else {
return Err(Error::MissingVotes);
};
let proofs: Result<BTreeSet<_>, _> = votes
.iter()
.map(|(public_id, vote)| {
if *vote.payload() == payload {
vote.create_proof(public_id)
} else {
Err(Error::MismatchedPayload)
}
})
.collect();
let proofs = proofs?;
Ok(Self { payload, proofs })
}
pub fn payload(&self) -> &Observation<T, P> {
&self.payload
}
pub fn proofs(&self) -> &BTreeSet<Proof<P>> {
&self.proofs
}
pub fn is_signed_by(&self, peer_id: &P) -> bool {
self.proofs.iter().any(|proof| proof.public_id() == peer_id)
}
pub fn add_vote(&mut self, peer_id: &P, vote: &Vote<T, P>) -> Result<bool, Error> {
if &self.payload != vote.payload() {
return Err(Error::MismatchedPayload);
}
let proof = vote.create_proof(peer_id)?;
Ok(self.proofs.insert(proof))
}
}
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
pub(crate) struct BlockGroup<T: NetworkEvent, P: PublicId>(pub VecDeque<Block<T, P>>);
impl<T: NetworkEvent, P: PublicId> BlockGroup<T, P> {
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
impl<T: NetworkEvent, P: PublicId> IntoIterator for BlockGroup<T, P> {
type Item = Block<T, P>;
type IntoIter = vec_deque::IntoIter<Block<T, P>>;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl<'a, T: NetworkEvent, P: PublicId> IntoIterator for &'a BlockGroup<T, P> {
type Item = &'a Block<T, P>;
type IntoIter = vec_deque::Iter<'a, Block<T, P>>;
fn into_iter(self) -> Self::IntoIter {
self.0.iter()
}
}
impl<T: NetworkEvent, P: PublicId> Deref for BlockGroup<T, P> {
type Target = VecDeque<Block<T, P>>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T: NetworkEvent, P: PublicId> DerefMut for BlockGroup<T, P> {
fn deref_mut(&mut self) -> &mut VecDeque<Block<T, P>> {
&mut self.0
}
}