Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
b0b6397
feature(client-lib, client-cli): introduce a function to download dig…
Jul 7, 2025
a85291d
refactor(client-lib): move merkleproof creation and verification insi…
Jul 9, 2025
697cd27
refactor(client-lib): remove compute_merkle_proof since logic is move…
Jul 9, 2025
a9c46ad
feature(client-lib): list missing immutable files when computing card…
Jul 10, 2025
1e31827
feature(client-lib): add function in VerifiedDigests to list tampered…
Jul 10, 2025
5cea4b5
feature(client-lib): compute cardano database message verify tampered…
Jul 10, 2025
3fcc376
feature(client-lib): display 10 elements of each missing and/or tampe…
Jul 11, 2025
b169529
feature(client-cli): adapt call of compute_cardano_database_message t…
Jul 11, 2025
b16c830
feature(client-cli): display missing and/or tampered immutables when
Jul 11, 2025
a079f02
feature(client-lib,client-cli): add arg --allow-missing in cardano-db…
Jul 16, 2025
a968e4f
fix(examples): realign immutables range with release-preprod environment
Jul 16, 2025
fcf3902
feature(client-lib, examples): adapt examples with the new compute_ca…
Jul 16, 2025
e169998
docs: update mithril client doc with new verify command arguments
Jul 18, 2025
8fa8b81
feature(client-lib): return also list of non verified files in case o…
Jul 18, 2025
48c5e77
feature(client-cli): improve verify command output with non verifiabl…
Jul 21, 2025
04b98e6
refactoring(client-lib,client-cli): improve name of cardano database …
Jul 22, 2025
92f16be
refactoring(client-lib): reorganize imports
Jul 22, 2025
8c183f5
feature(client-lib): rename ComputeCardanoDatabaseMessageError errors…
Jul 22, 2025
a819599
refactoring(client-lib): improve function comment
Sep 1, 2025
9370314
chore: upgrade crate versions
Sep 2, 2025
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
6 changes: 3 additions & 3 deletions Cargo.lock

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

3 changes: 3 additions & 0 deletions docs/website/root/manual/develop/nodes/mithril-client.md
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,9 @@ Here is a list of the available parameters:
| `digest` | - | - | - | Digest of the Cardano db snapshot to verify or `latest` for the latest artifact | - | - | :heavy_check_mark: |
| `db_dir` | `--db-dir` | - | - | Directory from where the immutable will be verified | - | - | - |
| `genesis_verification_key` | `--genesis-verification-key` | - | `GENESIS_VERIFICATION_KEY` | Genesis verification key to check the certificate chain | - | - | - |
| `start` | `--start` | - | - | The first immutable file number to verify | - | - | - |
| `end` | `--end` | - | - | The last immutable file number to verify | - | - | - |
| `allow_missing` | `--allow-missing` | - | - | If set, the verification will not fail if some immutable files are missing | `false` | - | - |
| `run_mode` | `--run-mode` | - | `RUN_MODE` | Run Mode | `dev` | - | - |
| `verbose` | `--verbose` | `-v` | - | Verbosity level (-v=warning, -vv=info, -vvv=debug, -vvvv=trace) | `0` | - | - |
| `config_directory` | `--config-directory` | - | - | Directory where configuration file is located | `./config` | - | - |
Expand Down
2 changes: 1 addition & 1 deletion examples/client-cardano-database-v2/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "client-cardano-database-v2"
description = "Mithril client Cardano database example"
version = "0.0.12"
version = "0.0.13"
authors = ["[email protected]", "[email protected]"]
documentation = "https://mithril.network/doc"
edition = "2021"
Expand Down
39 changes: 21 additions & 18 deletions examples/client-cardano-database-v2/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use std::time::Duration;
use tokio::sync::RwLock;

use mithril_client::feedback::{FeedbackReceiver, MithrilEvent, MithrilEventCardanoDatabase};
use mithril_client::{ClientBuilder, MessageBuilder, MithrilResult};
use mithril_client::{ClientBuilder, MessageBuilder, MithrilError, MithrilResult};

#[derive(Parser, Debug)]
#[command(version)]
Expand Down Expand Up @@ -82,7 +82,7 @@ async fn main() -> MithrilResult<()> {
.verify_chain(&cardano_database_snapshot.certificate_hash)
.await?;

let immutable_file_range = ImmutableFileRange::From(15000);
let immutable_file_range = ImmutableFileRange::From(4000);
let download_unpack_options = DownloadUnpackOptions {
allow_override: true,
include_ancillary: true,
Expand All @@ -98,19 +98,11 @@ async fn main() -> MithrilResult<()> {
)
.await?;

println!("Computing Cardano database Merkle proof...",);
let merkle_proof = client
println!("Downloading and verifying digests file authenticity...");
let verified_digests = client
.cardano_database_v2()
.compute_merkle_proof(
&certificate,
&cardano_database_snapshot,
&immutable_file_range,
&unpacked_dir,
)
.download_and_verify_digests(&certificate, &cardano_database_snapshot)
.await?;
merkle_proof
.verify()
.with_context(|| "Merkle proof verification failed")?;

println!("Sending usage statistics to the aggregator...");
let full_restoration = immutable_file_range == ImmutableFileRange::Full;
Expand All @@ -133,9 +125,17 @@ async fn main() -> MithrilResult<()> {
"Computing Cardano database snapshot '{}' message...",
cardano_database_snapshot.hash
);
let allow_missing_immutables_files = false;
let message = wait_spinner(
&progress_bar,
MessageBuilder::new().compute_cardano_database_message(&certificate, &merkle_proof),
MessageBuilder::new().compute_cardano_database_message(
&certificate,
&cardano_database_snapshot,
&immutable_file_range,
allow_missing_immutables_files,
&unpacked_dir,
&verified_digests,
),
)
.await?;

Expand Down Expand Up @@ -261,10 +261,13 @@ fn get_temp_dir() -> MithrilResult<PathBuf> {
Ok(dir)
}

async fn wait_spinner<T>(
pub async fn wait_spinner<T, E>(
progress_bar: &MultiProgress,
future: impl Future<Output = MithrilResult<T>>,
) -> MithrilResult<T> {
future: impl Future<Output = Result<T, E>>,
) -> MithrilResult<T>
where
MithrilError: From<E>,
{
let pb = progress_bar.add(ProgressBar::new_spinner());
let spinner = async move {
loop {
Expand All @@ -275,6 +278,6 @@ async fn wait_spinner<T>(

tokio::select! {
_ = spinner => Err(anyhow!("timeout")),
res = future => res,
res = future => res.map_err(Into::into),
}
}
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.26"
version = "0.12.27"
description = "A Mithril Client"
authors = { workspace = true }
edition = { workspace = true }
Expand Down
26 changes: 20 additions & 6 deletions mithril-client-cli/src/commands/cardano_db/download/v2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ use mithril_client::{
use crate::{
CommandContext,
commands::{
cardano_db::{download::DB_DIRECTORY_NAME, shared_steps},
cardano_db::{
download::DB_DIRECTORY_NAME,
shared_steps::{self, ComputeCardanoDatabaseMessageOptions},
},
client_builder,
},
utils::{
Expand Down Expand Up @@ -124,22 +127,33 @@ impl PreparedCardanoDbV2Download {
)
})?;

let merkle_proof = shared_steps::compute_verify_merkle_proof(
let verified_digests = shared_steps::download_and_verify_digests(
4,
&progress_printer,
&client,
&certificate,
&cardano_db_message,
&restoration_options.immutable_file_range,
&restoration_options.db_dir,
)
.await?;
.await
.with_context(|| {
format!(
"Can not download and verify digests file for cardano db snapshot with hash: '{}'",
self.hash
)
})?;

let options = ComputeCardanoDatabaseMessageOptions {
db_dir: restoration_options.db_dir.clone(),
immutable_file_range: restoration_options.immutable_file_range,
allow_missing: false,
};
let message = shared_steps::compute_cardano_db_snapshot_message(
5,
&progress_printer,
&certificate,
&merkle_proof,
&cardano_db_message,
&options,
&verified_digests,
)
.await?;

Expand Down
49 changes: 26 additions & 23 deletions mithril-client-cli/src/commands/cardano_db/shared_steps.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
use anyhow::{Context, anyhow};
use chrono::Utc;
use slog::{Logger, debug, warn};
use std::path::Path;
use std::path::{Path, PathBuf};

use mithril_client::{
CardanoDatabaseSnapshot, Client, MessageBuilder, MithrilCertificate, MithrilResult,
cardano_database_client::ImmutableFileRange,
common::{ImmutableFileNumber, MKProof, ProtocolMessage},
cardano_database_client::{ImmutableFileRange, VerifiedDigests},
common::{ImmutableFileNumber, ProtocolMessage},
};

use crate::utils::{CardanoDbUtils, ProgressPrinter};

pub struct ComputeCardanoDatabaseMessageOptions {
pub db_dir: PathBuf,
pub immutable_file_range: ImmutableFileRange,
pub allow_missing: bool,
}

pub async fn fetch_certificate_and_verifying_chain(
step_number: u16,
progress_printer: &ProgressPrinter,
Expand Down Expand Up @@ -47,45 +53,42 @@ pub fn immutable_file_range(
}
}

/// Computes and verifies the Merkle proof for the given certificate and database snapshot.
pub async fn compute_verify_merkle_proof(
pub async fn download_and_verify_digests(
step_number: u16,
progress_printer: &ProgressPrinter,
client: &Client,
certificate: &MithrilCertificate,
cardano_database_snapshot: &CardanoDatabaseSnapshot,
immutable_file_range: &ImmutableFileRange,
unpacked_dir: &Path,
) -> MithrilResult<MKProof> {
progress_printer.report_step(step_number, "Computing and verifying the Merkle proof…")?;
let merkle_proof = client
) -> MithrilResult<VerifiedDigests> {
progress_printer.report_step(step_number, "Downloading and verifying digests…")?;
let verified_digests = client
.cardano_database_v2()
.compute_merkle_proof(
certificate,
cardano_database_snapshot,
immutable_file_range,
Path::new(&unpacked_dir),
)
.download_and_verify_digests(certificate, cardano_database_snapshot)
.await?;

merkle_proof
.verify()
.with_context(|| "Merkle proof verification failed")?;

Ok(merkle_proof)
Ok(verified_digests)
}

/// Computes the Cardano database snapshot message using the provided certificate and Merkle proof.
pub async fn compute_cardano_db_snapshot_message(
step_number: u16,
progress_printer: &ProgressPrinter,
certificate: &MithrilCertificate,
merkle_proof: &MKProof,
cardano_database_snapshot: &CardanoDatabaseSnapshot,
options: &ComputeCardanoDatabaseMessageOptions,
verified_digest: &VerifiedDigests,
) -> MithrilResult<ProtocolMessage> {
progress_printer.report_step(step_number, "Computing the cardano db snapshot message")?;
let message = CardanoDbUtils::wait_spinner(
progress_printer,
MessageBuilder::new().compute_cardano_database_message(certificate, merkle_proof),
MessageBuilder::new().compute_cardano_database_message(
certificate,
cardano_database_snapshot,
&options.immutable_file_range,
options.allow_missing,
&options.db_dir,
verified_digest,
),
)
.await
.with_context(|| "Can not compute the cardano db snapshot message")?;
Expand Down
Loading
Loading