Add orphan iterator (#8636)

This commit is contained in:
carllin 2020-03-04 18:10:30 -08:00 committed by GitHub
parent 80aae18794
commit dec3da8f9d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 26 deletions

View File

@ -13,6 +13,7 @@ use solana_sdk::clock::DEFAULT_SLOTS_PER_EPOCH;
use solana_sdk::{clock::Slot, epoch_schedule::EpochSchedule, pubkey::Pubkey}; use solana_sdk::{clock::Slot, epoch_schedule::EpochSchedule, pubkey::Pubkey};
use std::{ use std::{
collections::BTreeSet, collections::BTreeSet,
iter::Iterator,
net::UdpSocket, net::UdpSocket,
ops::Bound::{Included, Unbounded}, ops::Bound::{Included, Unbounded},
sync::atomic::{AtomicBool, Ordering}, sync::atomic::{AtomicBool, Ordering},
@ -209,10 +210,8 @@ impl RepairService {
// TODO: Incorporate gossip to determine priorities for repair? // TODO: Incorporate gossip to determine priorities for repair?
// Try to resolve orphans in blockstore // Try to resolve orphans in blockstore
let mut orphans = blockstore.get_orphans(Some(MAX_ORPHANS)); let orphans = blockstore.orphans_iterator(root + 1).unwrap();
orphans.retain(|x| *x > root); Self::generate_repairs_for_orphans(orphans, &mut repairs);
Self::generate_repairs_for_orphans(&orphans[..], &mut repairs);
Ok(repairs) Ok(repairs)
} }
@ -240,8 +239,11 @@ impl RepairService {
} }
} }
fn generate_repairs_for_orphans(orphans: &[u64], repairs: &mut Vec<RepairType>) { fn generate_repairs_for_orphans(
repairs.extend(orphans.iter().map(|h| RepairType::Orphan(*h))); orphans: impl Iterator<Item = u64>,
repairs: &mut Vec<RepairType>,
) {
repairs.extend(orphans.take(MAX_ORPHANS).map(RepairType::Orphan));
} }
/// Repairs any fork starting at the input slot /// Repairs any fork starting at the input slot

View File

@ -1749,24 +1749,11 @@ impl Blockstore {
.is_some() .is_some()
} }
pub fn get_orphans(&self, max: Option<usize>) -> Vec<u64> { pub fn orphans_iterator<'a>(&'a self, slot: Slot) -> Result<impl Iterator<Item = u64> + 'a> {
let mut results = vec![]; let orphans_iter = self
let mut iter = self
.db .db
.raw_iterator_cf(self.db.cf_handle::<cf::Orphans>()) .iter::<cf::Orphans>(IteratorMode::From(slot, IteratorDirection::Forward))?;
.unwrap(); Ok(orphans_iter.map(|(slot, _)| slot))
iter.seek_to_first();
while iter.valid() {
if let Some(max) = max {
if results.len() > max {
break;
}
}
results.push(<cf::Orphans as Column>::index(&iter.key().unwrap()));
iter.next();
}
results
} }
/// Prune blockstore such that slots higher than `target_slot` are deleted and all references to /// Prune blockstore such that slots higher than `target_slot` are deleted and all references to
@ -3765,7 +3752,10 @@ pub mod tests {
.expect("Expect database get to succeed") .expect("Expect database get to succeed")
.unwrap(); .unwrap();
assert!(is_orphan(&meta)); assert!(is_orphan(&meta));
assert_eq!(blockstore.get_orphans(None), vec![1]); assert_eq!(
blockstore.orphans_iterator(0).unwrap().collect::<Vec<_>>(),
vec![1]
);
// Write slot 1 which chains to slot 0, so now slot 0 is the // Write slot 1 which chains to slot 0, so now slot 0 is the
// orphan, and slot 1 is no longer the orphan. // orphan, and slot 1 is no longer the orphan.
@ -3783,7 +3773,10 @@ pub mod tests {
.expect("Expect database get to succeed") .expect("Expect database get to succeed")
.unwrap(); .unwrap();
assert!(is_orphan(&meta)); assert!(is_orphan(&meta));
assert_eq!(blockstore.get_orphans(None), vec![0]); assert_eq!(
blockstore.orphans_iterator(0).unwrap().collect::<Vec<_>>(),
vec![0]
);
// Write some slot that also chains to existing slots and orphan, // Write some slot that also chains to existing slots and orphan,
// nothing should change // nothing should change
@ -3791,7 +3784,10 @@ pub mod tests {
let (shred5, _) = make_slot_entries(5, 1, 1); let (shred5, _) = make_slot_entries(5, 1, 1);
blockstore.insert_shreds(shred4, None, false).unwrap(); blockstore.insert_shreds(shred4, None, false).unwrap();
blockstore.insert_shreds(shred5, None, false).unwrap(); blockstore.insert_shreds(shred5, None, false).unwrap();
assert_eq!(blockstore.get_orphans(None), vec![0]); assert_eq!(
blockstore.orphans_iterator(0).unwrap().collect::<Vec<_>>(),
vec![0]
);
// Write zeroth slot, no more orphans // Write zeroth slot, no more orphans
blockstore.insert_shreds(shreds, None, false).unwrap(); blockstore.insert_shreds(shreds, None, false).unwrap();