@@ -11,7 +11,7 @@ use std::{
1111
1212use crate :: {
1313 commands:: { client_builder, SharedArgs } ,
14- configuration:: { ConfigError , ConfigSource } ,
14+ configuration:: { ConfigError , ConfigParameters , ConfigSource } ,
1515 utils:: {
1616 self , AncillaryLogMessage , CardanoDbDownloadChecker , CardanoDbUtils , ExpanderUtils ,
1717 IndicatifFeedbackReceiver , ProgressOutputType , ProgressPrinter ,
@@ -51,7 +51,7 @@ pub struct CardanoDbDownloadCommand {
5151 /// By default, only finalized immutable files are downloaded.
5252 /// The last ledger state snapshot and the last immutable file (the ancillary files) can be
5353 /// downloaded with this option.
54- #[ clap( long, requires = "ancillary_verification_key" ) ]
54+ #[ clap( long) ]
5555 include_ancillary : bool ,
5656
5757 /// Ancillary verification key to verify the ancillary files.
@@ -60,23 +60,50 @@ pub struct CardanoDbDownloadCommand {
6060}
6161
6262impl CardanoDbDownloadCommand {
63- /// Is JSON output enabled
64- pub fn is_json_output_enabled ( & self ) -> bool {
65- self . shared_args . json
66- }
67-
6863 /// Command execution
6964 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 {
7173 AncillaryLogMessage :: warn_ancillary_not_signed_by_mithril ( ) ;
74+ Some ( params. require ( "ancillary_verification_key" ) ?)
7275 } else {
7376 AncillaryLogMessage :: warn_fast_bootstrap_not_available ( ) ;
74- }
77+ None
78+ } ;
7579
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" ) ;
80107
81108 let progress_output_type = if self . is_json_output_enabled ( ) {
82109 ProgressOutputType :: JsonReporter
@@ -358,12 +385,19 @@ impl ConfigSource for CardanoDbDownloadCommand {
358385 ) ;
359386 }
360387
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+
361395 Ok ( map)
362396 }
363397}
364-
365398#[ cfg( test) ]
366399mod tests {
400+ use config:: ConfigBuilder ;
367401 use mithril_client:: {
368402 common:: { CardanoDbBeacon , ProtocolMessagePartKey , SignedEntityType } ,
369403 MithrilCertificateMetadata ,
@@ -398,14 +432,85 @@ mod tests {
398432 }
399433 }
400434
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+
401490 #[ 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+ ) ;
409514 }
410515
411516 #[ tokio:: test]
@@ -424,7 +529,7 @@ mod tests {
424529 "verify_cardano_db_signature_should_remove_db_dir_if_messages_mismatch" ,
425530 ) ;
426531
427- let result = CardanoDbDownloadCommand :: verify_cardano_db_signature (
532+ let result = PreparedCardanoDbDownload :: verify_cardano_db_signature (
428533 & Logger :: root ( slog:: Discard , slog:: o!( ) ) ,
429534 1 ,
430535 & progress_printer,
0 commit comments