Skip to content

Commit 8931101

Browse files
author
Damien LACHAUME / PALO-IT
committed
Refactor snapshot download command
- Split `execute` function - Use `mithril-client` types instead of `mithril-common` types
1 parent d7dcaa2 commit 8931101

File tree

4 files changed

+132
-44
lines changed

4 files changed

+132
-44
lines changed

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

Lines changed: 129 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ use std::{
1010
sync::Arc,
1111
};
1212

13-
use mithril_client::{ClientBuilder, MessageBuilder};
13+
use mithril_client::{
14+
common::ProtocolMessage, Client, ClientBuilder, MessageBuilder, MithrilCertificate, Snapshot,
15+
};
1416
use mithril_client_cli::{
1517
configuration::ConfigParameters,
1618
utils::{
@@ -90,24 +92,86 @@ impl SnapshotDownloadCommand {
9092
.await?
9193
.with_context(|| format!("Can not get the snapshot for digest: '{}'", self.digest))?;
9294

93-
progress_printer.report_step(1, "Checking local disk info…")?;
94-
if let Err(e) = SnapshotUnpacker::check_prerequisites(
95+
SnapshotDownloadCommand::check_local_disk_info(
96+
1,
97+
&progress_printer,
98+
&db_dir,
99+
&snapshot_message,
100+
)?;
101+
102+
let certificate = SnapshotDownloadCommand::fetching_certificate_and_verifying_chain(
103+
2,
104+
&progress_printer,
105+
&client,
106+
&snapshot_message,
107+
)
108+
.await?;
109+
110+
SnapshotDownloadCommand::downloading_and_unpacking_snapshot(
111+
3,
112+
&progress_printer,
113+
&client,
114+
&snapshot_message,
95115
&db_dir,
116+
)
117+
.await?;
118+
119+
let message = SnapshotDownloadCommand::computing_snapshot_digest(
120+
4,
121+
&progress_printer,
122+
&certificate,
123+
&db_dir,
124+
)
125+
.await?;
126+
127+
SnapshotDownloadCommand::verifying_snapshot_signature(
128+
5,
129+
&progress_printer,
130+
&certificate,
131+
&message,
132+
&snapshot_message,
133+
)
134+
.await?;
135+
136+
SnapshotDownloadCommand::log_download_information(&db_dir, &snapshot_message, self.json)?;
137+
138+
Ok(())
139+
}
140+
141+
fn check_local_disk_info(
142+
step_number: u16,
143+
progress_printer: &ProgressPrinter,
144+
db_dir: &PathBuf,
145+
snapshot_message: &Snapshot,
146+
) -> StdResult<()> {
147+
progress_printer.report_step(step_number, "Checking local disk info…")?;
148+
if let Err(e) = SnapshotUnpacker::check_prerequisites(
149+
db_dir,
96150
snapshot_message.size,
97151
snapshot_message.compression_algorithm.unwrap_or_default(),
98152
) {
99-
progress_printer.report_step(1, &SnapshotUtils::check_disk_space_error(e)?)?;
153+
progress_printer
154+
.report_step(step_number, &SnapshotUtils::check_disk_space_error(e)?)?;
100155
}
101156

102-
std::fs::create_dir_all(&db_dir).with_context(|| {
157+
std::fs::create_dir_all(db_dir).with_context(|| {
103158
format!(
104159
"Download: could not create target directory '{}'.",
105160
db_dir.display()
106161
)
107162
})?;
108163

164+
Ok(())
165+
}
166+
167+
async fn fetching_certificate_and_verifying_chain(
168+
step_number: u16,
169+
progress_printer: &ProgressPrinter,
170+
client: &Client,
171+
snapshot_message: &Snapshot,
172+
) -> StdResult<MithrilCertificate> {
109173
progress_printer.report_step(
110-
2,
174+
step_number,
111175
"Fetching the certificate and verifying the certificate chain…",
112176
)?;
113177
let certificate = client
@@ -117,25 +181,35 @@ impl SnapshotDownloadCommand {
117181
.with_context(|| {
118182
format!(
119183
"Can not verify the certificate chain from certificate_hash: '{}'",
120-
&snapshot_message.certificate_hash
184+
snapshot_message.certificate_hash
121185
)
122186
})?;
123187

124-
progress_printer.report_step(3, "Downloading and unpacking the snapshot…")?;
188+
Ok(certificate)
189+
}
190+
191+
async fn downloading_and_unpacking_snapshot(
192+
step_number: u16,
193+
progress_printer: &ProgressPrinter,
194+
client: &Client,
195+
snapshot_message: &Snapshot,
196+
db_dir: &Path,
197+
) -> StdResult<()> {
198+
progress_printer.report_step(step_number, "Downloading and unpacking the snapshot…")?;
125199
client
126200
.snapshot()
127-
.download_unpack(&snapshot_message, &db_dir)
201+
.download_unpack(snapshot_message, db_dir)
128202
.await
129203
.with_context(|| {
130204
format!(
131205
"Snapshot Service can not download and verify the snapshot for digest: '{}'",
132-
self.digest
206+
snapshot_message.digest
133207
)
134208
})?;
135209

136210
// The snapshot download does not fail if the statistic call fails.
137211
// It would be nice to implement tests to verify the behavior of `add_statistics`
138-
if let Err(e) = client.snapshot().add_statistics(&snapshot_message).await {
212+
if let Err(e) = client.snapshot().add_statistics(snapshot_message).await {
139213
warn!("Could not POST snapshot download statistics: {e:?}");
140214
}
141215

@@ -147,21 +221,40 @@ impl SnapshotDownloadCommand {
147221
);
148222
};
149223

150-
progress_printer.report_step(4, "Computing the snapshot digest…")?;
224+
Ok(())
225+
}
226+
227+
async fn computing_snapshot_digest(
228+
step_number: u16,
229+
progress_printer: &ProgressPrinter,
230+
certificate: &MithrilCertificate,
231+
db_dir: &Path,
232+
) -> StdResult<ProtocolMessage> {
233+
progress_printer.report_step(step_number, "Computing the snapshot digest…")?;
151234
let message = SnapshotUtils::wait_spinner(
152-
&progress_printer,
153-
MessageBuilder::new().compute_snapshot_message(&certificate, &db_dir),
235+
progress_printer,
236+
MessageBuilder::new().compute_snapshot_message(certificate, db_dir),
154237
)
155238
.await
156239
.with_context(|| {
157240
format!(
158241
"Can not compute the snapshot message from the directory: '{:?}'",
159-
&db_dir
242+
db_dir
160243
)
161244
})?;
162245

163-
progress_printer.report_step(5, "Verifying the snapshot signature…")?;
164-
if !certificate.match_message(&message) {
246+
Ok(message)
247+
}
248+
249+
async fn verifying_snapshot_signature(
250+
step_number: u16,
251+
progress_printer: &ProgressPrinter,
252+
certificate: &MithrilCertificate,
253+
message: &ProtocolMessage,
254+
snapshot_message: &Snapshot,
255+
) -> StdResult<()> {
256+
progress_printer.report_step(step_number, "Verifying the snapshot signature…")?;
257+
if !certificate.match_message(message) {
165258
debug!("Digest verification failed, removing unpacked files & directory.");
166259

167260
return Err(anyhow!(
@@ -170,14 +263,22 @@ impl SnapshotDownloadCommand {
170263
));
171264
}
172265

266+
Ok(())
267+
}
268+
269+
fn log_download_information(
270+
db_dir: &Path,
271+
snapshot_message: &Snapshot,
272+
json_output: bool,
273+
) -> StdResult<()> {
173274
let canonicalized_filepath = &db_dir.canonicalize().with_context(|| {
174275
format!(
175276
"Could not get canonicalized filepath of '{}'",
176277
db_dir.display()
177278
)
178279
})?;
179280

180-
if self.json {
281+
if json_output {
181282
println!(
182283
r#"{{"timestamp": "{}", "db_directory": "{}"}}"#,
183284
Utc::now().to_rfc3339(),
@@ -186,18 +287,19 @@ impl SnapshotDownloadCommand {
186287
} else {
187288
println!(
188289
r###"Snapshot '{}' has been unpacked and successfully checked against Mithril multi-signature contained in the certificate.
189-
190-
Files in the directory '{}' can be used to run a Cardano node with version >= {}.
191-
192-
If you are using Cardano Docker image, you can restore a Cardano Node with:
193-
194-
docker run -v cardano-node-ipc:/ipc -v cardano-node-data:/data --mount type=bind,source="{}",target=/data/db/ -e NETWORK={} inputoutput/cardano-node:8.1.2
195-
196-
"###,
197-
&self.digest,
290+
291+
Files in the directory '{}' can be used to run a Cardano node with version >= {}.
292+
293+
If you are using Cardano Docker image, you can restore a Cardano Node with:
294+
295+
docker run -v cardano-node-ipc:/ipc -v cardano-node-data:/data --mount type=bind,source="{}",target=/data/db/ -e NETWORK={} inputoutput/cardano-node:8.1.2
296+
297+
"###,
298+
snapshot_message.digest,
198299
db_dir.display(),
199300
snapshot_message
200301
.cardano_node_version
302+
.clone()
201303
.unwrap_or("latest".to_string()),
202304
canonicalized_filepath.display(),
203305
snapshot_message.beacon.network,

mithril-client-cli/src/commands/snapshot/list.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
use clap::Parser;
22
use cli_table::{format::Justify, print_stdout, Cell, Table};
33
use config::{builder::DefaultState, ConfigBuilder};
4-
use mithril_common::test_utils::fake_keys;
54
use slog_scope::logger;
65
use std::{collections::HashMap, sync::Arc};
76

87
use mithril_client::ClientBuilder;
9-
use mithril_client_cli::{common::StdResult, configuration::ConfigParameters};
8+
use mithril_client_cli::configuration::ConfigParameters;
9+
use mithril_common::{test_utils::fake_keys, StdResult};
1010

1111
/// Clap command to list existing snapshots
1212
#[derive(Parser, Debug, Clone)]

mithril-client-cli/src/lib.rs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,2 @@
11
pub mod configuration;
22
pub mod utils;
3-
4-
/// `mithril-common` re-exports
5-
pub mod common {
6-
pub use mithril_common::{
7-
certificate_chain::CertificateVerifier,
8-
crypto_helper::{ProtocolGenesisVerificationKey, ProtocolGenesisVerifier},
9-
entities::{Beacon, CompressionAlgorithm, Epoch},
10-
messages::{
11-
MithrilStakeDistributionListMessage, SnapshotListItemMessage, SnapshotListMessage,
12-
SnapshotMessage,
13-
},
14-
StdError, StdResult,
15-
};
16-
}

mithril-client-cli/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use std::io::Write;
1313
use std::sync::Arc;
1414
use std::{fs::File, path::PathBuf};
1515

16-
use mithril_client_cli::common::StdResult;
16+
use mithril_common::StdResult;
1717

1818
use commands::{
1919
mithril_stake_distribution::MithrilStakeDistributionCommands, snapshot::SnapshotCommands,

0 commit comments

Comments
 (0)