@@ -35,6 +35,15 @@ use tracing::{error, info, warn};
3535
3636type OutputVec = Vec < [ u32 ; 8 ] > ;
3737
38+ fn parse_usize_ge1 ( s : & str ) -> Result < usize , String > {
39+ let v: usize = s. parse ( ) . map_err ( |_| "must be a number" . to_string ( ) ) ?;
40+ if v >= 1 {
41+ Ok ( v)
42+ } else {
43+ Err ( "must be >= 1" . into ( ) )
44+ }
45+ }
46+
3847#[ derive( Parser , Debug ) ]
3948#[ clap( author, version, about, long_about = None ) ]
4049struct Args {
@@ -74,11 +83,11 @@ struct Args {
7483 #[ clap(
7584 long = "n_proof_attempts" ,
7685 help = "Number of attempts for proving, in case the proof verification fails." ,
77- default_value_t = 1 ,
86+ default_value_t = 1usize ,
7887 requires = "verify" ,
79- value_parser = clap :: value_parser! ( u16 ) . range ( 1 .. )
88+ value_parser = parse_usize_ge1
8089 ) ]
81- n_proof_attempts : u16 ,
90+ n_proof_attempts : usize ,
8291 #[ clap( long = "verify" , help = "Should verify the generated proof." ) ]
8392 verify : bool ,
8493 #[ clap(
@@ -123,7 +132,7 @@ struct ProveConfig {
123132 proofs_dir : PathBuf ,
124133 proof_format : ProofFormat ,
125134 verify : bool ,
126- n_proof_attempts : u16 ,
135+ n_proof_attempts : usize ,
127136 prover_params_json : Option < PathBuf > ,
128137}
129138
@@ -261,6 +270,7 @@ fn prove_with_retries(
261270 i + 1 ,
262271 prove_config. n_proof_attempts
263272 ) ;
273+ return Err ( StwoRunAndProveError :: Verification ) ;
264274 }
265275
266276 Err ( e) => return Err ( e) ,
@@ -416,7 +426,12 @@ mod tests {
416426 current_path. join ( RESOURCES_PATH ) . join ( file_name)
417427 }
418428
419- fn prepare_args ( n_proof_attempts : u16 ) -> ( Args , TempPath , TempDir ) {
429+ fn is_file_empty ( path : & PathBuf ) -> std:: io:: Result < bool > {
430+ let metadata = fs:: metadata ( path) ?;
431+ Ok ( metadata. len ( ) == 0 )
432+ }
433+
434+ fn prepare_args ( n_proof_attempts : usize ) -> ( Args , TempPath , TempDir ) {
420435 let program_output_tempfile = NamedTempFile :: new ( )
421436 . expect ( "Failed to create temp file for program output" )
422437 . into_temp_path ( ) ;
@@ -435,7 +450,10 @@ mod tests {
435450 ( args, program_output_tempfile, proofs_tempdir)
436451 }
437452
438- fn run_stwo_run_and_prove ( args : Args , prover : Box < dyn ProverTrait > ) {
453+ fn run_stwo_run_and_prove (
454+ args : Args ,
455+ prover : Box < dyn ProverTrait > ,
456+ ) -> Result < ( ) , StwoRunAndProveError > {
439457 let prove_config = ProveConfig {
440458 verify : args. verify ,
441459 proofs_dir : args. proofs_dir ,
@@ -451,30 +469,54 @@ mod tests {
451469 prove_config,
452470 prover,
453471 )
454- . expect ( "Failed to run stwo_run_and_prove." ) ;
455472 }
456473
457- fn run_with_successful_mock_prover ( ) -> ( TempPath , TempDir ) {
458- let ( args, program_output_tempfile, proofs_tempdir) = prepare_args ( 1 ) ;
474+ fn run_with_successful_mock_prover ( n_proof_attempts : usize ) -> ( TempPath , TempDir ) {
475+ let ( args, program_output_tempfile, proofs_tempdir) = prepare_args ( n_proof_attempts ) ;
459476
460477 let mut mock_prover = Box :: new ( MockProverTrait :: new ( ) ) ;
461478 mock_prover
462479 . expect_choose_channel_and_prove ( )
463- . times ( 1 )
480+ . times ( n_proof_attempts )
464481 . returning ( move |_, proof_file, _, _, _| {
465482 let expected_proof_file = get_path ( EXPECTED_PROOF_FILE_NAME ) ;
466483 fs:: copy ( & expected_proof_file, & proof_file) . expect ( "Failed to copy proof file." ) ;
467484 Ok ( vec ! [ ARRAY_SUM_EXPECTED_OUTPUT ] )
468485 } ) ;
469486
470- run_stwo_run_and_prove ( args, mock_prover) ;
487+ run_stwo_run_and_prove ( args, mock_prover) . expect ( "failed to run stwo_run_and_prove" ) ;
488+
489+ ( program_output_tempfile, proofs_tempdir)
490+ }
491+
492+ fn run_with_verification_error_mock_prover ( n_proof_attempts : usize ) -> ( TempPath , TempDir ) {
493+ let ( args, program_output_tempfile, proofs_tempdir) = prepare_args ( n_proof_attempts) ;
494+
495+ let mut mock_prover = Box :: new ( MockProverTrait :: new ( ) ) ;
496+ mock_prover
497+ . expect_choose_channel_and_prove ( )
498+ . times ( n_proof_attempts)
499+ . returning ( move |_, proof_file, _, _, _| {
500+ let expected_proof_file = get_path ( EXPECTED_PROOF_FILE_NAME ) ;
501+ fs:: copy ( & expected_proof_file, & proof_file) . expect ( "Failed to copy proof file." ) ;
502+ Err ( StwoRunAndProveError :: Verification )
503+ } ) ;
504+
505+ let result = run_stwo_run_and_prove ( args, mock_prover) ;
506+ assert ! (
507+ matches!( result, Err ( StwoRunAndProveError :: Verification ) ) ,
508+ "run and prove should return StwoRunAndProveError::Verification error but got: {:?}" ,
509+ result,
510+ ) ;
471511
472512 ( program_output_tempfile, proofs_tempdir)
473513 }
474514
475515 #[ test]
476- fn test_stwo_run_and_prove_proof ( ) {
477- let ( _, proofs_temp_dir) = run_with_successful_mock_prover ( ) ;
516+ fn test_stwo_run_and_prove ( ) {
517+ let ( output_temp_file, proofs_temp_dir) = run_with_successful_mock_prover ( 1 ) ;
518+
519+ // Verifying the proof content.
478520 let proof_file = proofs_temp_dir
479521 . path ( )
480522 . to_path_buf ( )
@@ -487,11 +529,8 @@ mod tests {
487529 proof_content, expected_proof_content,
488530 "Proof content does not match expected proof content"
489531 ) ;
490- }
491532
492- #[ test]
493- fn test_stwo_run_and_prove_output ( ) {
494- let ( output_temp_file, _) = run_with_successful_mock_prover ( ) ;
533+ // Verifying the proof output.
495534 let output_content =
496535 std:: fs:: read_to_string ( output_temp_file) . expect ( "Failed to read output file" ) ;
497536 let output_vec: OutputVec =
@@ -502,8 +541,26 @@ mod tests {
502541 ARRAY_SUM_EXPECTED_OUTPUT
503542 ) ;
504543 }
544+
545+ #[ test]
546+ fn test_stwo_run_and_prove_retries ( ) {
547+ let ( output_temp_file, proofs_temp_dir) = run_with_verification_error_mock_prover ( 3 ) ;
548+ let proofs_dir = proofs_temp_dir. path ( ) . to_path_buf ( ) ;
549+
550+ for i in 0 ..3 {
551+ let proof_file = proofs_dir. join ( format ! ( "proof_{}" , i) ) ;
552+ assert ! (
553+ proof_file. exists( ) ,
554+ "Proof file {:?} should exist after running with verifier failures" ,
555+ i + 1 ,
556+ ) ;
557+ }
558+ assert ! (
559+ is_file_empty( & output_temp_file. to_path_buf( ) ) . unwrap( ) ,
560+ "Output file should be empty after running with verifier failures" ,
561+ ) ;
562+ }
505563}
506564
507565// TODO(nitsan): Tests -
508- // add a retries test
509566// add an inner test to choose_channel_and_prove
0 commit comments