@@ -2,10 +2,13 @@ use cairo_air::utils::ProofFormat;
22use cairo_air:: verifier:: verify_cairo;
33use cairo_program_runner_lib:: cairo_run_program;
44use cairo_program_runner_lib:: utils:: { get_cairo_run_config, get_program, get_program_input} ;
5+ use cairo_vm:: Felt252 ;
56use cairo_vm:: types:: errors:: program_errors:: ProgramError ;
67use cairo_vm:: types:: layout_name:: LayoutName ;
78use cairo_vm:: vm:: errors:: cairo_run_errors:: CairoRunError ;
89use cairo_vm:: vm:: errors:: runner_errors:: RunnerError ;
10+ use cairo_vm:: vm:: errors:: vm_errors:: VirtualMachineError ;
11+ use cairo_vm:: vm:: runners:: cairo_runner:: CairoRunner ;
912use clap:: Parser ;
1013#[ cfg( test) ]
1114use mockall:: automock;
@@ -32,8 +35,6 @@ use stwo_cairo_utils::file_utils::{IoErrorWithPath, create_file, read_to_string}
3235use thiserror:: Error ;
3336use tracing:: { error, info, warn} ;
3437
35- type OutputVec = Vec < [ u32 ; 8 ] > ;
36-
3738fn parse_usize_ge1 ( s : & str ) -> Result < usize , String > {
3839 let v: usize = s. parse ( ) . map_err ( |_| "must be a number" . to_string ( ) ) ?;
3940 if v >= 1 {
@@ -119,8 +120,12 @@ enum StwoRunAndProveError {
119120 Serializing ( #[ from] sonic_rs:: error:: Error ) ,
120121 #[ error( transparent) ]
121122 Proving ( #[ from] ProvingError ) ,
123+ #[ error( transparent) ]
124+ VM ( #[ from] VirtualMachineError ) ,
122125 #[ error( "cairo verification failed." ) ]
123126 Verification ,
127+ #[ error( "Failed to parse output line as Felt decimal." ) ]
128+ OutputParsing ,
124129}
125130
126131// Implement From<Box<CairoRunError>> manually
@@ -193,11 +198,9 @@ fn stwo_run_and_prove(
193198 let runner = cairo_run_program ( & program, program_input, cairo_run_config) ?;
194199 info ! ( "Adapting prover input." ) ;
195200 let prover_input = adapter ( & runner) ;
196- let ( successful_proof_attempt, output_vec) =
197- prove_with_retries ( prover_input, prove_config, prover) ?;
198-
201+ let successful_proof_attempt = prove_with_retries ( prover_input, prove_config, prover) ?;
199202 if let Some ( output_path) = program_output {
200- save_output_to_file ( output_vec , output_path) ?;
203+ write_output_to_file ( runner , output_path) ?;
201204 }
202205
203206 Ok ( successful_proof_attempt)
@@ -211,7 +214,7 @@ fn prove_with_retries(
211214 prover_input : ProverInput ,
212215 prove_config : ProveConfig ,
213216 prover : Box < dyn ProverTrait > ,
214- ) -> Result < ( usize , OutputVec ) , StwoRunAndProveError > {
217+ ) -> Result < usize , StwoRunAndProveError > {
215218 let prover_params = match prove_config. prover_params_json {
216219 Some ( ref path) => sonic_rs:: from_str ( & read_to_string ( path) ?) ?,
217220 None => default_prod_prover_parameters ( ) ,
@@ -235,12 +238,12 @@ fn prove_with_retries(
235238 & proof_format,
236239 prove_config. verify ,
237240 ) {
238- Ok ( output_values ) => {
241+ Ok ( ( ) ) => {
239242 info ! (
240243 "Proof generated and verified successfully on attempt {}/{}" ,
241244 i, prove_config. n_proof_attempts
242245 ) ;
243- return Ok ( ( i , output_values ) ) ;
246+ return Ok ( i ) ;
244247 }
245248
246249 Err ( StwoRunAndProveError :: Verification ) => {
@@ -272,7 +275,7 @@ fn choose_channel_and_prove(
272275 proof_file_path : PathBuf ,
273276 proof_format : & ProofFormat ,
274277 verify : bool ,
275- ) -> Result < OutputVec , StwoRunAndProveError > {
278+ ) -> Result < ( ) , StwoRunAndProveError > {
276279 match prover_params. channel_hash {
277280 ChannelHash :: Blake2s => prove :: < Blake2sMerkleChannel > (
278281 prover_params,
@@ -300,7 +303,7 @@ trait ProverTrait {
300303 proof_file_path : PathBuf ,
301304 proof_format : & ProofFormat ,
302305 verify : bool ,
303- ) -> Result < OutputVec , StwoRunAndProveError > ;
306+ ) -> Result < ( ) , StwoRunAndProveError > ;
304307}
305308
306309struct StwoProverEntryPoint ;
@@ -313,7 +316,7 @@ impl ProverTrait for StwoProverEntryPoint {
313316 proof_file_path : PathBuf ,
314317 proof_format : & ProofFormat ,
315318 verify : bool ,
316- ) -> Result < OutputVec , StwoRunAndProveError > {
319+ ) -> Result < ( ) , StwoRunAndProveError > {
317320 choose_channel_and_prove (
318321 prover_params,
319322 prover_input,
@@ -334,7 +337,7 @@ fn prove<MC: MerkleChannel>(
334337 proof_file_path : PathBuf ,
335338 proof_format : & ProofFormat ,
336339 verify : bool ,
337- ) -> Result < OutputVec , StwoRunAndProveError >
340+ ) -> Result < ( ) , StwoRunAndProveError >
338341where
339342 SimdBackend : BackendForChannel < MC > ,
340343 MC :: H : Serialize ,
@@ -361,8 +364,6 @@ where
361364 }
362365 }
363366
364- let output_addresses_and_values = proof. claim . public_data . public_memory . output . clone ( ) ;
365-
366367 if verify {
367368 // We want to map this error to `StwoRunAndProveError::Verification` because we intend to
368369 // retry the proof generation in case of a verification failure. In the calling function we
@@ -372,23 +373,27 @@ where
372373 . map_err ( |_| StwoRunAndProveError :: Verification ) ?;
373374 }
374375
375- let output_values = output_addresses_and_values
376- . into_iter ( )
377- . map ( |( _, value) | value)
378- . collect ( ) ;
379-
380- Ok ( output_values)
376+ Ok ( ( ) )
381377}
382378
383- /// Saves the program output to the specified output path as [u32; 8] values,
384- /// that will be converted to [u256] in the Prover service.
385- fn save_output_to_file (
386- output_vec : OutputVec ,
379+ /// Write the program output to the specified output path as Felt252 values.
380+ fn write_output_to_file (
381+ mut runner : CairoRunner ,
387382 output_path : PathBuf ,
388383) -> Result < ( ) , StwoRunAndProveError > {
389384 info ! ( "Saving program output to: {:?}" , output_path) ;
390- let serialized_output = sonic_rs:: to_string ( & output_vec) ?;
391- std:: fs:: write ( output_path, serialized_output) ?;
385+ // TODO(Nitsan): move this function to cairo_program_runner_lib or a new utils lib,
386+ // and call it from here and from cairo_program_runner.
387+
388+ let mut output_buffer = String :: new ( ) ;
389+ runner. vm . write_output ( & mut output_buffer) ?;
390+ let output_lines = output_buffer
391+ . lines ( )
392+ . map ( |line : & str | {
393+ Felt252 :: from_dec_str ( line) . map_err ( |_| StwoRunAndProveError :: OutputParsing )
394+ } )
395+ . collect :: < Result < Vec < Felt252 > , _ > > ( ) ?;
396+ std:: fs:: write ( output_path, sonic_rs:: to_string_pretty ( & output_lines) ?) ?;
392397 Ok ( ( ) )
393398}
394399
@@ -399,7 +404,7 @@ mod tests {
399404 use std:: fs;
400405 use tempfile:: { NamedTempFile , TempDir , TempPath } ;
401406
402- const ARRAY_SUM_EXPECTED_OUTPUT : [ u32 ; 8 ] = [ 50 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ] ;
407+ const ARRAY_SUM_EXPECTED_OUTPUT : [ Felt252 ; 1 ] = [ Felt252 :: from_hex_unchecked ( "0x32" ) ] ;
403408 const RESOURCES_PATH : & str = "resources" ;
404409 const PROGRAM_FILE_NAME : & str = "array_sum.json" ;
405410 const PROVER_PARAMS_FILE_NAME : & str = "prover_params.json" ;
@@ -466,7 +471,7 @@ mod tests {
466471 . returning ( move |_, _, proof_file, _, _| {
467472 let expected_proof_file = get_path ( EXPECTED_PROOF_FILE_NAME ) ;
468473 fs:: copy ( & expected_proof_file, & proof_file) . expect ( "Failed to copy proof file." ) ;
469- Ok ( vec ! [ ARRAY_SUM_EXPECTED_OUTPUT ] )
474+ Ok ( ( ) )
470475 } ) ;
471476
472477 let successful_proof_attempt =
@@ -512,7 +517,7 @@ mod tests {
512517 // for the last attempt.
513518 let mut results = ( 0 ..n_proof_attempts. saturating_sub ( 1 ) )
514519 . map ( |_| Err ( StwoRunAndProveError :: Verification ) )
515- . chain ( std:: iter:: once ( Ok ( vec ! [ ARRAY_SUM_EXPECTED_OUTPUT ] ) ) ) ;
520+ . chain ( std:: iter:: once ( Ok ( ( ) ) ) ) ;
516521
517522 mock_prover
518523 . expect_choose_channel_and_prove ( )
@@ -556,10 +561,10 @@ mod tests {
556561 // Verifying the proof output.
557562 let output_content =
558563 std:: fs:: read_to_string ( output_temp_file) . expect ( "Failed to read output file" ) ;
559- let output_vec : OutputVec =
564+ let output : Vec < Felt252 > =
560565 sonic_rs:: from_str ( & output_content) . expect ( "Failed to parse output" ) ;
561566 assert_eq ! (
562- output_vec [ 0 ] , ARRAY_SUM_EXPECTED_OUTPUT ,
567+ output , ARRAY_SUM_EXPECTED_OUTPUT ,
563568 "Expected output to be {:?}" ,
564569 ARRAY_SUM_EXPECTED_OUTPUT
565570 ) ;
0 commit comments