@@ -11,7 +11,7 @@ use std::{
11
11
12
12
use crate :: {
13
13
commands:: { client_builder, SharedArgs } ,
14
- configuration:: { ConfigError , ConfigSource } ,
14
+ configuration:: { ConfigError , ConfigParameters , ConfigSource } ,
15
15
utils:: {
16
16
self , AncillaryLogMessage , CardanoDbDownloadChecker , CardanoDbUtils , ExpanderUtils ,
17
17
IndicatifFeedbackReceiver , ProgressOutputType , ProgressPrinter ,
@@ -51,7 +51,7 @@ pub struct CardanoDbDownloadCommand {
51
51
/// By default, only finalized immutable files are downloaded.
52
52
/// The last ledger state snapshot and the last immutable file (the ancillary files) can be
53
53
/// downloaded with this option.
54
- #[ clap( long, requires = "ancillary_verification_key" ) ]
54
+ #[ clap( long) ]
55
55
include_ancillary : bool ,
56
56
57
57
/// Ancillary verification key to verify the ancillary files.
@@ -60,23 +60,50 @@ pub struct CardanoDbDownloadCommand {
60
60
}
61
61
62
62
impl CardanoDbDownloadCommand {
63
- /// Is JSON output enabled
64
- pub fn is_json_output_enabled ( & self ) -> bool {
65
- self . shared_args . json
66
- }
67
-
68
63
/// Command execution
69
64
pub async fn execute ( & self , context : CommandContext ) -> MithrilResult < ( ) > {
70
- if self . include_ancillary {
65
+ let params = context. config_parameters ( ) ?. add_source ( self ) ?;
66
+ let prepared_command = self . prepare ( & params) ?;
67
+
68
+ prepared_command. execute ( context. logger ( ) , params) . await
69
+ }
70
+
71
+ fn prepare ( & self , params : & ConfigParameters ) -> MithrilResult < PreparedCardanoDbDownload > {
72
+ let ancillary_verification_key = if self . include_ancillary {
71
73
AncillaryLogMessage :: warn_ancillary_not_signed_by_mithril ( ) ;
74
+ Some ( params. require ( "ancillary_verification_key" ) ?)
72
75
} else {
73
76
AncillaryLogMessage :: warn_fast_bootstrap_not_available ( ) ;
74
- }
77
+ None
78
+ } ;
75
79
76
- let params = context. config_parameters ( ) ?. add_source ( self ) ?;
77
- let download_dir: & String = & params. require ( "download_dir" ) ?;
78
- let db_dir = Path :: new ( download_dir) . join ( "db" ) ;
79
- let logger = context. logger ( ) ;
80
+ Ok ( PreparedCardanoDbDownload {
81
+ shared_args : self . shared_args . clone ( ) ,
82
+ digest : self . digest . clone ( ) ,
83
+ download_dir : params. require ( "download_dir" ) ?,
84
+ include_ancillary : self . include_ancillary ,
85
+ ancillary_verification_key,
86
+ } )
87
+ }
88
+ }
89
+
90
+ #[ derive( Debug , Clone ) ]
91
+ struct PreparedCardanoDbDownload {
92
+ shared_args : SharedArgs ,
93
+ digest : String ,
94
+ download_dir : String ,
95
+ include_ancillary : bool ,
96
+ ancillary_verification_key : Option < String > ,
97
+ }
98
+
99
+ impl PreparedCardanoDbDownload {
100
+ fn is_json_output_enabled ( & self ) -> bool {
101
+ self . shared_args . json
102
+ }
103
+
104
+ /// Command execution
105
+ pub async fn execute ( & self , logger : & Logger , params : ConfigParameters ) -> MithrilResult < ( ) > {
106
+ let db_dir = Path :: new ( & self . download_dir ) . join ( "db" ) ;
80
107
81
108
let progress_output_type = if self . is_json_output_enabled ( ) {
82
109
ProgressOutputType :: JsonReporter
@@ -358,12 +385,19 @@ impl ConfigSource for CardanoDbDownloadCommand {
358
385
) ;
359
386
}
360
387
388
+ if let Some ( ancillary_verification_key) = self . ancillary_verification_key . clone ( ) {
389
+ map. insert (
390
+ "ancillary_verification_key" . to_string ( ) ,
391
+ ancillary_verification_key,
392
+ ) ;
393
+ }
394
+
361
395
Ok ( map)
362
396
}
363
397
}
364
-
365
398
#[ cfg( test) ]
366
399
mod tests {
400
+ use config:: ConfigBuilder ;
367
401
use mithril_client:: {
368
402
common:: { CardanoDbBeacon , ProtocolMessagePartKey , SignedEntityType } ,
369
403
MithrilCertificateMetadata ,
@@ -398,14 +432,85 @@ mod tests {
398
432
}
399
433
}
400
434
435
+ fn dummy_command ( ) -> CardanoDbDownloadCommand {
436
+ CardanoDbDownloadCommand {
437
+ shared_args : SharedArgs { json : false } ,
438
+ digest : "whatever_digest" . to_string ( ) ,
439
+ download_dir : Some ( std:: path:: PathBuf :: from ( "whatever_dir" ) ) ,
440
+ genesis_verification_key : "whatever" . to_string ( ) . into ( ) ,
441
+ include_ancillary : true ,
442
+ ancillary_verification_key : "whatever" . to_string ( ) . into ( ) ,
443
+ }
444
+ }
445
+
446
+ #[ tokio:: test]
447
+ async fn ancillary_verification_key_is_mandatory_when_include_ancillary_is_true ( ) {
448
+ let command = CardanoDbDownloadCommand {
449
+ include_ancillary : true ,
450
+ ancillary_verification_key : None ,
451
+ ..dummy_command ( )
452
+ } ;
453
+ let command_context = CommandContext :: new (
454
+ ConfigBuilder :: default ( ) ,
455
+ false ,
456
+ Logger :: root ( slog:: Discard , slog:: o!( ) ) ,
457
+ ) ;
458
+
459
+ let result = command. execute ( command_context) . await ;
460
+
461
+ assert ! ( result. is_err( ) ) ;
462
+ assert_eq ! (
463
+ result. unwrap_err( ) . to_string( ) ,
464
+ "Parameter 'ancillary_verification_key' is mandatory."
465
+ ) ;
466
+ }
467
+
468
+ #[ test]
469
+ fn ancillary_verification_key_can_be_read_through_configuration_file ( ) {
470
+ let command = CardanoDbDownloadCommand {
471
+ ancillary_verification_key : None ,
472
+ ..dummy_command ( )
473
+ } ;
474
+ let config = config:: Config :: builder ( )
475
+ . set_default ( "ancillary_verification_key" , "value from config" )
476
+ . expect ( "Failed to build config builder" ) ;
477
+ let command_context =
478
+ CommandContext :: new ( config, false , Logger :: root ( slog:: Discard , slog:: o!( ) ) ) ;
479
+ let config_parameters = command_context
480
+ . config_parameters ( )
481
+ . unwrap ( )
482
+ . add_source ( & command)
483
+ . unwrap ( ) ;
484
+
485
+ let result = command. prepare ( & config_parameters) ;
486
+
487
+ assert ! ( result. is_ok( ) ) ;
488
+ }
489
+
401
490
#[ test]
402
- fn ancillary_verification_key_is_mandatory_when_include_ancillary_is_true ( ) {
403
- CardanoDbDownloadCommand :: try_parse_from ( [
404
- "cdbv1-command" ,
405
- "--include-ancillary" ,
406
- "whatever_digest" ,
407
- ] )
408
- . expect_err ( "The command should fail because ancillary_verification_key is not set" ) ;
491
+ fn db_download_dir_is_mandatory_to_execute_command ( ) {
492
+ let command = CardanoDbDownloadCommand {
493
+ download_dir : None ,
494
+ ..dummy_command ( )
495
+ } ;
496
+ let command_context = CommandContext :: new (
497
+ ConfigBuilder :: default ( ) ,
498
+ false ,
499
+ Logger :: root ( slog:: Discard , slog:: o!( ) ) ,
500
+ ) ;
501
+ let config_parameters = command_context
502
+ . config_parameters ( )
503
+ . unwrap ( )
504
+ . add_source ( & command)
505
+ . unwrap ( ) ;
506
+
507
+ let result = command. prepare ( & config_parameters) ;
508
+
509
+ assert ! ( result. is_err( ) ) ;
510
+ assert_eq ! (
511
+ result. unwrap_err( ) . to_string( ) ,
512
+ "Parameter 'download_dir' is mandatory."
513
+ ) ;
409
514
}
410
515
411
516
#[ tokio:: test]
@@ -424,7 +529,7 @@ mod tests {
424
529
"verify_cardano_db_signature_should_remove_db_dir_if_messages_mismatch" ,
425
530
) ;
426
531
427
- let result = CardanoDbDownloadCommand :: verify_cardano_db_signature (
532
+ let result = PreparedCardanoDbDownload :: verify_cardano_db_signature (
428
533
& Logger :: root ( slog:: Discard , slog:: o!( ) ) ,
429
534
1 ,
430
535
& progress_printer,
0 commit comments