use borsh::{BorshDeserialize, BorshSerialize};
use crate::{
block_tree::{
accessors::internal::{BlockTreeError, BlockTreeSingleton},
pluggables::KVStore,
},
hotstuff::types::PhaseCertificate,
types::{
crypto_primitives::{CryptoHasher, Digest},
data_types::*,
},
};
use super::signed_messages::Certificate;
#[derive(Clone, BorshSerialize, BorshDeserialize)]
pub struct Block {
pub height: BlockHeight,
pub hash: CryptoHash,
pub justify: PhaseCertificate,
pub data_hash: CryptoHash,
pub data: Data,
}
impl Block {
pub fn new(
height: BlockHeight,
justify: PhaseCertificate,
data_hash: CryptoHash,
data: Data,
) -> Block {
assert!(justify.phase.is_generic() || justify.phase.is_decide());
Block {
height,
hash: Block::hash(height, &justify, &data_hash),
justify,
data_hash,
data,
}
}
pub fn hash(
height: BlockHeight,
justify: &PhaseCertificate,
data_hash: &CryptoHash,
) -> CryptoHash {
let mut hasher = CryptoHasher::new();
hasher.update(&height.try_to_vec().unwrap());
hasher.update(&justify.try_to_vec().unwrap());
hasher.update(&data_hash.try_to_vec().unwrap());
CryptoHash::new(hasher.finalize().into())
}
pub fn is_correct<K: KVStore>(
&self,
block_tree: &BlockTreeSingleton<K>,
) -> Result<bool, BlockTreeError> {
Ok(
self.hash == Block::hash(self.height, &self.justify, &self.data_hash)
&& self.justify.is_correct(block_tree)?,
)
}
}