Skip to content

Commit eb0c854

Browse files
committed
refactor(client-cli): refactor find_oldest_ledger_state_snapshot
Extracts and sorts valid ledger snapshots by slot number, then returns the oldest one.
1 parent 2bcfaad commit eb0c854

File tree

1 file changed

+61
-29
lines changed

1 file changed

+61
-29
lines changed

mithril-client-cli/src/commands/tools/snapshot_converter.rs

Lines changed: 61 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -305,41 +305,48 @@ impl SnapshotConverterCommand {
305305
.join(SNAPSHOT_CONVERTER_CONFIG_FILE)
306306
}
307307

308-
/// Finds the oldest ledger snapshot (by slot number) in the `ledger/` directory of a Cardano node database.
309-
fn find_oldest_ledger_state_snapshot(db_dir: &Path) -> MithrilResult<PathBuf> {
310-
let ledger_dir = db_dir.join(LEDGER_DIR);
311-
let entries = read_dir(&ledger_dir).with_context(|| {
308+
/// Returns the list of valid ledger snapshot directories sorted in ascending order of slot number.
309+
///
310+
/// Only directories with numeric names are considered valid snapshots.
311+
fn get_sorted_snapshot_dirs(ledger_dir: &Path) -> MithrilResult<Vec<(u64, PathBuf)>> {
312+
let entries = read_dir(ledger_dir).with_context(|| {
312313
format!(
313314
"Failed to read ledger state snapshots directory: {}",
314315
ledger_dir.display()
315316
)
316317
})?;
317-
let mut min_slot: Option<(u64, PathBuf)> = None;
318-
319-
for entry in entries {
320-
let entry = entry?;
321-
let slot = match Self::extract_slot_number(&entry.path()) {
322-
Ok(number) => number,
323-
Err(_) => continue,
324-
};
325-
326-
let path = entry.path();
327-
if path.is_dir()
328-
&& (min_slot
329-
.as_ref()
330-
.map(|(min, _)| slot < *min)
331-
.unwrap_or(true))
332-
{
333-
min_slot = Some((slot, path));
334-
}
335-
}
336318

337-
min_slot.map(|(_, path)| path).ok_or_else(|| {
338-
anyhow!(
339-
"No valid ledger state snapshot found in directory: {}",
340-
ledger_dir.display()
341-
)
342-
})
319+
let mut snapshots = entries
320+
.filter_map(|entry| {
321+
let path = entry.ok()?.path();
322+
if !path.is_dir() {
323+
return None;
324+
}
325+
SnapshotConverterCommand::extract_slot_number(&path)
326+
.ok()
327+
.map(|slot| (slot, path))
328+
})
329+
.collect::<Vec<_>>();
330+
331+
snapshots.sort_by_key(|(slot, _)| *slot);
332+
333+
Ok(snapshots)
334+
}
335+
336+
/// Finds the oldest ledger snapshot (by slot number) in the `ledger/` directory of a Cardano node database.
337+
fn find_oldest_ledger_state_snapshot(db_dir: &Path) -> MithrilResult<PathBuf> {
338+
let ledger_dir = db_dir.join(LEDGER_DIR);
339+
let snapshots_by_slot = Self::get_sorted_snapshot_dirs(&ledger_dir)?;
340+
snapshots_by_slot
341+
.into_iter()
342+
.map(|(_, path)| path)
343+
.next()
344+
.ok_or_else(|| {
345+
anyhow!(
346+
"No valid ledger state snapshot found in directory: {}",
347+
ledger_dir.display()
348+
)
349+
})
343350
}
344351

345352
fn copy_oldest_ledger_state_snapshot(
@@ -822,6 +829,31 @@ mod tests {
822829
SnapshotConverterCommand::find_oldest_ledger_state_snapshot(&temp_dir)
823830
.expect_err("Should return error if no valid ledger snapshot directory found");
824831
}
832+
833+
#[test]
834+
fn get_sorted_snapshot_dirs_returns_sorted_valid_directories() {
835+
let temp_dir = temp_dir_create!();
836+
let ledger_dir = temp_dir.join(LEDGER_DIR);
837+
create_dir(&ledger_dir).unwrap();
838+
839+
create_dir(ledger_dir.join("1500")).unwrap();
840+
create_dir(ledger_dir.join("1000")).unwrap();
841+
create_dir(ledger_dir.join("2000")).unwrap();
842+
File::create(ledger_dir.join("500")).unwrap();
843+
create_dir(ledger_dir.join("notanumber")).unwrap();
844+
845+
let snapshots =
846+
SnapshotConverterCommand::get_sorted_snapshot_dirs(&ledger_dir).unwrap();
847+
848+
assert_eq!(
849+
snapshots,
850+
vec![
851+
(1000, ledger_dir.join("1000")),
852+
(1500, ledger_dir.join("1500")),
853+
(2000, ledger_dir.join("2000")),
854+
]
855+
);
856+
}
825857
}
826858

827859
mod commit_converted_snapshot {

0 commit comments

Comments
 (0)