Add orphan iterator (#8636)
This commit is contained in:
parent
80aae18794
commit
dec3da8f9d
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in New Issue