Skip to content

Commit d399cfe

Browse files
authored
Merge pull request #2345 from input-output-hk/dlachaume/2292/enhance-computation-required-disk-space-client-cli
Feat: improve disk space calculation for Incremental DB Restoration
2 parents b480fda + 3197a4a commit d399cfe

File tree

3 files changed

+169
-8
lines changed

3 files changed

+169
-8
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mithril-client-cli/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "mithril-client-cli"
3-
version = "0.11.6"
3+
version = "0.11.7"
44
description = "A Mithril Client"
55
authors = { workspace = true }
66
edition = { workspace = true }

mithril-client-cli/src/commands/cardano_db_v2/download.rs

Lines changed: 167 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,13 @@ use crate::{
2626
CommandContext,
2727
};
2828

29+
const DISK_SPACE_SAFETY_MARGIN_RATIO: f64 = 0.1;
30+
2931
struct RestorationOptions {
3032
db_dir: PathBuf,
3133
immutable_file_range: ImmutableFileRange,
3234
download_unpack_options: DownloadUnpackOptions,
35+
disk_space_safety_margin_ratio: f64,
3336
}
3437

3538
/// Clap command to download a Cardano db and verify its associated certificate.
@@ -107,6 +110,7 @@ impl CardanoDbV2DownloadCommand {
107110
include_ancillary: self.include_ancillary,
108111
..DownloadUnpackOptions::default()
109112
},
113+
disk_space_safety_margin_ratio: DISK_SPACE_SAFETY_MARGIN_RATIO,
110114
};
111115
let logger = context.logger();
112116

@@ -148,7 +152,7 @@ impl CardanoDbV2DownloadCommand {
148152
Self::check_local_disk_info(
149153
1,
150154
&progress_printer,
151-
&restoration_options.db_dir,
155+
&restoration_options,
152156
&cardano_db_message,
153157
self.allow_override,
154158
)?;
@@ -216,19 +220,60 @@ impl CardanoDbV2DownloadCommand {
216220
Ok(())
217221
}
218222

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+
219264
fn check_local_disk_info(
220265
step_number: u16,
221266
progress_printer: &ProgressPrinter,
222-
db_dir: &Path,
267+
restoration_options: &RestorationOptions,
223268
cardano_db: &CardanoDatabaseSnapshot,
224269
allow_override: bool,
225270
) -> MithrilResult<()> {
226271
progress_printer.report_step(step_number, "Checking local disk info…")?;
227272

228-
CardanoDbDownloadChecker::ensure_dir_exist(db_dir)?;
273+
CardanoDbDownloadChecker::ensure_dir_exist(&restoration_options.db_dir)?;
229274
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),
232277
allow_override,
233278
) {
234279
progress_printer
@@ -463,7 +508,10 @@ impl ConfigSource for CardanoDbV2DownloadCommand {
463508
#[cfg(test)]
464509
mod tests {
465510
use mithril_client::{
466-
common::{CardanoDbBeacon, ProtocolMessagePartKey, SignedEntityType},
511+
common::{
512+
AncillaryMessagePart, CardanoDbBeacon, DigestsMessagePart, ImmutablesMessagePart,
513+
ProtocolMessagePartKey, SignedEntityType,
514+
},
467515
MithrilCertificateMetadata,
468516
};
469517
use mithril_common::test_utils::TempDir;
@@ -567,4 +615,117 @@ mod tests {
567615

568616
assert_eq!(range, ImmutableFileRange::UpTo(345));
569617
}
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+
}
570731
}

0 commit comments

Comments
 (0)