@@ -305,41 +305,48 @@ impl SnapshotConverterCommand {
305
305
. join ( SNAPSHOT_CONVERTER_CONFIG_FILE )
306
306
}
307
307
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 ( || {
312
313
format ! (
313
314
"Failed to read ledger state snapshots directory: {}" ,
314
315
ledger_dir. display( )
315
316
)
316
317
} ) ?;
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
- }
336
318
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
+ } )
343
350
}
344
351
345
352
fn copy_oldest_ledger_state_snapshot (
@@ -822,6 +829,31 @@ mod tests {
822
829
SnapshotConverterCommand :: find_oldest_ledger_state_snapshot ( & temp_dir)
823
830
. expect_err ( "Should return error if no valid ledger snapshot directory found" ) ;
824
831
}
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
+ }
825
857
}
826
858
827
859
mod commit_converted_snapshot {
0 commit comments