1
1
use std:: {
2
2
env, fmt,
3
- fs:: { create_dir, read_dir} ,
3
+ fs:: { create_dir, read_dir, remove_dir_all , rename } ,
4
4
path:: { Path , PathBuf } ,
5
5
process:: Command ,
6
6
} ;
@@ -87,6 +87,10 @@ pub struct SnapshotConverterCommand {
87
87
/// UTxO-HD flavor to convert the ledger snapshot to.
88
88
#[ clap( long) ]
89
89
utxo_hd_flavor : UTxOHDFlavor ,
90
+
91
+ /// If set, the converted snapshot replaces the current one in the db directory.
92
+ #[ clap( long) ]
93
+ commit : bool ,
90
94
}
91
95
92
96
impl SnapshotConverterCommand {
@@ -133,6 +137,7 @@ impl SnapshotConverterCommand {
133
137
& distribution_dir,
134
138
& self . cardano_network ,
135
139
& self . utxo_hd_flavor ,
140
+ self . commit ,
136
141
)
137
142
. with_context ( || {
138
143
format ! (
@@ -188,6 +193,7 @@ impl SnapshotConverterCommand {
188
193
distribution_dir : & Path ,
189
194
cardano_network : & CardanoNetwork ,
190
195
utxo_hd_flavor : & UTxOHDFlavor ,
196
+ commit : bool ,
191
197
) -> MithrilResult < ( ) > {
192
198
let snapshots_path = work_dir. join ( SNAPSHOTS_DIR ) ;
193
199
let copied_snapshot_path =
@@ -210,6 +216,17 @@ impl SnapshotConverterCommand {
210
216
utxo_hd_flavor,
211
217
) ?;
212
218
219
+ if commit {
220
+ Self :: commit_converted_snapshot ( db_dir, & converted_snapshot_path) . with_context (
221
+ || "Failed to overwrite the ledger state with the converted snapshot." ,
222
+ ) ?;
223
+ } else {
224
+ println ! (
225
+ "Converted snapshot available at: {} (use --commit to replace original)" ,
226
+ converted_snapshot_path. display( )
227
+ ) ;
228
+ }
229
+
213
230
Ok ( ( ) )
214
231
}
215
232
@@ -359,18 +376,64 @@ impl SnapshotConverterCommand {
359
376
. parse :: < u64 > ( )
360
377
. with_context ( || format ! ( "Invalid slot number in path filename: {}" , file_name_str) )
361
378
}
379
+
380
+ /// Commits the converted snapshot by replacing the current ledger state snapshots in the database directory.
381
+ fn commit_converted_snapshot (
382
+ db_dir : & Path ,
383
+ converted_snapshot_path : & Path ,
384
+ ) -> MithrilResult < ( ) > {
385
+ let ledger_dir = db_dir. join ( LEDGER_DIR ) ;
386
+ println ! (
387
+ "Replacing ledger state snapshots located in '{}' with converted snapshot at: '{}'" ,
388
+ ledger_dir. display( ) ,
389
+ converted_snapshot_path. display( )
390
+ ) ;
391
+
392
+ let filename = converted_snapshot_path
393
+ . file_name ( )
394
+ . ok_or_else ( || anyhow ! ( "Missing filename in converted snapshot path" ) ) ?
395
+ . to_string_lossy ( ) ;
396
+
397
+ let ( slot_number, _) = filename
398
+ . split_once ( '_' )
399
+ . ok_or_else ( || anyhow ! ( "Invalid converted snapshot name format: {}" , filename) ) ?;
400
+
401
+ remove_dir_all ( & ledger_dir) . with_context ( || {
402
+ format ! (
403
+ "Failed to remove old ledger state snapshot directory: {}" ,
404
+ ledger_dir. display( )
405
+ )
406
+ } ) ?;
407
+
408
+ create_dir ( & ledger_dir) . with_context ( || {
409
+ format ! (
410
+ "Failed to recreate ledger state snapshot directory: {}" ,
411
+ ledger_dir. display( )
412
+ )
413
+ } ) ?;
414
+
415
+ let destination = ledger_dir. join ( slot_number) ;
416
+ rename ( converted_snapshot_path, & destination) . with_context ( || {
417
+ format ! (
418
+ "Failed to move converted snapshot to ledger directory: {}" ,
419
+ destination. display( )
420
+ )
421
+ } ) ?;
422
+
423
+ Ok ( ( ) )
424
+ }
362
425
}
363
426
364
427
#[ cfg( test) ]
365
428
mod tests {
429
+ use mithril_common:: temp_dir_create;
430
+
366
431
use super :: * ;
367
432
368
433
mod download_cardano_node_distribution {
369
434
use mockall:: predicate:: eq;
370
435
use reqwest:: Url ;
371
436
372
- use mithril_common:: temp_dir_create;
373
-
374
437
use crate :: utils:: { GitHubRelease , MockGitHubReleaseRetriever , MockHttpDownloader } ;
375
438
376
439
use super :: * ;
@@ -740,4 +803,46 @@ mod tests {
740
803
. expect_err ( "Should return error if no valid ledger snapshot directory found" ) ;
741
804
}
742
805
}
806
+
807
+ mod commit_converted_snapshot {
808
+ use std:: fs:: File ;
809
+
810
+ use super :: * ;
811
+
812
+ #[ test]
813
+ fn moves_converted_snapshot_to_ledger_directory ( ) {
814
+ let tmp_dir = temp_dir_create ! ( ) ;
815
+ let ledger_dir = tmp_dir. join ( LEDGER_DIR ) ;
816
+ create_dir ( & ledger_dir) . unwrap ( ) ;
817
+ let previous_snapshot = ledger_dir. join ( "123" ) ;
818
+ File :: create ( & previous_snapshot) . unwrap ( ) ;
819
+
820
+ let converted_snapshot = tmp_dir. join ( "456_lmdb" ) ;
821
+ File :: create ( & converted_snapshot) . unwrap ( ) ;
822
+
823
+ assert ! ( previous_snapshot. exists( ) ) ;
824
+ SnapshotConverterCommand :: commit_converted_snapshot ( & tmp_dir, & converted_snapshot)
825
+ . unwrap ( ) ;
826
+
827
+ assert ! ( !previous_snapshot. exists( ) ) ;
828
+ assert ! ( ledger_dir. join( "456" ) . exists( ) ) ;
829
+ }
830
+
831
+ #[ test]
832
+ fn fails_if_converted_snapshot_has_invalid_filename ( ) {
833
+ let tmp_dir = temp_dir_create ! ( ) ;
834
+ let ledger_dir = tmp_dir. join ( LEDGER_DIR ) ;
835
+ create_dir ( & ledger_dir) . unwrap ( ) ;
836
+ let previous_snapshot = ledger_dir. join ( "123" ) ;
837
+ File :: create ( & previous_snapshot) . unwrap ( ) ;
838
+
839
+ let converted_snapshot = tmp_dir. join ( "456" ) ;
840
+ File :: create ( & converted_snapshot) . unwrap ( ) ;
841
+
842
+ SnapshotConverterCommand :: commit_converted_snapshot ( & tmp_dir, & converted_snapshot)
843
+ . expect_err ( "Should fail if converted snapshot has invalid filename" ) ;
844
+
845
+ assert ! ( previous_snapshot. exists( ) ) ;
846
+ }
847
+ }
743
848
}
0 commit comments