@@ -10,7 +10,9 @@ use std::{
10
10
sync:: Arc ,
11
11
} ;
12
12
13
- use mithril_client:: { ClientBuilder , MessageBuilder } ;
13
+ use mithril_client:: {
14
+ common:: ProtocolMessage , Client , ClientBuilder , MessageBuilder , MithrilCertificate , Snapshot ,
15
+ } ;
14
16
use mithril_client_cli:: {
15
17
configuration:: ConfigParameters ,
16
18
utils:: {
@@ -90,24 +92,86 @@ impl SnapshotDownloadCommand {
90
92
. await ?
91
93
. with_context ( || format ! ( "Can not get the snapshot for digest: '{}'" , self . digest) ) ?;
92
94
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,
95
115
& 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,
96
150
snapshot_message. size ,
97
151
snapshot_message. compression_algorithm . unwrap_or_default ( ) ,
98
152
) {
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) ?) ?;
100
155
}
101
156
102
- std:: fs:: create_dir_all ( & db_dir) . with_context ( || {
157
+ std:: fs:: create_dir_all ( db_dir) . with_context ( || {
103
158
format ! (
104
159
"Download: could not create target directory '{}'." ,
105
160
db_dir. display( )
106
161
)
107
162
} ) ?;
108
163
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 > {
109
173
progress_printer. report_step (
110
- 2 ,
174
+ step_number ,
111
175
"Fetching the certificate and verifying the certificate chain…" ,
112
176
) ?;
113
177
let certificate = client
@@ -117,25 +181,35 @@ impl SnapshotDownloadCommand {
117
181
. with_context ( || {
118
182
format ! (
119
183
"Can not verify the certificate chain from certificate_hash: '{}'" ,
120
- & snapshot_message. certificate_hash
184
+ snapshot_message. certificate_hash
121
185
)
122
186
} ) ?;
123
187
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…" ) ?;
125
199
client
126
200
. snapshot ( )
127
- . download_unpack ( & snapshot_message, & db_dir)
201
+ . download_unpack ( snapshot_message, db_dir)
128
202
. await
129
203
. with_context ( || {
130
204
format ! (
131
205
"Snapshot Service can not download and verify the snapshot for digest: '{}'" ,
132
- self . digest
206
+ snapshot_message . digest
133
207
)
134
208
} ) ?;
135
209
136
210
// The snapshot download does not fail if the statistic call fails.
137
211
// 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 {
139
213
warn ! ( "Could not POST snapshot download statistics: {e:?}" ) ;
140
214
}
141
215
@@ -147,21 +221,40 @@ impl SnapshotDownloadCommand {
147
221
) ;
148
222
} ;
149
223
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…" ) ?;
151
234
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) ,
154
237
)
155
238
. await
156
239
. with_context ( || {
157
240
format ! (
158
241
"Can not compute the snapshot message from the directory: '{:?}'" ,
159
- & db_dir
242
+ db_dir
160
243
)
161
244
} ) ?;
162
245
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) {
165
258
debug ! ( "Digest verification failed, removing unpacked files & directory." ) ;
166
259
167
260
return Err ( anyhow ! (
@@ -170,14 +263,22 @@ impl SnapshotDownloadCommand {
170
263
) ) ;
171
264
}
172
265
266
+ Ok ( ( ) )
267
+ }
268
+
269
+ fn log_download_information (
270
+ db_dir : & Path ,
271
+ snapshot_message : & Snapshot ,
272
+ json_output : bool ,
273
+ ) -> StdResult < ( ) > {
173
274
let canonicalized_filepath = & db_dir. canonicalize ( ) . with_context ( || {
174
275
format ! (
175
276
"Could not get canonicalized filepath of '{}'" ,
176
277
db_dir. display( )
177
278
)
178
279
} ) ?;
179
280
180
- if self . json {
281
+ if json_output {
181
282
println ! (
182
283
r#"{{"timestamp": "{}", "db_directory": "{}"}}"# ,
183
284
Utc :: now( ) . to_rfc3339( ) ,
@@ -186,18 +287,19 @@ impl SnapshotDownloadCommand {
186
287
} else {
187
288
println ! (
188
289
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,
198
299
db_dir. display( ) ,
199
300
snapshot_message
200
301
. cardano_node_version
302
+ . clone( )
201
303
. unwrap_or( "latest" . to_string( ) ) ,
202
304
canonicalized_filepath. display( ) ,
203
305
snapshot_message. beacon. network,
0 commit comments