@@ -2,6 +2,7 @@ use anyhow::{bail, ensure, Context, Result};
2
2
use bincode:: enc:: write:: Writer ;
3
3
use cairo_lang_executable:: executable:: { EntryPointKind , Executable } ;
4
4
use cairo_lang_runner:: { build_hints_dict, Arg , CairoHintProcessor } ;
5
+ use cairo_lang_utils:: bigint:: BigUintAsHex ;
5
6
use cairo_vm:: cairo_run:: cairo_run_program;
6
7
use cairo_vm:: cairo_run:: CairoRunConfig ;
7
8
use cairo_vm:: types:: layout_name:: LayoutName ;
@@ -48,9 +49,8 @@ struct Args {
48
49
49
50
#[ derive( Parser , Clone , Debug ) ]
50
51
struct ExecutionArgs {
51
- /// Serialized arguments to the executable function.
52
- #[ arg( long, value_delimiter = ',' ) ]
53
- arguments : Vec < BigInt > ,
52
+ #[ command( flatten) ]
53
+ pub arguments : ProgramArguments ,
54
54
55
55
/// Desired execution output, either default Standard or CairoPie
56
56
#[ arg( long, default_value = "standard" ) ]
@@ -65,6 +65,37 @@ struct ExecutionArgs {
65
65
print_program_output : bool ,
66
66
}
67
67
68
+ #[ derive( Parser , Debug , Clone ) ]
69
+ pub struct ProgramArguments {
70
+ /// Serialized arguments to the executable function.
71
+ #[ arg( long, value_delimiter = ',' ) ]
72
+ arguments : Vec < BigInt > ,
73
+
74
+ /// Serialized arguments to the executable function from a file.
75
+ #[ arg( long, conflicts_with = "arguments" ) ]
76
+ arguments_file : Option < Utf8PathBuf > ,
77
+ }
78
+
79
+ impl ProgramArguments {
80
+ pub fn read_arguments ( self ) -> Result < Vec < Arg > > {
81
+ if let Some ( path) = self . arguments_file {
82
+ let file = fs:: File :: open ( & path) . with_context ( || "reading arguments file failed" ) ?;
83
+ let as_vec: Vec < BigUintAsHex > = serde_json:: from_reader ( file)
84
+ . with_context ( || "deserializing arguments file failed" ) ?;
85
+ Ok ( as_vec
86
+ . into_iter ( )
87
+ . map ( |v| Arg :: Value ( v. value . into ( ) ) )
88
+ . collect ( ) )
89
+ } else {
90
+ Ok ( self
91
+ . arguments
92
+ . iter ( )
93
+ . map ( |v| Arg :: Value ( v. into ( ) ) )
94
+ . collect ( ) )
95
+ }
96
+ }
97
+ }
98
+
68
99
#[ derive( ValueEnum , Clone , Debug ) ]
69
100
enum OutputFormat {
70
101
CairoPie ,
@@ -142,7 +173,7 @@ fn main_inner(args: Args, ui: Ui) -> Result<(), anyhow::Error> {
142
173
. entrypoints
143
174
. iter ( )
144
175
. find ( |e| matches ! ( e. kind, EntryPointKind :: Standalone ) )
145
- . with_context ( || "No `Standalone` entrypoint found. " ) ?;
176
+ . with_context ( || "no `Standalone` entrypoint found" ) ?;
146
177
Program :: new_for_proof (
147
178
entrypoint. builtins . clone ( ) ,
148
179
data,
@@ -159,7 +190,7 @@ fn main_inner(args: Args, ui: Ui) -> Result<(), anyhow::Error> {
159
190
. entrypoints
160
191
. iter ( )
161
192
. find ( |e| matches ! ( e. kind, EntryPointKind :: Bootloader ) )
162
- . with_context ( || "No `Bootloader` entrypoint found. " ) ?;
193
+ . with_context ( || "no `Bootloader` entrypoint found" ) ?;
163
194
Program :: new (
164
195
entrypoint. builtins . clone ( ) ,
165
196
data,
@@ -171,17 +202,11 @@ fn main_inner(args: Args, ui: Ui) -> Result<(), anyhow::Error> {
171
202
None ,
172
203
)
173
204
}
174
- . with_context ( || "Failed setting up program. " ) ?;
205
+ . with_context ( || "failed setting up program" ) ?;
175
206
176
207
let mut hint_processor = CairoHintProcessor {
177
208
runner : None ,
178
- user_args : vec ! [ vec![ Arg :: Array (
179
- args. run
180
- . arguments
181
- . iter( )
182
- . map( |v| Arg :: Value ( v. into( ) ) )
183
- . collect( ) ,
184
- ) ] ] ,
209
+ user_args : vec ! [ vec![ Arg :: Array ( args. run. arguments. read_arguments( ) ?) ] ] ,
185
210
string_to_hint,
186
211
starknet_state : Default :: default ( ) ,
187
212
run_resources : Default :: default ( ) ,
@@ -203,12 +228,12 @@ fn main_inner(args: Args, ui: Ui) -> Result<(), anyhow::Error> {
203
228
. with_context ( || "Cairo program run failed" ) ?;
204
229
205
230
if args. run . print_program_output {
206
- let mut output_buffer = "Program Output :\n " . to_string ( ) ;
231
+ let mut output_buffer = "Program output :\n " . to_string ( ) ;
207
232
runner. vm . write_output ( & mut output_buffer) ?;
208
- print ! ( "{ output_buffer}" ) ;
233
+ ui . print ( output_buffer. trim_end ( ) ) ;
209
234
}
210
235
211
- let output_dir = scarb_target_dir. join ( "scarb- execute" ) ;
236
+ let output_dir = scarb_target_dir. join ( "execute" ) ;
212
237
create_output_dir ( output_dir. as_std_path ( ) ) ?;
213
238
214
239
if args. run . output . is_cairo_pie ( ) {
@@ -231,7 +256,7 @@ fn main_inner(args: Args, ui: Ui) -> Result<(), anyhow::Error> {
231
256
let relocated_trace = runner
232
257
. relocated_trace
233
258
. as_ref ( )
234
- . with_context ( || "Trace not relocated. " ) ?;
259
+ . with_context ( || "trace not relocated" ) ?;
235
260
let mut writer = FileWriter :: new ( 3 * 1024 * 1024 , & trace_path) ?;
236
261
cairo_run:: write_encoded_trace ( relocated_trace, & mut writer) ?;
237
262
writer. flush ( ) ?;
@@ -253,7 +278,7 @@ fn main_inner(args: Args, ui: Ui) -> Result<(), anyhow::Error> {
253
278
. get_air_private_input ( )
254
279
. to_serializable ( trace_path. to_string ( ) , memory_path. to_string ( ) )
255
280
. serialize_json ( )
256
- . with_context ( || "Failed serializing private input. " ) ?;
281
+ . with_context ( || "failed serializing private input" ) ?;
257
282
fs:: write ( air_private_input_path, output_value) ?;
258
283
}
259
284
@@ -275,14 +300,14 @@ fn load_prebuilt_executable(path: &Utf8Path, filename: String) -> Result<Executa
275
300
ensure ! (
276
301
file_path. exists( ) ,
277
302
formatdoc! { r#"
278
- package has not been compiled, file does not exist: {filename}
303
+ package has not been compiled, file does not exist: ` {filename}`
279
304
help: run `scarb build` to compile the package
280
305
"# }
281
306
) ;
282
307
let file = fs:: File :: open ( & file_path)
283
- . with_context ( || format ! ( "failed to open executable program: {file_path}" ) ) ?;
308
+ . with_context ( || format ! ( "failed to open executable program: ` {file_path}` " ) ) ?;
284
309
serde_json:: from_reader ( file)
285
- . with_context ( || format ! ( "failed to deserialize executable program: {file_path}" ) )
310
+ . with_context ( || format ! ( "failed to deserialize executable program: ` {file_path}` " ) )
286
311
}
287
312
288
313
fn incremental_create_output_file (
@@ -294,7 +319,7 @@ fn incremental_create_output_file(
294
319
path,
295
320
name,
296
321
extension,
297
- "Failed to create output directory. " ,
322
+ "failed to create output directory" ,
298
323
|p| {
299
324
OpenOptions :: new ( )
300
325
. write ( true )
@@ -306,7 +331,7 @@ fn incremental_create_output_file(
306
331
}
307
332
308
333
fn incremental_create_output_dir ( path : & Utf8Path , name : String ) -> Result < Utf8PathBuf > {
309
- incremental_attempt_io_creation ( path, name, "" , "Failed to create output directory. " , |p| {
334
+ incremental_attempt_io_creation ( path, name, "" , "failed to create output directory" , |p| {
310
335
fs:: create_dir ( p)
311
336
} )
312
337
}
0 commit comments