use serde::{Deserialize, Serialize};
use thiserror::Error;
use crate::components::consensus::traits::Context;
use super::validators::ValidatorIndex;
#[derive(Debug, Error, 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, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
#[serde(bound(
serialize = "C::Hash: Serialize",
deserialize = "C::Hash: Deserialize<'de>",
))]
pub(crate) struct Endorsement<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(crate) fn hash(&self) -> C::Hash {
<C as Context>::hash(
&bincode::serialize(&(self.unit, self.creator)).expect("serialize endorsement"),
)
}
}
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
#[serde(bound(
serialize = "C::Signature: Serialize",
deserialize = "C::Signature: Deserialize<'de>",
))]
pub(crate) struct SignedEndorsement<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(crate) fn unit(&self) -> &C::Hash {
&self.endorsement.unit
}
pub(crate) fn validator_idx(&self) -> ValidatorIndex {
self.endorsement.creator
}
pub(crate) fn signature(&self) -> &C::Signature {
&self.signature
}
pub(crate) fn hash(&self) -> C::Hash {
self.endorsement.hash()
}
}