@@ -14,6 +14,7 @@ use clap::Parser;
1414use mockall:: automock;
1515use serde:: Serialize ;
1616use std:: env;
17+ use std:: fs;
1718use std:: io:: Write ;
1819use std:: path:: PathBuf ;
1920use stwo_cairo_adapter:: ProverInput ;
@@ -35,6 +36,10 @@ use stwo_cairo_utils::file_utils::{IoErrorWithPath, create_file, read_to_string}
3536use thiserror:: Error ;
3637use tracing:: { error, info, warn} ;
3738
39+ static PROOF_PREFIX : & str = "proof_" ;
40+ static SUCCESS_SUFFIX : & str = "_success" ;
41+ static FAILURE_SUFFIX : & str = "_failure" ;
42+
3843fn parse_usize_ge1 ( s : & str ) -> Result < usize , String > {
3944 let v: usize = s. parse ( ) . map_err ( |_| "must be a number" . to_string ( ) ) ?;
4045 if v >= 1 {
@@ -205,7 +210,7 @@ fn stwo_run_and_prove(
205210 program_output : Option < PathBuf > ,
206211 prove_config : ProveConfig ,
207212 prover : Box < dyn ProverTrait > ,
208- ) -> Result < usize , StwoRunAndProveError > {
213+ ) -> Result < ( ) , StwoRunAndProveError > {
209214 let cairo_run_config = get_cairo_run_config (
210215 // we don't use dynamic layout in stwo
211216 & None ,
@@ -228,13 +233,13 @@ fn stwo_run_and_prove(
228233 info ! ( "Running cairo run program." ) ;
229234 let runner = cairo_run_program ( & program, program_input, cairo_run_config) ?;
230235 info ! ( "Adapting prover input." ) ;
231- let prover_input = adapter ( & runner) ;
232- let successful_proof_attempt = prove_with_retries ( prover_input, prove_config, prover) ?;
236+ let prover_input: ProverInput = adapter ( & runner) ;
237+ prove_with_retries ( prover_input, prove_config, prover) ?;
233238 if let Some ( output_path) = program_output {
234239 write_output_to_file ( runner, output_path) ?;
235240 }
236241
237- Ok ( successful_proof_attempt )
242+ Ok ( ( ) )
238243}
239244
240245/// Prepares the prover parameters and generates proof given the prover input and parameters.
@@ -245,7 +250,7 @@ fn prove_with_retries(
245250 prover_input : ProverInput ,
246251 prove_config : ProveConfig ,
247252 prover : Box < dyn ProverTrait > ,
248- ) -> Result < usize , StwoRunAndProveError > {
253+ ) -> Result < ( ) , StwoRunAndProveError > {
249254 let prover_params = match prove_config. prover_params_json {
250255 Some ( ref path) => sonic_rs:: from_str (
251256 & read_to_string ( path) . map_err ( |e| StwoRunAndProveError :: from ( ( e, path. clone ( ) ) ) ) ?,
@@ -263,12 +268,17 @@ fn prove_with_retries(
263268 "Attempting to generate proof {}/{}." ,
264269 i, prove_config. n_proof_attempts
265270 ) ;
266- let proof_file_path = prove_config. proofs_dir . join ( format ! ( "proof_{i}" ) ) ;
271+ let proof_file_path = prove_config
272+ . proofs_dir
273+ . join ( format ! ( "{}{}" , PROOF_PREFIX , i) ) ;
274+ let proof_file_name = proof_file_path
275+ . file_name ( )
276+ . ok_or_else ( || std:: io:: Error :: new ( std:: io:: ErrorKind :: InvalidInput , "no file name" ) ) ?;
267277
268278 match prover. choose_channel_and_prove (
269279 prover_params,
270280 prover_input. clone ( ) ,
271- proof_file_path,
281+ proof_file_path. clone ( ) ,
272282 & proof_format,
273283 prove_config. verify ,
274284 ) {
@@ -277,10 +287,22 @@ fn prove_with_retries(
277287 "Proof generated and verified successfully on attempt {}/{}" ,
278288 i, prove_config. n_proof_attempts
279289 ) ;
280- return Ok ( i) ;
290+ let success_path = proof_file_path. with_file_name ( format ! (
291+ "{}{}" ,
292+ proof_file_name. to_string_lossy( ) ,
293+ SUCCESS_SUFFIX
294+ ) ) ;
295+ fs:: rename ( proof_file_path, & success_path) ?;
296+ return Ok ( ( ) ) ;
281297 }
282298
283299 Err ( StwoRunAndProveError :: Verification ) => {
300+ let failure_path = proof_file_path. with_file_name ( format ! (
301+ "{}{}" ,
302+ proof_file_name. to_string_lossy( ) ,
303+ FAILURE_SUFFIX
304+ ) ) ;
305+ fs:: rename ( proof_file_path, & failure_path) ?;
284306 if i < prove_config. n_proof_attempts {
285307 warn ! (
286308 "Proof verification failed on attempt {}/{}. Retrying." ,
@@ -420,7 +442,7 @@ fn write_output_to_file(
420442 output_path : PathBuf ,
421443) -> Result < ( ) , StwoRunAndProveError > {
422444 info ! ( "Saving program output to: {:?}" , output_path) ;
423- // TODO(Nitsan): move this function to cairo_program_runner_lib or a new utils lib,
445+ // TODO(Nitsan): move this function to cairo_program_runner_lib or a new utils lib,
424446 // and call it from here and from cairo_program_runner.
425447
426448 let mut output_buffer = String :: new ( ) ;
@@ -448,7 +470,6 @@ mod tests {
448470 const PROGRAM_FILE_NAME : & str = "array_sum.json" ;
449471 const PROVER_PARAMS_FILE_NAME : & str = "prover_params.json" ;
450472 const EXPECTED_PROOF_FILE_NAME : & str = "array_sum_proof" ;
451- const FIRST_PROOF_FILE_NAME : & str = "proof_1" ;
452473
453474 fn get_path ( file_name : & str ) -> PathBuf {
454475 let current_path = env:: current_dir ( ) . expect ( "failed to get current directory" ) ;
@@ -482,7 +503,7 @@ mod tests {
482503 fn run_stwo_run_and_prove (
483504 args : Args ,
484505 prover : Box < dyn ProverTrait > ,
485- ) -> Result < usize , StwoRunAndProveError > {
506+ ) -> Result < ( ) , StwoRunAndProveError > {
486507 let prove_config = ProveConfig {
487508 verify : args. verify ,
488509 proofs_dir : args. proofs_dir ,
@@ -513,14 +534,7 @@ mod tests {
513534 Ok ( ( ) )
514535 } ) ;
515536
516- let successful_proof_attempt =
517- run_stwo_run_and_prove ( args, mock_prover) . expect ( "failed to run stwo_run_and_prove" ) ;
518-
519- assert_eq ! (
520- successful_proof_attempt, 1 ,
521- "successful proof attempt should be 1, but got {:?}" ,
522- successful_proof_attempt
523- ) ;
537+ run_stwo_run_and_prove ( args, mock_prover) . expect ( "failed to run stwo_run_and_prove" ) ;
524538
525539 ( program_output_tempfile, proofs_tempdir)
526540 }
@@ -567,15 +581,7 @@ mod tests {
567581 results. next ( ) . unwrap ( )
568582 } ) ;
569583
570- let successful_proof_attempt =
571- run_stwo_run_and_prove ( args, mock_prover) . expect ( "failed to run stwo_run_and_prove" ) ;
572-
573- assert_eq ! (
574- successful_proof_attempt, n_proof_attempts,
575- "successful proof attempt should be {:?}, but got {:?}" ,
576- n_proof_attempts, successful_proof_attempt
577- ) ;
578-
584+ run_stwo_run_and_prove ( args, mock_prover) . expect ( "failed to run stwo_run_and_prove" ) ;
579585 ( program_output_tempfile, proofs_tempdir)
580586 }
581587
@@ -587,7 +593,7 @@ mod tests {
587593 let proof_file = proofs_temp_dir
588594 . path ( )
589595 . to_path_buf ( )
590- . join ( FIRST_PROOF_FILE_NAME ) ;
596+ . join ( format ! ( "{}1{}" , PROOF_PREFIX , SUCCESS_SUFFIX ) ) ;
591597 let proof_content = std:: fs:: read_to_string ( proof_file) . expect ( "Failed to read proof file" ) ;
592598 let expected_proof_file = get_path ( EXPECTED_PROOF_FILE_NAME ) ;
593599 let expected_proof_content = std:: fs:: read_to_string ( expected_proof_file)
@@ -617,11 +623,11 @@ mod tests {
617623 let proofs_dir = proofs_temp_dir. path ( ) . to_path_buf ( ) ;
618624
619625 ( 1 ..=n_proof_attempts) . for_each ( |i| {
620- let proof_file = proofs_dir. join ( format ! ( "proof_{} " , i ) ) ;
626+ let proof_file = proofs_dir. join ( format ! ( "{}{}{} " , PROOF_PREFIX , i , FAILURE_SUFFIX ) ) ;
621627 assert ! (
622628 proof_file. exists( ) ,
623629 "Proof file {:?} should exist after running with verifier failures" ,
624- i ,
630+ proof_file ,
625631 ) ;
626632 } ) ;
627633
@@ -640,11 +646,17 @@ mod tests {
640646 let proofs_dir = proofs_temp_dir. path ( ) . to_path_buf ( ) ;
641647
642648 ( 1 ..=n_proof_attempts) . for_each ( |i| {
643- let proof_file = proofs_dir. join ( format ! ( "proof_{}" , i) ) ;
649+ let proof_file;
650+ if i < n_proof_attempts {
651+ proof_file = proofs_dir. join ( format ! ( "{}{}{}" , PROOF_PREFIX , i, FAILURE_SUFFIX ) ) ;
652+ }
653+ else {
654+ proof_file = proofs_dir. join ( format ! ( "{}{}{}" , PROOF_PREFIX , i, SUCCESS_SUFFIX ) ) ;
655+ }
644656 assert ! (
645657 proof_file. exists( ) ,
646658 "Proof file {:?} should exist after a run that succeeds on attempt {:?} of proof and verify" ,
647- i , n_proof_attempts,
659+ proof_file , n_proof_attempts,
648660 ) ;
649661 } ) ;
650662
0 commit comments