hotstuff_rs/pacemaker/
messages.rsuse std::mem;
use borsh::{BorshDeserialize, BorshSerialize};
use crate::{
hotstuff::types::PhaseCertificate,
networking::{messages::ProgressMessage, receiving::Cacheable},
types::{
crypto_primitives::Keypair,
data_types::*,
signed_messages::{SignedMessage, Vote},
},
};
use super::types::TimeoutCertificate;
#[derive(Clone, BorshSerialize, BorshDeserialize)]
pub enum PacemakerMessage {
TimeoutVote(TimeoutVote),
AdvanceView(AdvanceView),
}
impl PacemakerMessage {
pub(crate) fn timeout_vote(
keypair: &Keypair,
chain_id: ChainID,
view: ViewNumber,
highest_tc: Option<TimeoutCertificate>,
) -> PacemakerMessage {
let message = &(chain_id, view).try_to_vec().unwrap();
let signature = keypair.sign(message);
PacemakerMessage::TimeoutVote(TimeoutVote {
chain_id,
view,
signature,
highest_tc,
})
}
pub fn advance_view(progress_certificate: ProgressCertificate) -> PacemakerMessage {
PacemakerMessage::AdvanceView(AdvanceView {
progress_certificate,
})
}
pub fn chain_id(&self) -> ChainID {
match self {
PacemakerMessage::TimeoutVote(TimeoutVote { chain_id, .. }) => *chain_id,
PacemakerMessage::AdvanceView(AdvanceView {
progress_certificate,
}) => progress_certificate.chain_id(),
}
}
pub fn view(&self) -> ViewNumber {
match self {
PacemakerMessage::TimeoutVote(TimeoutVote { view, .. }) => *view,
PacemakerMessage::AdvanceView(AdvanceView {
progress_certificate,
}) => progress_certificate.view(),
}
}
pub fn size(&self) -> u64 {
match self {
PacemakerMessage::TimeoutVote(_) => mem::size_of::<TimeoutVote>() as u64,
PacemakerMessage::AdvanceView(_) => mem::size_of::<AdvanceView>() as u64,
}
}
}
impl Cacheable for PacemakerMessage {
fn size(&self) -> u64 {
self.size()
}
fn view(&self) -> ViewNumber {
self.view()
}
}
impl Into<ProgressMessage> for PacemakerMessage {
fn into(self) -> ProgressMessage {
ProgressMessage::PacemakerMessage(self)
}
}
#[derive(Clone, BorshSerialize, BorshDeserialize)]
pub struct TimeoutVote {
pub chain_id: ChainID,
pub view: ViewNumber,
pub signature: SignatureBytes,
pub highest_tc: Option<TimeoutCertificate>,
}
impl SignedMessage for TimeoutVote {
fn message_bytes(&self) -> Vec<u8> {
(self.chain_id, self.view).try_to_vec().unwrap()
}
fn signature_bytes(&self) -> SignatureBytes {
self.signature
}
}
impl Vote for TimeoutVote {
fn chain_id(&self) -> ChainID {
self.chain_id
}
fn view(&self) -> ViewNumber {
self.view
}
}
#[derive(Clone, BorshSerialize, BorshDeserialize)]
pub struct AdvanceView {
pub progress_certificate: ProgressCertificate,
}
#[derive(Clone, BorshSerialize, BorshDeserialize)]
pub enum ProgressCertificate {
TimeoutCertificate(TimeoutCertificate),
PhaseCertificate(PhaseCertificate),
}
impl ProgressCertificate {
pub fn chain_id(&self) -> ChainID {
match self {
ProgressCertificate::TimeoutCertificate(TimeoutCertificate { chain_id, .. }) => {
*chain_id
}
ProgressCertificate::PhaseCertificate(PhaseCertificate { chain_id, .. }) => *chain_id,
}
}
pub fn view(&self) -> ViewNumber {
match self {
ProgressCertificate::TimeoutCertificate(TimeoutCertificate { view, .. }) => *view,
ProgressCertificate::PhaseCertificate(PhaseCertificate { view, .. }) => *view,
}
}
}
impl From<PhaseCertificate> for ProgressCertificate {
fn from(value: PhaseCertificate) -> Self {
ProgressCertificate::PhaseCertificate(value)
}
}
impl From<TimeoutCertificate> for ProgressCertificate {
fn from(value: TimeoutCertificate) -> Self {
ProgressCertificate::TimeoutCertificate(value)
}
}