From dec3da8f9d27a19fd4220f5dfab8db9afde4fa37 Mon Sep 17 00:00:00 2001 From: carllin Date: Wed, 4 Mar 2020 18:10:30 -0800 Subject: [PATCH] Add orphan iterator (#8636) --- core/src/repair_service.rs | 14 ++++++++------ ledger/src/blockstore.rs | 36 ++++++++++++++++-------------------- 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/core/src/repair_service.rs b/core/src/repair_service.rs index 981d4659c4..cfd22d4f6f 100644 --- a/core/src/repair_service.rs +++ b/core/src/repair_service.rs @@ -13,6 +13,7 @@ use solana_sdk::clock::DEFAULT_SLOTS_PER_EPOCH; use solana_sdk::{clock::Slot, epoch_schedule::EpochSchedule, pubkey::Pubkey}; use std::{ collections::BTreeSet, + iter::Iterator, net::UdpSocket, ops::Bound::{Included, Unbounded}, sync::atomic::{AtomicBool, Ordering}, @@ -209,10 +210,8 @@ impl RepairService { // TODO: Incorporate gossip to determine priorities for repair? // Try to resolve orphans in blockstore - let mut orphans = blockstore.get_orphans(Some(MAX_ORPHANS)); - orphans.retain(|x| *x > root); - - Self::generate_repairs_for_orphans(&orphans[..], &mut repairs); + let orphans = blockstore.orphans_iterator(root + 1).unwrap(); + Self::generate_repairs_for_orphans(orphans, &mut repairs); Ok(repairs) } @@ -240,8 +239,11 @@ impl RepairService { } } - fn generate_repairs_for_orphans(orphans: &[u64], repairs: &mut Vec) { - repairs.extend(orphans.iter().map(|h| RepairType::Orphan(*h))); + fn generate_repairs_for_orphans( + orphans: impl Iterator, + repairs: &mut Vec, + ) { + repairs.extend(orphans.take(MAX_ORPHANS).map(RepairType::Orphan)); } /// Repairs any fork starting at the input slot diff --git a/ledger/src/blockstore.rs b/ledger/src/blockstore.rs index 66de705df2..f7a04405bc 100644 --- a/ledger/src/blockstore.rs +++ b/ledger/src/blockstore.rs @@ -1749,24 +1749,11 @@ impl Blockstore { .is_some() } - pub fn get_orphans(&self, max: Option) -> Vec { - let mut results = vec![]; - - let mut iter = self + pub fn orphans_iterator<'a>(&'a self, slot: Slot) -> Result + 'a> { + let orphans_iter = self .db - .raw_iterator_cf(self.db.cf_handle::()) - .unwrap(); - iter.seek_to_first(); - while iter.valid() { - if let Some(max) = max { - if results.len() > max { - break; - } - } - results.push(::index(&iter.key().unwrap())); - iter.next(); - } - results + .iter::(IteratorMode::From(slot, IteratorDirection::Forward))?; + Ok(orphans_iter.map(|(slot, _)| slot)) } /// 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") .unwrap(); assert!(is_orphan(&meta)); - assert_eq!(blockstore.get_orphans(None), vec![1]); + assert_eq!( + blockstore.orphans_iterator(0).unwrap().collect::>(), + vec![1] + ); // Write slot 1 which chains to slot 0, so now slot 0 is the // orphan, and slot 1 is no longer the orphan. @@ -3783,7 +3773,10 @@ pub mod tests { .expect("Expect database get to succeed") .unwrap(); assert!(is_orphan(&meta)); - assert_eq!(blockstore.get_orphans(None), vec![0]); + assert_eq!( + blockstore.orphans_iterator(0).unwrap().collect::>(), + vec![0] + ); // Write some slot that also chains to existing slots and orphan, // nothing should change @@ -3791,7 +3784,10 @@ pub mod tests { let (shred5, _) = make_slot_entries(5, 1, 1); blockstore.insert_shreds(shred4, 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![0] + ); // Write zeroth slot, no more orphans blockstore.insert_shreds(shreds, None, false).unwrap();