Add Blockstore::highest_slot() method (#27981)
This commit is contained in:
parent
fb686cc83b
commit
e4affb9fea
|
@ -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();
|
||||
|
|
|
@ -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!();
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue