Add blockstore skipped api (#14145)

* Add blockstore api to determine if a slot was skipped

* Return custom rpc error if slot is skipped
This commit is contained in:
Tyera Eulberg
2020-12-16 13:40:36 -07:00
committed by GitHub
parent 636a455790
commit ac0d32bc7e
3 changed files with 53 additions and 4 deletions

View File

@@ -2649,6 +2649,21 @@ impl Blockstore {
matches!(self.db.get::<cf::Root>(slot), Ok(Some(true)))
}
/// Returns true if a slot is between the rooted slot bounds of the ledger, but has not itself
/// been rooted. This is either because the slot was skipped, or due to a gap in ledger data,
/// as when booting from a newer snapshot.
pub fn is_skipped(&self, slot: Slot) -> bool {
let lowest_root = self
.rooted_slot_iterator(0)
.ok()
.and_then(|mut iter| iter.next())
.unwrap_or_default();
match self.db.get::<cf::Root>(slot).ok().flatten() {
Some(_) => false,
None => slot < self.max_root() && slot > lowest_root,
}
}
pub fn set_roots(&self, rooted_slots: &[u64]) -> Result<()> {
let mut write_batch = self.db.batch()?;
for slot in rooted_slots {
@@ -5523,6 +5538,25 @@ pub mod tests {
Blockstore::destroy(&blockstore_path).expect("Expected successful database destruction");
}
#[test]
fn test_is_skipped() {
let blockstore_path = get_tmp_ledger_path!();
let blockstore = Blockstore::open(&blockstore_path).unwrap();
let roots = vec![2, 4, 7, 12, 15];
blockstore.set_roots(&roots).unwrap();
for i in 0..20 {
if i < 2 || roots.contains(&i) || i > 15 {
assert!(!blockstore.is_skipped(i));
} else {
assert!(blockstore.is_skipped(i));
}
}
drop(blockstore);
Blockstore::destroy(&blockstore_path).expect("Expected successful database destruction");
}
#[test]
fn test_iter_bounds() {
let blockstore_path = get_tmp_ledger_path!();