use chio_core::hashing::Hash;
use chio_core::merkle::MerkleProof;
use super::{checkpoint_chain_root, CheckpointError, KernelCheckpoint};
#[derive(Debug, Clone, Copy)]
pub enum CheckpointConsistencyAnchor<'a> {
Genesis,
VerifiedChainRoot(Hash),
ChainPrefix(&'a [Hash]),
}
pub(super) fn consistency_prefix_is_anchored(
previous: &KernelCheckpoint,
from_size: usize,
from_chain_root: &Hash,
anchor: CheckpointConsistencyAnchor<'_>,
) -> Result<bool, CheckpointError> {
match anchor {
CheckpointConsistencyAnchor::Genesis => {
if from_size != 1 {
return Err(CheckpointError::Continuity(format!(
"consistency proof from checkpoint {} is unanchored; only a pair starting at checkpoint 1 anchors itself",
previous.body.checkpoint_seq
)));
}
Ok(true)
}
CheckpointConsistencyAnchor::VerifiedChainRoot(pinned) => Ok(pinned == *from_chain_root),
CheckpointConsistencyAnchor::ChainPrefix(chain_leaf_hashes) => Ok(chain_leaf_hashes.len()
== from_size
&& checkpoint_chain_root(chain_leaf_hashes)? == *from_chain_root),
}
}
pub(super) fn chain_leaf_is_committed(
inclusion: &MerkleProof,
size: usize,
leaf: Hash,
root: &Hash,
) -> bool {
inclusion.tree_size == size
&& size.checked_sub(1) == Some(inclusion.leaf_index)
&& inclusion.verify_hash(leaf, root)
}