@@ -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