use datasize::DataSize;
use serde::{Deserialize, Serialize};
use super::State;
use crate::components::consensus::traits::Context;
#[derive(Clone, DataSize, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct Block<C>
where
C: Context,
{
pub height: u64,
pub value: C::ConsensusValue,
pub skip_idx: Vec<C::Hash>,
}
impl<C: Context> Block<C> {
pub(crate) fn new(
parent_hash: Option<C::Hash>,
value: C::ConsensusValue,
state: &State<C>,
) -> Block<C> {
let (parent, mut skip_idx) = match parent_hash {
None => return Block::initial(value),
Some(hash) => (state.block(&hash), vec![hash]),
};
#[allow(clippy::arithmetic_side_effects)]
let height = parent.height + 1;
for i in 0..height.trailing_zeros() as usize {
let ancestor = state.block(&skip_idx[i]);
skip_idx.push(ancestor.skip_idx[i]);
}
Block {
height,
value,
skip_idx,
}
}
pub fn parent(&self) -> Option<&C::Hash> {
self.skip_idx.first()
}
fn initial(value: C::ConsensusValue) -> Block<C> {
Block {
height: 0,
value,
skip_idx: vec![],
}
}
}