@@ -26,10 +26,13 @@ use crate::{
26
26
CommandContext ,
27
27
} ;
28
28
29
+ const DISK_SPACE_SAFETY_MARGIN_RATIO : f64 = 0.1 ;
30
+
29
31
struct RestorationOptions {
30
32
db_dir : PathBuf ,
31
33
immutable_file_range : ImmutableFileRange ,
32
34
download_unpack_options : DownloadUnpackOptions ,
35
+ disk_space_safety_margin_ratio : f64 ,
33
36
}
34
37
35
38
/// Clap command to download a Cardano db and verify its associated certificate.
@@ -107,6 +110,7 @@ impl CardanoDbV2DownloadCommand {
107
110
include_ancillary : self . include_ancillary ,
108
111
..DownloadUnpackOptions :: default ( )
109
112
} ,
113
+ disk_space_safety_margin_ratio : DISK_SPACE_SAFETY_MARGIN_RATIO ,
110
114
} ;
111
115
let logger = context. logger ( ) ;
112
116
@@ -148,7 +152,7 @@ impl CardanoDbV2DownloadCommand {
148
152
Self :: check_local_disk_info (
149
153
1 ,
150
154
& progress_printer,
151
- & restoration_options. db_dir ,
155
+ & restoration_options,
152
156
& cardano_db_message,
153
157
self . allow_override ,
154
158
) ?;
@@ -216,19 +220,60 @@ impl CardanoDbV2DownloadCommand {
216
220
Ok ( ( ) )
217
221
}
218
222
223
+ fn compute_total_immutables_restored_size (
224
+ cardano_db : & CardanoDatabaseSnapshot ,
225
+ restoration_options : & RestorationOptions ,
226
+ ) -> u64 {
227
+ let total_immutables_restored = restoration_options
228
+ . immutable_file_range
229
+ . length ( cardano_db. beacon . immutable_file_number ) ;
230
+
231
+ total_immutables_restored * cardano_db. immutables . average_size_uncompressed
232
+ }
233
+
234
+ fn add_safety_margin ( size : u64 , margin_ratio : f64 ) -> u64 {
235
+ ( size as f64 * ( 1.0 + margin_ratio) ) as u64
236
+ }
237
+
238
+ fn compute_required_disk_space_for_snapshot (
239
+ cardano_db : & CardanoDatabaseSnapshot ,
240
+ restoration_options : & RestorationOptions ,
241
+ ) -> u64 {
242
+ if restoration_options. immutable_file_range == ImmutableFileRange :: Full {
243
+ cardano_db. total_db_size_uncompressed
244
+ } else {
245
+ let total_immutables_restored_size =
246
+ Self :: compute_total_immutables_restored_size ( cardano_db, restoration_options) ;
247
+
248
+ let mut total_size =
249
+ total_immutables_restored_size + cardano_db. digests . size_uncompressed ;
250
+ if restoration_options
251
+ . download_unpack_options
252
+ . include_ancillary
253
+ {
254
+ total_size += cardano_db. ancillary . size_uncompressed ;
255
+ }
256
+
257
+ Self :: add_safety_margin (
258
+ total_size,
259
+ restoration_options. disk_space_safety_margin_ratio ,
260
+ )
261
+ }
262
+ }
263
+
219
264
fn check_local_disk_info (
220
265
step_number : u16 ,
221
266
progress_printer : & ProgressPrinter ,
222
- db_dir : & Path ,
267
+ restoration_options : & RestorationOptions ,
223
268
cardano_db : & CardanoDatabaseSnapshot ,
224
269
allow_override : bool ,
225
270
) -> MithrilResult < ( ) > {
226
271
progress_printer. report_step ( step_number, "Checking local disk info…" ) ?;
227
272
228
- CardanoDbDownloadChecker :: ensure_dir_exist ( db_dir) ?;
273
+ CardanoDbDownloadChecker :: ensure_dir_exist ( & restoration_options . db_dir ) ?;
229
274
if let Err ( e) = CardanoDbDownloadChecker :: check_prerequisites_for_uncompressed_data (
230
- db_dir,
231
- cardano_db. total_db_size_uncompressed ,
275
+ & restoration_options . db_dir ,
276
+ Self :: compute_required_disk_space_for_snapshot ( cardano_db, restoration_options ) ,
232
277
allow_override,
233
278
) {
234
279
progress_printer
@@ -463,7 +508,10 @@ impl ConfigSource for CardanoDbV2DownloadCommand {
463
508
#[ cfg( test) ]
464
509
mod tests {
465
510
use mithril_client:: {
466
- common:: { CardanoDbBeacon , ProtocolMessagePartKey , SignedEntityType } ,
511
+ common:: {
512
+ AncillaryMessagePart , CardanoDbBeacon , DigestsMessagePart , ImmutablesMessagePart ,
513
+ ProtocolMessagePartKey , SignedEntityType ,
514
+ } ,
467
515
MithrilCertificateMetadata ,
468
516
} ;
469
517
use mithril_common:: test_utils:: TempDir ;
@@ -567,4 +615,117 @@ mod tests {
567
615
568
616
assert_eq ! ( range, ImmutableFileRange :: UpTo ( 345 ) ) ;
569
617
}
618
+
619
+ #[ test]
620
+ fn compute_required_disk_space_for_snapshot_when_full_restoration ( ) {
621
+ let cardano_db_snapshot = CardanoDatabaseSnapshot {
622
+ total_db_size_uncompressed : 123 ,
623
+ ..CardanoDatabaseSnapshot :: dummy ( )
624
+ } ;
625
+ let restoration_options = RestorationOptions {
626
+ immutable_file_range : ImmutableFileRange :: Full ,
627
+ db_dir : PathBuf :: from ( "db_dir" ) ,
628
+ download_unpack_options : DownloadUnpackOptions :: default ( ) ,
629
+ disk_space_safety_margin_ratio : 0.0 ,
630
+ } ;
631
+
632
+ let required_size = CardanoDbV2DownloadCommand :: compute_required_disk_space_for_snapshot (
633
+ & cardano_db_snapshot,
634
+ & restoration_options,
635
+ ) ;
636
+
637
+ assert_eq ! ( required_size, 123 ) ;
638
+ }
639
+
640
+ #[ test]
641
+ fn compute_required_disk_space_for_snapshot_when_partial_restoration_and_no_ancillary_files ( ) {
642
+ let cardano_db_snapshot = CardanoDatabaseSnapshot {
643
+ digests : DigestsMessagePart {
644
+ size_uncompressed : 50 ,
645
+ locations : vec ! [ ] ,
646
+ } ,
647
+ immutables : ImmutablesMessagePart {
648
+ average_size_uncompressed : 100 ,
649
+ locations : vec ! [ ] ,
650
+ } ,
651
+ ancillary : AncillaryMessagePart {
652
+ size_uncompressed : 300 ,
653
+ locations : vec ! [ ] ,
654
+ } ,
655
+ ..CardanoDatabaseSnapshot :: dummy ( )
656
+ } ;
657
+ let restoration_options = RestorationOptions {
658
+ immutable_file_range : ImmutableFileRange :: Range ( 10 , 19 ) ,
659
+ db_dir : PathBuf :: from ( "db_dir" ) ,
660
+ download_unpack_options : DownloadUnpackOptions {
661
+ include_ancillary : false ,
662
+ ..DownloadUnpackOptions :: default ( )
663
+ } ,
664
+ disk_space_safety_margin_ratio : 0.0 ,
665
+ } ;
666
+
667
+ let required_size = CardanoDbV2DownloadCommand :: compute_required_disk_space_for_snapshot (
668
+ & cardano_db_snapshot,
669
+ & restoration_options,
670
+ ) ;
671
+
672
+ let digest_size = cardano_db_snapshot. digests . size_uncompressed ;
673
+ let average_size_uncompressed_immutable =
674
+ cardano_db_snapshot. immutables . average_size_uncompressed ;
675
+
676
+ let expected_size = digest_size + 10 * average_size_uncompressed_immutable;
677
+ assert_eq ! ( required_size, expected_size) ;
678
+ }
679
+
680
+ #[ test]
681
+ fn compute_required_disk_space_for_snapshot_when_partial_restoration_and_ancillary_files ( ) {
682
+ let cardano_db_snapshot = CardanoDatabaseSnapshot {
683
+ digests : DigestsMessagePart {
684
+ size_uncompressed : 50 ,
685
+ locations : vec ! [ ] ,
686
+ } ,
687
+ immutables : ImmutablesMessagePart {
688
+ average_size_uncompressed : 100 ,
689
+ locations : vec ! [ ] ,
690
+ } ,
691
+ ancillary : AncillaryMessagePart {
692
+ size_uncompressed : 300 ,
693
+ locations : vec ! [ ] ,
694
+ } ,
695
+ ..CardanoDatabaseSnapshot :: dummy ( )
696
+ } ;
697
+ let restoration_options = RestorationOptions {
698
+ immutable_file_range : ImmutableFileRange :: Range ( 10 , 19 ) ,
699
+ db_dir : PathBuf :: from ( "db_dir" ) ,
700
+ download_unpack_options : DownloadUnpackOptions {
701
+ include_ancillary : true ,
702
+ ..DownloadUnpackOptions :: default ( )
703
+ } ,
704
+ disk_space_safety_margin_ratio : 0.0 ,
705
+ } ;
706
+
707
+ let required_size = CardanoDbV2DownloadCommand :: compute_required_disk_space_for_snapshot (
708
+ & cardano_db_snapshot,
709
+ & restoration_options,
710
+ ) ;
711
+
712
+ let digest_size = cardano_db_snapshot. digests . size_uncompressed ;
713
+ let average_size_uncompressed_immutable =
714
+ cardano_db_snapshot. immutables . average_size_uncompressed ;
715
+ let ancillary_size = cardano_db_snapshot. ancillary . size_uncompressed ;
716
+
717
+ let expected_size = digest_size + 10 * average_size_uncompressed_immutable + ancillary_size;
718
+ assert_eq ! ( required_size, expected_size) ;
719
+ }
720
+
721
+ #[ test]
722
+ fn add_safety_margin_apply_margin_with_ratio ( ) {
723
+ assert_eq ! ( CardanoDbV2DownloadCommand :: add_safety_margin( 100 , 0.1 ) , 110 ) ;
724
+ assert_eq ! ( CardanoDbV2DownloadCommand :: add_safety_margin( 100 , 0.5 ) , 150 ) ;
725
+ assert_eq ! ( CardanoDbV2DownloadCommand :: add_safety_margin( 100 , 1.5 ) , 250 ) ;
726
+
727
+ assert_eq ! ( CardanoDbV2DownloadCommand :: add_safety_margin( 0 , 0.1 ) , 0 ) ;
728
+
729
+ assert_eq ! ( CardanoDbV2DownloadCommand :: add_safety_margin( 100 , 0.0 ) , 100 ) ;
730
+ }
570
731
}
0 commit comments