Skip to content

Commit 38e4c3e

Browse files
authored
Merge pull request #2671 from input-output-hk/ctl/2618-list-invalid-or-missing-immutable-files-in-verify-command-REFACTORING
refactor: listing of invalid or missing immutable files in verify command
2 parents 9d9e963 + fa40323 commit 38e4c3e

File tree

14 files changed

+983
-858
lines changed

14 files changed

+983
-858
lines changed

Cargo.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/website/root/manual/develop/nodes/mithril-client-library.md

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -327,21 +327,32 @@ async fn main() -> mithril_client::MithrilResult<()> {
327327
.download_unpack(
328328
&snapshot,
329329
&immutable_file_range,
330-
target_directory,
330+
&target_directory,
331331
download_unpack_options,
332332
)
333333
.await?;
334334

335+
let verified_digests = client
336+
.cardano_database_v2()
337+
.download_and_verify_digests(
338+
&certificate,
339+
&snapshot
340+
)
341+
.await?;
342+
343+
let allow_missing_immutables_files = false;
335344
let merkle_proof = client
336345
.cardano_database_v2()
337-
.compute_merkle_proof(
346+
.verify_cardano_database(
338347
&certificate,
339348
&snapshot,
340349
&immutable_file_range,
341-
target_directory,
342-
)
343-
.await?;
344-
merkle_proof.verify()?;
350+
allow_missing_immutables_files,
351+
&target_directory,
352+
&verified_digest,
353+
),
354+
)
355+
.await?;
345356

346357
let message = MessageBuilder::new()
347358
.compute_cardano_database_message(&certificate, &merkle_proof)

examples/client-cardano-database-v2/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "client-cardano-database-v2"
33
description = "Mithril client Cardano database example"
4-
version = "0.0.13"
4+
version = "0.0.14"
55
66
documentation = "https://mithril.network/doc"
77
edition = "2021"

examples/client-cardano-database-v2/src/main.rs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -121,21 +121,27 @@ async fn main() -> MithrilResult<()> {
121121
println!("Could not send usage statistics to the aggregator: {e:?}");
122122
}
123123

124-
println!(
125-
"Computing Cardano database snapshot '{}' message...",
126-
cardano_database_snapshot.hash
127-
);
124+
println!("Verifying Cardano database...",);
128125
let allow_missing_immutables_files = false;
129-
let message = wait_spinner(
130-
&progress_bar,
131-
MessageBuilder::new().compute_cardano_database_message(
126+
let merkle_proof = client
127+
.cardano_database_v2()
128+
.verify_cardano_database(
132129
&certificate,
133130
&cardano_database_snapshot,
134131
&immutable_file_range,
135132
allow_missing_immutables_files,
136133
&unpacked_dir,
137134
&verified_digests,
138-
),
135+
)
136+
.await?;
137+
138+
println!(
139+
"Computing Cardano database snapshot '{}' message...",
140+
cardano_database_snapshot.hash
141+
);
142+
let message = wait_spinner(
143+
&progress_bar,
144+
MessageBuilder::new().compute_cardano_database_message(&certificate, &merkle_proof),
139145
)
140146
.await?;
141147

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.12.27"
3+
version = "0.12.28"
44
description = "A Mithril Client"
55
authors = { workspace = true }
66
edition = { workspace = true }

mithril-client-cli/src/commands/cardano_db/download/v2.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ impl PreparedCardanoDbV2Download {
6565
} else {
6666
ProgressOutputType::Tty
6767
};
68-
let progress_printer = ProgressPrinter::new(progress_output_type, 6);
68+
let progress_printer = ProgressPrinter::new(progress_output_type, 7);
6969
let client = client_builder(context.config_parameters())?
7070
.add_feedback_receiver(Arc::new(IndicatifFeedbackReceiver::new(
7171
progress_output_type,
@@ -147,19 +147,30 @@ impl PreparedCardanoDbV2Download {
147147
immutable_file_range: restoration_options.immutable_file_range,
148148
allow_missing: false,
149149
};
150-
let message = shared_steps::compute_cardano_db_snapshot_message(
150+
151+
let merkle_proof = shared_steps::verify_cardano_database(
151152
5,
152153
&progress_printer,
154+
&client,
153155
&certificate,
154156
&cardano_db_message,
155157
&options,
156158
&verified_digests,
157159
)
160+
.await
161+
.with_context(|| format!("Can not verify cardano database for hash: '{}'", self.hash))?;
162+
163+
let message = shared_steps::compute_cardano_db_snapshot_message(
164+
6,
165+
&progress_printer,
166+
&certificate,
167+
&merkle_proof,
168+
)
158169
.await?;
159170

160171
shared_steps::verify_message_matches_certificate(
161172
context.logger(),
162-
6,
173+
7,
163174
&progress_printer,
164175
&certificate,
165176
&message,

mithril-client-cli/src/commands/cardano_db/shared_steps.rs

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::path::{Path, PathBuf};
66
use mithril_client::{
77
CardanoDatabaseSnapshot, Client, MessageBuilder, MithrilCertificate, MithrilResult,
88
cardano_database_client::{ImmutableFileRange, VerifiedDigests},
9-
common::{ImmutableFileNumber, ProtocolMessage},
9+
common::{ImmutableFileNumber, MKProof, ProtocolMessage},
1010
};
1111

1212
use crate::utils::{CardanoDbUtils, ProgressPrinter};
@@ -69,19 +69,19 @@ pub async fn download_and_verify_digests(
6969
Ok(verified_digests)
7070
}
7171

72-
/// Computes the Cardano database snapshot message using the provided certificate and Merkle proof.
73-
pub async fn compute_cardano_db_snapshot_message(
72+
pub async fn verify_cardano_database(
7473
step_number: u16,
7574
progress_printer: &ProgressPrinter,
75+
client: &Client,
7676
certificate: &MithrilCertificate,
7777
cardano_database_snapshot: &CardanoDatabaseSnapshot,
7878
options: &ComputeCardanoDatabaseMessageOptions,
7979
verified_digest: &VerifiedDigests,
80-
) -> MithrilResult<ProtocolMessage> {
81-
progress_printer.report_step(step_number, "Computing the cardano db snapshot message")?;
82-
let message = CardanoDbUtils::wait_spinner(
80+
) -> MithrilResult<MKProof> {
81+
progress_printer.report_step(step_number, "Verifying the cardano database")?;
82+
let merkle_proof = CardanoDbUtils::wait_spinner(
8383
progress_printer,
84-
MessageBuilder::new().compute_cardano_database_message(
84+
client.cardano_database_v2().verify_cardano_database(
8585
certificate,
8686
cardano_database_snapshot,
8787
&options.immutable_file_range,
@@ -91,6 +91,24 @@ pub async fn compute_cardano_db_snapshot_message(
9191
),
9292
)
9393
.await
94+
.with_context(|| "Can not verify the cardano database")?;
95+
96+
Ok(merkle_proof)
97+
}
98+
99+
/// Computes the Cardano database snapshot message using the provided certificate and Merkle proof.
100+
pub async fn compute_cardano_db_snapshot_message(
101+
step_number: u16,
102+
progress_printer: &ProgressPrinter,
103+
certificate: &MithrilCertificate,
104+
merkle_proof: &MKProof,
105+
) -> MithrilResult<ProtocolMessage> {
106+
progress_printer.report_step(step_number, "Computing the cardano db snapshot message")?;
107+
let message = CardanoDbUtils::wait_spinner(
108+
progress_printer,
109+
MessageBuilder::new().compute_cardano_database_message(certificate, merkle_proof),
110+
)
111+
.await
94112
.with_context(|| "Can not compute the cardano db snapshot message")?;
95113

96114
Ok(message)

mithril-client-cli/src/commands/cardano_db/verify.rs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ use anyhow::Context;
88
use chrono::{DateTime, Utc};
99
use clap::Parser;
1010
use mithril_client::{
11-
CardanoDatabaseSnapshot, ComputeCardanoDatabaseMessageError, ImmutableVerificationResult,
12-
MithrilResult, cardano_database_client::ImmutableFileRange, common::ImmutableFileNumber,
11+
CardanoDatabaseSnapshot, MithrilResult,
12+
cardano_database_client::ImmutableFileRange,
13+
cardano_database_client::{CardanoDatabaseVerificationError, ImmutableVerificationResult},
14+
common::ImmutableFileNumber,
1315
};
1416

1517
use crate::{
@@ -85,7 +87,7 @@ impl CardanoDbVerifyCommand {
8587
} else {
8688
ProgressOutputType::Tty
8789
};
88-
let progress_printer = ProgressPrinter::new(progress_output_type, 4);
90+
let progress_printer = ProgressPrinter::new(progress_output_type, 5);
8991
let client = client_builder(context.config_parameters())?
9092
.add_feedback_receiver(Arc::new(IndicatifFeedbackReceiver::new(
9193
progress_output_type,
@@ -146,19 +148,21 @@ impl CardanoDbVerifyCommand {
146148
immutable_file_range,
147149
allow_missing: self.allow_missing,
148150
};
149-
let message = shared_steps::compute_cardano_db_snapshot_message(
151+
152+
let merkle_proof = shared_steps::verify_cardano_database(
150153
3,
151154
&progress_printer,
155+
&client,
152156
&certificate,
153157
&cardano_db_message,
154158
&options,
155159
&verified_digests,
156160
)
157161
.await;
158162

159-
match message {
160-
Err(e) => match e.downcast_ref::<ComputeCardanoDatabaseMessageError>() {
161-
Some(ComputeCardanoDatabaseMessageError::ImmutableFilesVerification(lists)) => {
163+
match merkle_proof {
164+
Err(e) => match e.downcast_ref::<CardanoDatabaseVerificationError>() {
165+
Some(CardanoDatabaseVerificationError::ImmutableFilesVerification(lists)) => {
162166
Self::print_immutables_verification_error(
163167
lists,
164168
context.is_json_output_enabled(),
@@ -167,10 +171,18 @@ impl CardanoDbVerifyCommand {
167171
}
168172
_ => Err(e),
169173
},
170-
Ok(message) => {
174+
Ok(merkle_proof) => {
175+
let message = shared_steps::compute_cardano_db_snapshot_message(
176+
4,
177+
&progress_printer,
178+
&certificate,
179+
&merkle_proof,
180+
)
181+
.await?;
182+
171183
shared_steps::verify_message_matches_certificate(
172184
&context.logger().clone(),
173-
4,
185+
5,
174186
&progress_printer,
175187
&certificate,
176188
&message,

mithril-client/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"
3-
version = "0.12.28"
3+
version = "0.12.29"
44
description = "Mithril client library"
55
authors = { workspace = true }
66
edition = { workspace = true }

mithril-client/src/cardano_database_client/api.rs

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,17 @@ use std::sync::Arc;
66
use slog::Logger;
77

88
#[cfg(feature = "fs")]
9-
use mithril_common::messages::{CardanoDatabaseSnapshotMessage, CertificateMessage};
9+
use mithril_common::{
10+
crypto_helper::MKProof,
11+
messages::{CardanoDatabaseSnapshotMessage, CertificateMessage},
12+
};
1013

1114
#[cfg(feature = "fs")]
1215
use mithril_cardano_node_internal_database::entities::ImmutableFile;
1316

1417
use crate::aggregator_client::AggregatorClient;
1518
#[cfg(feature = "fs")]
16-
use crate::cardano_database_client::VerifiedDigests;
19+
use crate::cardano_database_client::{VerifiedDigests, proving::CardanoDatabaseVerificationError};
1720
#[cfg(feature = "fs")]
1821
use crate::feedback::FeedbackSender;
1922
#[cfg(feature = "fs")]
@@ -111,6 +114,29 @@ impl CardanoDatabaseClient {
111114
.await
112115
}
113116

117+
/// Verify a local cardano database
118+
#[cfg(feature = "fs")]
119+
pub async fn verify_cardano_database(
120+
&self,
121+
certificate: &CertificateMessage,
122+
cardano_database_snapshot: &CardanoDatabaseSnapshotMessage,
123+
immutable_file_range: &ImmutableFileRange,
124+
allow_missing: bool,
125+
database_dir: &Path,
126+
verified_digests: &VerifiedDigests,
127+
) -> Result<MKProof, CardanoDatabaseVerificationError> {
128+
self.artifact_prover
129+
.verify_cardano_database(
130+
certificate,
131+
cardano_database_snapshot,
132+
immutable_file_range,
133+
allow_missing,
134+
database_dir,
135+
verified_digests,
136+
)
137+
.await
138+
}
139+
114140
/// Checks if immutable directory exists with at least one immutable in it
115141
#[cfg(feature = "fs")]
116142
pub fn check_has_immutables(&self, database_dir: &Path) -> MithrilResult<()> {
@@ -157,6 +183,8 @@ pub(crate) mod test_dependency_injector {
157183
ancillary_verifier: Option<Arc<AncillaryVerifier>>,
158184
#[cfg(feature = "fs")]
159185
feedback_receivers: Vec<Arc<dyn FeedbackReceiver>>,
186+
#[cfg(feature = "fs")]
187+
logger: Logger,
160188
}
161189

162190
impl CardanoDatabaseClientDependencyInjector {
@@ -175,9 +203,17 @@ pub(crate) mod test_dependency_injector {
175203
ancillary_verifier: None,
176204
#[cfg(feature = "fs")]
177205
feedback_receivers: vec![],
206+
#[cfg(feature = "fs")]
207+
logger: TestLogger::stdout(),
178208
}
179209
}
180210

211+
#[cfg(feature = "fs")]
212+
pub(crate) fn with_logger(self, logger: Logger) -> Self {
213+
#[cfg(feature = "fs")]
214+
Self { logger, ..self }
215+
}
216+
181217
pub(crate) fn with_aggregator_client_mock_config<F>(mut self, config: F) -> Self
182218
where
183219
F: FnOnce(&mut MockAggregatorClient),
@@ -230,7 +266,7 @@ pub(crate) mod test_dependency_injector {
230266
self.http_file_downloader,
231267
self.ancillary_verifier,
232268
FeedbackSender::new(&self.feedback_receivers),
233-
TestLogger::stdout(),
269+
self.logger,
234270
)
235271
}
236272

0 commit comments

Comments
 (0)