use crate::{blockcfg::HeaderHash, blockchain::Ref};
use std::sync::Arc;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Checkpoints(Vec<HeaderHash>);
impl Checkpoints {
pub fn new_from(from: Arc<Ref>) -> Self {
let mut checkpoints = vec![from.hash(), from.block_parent_hash()];
let block0_hash = from.ledger().get_static_parameters().block0_initial_hash;
let mut ignore_prev = 0;
let mut current_ref = from;
while let Some(prev_epoch) = current_ref.last_ref_previous_epoch() {
current_ref = Arc::clone(prev_epoch);
for _ in 0..ignore_prev {
if let Some(prev_epoch) = current_ref.last_ref_previous_epoch() {
current_ref = Arc::clone(prev_epoch);
} else {
break;
}
}
let hash = current_ref.hash();
if checkpoints[checkpoints.len() - 1] != hash {
ignore_prev += 1;
checkpoints.push(hash);
}
}
if block0_hash != checkpoints[1] {
checkpoints.push(block0_hash);
}
Checkpoints(checkpoints)
}
pub fn iter(&self) -> impl Iterator<Item = &HeaderHash> {
self.0.iter()
}
pub fn as_slice(&self) -> &[HeaderHash] {
self.0.as_slice()
}
}
impl AsRef<[HeaderHash]> for Checkpoints {
fn as_ref(&self) -> &[HeaderHash] {
self.as_slice()
}
}
impl IntoIterator for Checkpoints {
type Item = HeaderHash;
type IntoIter = ::std::vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl From<Checkpoints> for Vec<HeaderHash> {
fn from(checkpoints: Checkpoints) -> Self {
checkpoints.0
}
}