Skip to content

Add warning in client about ancillary files #2473

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion mithril-client-cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mithril-client-cli"
version = "0.12.1"
version = "0.12.2"
description = "A Mithril Client"
authors = { workspace = true }
edition = { workspace = true }
Expand Down
10 changes: 8 additions & 2 deletions mithril-client-cli/src/commands/cardano_db/download.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ use crate::{
commands::{client_builder, SharedArgs},
configuration::{ConfigError, ConfigSource},
utils::{
self, CardanoDbDownloadChecker, CardanoDbUtils, ExpanderUtils, IndicatifFeedbackReceiver,
ProgressOutputType, ProgressPrinter,
self, AncillaryLogMessage, CardanoDbDownloadChecker, CardanoDbUtils, ExpanderUtils,
IndicatifFeedbackReceiver, ProgressOutputType, ProgressPrinter,
},
CommandContext,
};
Expand Down Expand Up @@ -67,6 +67,12 @@ impl CardanoDbDownloadCommand {

/// Command execution
pub async fn execute(&self, context: CommandContext) -> MithrilResult<()> {
if self.include_ancillary {
AncillaryLogMessage::warn_ancillary_not_signed_by_mithril();
} else {
AncillaryLogMessage::warn_fast_bootstrap_not_available();
}

let params = context.config_parameters()?.add_source(self)?;
let download_dir: &String = &params.require("download_dir")?;
let db_dir = Path::new(download_dir).join("db");
Expand Down
10 changes: 8 additions & 2 deletions mithril-client-cli/src/commands/cardano_db_v2/download.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ use crate::{
commands::{client_builder, SharedArgs},
configuration::{ConfigError, ConfigSource},
utils::{
self, CardanoDbDownloadChecker, CardanoDbUtils, ExpanderUtils, IndicatifFeedbackReceiver,
ProgressOutputType, ProgressPrinter,
self, AncillaryLogMessage, CardanoDbDownloadChecker, CardanoDbUtils, ExpanderUtils,
IndicatifFeedbackReceiver, ProgressOutputType, ProgressPrinter,
},
CommandContext,
};
Expand Down Expand Up @@ -107,6 +107,12 @@ impl CardanoDbV2DownloadCommand {

/// Command execution
pub async fn execute(&self, context: CommandContext) -> MithrilResult<()> {
if self.include_ancillary {
AncillaryLogMessage::warn_ancillary_not_signed_by_mithril();
} else {
AncillaryLogMessage::warn_fast_bootstrap_not_available();
}

let params = context.config_parameters()?.add_source(self)?;
let download_dir: &String = &params.require("download_dir")?;
let restoration_options = RestorationOptions {
Expand Down
18 changes: 18 additions & 0 deletions mithril-client-cli/src/utils/cardano_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,24 @@ impl CardanoDbUtils {
}
}

pub struct AncillaryLogMessage {}

impl AncillaryLogMessage {
/// This method provides guidance on how to enable fast bootstrap by including ancillary files
pub fn warn_fast_bootstrap_not_available() {
println!("The fast bootstrap of the Cardano node is not available with the current parameters used in this command: this means that the ledger state will be recomputed from genesis at startup of the Cardano node.

In order to activate the fast bootstrap of the Cardano node, add the following parameters to the command:

--include-ancillary
and --ancillary-verification-key (or environment variable ANCILLARY_VERIFICATION_KEY). Caution: The ancillary files, including the ledger state, are not currently signed by Mithril. As a mitigation, IOG owned keys are used to sign these files. For more information, please refer to the network configuration page of the documentation (https://mithril.network/doc/manual/getting-started/network-configurations).");
}

pub fn warn_ancillary_not_signed_by_mithril() {
println!("Ancillary verification does not use the Mithril certification: as a mitigation, IOG owned keys are used to sign these files.");
}
}

#[cfg(test)]
mod test {
use super::*;
Expand Down
2 changes: 1 addition & 1 deletion mithril-client/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mithril-client"
version = "0.12.2"
version = "0.12.3"
description = "Mithril client library"
authors = { workspace = true }
edition = { workspace = true }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ use mithril_common::messages::{
use crate::cardano_database_client::ImmutableFileRange;
use crate::feedback::{FeedbackSender, MithrilEvent, MithrilEventCardanoDatabase};
use crate::file_downloader::{DownloadEvent, FileDownloader, FileDownloaderUri};
use crate::utils::{create_bootstrap_node_files, AncillaryVerifier, VecDequeExtensions};
use crate::utils::{
create_bootstrap_node_files, AncillaryVerifier, VecDequeExtensions,
ANCILLARIES_NOT_SIGNED_BY_MITHRIL,
};
use crate::MithrilResult;

use super::download_task::{DownloadKind, DownloadTask, LocationToDownload};
Expand Down Expand Up @@ -77,11 +80,14 @@ impl InternalArtifactDownloader {
&download_id,
)?);
if download_unpack_options.include_ancillary {
slog::warn!(self.logger, "{}", ANCILLARIES_NOT_SIGNED_BY_MITHRIL);
tasks.push_back(self.new_ancillary_download_task(
&cardano_database_snapshot.ancillary,
target_dir,
&download_id,
)?);
} else {
slog::warn!(self.logger, "The fast bootstrap of the Cardano node is not available with the current parameters used in this command: the ledger state will be recomputed from genesis at startup of the Cardano node. Set the include_ancillary entry to true in the DownloadUnpackOptions.");
}
self.batch_download_unpack(tasks, download_unpack_options.max_parallel_downloads)
.await?;
Expand Down Expand Up @@ -463,7 +469,7 @@ mod tests {
}

mod building_download_tasks {
use mithril_common::test_utils::fake_keys;
use mithril_common::{entities::CompressionAlgorithm, test_utils::fake_keys};

use crate::file_downloader::MockFileDownloader;

Expand Down Expand Up @@ -507,6 +513,115 @@ mod tests {
);
}

#[tokio::test]
async fn download_unpack_must_warn_that_ancillary_not_signed_by_mithril_when_included() {
let (logger, log_inspector) = TestLogger::memory();
let total_immutable_files = 2;
let immutable_file_range = ImmutableFileRange::Range(1, total_immutable_files);
let target_dir = temp_dir_create!();
let artifact_downloader = InternalArtifactDownloader::new(
Arc::new(MockFileDownloader::new()),
None,
FeedbackSender::new(&[]),
logger,
);

let download_unpack_options = DownloadUnpackOptions {
include_ancillary: true,
..DownloadUnpackOptions::default()
};
let cardano_database_snapshot = CardanoDatabaseSnapshot {
hash: "hash-123".to_string(),
immutables: ImmutablesMessagePart {
average_size_uncompressed: 512,
locations: vec![ImmutablesLocation::CloudStorage {
uri: MultiFilesUri::Template(TemplateUri(
"http://whatever/{immutable_file_number}.tar.gz".to_string(),
)),
compression_algorithm: Some(CompressionAlgorithm::Gzip),
}],
},
ancillary: AncillaryMessagePart {
size_uncompressed: 2048,
locations: vec![AncillaryLocation::Unknown {}],
},
beacon: CardanoDbBeacon {
epoch: Epoch(123),
immutable_file_number: 2,
},
..CardanoDatabaseSnapshot::dummy()
};

let _ = artifact_downloader
.download_unpack(
&cardano_database_snapshot,
&immutable_file_range,
target_dir.as_path(),
download_unpack_options,
)
.await;

assert!(
log_inspector.contains_log(&format!("WARN {}", ANCILLARIES_NOT_SIGNED_BY_MITHRIL)),
"Expected log message not found, logs: {log_inspector}"
);
}

#[tokio::test]
async fn download_unpack_without_ancillary_must_warn_that_fast_boostrap_wont_be_available()
{
let (logger, log_inspector) = TestLogger::memory();
let total_immutable_files = 2;
let immutable_file_range = ImmutableFileRange::Range(1, total_immutable_files);
let target_dir = temp_dir_create!();
let artifact_downloader = InternalArtifactDownloader::new(
Arc::new(MockFileDownloader::new()),
None,
FeedbackSender::new(&[]),
logger,
);

let download_unpack_options = DownloadUnpackOptions {
include_ancillary: false,
..DownloadUnpackOptions::default()
};
let cardano_database_snapshot = CardanoDatabaseSnapshot {
hash: "hash-123".to_string(),
immutables: ImmutablesMessagePart {
average_size_uncompressed: 512,
locations: vec![ImmutablesLocation::CloudStorage {
uri: MultiFilesUri::Template(TemplateUri(
"http://whatever/{immutable_file_number}.tar.gz".to_string(),
)),
compression_algorithm: Some(CompressionAlgorithm::Gzip),
}],
},
ancillary: AncillaryMessagePart {
size_uncompressed: 2048,
locations: vec![AncillaryLocation::Unknown {}],
},
beacon: CardanoDbBeacon {
epoch: Epoch(123),
immutable_file_number: 2,
},
..CardanoDatabaseSnapshot::dummy()
};

let _ = artifact_downloader
.download_unpack(
&cardano_database_snapshot,
&immutable_file_range,
target_dir.as_path(),
download_unpack_options,
)
.await;

assert!(
log_inspector.contains_log("The fast bootstrap of the Cardano node is not available with the current parameters used in this command: the ledger state will be recomputed from genesis at startup of the Cardano node. Set the include_ancillary entry to true in the DownloadUnpackOptions."),
"Expected log message not found, logs: {log_inspector}"
);
}

#[tokio::test]
async fn building_ancillary_download_tasks_fails_if_all_locations_are_unknown() {
let target_dir = temp_dir_create!();
Expand Down
44 changes: 36 additions & 8 deletions mithril-client/src/snapshot_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ use crate::file_downloader::{DownloadEvent, FileDownloader};
use crate::utils::create_bootstrap_node_files;
#[cfg(feature = "fs")]
use crate::utils::AncillaryVerifier;
use crate::utils::ANCILLARIES_NOT_SIGNED_BY_MITHRIL;
use crate::{MithrilResult, Snapshot, SnapshotListItem};

/// Error for the Snapshot client
Expand Down Expand Up @@ -255,6 +256,10 @@ impl SnapshotClient {
snapshot: &Snapshot,
target_dir: &Path,
) -> MithrilResult<()> {
slog::warn!(
self.logger,
"The fast bootstrap of the Cardano node is not available with the current parameters used in this command: the ledger state will be recomputed from genesis at startup of the Cardano node. Use the extra function download_unpack_full to allow it."
);
use crate::feedback::MithrilEvent;
let download_id = MithrilEvent::new_snapshot_download_id();
self.download_unpack_immutables_files(snapshot, target_dir, &download_id)
Expand Down Expand Up @@ -296,10 +301,7 @@ impl SnapshotClient {
target_dir: &Path,
download_id: &str,
) -> MithrilResult<()> {
slog::info!(
self.logger,
"Ancillary verification doesn't use the Mithril certification: it is done with a signature made with an IOG owned key."
);
slog::warn!(self.logger, "{}", ANCILLARIES_NOT_SIGNED_BY_MITHRIL);

match &snapshot.ancillary_locations {
None => Ok(()),
Expand Down Expand Up @@ -622,6 +624,35 @@ mod tests {
}
}

mod download_unpack {
use super::*;

#[tokio::test]
async fn warn_that_fast_boostrap_is_not_available_without_ancillary_files() {
let (logger, log_inspector) = TestLogger::memory();
let snapshot = Snapshot::dummy();

let mut mock_downloader = MockFileDownloader::new();
mock_downloader
.expect_download_unpack()
.returning(|_, _, _, _, _| Ok(()));

let client = SnapshotClient {
logger,
..setup_snapshot_client(Arc::new(mock_downloader), None)
};

let _result = client
.download_unpack(&snapshot, &PathBuf::from("/whatever"))
.await;

assert!(
log_inspector.contains_log("WARN The fast bootstrap of the Cardano node is not available with the current parameters used in this command: the ledger state will be recomputed from genesis at startup of the Cardano node. Use the extra function download_unpack_full to allow it."),
"Expected log message not found, logs: {log_inspector}"
);
}
}

mod download_unpack_ancillary {
use mithril_common::crypto_helper::ManifestSigner;
use mithril_common::test_utils::fake_keys;
Expand Down Expand Up @@ -660,10 +691,7 @@ mod tests {
.unwrap();

assert!(
log_inspector.contains_log(
"Ancillary verification doesn't use the Mithril certification: it is \
done with a signature made with an IOG owned key."
),
log_inspector.contains_log(&format!("WARN {}", ANCILLARIES_NOT_SIGNED_BY_MITHRIL)),
"Expected log message not found, logs: {log_inspector}"
);
}
Expand Down
2 changes: 2 additions & 0 deletions mithril-client/src/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//! Utilities module
//! This module contains tools needed mostly for the snapshot download and unpack.

pub const ANCILLARIES_NOT_SIGNED_BY_MITHRIL:&str = "Ancillary verification does not use the Mithril certification: as a mitigation, IOG owned keys are used to sign these files.";

cfg_fs! {
mod ancillary_verifier;
mod stream_reader;
Expand Down
Loading