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 = Arc::new(blockstore);
|
||||||
let blockstore_root_scan = BlockstoreRootScan::new(config, &blockstore, exit);
|
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 {
|
let process_options = blockstore_processor::ProcessOptions {
|
||||||
poh_verify: config.poh_verify,
|
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> {
|
pub struct ProcessBlockStore<'a> {
|
||||||
id: &'a Pubkey,
|
id: &'a Pubkey,
|
||||||
vote_account: &'a Pubkey,
|
vote_account: &'a Pubkey,
|
||||||
|
@ -1598,7 +1577,7 @@ impl<'a> ProcessBlockStore<'a> {
|
||||||
*self.start_progress.write().unwrap() = ValidatorStartProgress::LoadingLedger;
|
*self.start_progress.write().unwrap() = ValidatorStartProgress::LoadingLedger;
|
||||||
|
|
||||||
let exit = Arc::new(AtomicBool::new(false));
|
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 bank_forks = self.bank_forks.clone();
|
||||||
let exit = exit.clone();
|
let exit = exit.clone();
|
||||||
let start_progress = self.start_progress.clone();
|
let start_progress = self.start_progress.clone();
|
||||||
|
|
|
@ -3226,6 +3226,16 @@ impl Blockstore {
|
||||||
self.last_root()
|
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 {
|
pub fn lowest_cleanup_slot(&self) -> Slot {
|
||||||
*self.lowest_cleanup_slot.read().unwrap()
|
*self.lowest_cleanup_slot.read().unwrap()
|
||||||
}
|
}
|
||||||
|
@ -8433,6 +8443,27 @@ pub mod tests {
|
||||||
assert_eq!(blockstore.lowest_slot(), 6);
|
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]
|
#[test]
|
||||||
fn test_recovery() {
|
fn test_recovery() {
|
||||||
let ledger_path = get_tmp_ledger_path_auto_delete!();
|
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 Ok(Some(highest_slot)) = blockstore.highest_slot() {
|
||||||
if let Some((slot, _meta)) = metas.last() {
|
info!("ledger holds data through slot {}", highest_slot);
|
||||||
info!("ledger holds data through slot {}", slot);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut timing = ExecuteTimings::default();
|
let mut timing = ExecuteTimings::default();
|
||||||
|
|
Loading…
Reference in New Issue