@@ -7,14 +7,17 @@ use blake2s_u32::Blake2sState;
77use clap:: { Parser , Subcommand } ;
88use cli_lib:: generate_constants:: generate_constants_for_binary;
99use cli_lib:: prover_utils:: {
10- create_proofs, generate_oracle_data_from_metadata, u32_from_hex_string, ProvingLimit ,
11- VerifierCircuitsIdentifiers , DEFAULT_CYCLES ,
10+ create_final_proofs_from_program_proof, create_proofs, generate_oracle_data_from_metadata,
11+ serialize_to_file, u32_from_hex_string, ProvingLimit , VerifierCircuitsIdentifiers ,
12+ DEFAULT_CYCLES ,
1213} ;
1314use cli_lib:: Machine ;
1415
1516use cli_lib:: vk:: generate_vk;
17+ use execution_utils:: ProgramProof ;
1618use reqwest:: blocking:: Client ;
1719use serde_json:: Value ;
20+ use std:: path:: Path ;
1821use std:: { fs, io:: Write , iter} ;
1922
2023use prover:: {
@@ -87,6 +90,14 @@ enum Commands {
8790 #[ arg( long) ]
8891 gpu : bool ,
8992 } ,
93+ /// Run the 'final' step of proving (for example on the output from ZKSmith)
94+ ProveFinal {
95+ // Either load data from the input file or from RPC
96+ #[ clap( flatten) ]
97+ input : InputConfig ,
98+ #[ arg( long, default_value = "output" ) ]
99+ output_dir : String ,
100+ } ,
90101 /// Verifies a single proof.
91102 Verify {
92103 /// Path to proof file.
@@ -183,6 +194,12 @@ fn fetch_data_from_json_rpc(
183194 }
184195}
185196
197+ fn fetch_data_from_url ( url : & str ) -> Result < Option < String > , reqwest:: Error > {
198+ let client = Client :: new ( ) ;
199+ let response = client. get ( url) . send ( ) ?. text ( ) ?;
200+ Ok ( Some ( response) )
201+ }
202+
186203fn fetch_input_hex_string ( input : & InputConfig ) -> Result < Option < String > , reqwest:: Error > {
187204 if let Some ( input_file) = & input. input_file {
188205 Ok ( Some (
@@ -198,6 +215,21 @@ fn fetch_input_hex_string(input: &InputConfig) -> Result<Option<String>, reqwest
198215 }
199216}
200217
218+ fn fetch_final_input_json ( input : & InputConfig ) -> Result < Option < String > , reqwest:: Error > {
219+ if let Some ( input_file) = & input. input_file {
220+ Ok ( Some (
221+ fs:: read_to_string ( input_file) . unwrap ( ) . trim ( ) . to_string ( ) ,
222+ ) )
223+ } else if let Some ( url) = & input. input_rpc {
224+ let batch = input
225+ . input_batch
226+ . expect ( "input_batch must be set if input_rpc is set" ) ;
227+ fetch_data_from_url ( format ! ( "{}/downloads/{}" , url, batch) . as_str ( ) )
228+ } else {
229+ Ok ( None )
230+ }
231+ }
232+
201233fn main ( ) {
202234 let cli = Cli :: parse ( ) ;
203235 match & cli. command {
@@ -225,6 +257,19 @@ fn main() {
225257 gpu. clone ( ) ,
226258 ) ;
227259 }
260+ Commands :: ProveFinal { input, output_dir } => {
261+ let input = fetch_final_input_json ( input) . expect ( "Failed to fetch" ) ;
262+
263+ let input_program_proof: ProgramProof = serde_json:: from_str ( & input. unwrap ( ) )
264+ . expect ( "Failed to parse input_hex into ProgramProof" ) ;
265+
266+ let program_proof = create_final_proofs_from_program_proof ( input_program_proof) ;
267+
268+ serialize_to_file (
269+ & program_proof,
270+ & Path :: new ( output_dir) . join ( "final_program_proof.json" ) ,
271+ ) ;
272+ }
228273 Commands :: Verify { proof } => {
229274 #[ cfg( feature = "include_verifiers" ) ]
230275 verify_proof ( proof) ;
0 commit comments