use candid::CandidType;
use ex3_serde::bincode;
use serde::{Deserialize, Serialize};
use serde_bytes::ByteBuf;
use crate::{BlockHash, BlockHeight, CandidBlockHeight, CandidPackageId, MerkleRoot, PackageId};
#[derive(Serialize, Deserialize, Clone, Debug, Ord, PartialOrd, PartialEq, Eq)]
pub struct BlockHead {
pub version: u8,
pub height: BlockHeight,
pub p_id: PackageId,
pub pre_block_hash: BlockHash,
pub tx_root: MerkleRoot,
pub balance_changed_root: MerkleRoot,
pub data_integrity_root: MerkleRoot,
pub rejected_tx_root: MerkleRoot,
}
#[derive(CandidType, Deserialize, Clone, Debug, Ord, PartialOrd, PartialEq, Eq)]
pub struct CandidBlockHead {
pub version: u8,
pub height: CandidBlockHeight,
pub p_id: CandidPackageId,
pub pre_block_hash: BlockHash,
pub tx_root: MerkleRoot,
pub balance_changed_root: MerkleRoot,
pub data_integrity_root: MerkleRoot,
pub rejected_tx_root: MerkleRoot,
}
impl From<CandidBlockHead> for BlockHead {
fn from(candid_block_head: CandidBlockHead) -> Self {
BlockHead {
version: candid_block_head.version,
height: candid_block_head.height.0,
p_id: candid_block_head.p_id.0,
pre_block_hash: candid_block_head.pre_block_hash,
tx_root: candid_block_head.tx_root,
balance_changed_root: candid_block_head.balance_changed_root,
data_integrity_root: candid_block_head.data_integrity_root,
rejected_tx_root: candid_block_head.rejected_tx_root,
}
}
}
impl From<BlockHead> for CandidBlockHead {
fn from(block_head: BlockHead) -> Self {
CandidBlockHead {
version: block_head.version,
height: block_head.height.into(),
p_id: block_head.p_id.into(),
pre_block_hash: block_head.pre_block_hash,
tx_root: block_head.tx_root,
balance_changed_root: block_head.balance_changed_root,
data_integrity_root: block_head.data_integrity_root,
rejected_tx_root: block_head.rejected_tx_root,
}
}
}
impl BlockHead {
pub fn hash(&self) -> BlockHash {
let block_head_bytes = bincode::serialize(&self).unwrap();
ex3_crypto::sha256(block_head_bytes.as_slice())
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct EncodedBlockHead(pub ByteBuf);
impl From<BlockHead> for EncodedBlockHead {
fn from(head: BlockHead) -> Self {
let bytes = bincode::serialize(&head).unwrap();
EncodedBlockHead(ByteBuf::from(bytes))
}
}
impl From<EncodedBlockHead> for BlockHead {
fn from(encoded_head: EncodedBlockHead) -> Self {
bincode::deserialize(encoded_head.0.as_slice()).expect("Decode block head should success")
}
}
impl std::ops::Deref for EncodedBlockHead {
type Target = ByteBuf;
fn deref(&self) -> &Self::Target {
&self.0
}
}
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
pub struct BlockHeadExt {
pub height: BlockHeight,
pub validate_on_chain: bool,
pub sharding_reported: bool,
pub has_local_body: bool,
}