Skip to content

Commit

Permalink
feat(chain): add query and query_multi methods to CheckPoint
Browse files Browse the repository at this point in the history
These methods allow us to query for checkpoints contained within the
linked list by height. This is useful to determine checkpoints to fetch
for chain sources without having to refer back to the `LocalChain`.

Currently this is not implemented efficiently, but in the future, we
will change `CheckPoint` to use a skip list structure.
  • Loading branch information
evanlinjin committed Mar 6, 2024
1 parent c01983d commit 6acf5c5
Showing 1 changed file with 28 additions and 0 deletions.
28 changes: 28 additions & 0 deletions crates/chain/src/local_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use core::convert::Infallible;

use crate::collections::BTreeMap;
use crate::{BlockId, ChainOracle};
use alloc::collections::BTreeSet;
use alloc::sync::Arc;
use bitcoin::block::Header;
use bitcoin::BlockHash;
Expand Down Expand Up @@ -148,6 +149,33 @@ impl CheckPoint {
pub fn iter(&self) -> CheckPointIter {
self.clone().into_iter()
}

/// Find checkpoint at `height`.
///
/// Returns `None` if checkpoint at `height` does not exist`.
pub fn query(&self, height: u32) -> Option<Self> {
self.iter()
.take_while(|cp| cp.height() >= height)
.find(|cp| cp.height() == height)
}

/// Find checkpoints of the given `heights`.
///
/// This returns an iterator which iterates over the requested heights and whether a
/// corresponding checkpoint is found.
pub fn query_multi(&self, heights: BTreeSet<u32>) -> impl Iterator<Item = (u32, Option<Self>)> {
let mut cp_iter = self.iter();
let mut current_cp = cp_iter.next();
heights.into_iter().rev().map(move |h| {
loop {
match current_cp.as_ref() {
Some(cp) if cp.height() > h => current_cp = cp_iter.next(),
Some(cp) if cp.height() == h => return (h, Some(cp.clone())),
_ => return (h, None),
}
}
})
}
}

/// Iterates over checkpoints backwards.
Expand Down

0 comments on commit 6acf5c5

Please sign in to comment.