Add Blockstore::highest_slot() method (#27981)

This commit is contained in:
steviez 2022-09-23 04:53:43 -05:00 committed by GitHub
parent fb686cc83b
commit e4affb9fea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 29 deletions

View File

@ -1418,7 +1418,9 @@ fn load_blockstore(
let blockstore = Arc::new(blockstore);
let blockstore_root_scan = BlockstoreRootScan::new(config, &blockstore, exit);
let halt_at_slot = config.halt_at_slot.or_else(|| highest_slot(&blockstore));
let halt_at_slot = config
.halt_at_slot
.or_else(|| blockstore.highest_slot().unwrap_or(None));
let process_options = blockstore_processor::ProcessOptions {
poh_verify: config.poh_verify,
@ -1517,29 +1519,6 @@ fn load_blockstore(
))
}
fn highest_slot(blockstore: &Blockstore) -> Option<Slot> {
let mut start = Measure::start("Blockstore search for highest slot");
let highest_slot = blockstore
.slot_meta_iterator(0)
.map(|metas| {
let slots: Vec<_> = metas.map(|(slot, _)| slot).collect();
if slots.is_empty() {
info!("Ledger is empty");
None
} else {
let first = slots.first().unwrap();
Some(*slots.last().unwrap_or(first))
}
})
.unwrap_or_else(|err| {
warn!("Failed to ledger slot meta: {}", err);
None
});
start.stop();
info!("{}. Found slot {:?}", start, highest_slot);
highest_slot
}
pub struct ProcessBlockStore<'a> {
id: &'a Pubkey,
vote_account: &'a Pubkey,
@ -1598,7 +1577,7 @@ impl<'a> ProcessBlockStore<'a> {
*self.start_progress.write().unwrap() = ValidatorStartProgress::LoadingLedger;
let exit = Arc::new(AtomicBool::new(false));
if let Some(max_slot) = highest_slot(self.blockstore) {
if let Ok(Some(max_slot)) = self.blockstore.highest_slot() {
let bank_forks = self.bank_forks.clone();
let exit = exit.clone();
let start_progress = self.start_progress.clone();

View File

@ -3226,6 +3226,16 @@ impl Blockstore {
self.last_root()
}
/// Returns the highest available slot in the blockstore
pub fn highest_slot(&self) -> Result<Option<Slot>> {
let highest_slot = self
.db
.iter::<cf::SlotMeta>(IteratorMode::End)?
.next()
.map(|(slot, _)| slot);
Ok(highest_slot)
}
pub fn lowest_cleanup_slot(&self) -> Slot {
*self.lowest_cleanup_slot.read().unwrap()
}
@ -8433,6 +8443,27 @@ pub mod tests {
assert_eq!(blockstore.lowest_slot(), 6);
}
#[test]
fn test_highest_slot() {
let ledger_path = get_tmp_ledger_path_auto_delete!();
let blockstore = Blockstore::open(ledger_path.path()).unwrap();
assert_eq!(blockstore.highest_slot().unwrap(), None);
for slot in 0..10 {
let (shreds, _) = make_slot_entries(slot, 0, 1);
blockstore.insert_shreds(shreds, None, false).unwrap();
assert_eq!(blockstore.highest_slot().unwrap(), Some(slot));
}
blockstore
.run_purge(5, 10, PurgeType::PrimaryIndex)
.unwrap();
assert_eq!(blockstore.highest_slot().unwrap(), Some(4));
blockstore.run_purge(0, 4, PurgeType::PrimaryIndex).unwrap();
assert_eq!(blockstore.highest_slot().unwrap(), None);
}
#[test]
fn test_recovery() {
let ledger_path = get_tmp_ledger_path_auto_delete!();

View File

@ -820,10 +820,8 @@ pub fn process_blockstore_from_root(
);
}
if let Ok(metas) = blockstore.slot_meta_iterator(start_slot) {
if let Some((slot, _meta)) = metas.last() {
info!("ledger holds data through slot {}", slot);
}
if let Ok(Some(highest_slot)) = blockstore.highest_slot() {
info!("ledger holds data through slot {}", highest_slot);
}
let mut timing = ExecuteTimings::default();