use std::mem;
use borsh::{BorshDeserialize, BorshSerialize};
use crate::{
hotstuff::types::PhaseCertificate,
types::{block::*, crypto_primitives::Keypair, data_types::*, signed_messages::SignedMessage},
};
#[derive(Clone, BorshSerialize, BorshDeserialize)]
pub enum BlockSyncMessage {
BlockSyncRequest(BlockSyncRequest),
BlockSyncResponse(BlockSyncResponse),
}
impl BlockSyncMessage {
pub fn block_sync_request(
chain_id: ChainID,
start_height: BlockHeight,
limit: u32,
) -> BlockSyncMessage {
BlockSyncMessage::BlockSyncRequest(BlockSyncRequest {
chain_id,
start_height,
limit,
})
}
pub fn block_sync_response(
blocks: Vec<Block>,
highest_pc: PhaseCertificate,
) -> BlockSyncMessage {
BlockSyncMessage::BlockSyncResponse(BlockSyncResponse { blocks, highest_pc })
}
}
#[derive(Clone, BorshSerialize, BorshDeserialize)]
pub struct BlockSyncRequest {
pub chain_id: ChainID,
pub start_height: BlockHeight,
pub limit: u32,
}
#[derive(Clone, BorshSerialize, BorshDeserialize)]
pub struct BlockSyncResponse {
pub blocks: Vec<Block>,
pub highest_pc: PhaseCertificate,
}
#[derive(Clone, BorshSerialize, BorshDeserialize)]
pub enum BlockSyncAdvertiseMessage {
AdvertiseBlock(AdvertiseBlock),
AdvertisePC(AdvertisePC),
}
impl BlockSyncAdvertiseMessage {
pub(crate) fn advertise_block(
me: &Keypair,
chain_id: ChainID,
highest_committed_block_height: BlockHeight,
) -> Self {
let message = &(chain_id, highest_committed_block_height)
.try_to_vec()
.unwrap();
let signature = me.sign(message);
BlockSyncAdvertiseMessage::AdvertiseBlock(AdvertiseBlock {
chain_id,
highest_committed_block_height,
signature,
})
}
pub(crate) fn advertise_pc(highest_pc: PhaseCertificate) -> Self {
BlockSyncAdvertiseMessage::AdvertisePC(AdvertisePC { highest_pc })
}
pub fn chain_id(&self) -> ChainID {
match self {
BlockSyncAdvertiseMessage::AdvertiseBlock(msg) => msg.chain_id,
BlockSyncAdvertiseMessage::AdvertisePC(msg) => msg.highest_pc.chain_id,
}
}
pub fn size(&self) -> u64 {
match self {
BlockSyncAdvertiseMessage::AdvertiseBlock(_) => mem::size_of::<AdvertiseBlock>() as u64,
BlockSyncAdvertiseMessage::AdvertisePC(_) => mem::size_of::<AdvertisePC>() as u64,
}
}
}
#[derive(Clone, BorshSerialize, BorshDeserialize)]
pub struct AdvertiseBlock {
pub chain_id: ChainID,
pub highest_committed_block_height: BlockHeight,
pub signature: SignatureBytes,
}
impl SignedMessage for AdvertiseBlock {
fn message_bytes(&self) -> Vec<u8> {
(self.chain_id, self.highest_committed_block_height)
.try_to_vec()
.unwrap()
}
fn signature_bytes(&self) -> SignatureBytes {
self.signature
}
}
#[derive(Clone, BorshSerialize, BorshDeserialize)]
pub struct AdvertisePC {
pub highest_pc: PhaseCertificate,
}