44#![ forbid( unsafe_code) ]
55
66use cairo_vm:: {
7- cairo_run:: CairoRunConfig ,
8- types:: { layout_name:: LayoutName , program:: Program } ,
9- vm:: {
10- errors:: vm_exception:: VmException ,
11- runners:: cairo_runner:: { CairoRunner , RunnerMode } ,
12- } ,
7+ cairo_run:: { self , cairo_run_program} ,
8+ types:: { layout:: CairoLayoutParams , layout_name:: LayoutName , program:: Program } ,
139} ;
1410use clap:: Parser ;
1511use dry_hint_processor:: {
@@ -19,70 +15,101 @@ use dry_hint_processor::{
1915use hints:: vars;
2016use std:: { env, path:: PathBuf } ;
2117use tracing:: debug;
22- use types:: HDPDryRunInput ;
18+ use types:: { error :: Error , HDPDryRunInput } ;
2319
2420#[ derive( Parser , Debug ) ]
2521#[ clap( author, version, about, long_about = None ) ]
2622struct Args {
27- #[ clap( long = "layout" , default_value = "plain" , value_enum) ]
28- layout : LayoutName ,
29- #[ structopt( long = "proof_mode" ) ]
30- proof_mode : bool ,
3123 #[ structopt( long = "program_input" ) ]
3224 program_input : PathBuf ,
3325 #[ structopt( long = "program_output" ) ]
3426 program_output : PathBuf ,
27+ #[ clap( long = "trace_file" , value_parser) ]
28+ trace_file : Option < PathBuf > ,
29+ #[ structopt( long = "print_output" ) ]
30+ print_output : bool ,
31+ #[ structopt( long = "memory_file" ) ]
32+ memory_file : Option < PathBuf > ,
33+ /// When using dynamic layout, it's parameters must be specified through a layout params file.
34+ #[ clap( long = "layout" , default_value = "plain" , value_enum) ]
35+ layout : LayoutName ,
36+ /// Required when using with dynamic layout.
37+ /// Ignored otherwise.
38+ #[ clap( long = "cairo_layout_params_file" , required_if_eq( "layout" , "dynamic" ) ) ]
39+ cairo_layout_params_file : Option < PathBuf > ,
40+ #[ structopt( long = "proof_mode" ) ]
41+ proof_mode : bool ,
42+ #[ structopt( long = "secure_run" ) ]
43+ secure_run : Option < bool > ,
44+ #[ clap( long = "air_public_input" , requires = "proof_mode" ) ]
45+ air_public_input : Option < PathBuf > ,
46+ #[ clap(
47+ long = "air_private_input" ,
48+ requires_all = [ "proof_mode" , "trace_file" , "memory_file" ]
49+ ) ]
50+ air_private_input : Option < PathBuf > ,
51+ #[ clap(
52+ long = "cairo_pie_output" ,
53+ // We need to add these air_private_input & air_public_input or else
54+ // passing cairo_pie_output + either of these without proof_mode will not fail
55+ conflicts_with_all = [ "proof_mode" , "air_private_input" , "air_public_input" ]
56+ ) ]
57+ cairo_pie_output : Option < PathBuf > ,
58+ #[ structopt( long = "allow_missing_builtins" ) ]
59+ allow_missing_builtins : Option < bool > ,
3560}
3661
3762#[ tokio:: main( flavor = "multi_thread" , worker_threads = 1 ) ]
38- async fn main ( ) -> Result < ( ) , HdpOsError > {
63+ async fn main ( ) -> Result < ( ) , Error > {
3964 tracing_subscriber:: fmt:: init ( ) ;
4065
41- let args = Args :: try_parse_from ( std:: env:: args ( ) ) . map_err ( HdpOsError :: Args ) ?;
66+ let args = Args :: try_parse_from ( std:: env:: args ( ) ) . map_err ( Error :: Cli ) ?;
67+
68+ let cairo_layout_params = match args. cairo_layout_params_file {
69+ Some ( file) => Some ( CairoLayoutParams :: from_file ( & file) ?) ,
70+ None => None ,
71+ } ;
4272
4373 // Init CairoRunConfig
44- let cairo_run_config = CairoRunConfig {
74+ let cairo_run_config = cairo_run:: CairoRunConfig {
75+ trace_enabled : args. trace_file . is_some ( ) || args. air_public_input . is_some ( ) ,
76+ relocate_mem : args. memory_file . is_some ( ) || args. air_public_input . is_some ( ) ,
4577 layout : args. layout ,
46- relocate_mem : true ,
47- trace_enabled : true ,
78+ proof_mode : args. proof_mode ,
79+ secure_run : args. secure_run ,
80+ allow_missing_builtins : args. allow_missing_builtins ,
81+ dynamic_layout_params : cairo_layout_params,
4882 ..Default :: default ( )
4983 } ;
5084
5185 // Locate the compiled program file in the `OUT_DIR` folder.
5286 let out_dir = PathBuf :: from ( env:: var ( "OUT_DIR" ) . expect ( "OUT_DIR is not set" ) ) ;
5387 let program_file_path = out_dir. join ( "cairo" ) . join ( "compiled.json" ) ;
5488
55- let program_file = std:: fs:: read ( program_file_path) . map_err ( HdpOsError :: IO ) ?;
56- let program_inputs: HDPDryRunInput = serde_json:: from_slice ( & std:: fs:: read ( args. program_input ) . map_err ( HdpOsError :: IO ) ?) ?;
89+ let program_file = std:: fs:: read ( program_file_path) . map_err ( Error :: IO ) ?;
90+ let program_inputs: HDPDryRunInput = serde_json:: from_slice ( & std:: fs:: read ( args. program_input ) . map_err ( Error :: IO ) ?) ?;
5791
5892 // Load the Program
59- let program = Program :: from_bytes ( & program_file, Some ( cairo_run_config. entrypoint ) ) . map_err ( |e| HdpOsError :: Runner ( e . into ( ) ) ) ?;
93+ let program = Program :: from_bytes ( & program_file, Some ( cairo_run_config. entrypoint ) ) ?;
6094
61- let runner_mode = if cairo_run_config. proof_mode {
62- RunnerMode :: ProofModeCairo1
63- } else {
64- RunnerMode :: ExecutionMode
65- } ;
66-
67- // Init cairo runner
68- let mut cairo_runner = CairoRunner :: new_v2 ( & program, cairo_run_config. layout , None , runner_mode, cairo_run_config. trace_enabled )
69- . map_err ( |e| HdpOsError :: Runner ( e. into ( ) ) ) ?;
70-
71- // Init the Cairo VM
72- let end = cairo_runner
73- . initialize ( cairo_run_config. allow_missing_builtins . unwrap_or ( false ) )
74- . map_err ( |e| HdpOsError :: Runner ( e. into ( ) ) ) ?;
75-
76- // Run the Cairo VM
7795 let mut hint_processor = CustomHintProcessor :: new ( program_inputs) ;
78- cairo_runner
79- . run_until_pc ( end, & mut hint_processor)
80- . map_err ( |err| VmException :: from_vm_error ( & cairo_runner, err) )
81- . map_err ( |e| HdpOsError :: Runner ( e. into ( ) ) ) ?;
96+ let mut cairo_runner = cairo_run_program ( & program, & cairo_run_config, & mut hint_processor) . unwrap ( ) ;
8297
83- cairo_runner. vm . compute_segments_effective_sizes ( ) ;
8498 debug ! ( "{:?}" , cairo_runner. get_execution_resources( ) ) ;
8599
100+ if args. print_output {
101+ let mut output_buffer = "Program Output:\n " . to_string ( ) ;
102+ cairo_runner. vm . write_output ( & mut output_buffer) ?;
103+ print ! ( "{output_buffer}" ) ;
104+ }
105+
106+ if let Some ( ref file_name) = args. cairo_pie_output {
107+ cairo_runner
108+ . get_cairo_pie ( )
109+ . map_err ( |e| Error :: CairoPie ( e. to_string ( ) ) ) ?
110+ . write_zip_file ( file_name) ?
111+ }
112+
86113 std:: fs:: write (
87114 args. program_output ,
88115 serde_json:: to_vec :: < SyscallHandler > (
@@ -94,26 +121,9 @@ async fn main() -> Result<(), HdpOsError> {
94121 . try_read ( )
95122 . unwrap ( ) ,
96123 )
97- . map_err ( |e| HdpOsError :: IO ( e. into ( ) ) ) ?,
124+ . map_err ( |e| Error :: IO ( e. into ( ) ) ) ?,
98125 )
99- . map_err ( HdpOsError :: IO ) ?;
126+ . map_err ( Error :: IO ) ?;
100127
101128 Ok ( ( ) )
102129}
103-
104- use cairo_vm:: vm:: errors:: cairo_run_errors:: CairoRunError ;
105- use thiserror:: Error ;
106-
107- #[ derive( Error , Debug ) ]
108- pub enum HdpOsError {
109- #[ error( transparent) ]
110- Args ( #[ from] clap:: error:: Error ) ,
111- #[ error( "Runner Error: {0}" ) ]
112- Runner ( CairoRunError ) ,
113- #[ error( "Output Error: {0}" ) ]
114- Output ( String ) ,
115- #[ error( transparent) ]
116- IO ( #[ from] std:: io:: Error ) ,
117- #[ error( transparent) ]
118- SerdeJson ( #[ from] serde_json:: Error ) ,
119- }
0 commit comments