use datasize::DataSize;
use serde::{Deserialize, Serialize};
use thiserror::Error;
use crate::components::consensus::{traits::Context, utils::ValidatorIndex};
#[derive(Debug, Error, Eq, PartialEq)]
pub(crate) enum EndorsementError {
#[error("The creator is not a validator.")]
Creator,
#[error("The creator is banned.")]
Banned,
#[error("The signature is invalid.")]
Signature,
#[error("The list of endorsements is empty.")]
Empty,
}
#[derive(Clone, DataSize, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
#[serde(bound(
serialize = "C::Hash: Serialize",
deserialize = "C::Hash: Deserialize<'de>",
))]
pub struct Endorsement<C>
where
C: Context,
{
unit: C::Hash,
creator: ValidatorIndex,
}
impl<C: Context> Endorsement<C> {
pub(crate) fn new(vhash: C::Hash, creator: ValidatorIndex) -> Self {
Endorsement {
unit: vhash,
creator,
}
}
pub fn hash(&self) -> C::Hash {
<C as Context>::hash(
&bincode::serialize(&(self.unit, self.creator)).expect("serialize endorsement"),
)
}
}
mod specimen_support {
use crate::{
components::consensus::ClContext,
utils::specimen::{Cache, LargestSpecimen, SizeEstimator},
};
use super::Endorsement;
impl LargestSpecimen for Endorsement<ClContext> {
fn largest_specimen<E: SizeEstimator>(estimator: &E, cache: &mut Cache) -> Self {
Endorsement {
unit: LargestSpecimen::largest_specimen(estimator, cache),
creator: LargestSpecimen::largest_specimen(estimator, cache),
}
}
}
}
#[derive(Clone, DataSize, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
#[serde(bound(
serialize = "C::Signature: Serialize",
deserialize = "C::Signature: Deserialize<'de>",
))]
pub struct SignedEndorsement<C>
where
C: Context,
{
endorsement: Endorsement<C>,
signature: C::Signature,
}
impl<C: Context> SignedEndorsement<C> {
pub fn new(endorsement: Endorsement<C>, signature: C::Signature) -> Self {
SignedEndorsement {
endorsement,
signature,
}
}
pub fn unit(&self) -> &C::Hash {
&self.endorsement.unit
}
pub fn validator_idx(&self) -> ValidatorIndex {
self.endorsement.creator
}
pub fn signature(&self) -> &C::Signature {
&self.signature
}
pub fn hash(&self) -> C::Hash {
self.endorsement.hash()
}
}