From e0aa3f7a948bd0b9cc52f1666e686fd4f0270766 Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 3 Jan 2024 17:14:22 -0300 Subject: [PATCH 01/30] Add proof_mode flag to cairo1-run --- cairo1-run/src/main.rs | 129 ++++++++++++++++++++++++++++------------- 1 file changed, 90 insertions(+), 39 deletions(-) diff --git a/cairo1-run/src/main.rs b/cairo1-run/src/main.rs index 2518d2af6e..4cd3f02a89 100644 --- a/cairo1-run/src/main.rs +++ b/cairo1-run/src/main.rs @@ -77,6 +77,8 @@ struct Args { memory_file: Option, #[clap(long = "layout", default_value = "plain", value_parser=validate_layout)] layout: String, + #[clap(long = "proof_mode", value_parser)] + proof_mode: bool, } fn validate_layout(value: &str) -> Result { @@ -202,35 +204,41 @@ fn run(args: impl Iterator) -> Result, Erro &type_sizes, main_func, initial_gas, + args.proof_mode, )?; - println!("Compiling with proof mode and running ..."); - - // This information can be useful for the users using the prover. - println!("Builtins used: {:?}", builtins); - - // Prepare "canonical" proof mode instructions. These are usually added by the compiler in cairo 0 - let mut ctx = casm! {}; - casm_extend! {ctx, - call rel 4; - jmp rel 0; - }; - let proof_mode_header = ctx.instructions; - // Get the user program instructions let program_instructions = casm_program.instructions.iter(); // This footer is used by lib funcs let libfunc_footer = create_code_footer(); - // This is the program we are actually proving - // With embedded proof mode, cairo1 header and the libfunc footer + let proof_mode_header = if args.proof_mode { + println!("Compiling with proof mode and running ..."); + + // This information can be useful for the users using the prover. + println!("Builtins used: {:?}", builtins); + + // Prepare "canonical" proof mode instructions. These are usually added by the compiler in cairo 0 + let mut ctx = casm! {}; + casm_extend! {ctx, + call rel 4; + jmp rel 0; + }; + ctx.instructions + } else { + casm! {}.instructions + }; + + // This is the program we are actually running/proving + // With (embedded proof mode), cairo1 header and the libfunc footer let instructions = chain!( proof_mode_header.iter(), entry_code.iter(), program_instructions, libfunc_footer.iter() - ); + ) + .into_iter(); let (processor_hints, program_hints) = build_hints_vec(instructions.clone()); @@ -244,36 +252,59 @@ fn run(args: impl Iterator) -> Result, Erro let data_len = data.len(); - let starting_pc = 0; - - let program = Program::new_for_proof( - builtins, - data, - starting_pc, - // Proof mode is on top - // jmp rel 0 is on PC == 2 - 2, - program_hints, - ReferenceManager { - references: Vec::new(), - }, - HashMap::new(), - vec![], - None, - )?; + let program = if args.proof_mode { + Program::new_for_proof( + builtins, + data, + 0, + // Proof mode is on top + // jmp rel 0 is on PC == 2 + 2, + program_hints, + ReferenceManager { + references: Vec::new(), + }, + HashMap::new(), + vec![], + None, + )? + } else { + Program::new( + builtins, + data, + Some(0), + program_hints, + ReferenceManager { + references: Vec::new(), + }, + HashMap::new(), + vec![], + None, + )? + }; - let mut runner = CairoRunner::new_v2(&program, &args.layout, RunnerMode::ProofModeCairo1)?; + let runner_mode = if args.proof_mode { + RunnerMode::ProofModeCairo1 + } else { + RunnerMode::ExecutionMode + }; + + let mut runner = CairoRunner::new_v2(&program, &args.layout, runner_mode)?; let mut vm = VirtualMachine::new(args.trace_file.is_some()); let end = runner.initialize(&mut vm)?; additional_initialization(&mut vm, data_len)?; - // Run it until the infinite loop + // Run it until the end/ infinite loop in proof_mode runner.run_until_pc(end, &mut vm, &mut hint_processor)?; - // Then pad it to the power of 2 - runner.run_until_next_power_of_2(&mut vm, &mut hint_processor)?; + if args.proof_mode { + // Then pad it to the power of 2 + runner.run_until_next_power_of_2(&mut vm, &mut hint_processor)?; + } else { + runner.end_run(true, false, &mut vm, &mut hint_processor)?; + } // Fetch return type data let return_type_id = main_func @@ -465,6 +496,7 @@ fn create_entry_code( type_sizes: &UnorderedHashMap, func: &Function, initial_gas: usize, + proof_mode: bool, ) -> Result<(Vec, Vec), Error> { let mut ctx = casm! {}; // The builtins in the formatting expected by the runner. @@ -497,8 +529,11 @@ fn create_entry_code( let ty_size = type_sizes[ty]; let generic_ty = &info.long_id.generic_id; if let Some(offset) = builtin_offset.get(generic_ty) { - // Everything is off by 2 due to the proof mode header - let offset = offset + 2; + let mut offset = *offset; + if proof_mode { + // Everything is off by 2 due to the proof mode header + offset = offset + 2; + } casm_extend! {ctx, [ap + 0] = [fp - offset], ap++; } @@ -661,6 +696,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/fibonacci.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/fibonacci.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] fn test_run_fibonacci_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(89)]); @@ -668,6 +704,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/factorial.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/factorial.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] fn test_run_factorial_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(3628800)]); @@ -675,6 +712,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/array_get.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/array_get.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] fn test_run_array_get_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(3)]); @@ -682,6 +720,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/enum_flow.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/enum_flow.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] fn test_run_enum_flow_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(300)]); @@ -689,6 +728,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/enum_match.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/enum_match.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] fn test_run_enum_match_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(10), MaybeRelocatable::from(felt_str("3618502788666131213697322783095070105623107215331596699973092056135872020471"))]); @@ -696,6 +736,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/hello.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/hello.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] fn test_run_hello_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(1), MaybeRelocatable::from(1234)]); @@ -703,6 +744,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/ops.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/ops.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] fn test_run_ops_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(6)]); @@ -710,6 +752,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/print.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/print.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] fn test_run_print_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![]); @@ -717,6 +760,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/recursion.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/recursion.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] fn test_run_recursion_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(felt_str("1154076154663935037074198317650845438095734251249125412074882362667803016453"))]); @@ -724,6 +768,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/sample.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/sample.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] fn test_run_sample_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(felt_str("5050"))]); @@ -731,6 +776,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/poseidon.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/poseidon.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] fn test_run_poseidon_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(felt_str("1099385018355113290651252669115094675591288647745213771718157553170111442461"))]); @@ -738,6 +784,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/poseidon_pedersen.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/poseidon_pedersen.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] fn test_run_poseidon_pedersen_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(felt_str("1036257840396636296853154602823055519264738423488122322497453114874087006398"))]); @@ -745,6 +792,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/pedersen_example.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/pedersen_example.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] fn test_run_pedersen_example_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(felt_str("1089549915800264549621536909767699778745926517555586332772759280702396009108"))]); @@ -752,6 +800,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/simple.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/simple.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] fn test_run_simple_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(1)]); @@ -759,6 +808,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/simple_struct.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/simple_struct.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] fn test_run_simple_struct_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(100)]); @@ -766,6 +816,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/dictionaries.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/dictionaries.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] fn test_run_dictionaries(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(1024)]); From 2357010553713bd1d01f9b9beaac00163de1d166 Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 3 Jan 2024 17:20:25 -0300 Subject: [PATCH 02/30] Add Changelog entry --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 40f85f5d5f..ac6dd24a22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ #### Upcoming Changes +* feat: Add `proof_mode` flag to `cairo1-run` [#1537] (https://github.com/lambdaclass/cairo-vm/pull/1537) + * The cairo1-run crate no longer compiles and executes in proof_mode by default + * Add flag `proof_mode` to cairo1-run crate. Activating this flag will enable proof_mode compilation and execution + * feat(BREAKING): Replace `cairo-felt` crate with `starknet-types-core` (0.0.5) [#1408](https://github.com/lambdaclass/cairo-vm/pull/1408) * feat(BREAKING): Add Cairo 1 proof mode compilation and execution [#1517] (https://github.com/lambdaclass/cairo-vm/pull/1517) From 7e3b34c663cf1e7259d571c43e4dceb59a227cb6 Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 3 Jan 2024 17:22:19 -0300 Subject: [PATCH 03/30] Clippy --- cairo1-run/src/main.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cairo1-run/src/main.rs b/cairo1-run/src/main.rs index 4cd3f02a89..40aa77775f 100644 --- a/cairo1-run/src/main.rs +++ b/cairo1-run/src/main.rs @@ -237,8 +237,7 @@ fn run(args: impl Iterator) -> Result, Erro entry_code.iter(), program_instructions, libfunc_footer.iter() - ) - .into_iter(); + ); let (processor_hints, program_hints) = build_hints_vec(instructions.clone()); From 07c112f51dd57761628296de33dabcc764adff1e Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 3 Jan 2024 17:28:54 -0300 Subject: [PATCH 04/30] clippy --- cairo1-run/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cairo1-run/src/main.rs b/cairo1-run/src/main.rs index 40aa77775f..1d8dae79e5 100644 --- a/cairo1-run/src/main.rs +++ b/cairo1-run/src/main.rs @@ -531,7 +531,7 @@ fn create_entry_code( let mut offset = *offset; if proof_mode { // Everything is off by 2 due to the proof mode header - offset = offset + 2; + offset += 2; } casm_extend! {ctx, [ap + 0] = [fp - offset], ap++; From 43dd6ed5c017f2b8a9a15f4293f749486e6cfe1d Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 3 Jan 2024 18:03:13 -0300 Subject: [PATCH 05/30] Add `air_public_input` flag --- cairo1-run/src/main.rs | 55 ++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/cairo1-run/src/main.rs b/cairo1-run/src/main.rs index 1d8dae79e5..1eca8a1860 100644 --- a/cairo1-run/src/main.rs +++ b/cairo1-run/src/main.rs @@ -79,6 +79,8 @@ struct Args { layout: String, #[clap(long = "proof_mode", value_parser)] proof_mode: bool, + #[clap(long = "air_public_input", value_parser)] + air_public_input: Option, } fn validate_layout(value: &str) -> Result { @@ -173,6 +175,13 @@ impl FileWriter { fn run(args: impl Iterator) -> Result, Error> { let args = Args::try_parse_from(args)?; + if args.air_public_input.is_some() && !args.proof_mode { + let error = Args::command().error( + clap::error::ErrorKind::ArgumentConflict, + "--air_public_input can only be used in proof_mode.", + ); + return Err(Error::Cli(error)); + } let compiler_config = CompilerConfig { replace_ids: true, @@ -297,12 +306,11 @@ fn run(args: impl Iterator) -> Result, Erro // Run it until the end/ infinite loop in proof_mode runner.run_until_pc(end, &mut vm, &mut hint_processor)?; - + runner.end_run(false, false, &mut vm, &mut hint_processor)?; + vm.verify_auto_deductions()?; + runner.read_return_values(&mut vm)?; if args.proof_mode { - // Then pad it to the power of 2 - runner.run_until_next_power_of_2(&mut vm, &mut hint_processor)?; - } else { - runner.end_run(true, false, &mut vm, &mut hint_processor)?; + runner.finalize_segments(&mut vm)?; } // Fetch return type data @@ -354,6 +362,11 @@ fn run(args: impl Iterator) -> Result, Erro runner.relocate(&mut vm, true)?; + if let Some(file_path) = args.air_public_input { + let json = runner.get_air_public_input(&vm)?.serialize_json()?; + std::fs::write(file_path, json)?; + } + if let Some(trace_path) = args.trace_file { let relocated_trace = runner .relocated_trace @@ -695,7 +708,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/fibonacci.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/fibonacci.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/fibonacci.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null"].as_slice())] fn test_run_fibonacci_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(89)]); @@ -703,7 +716,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/factorial.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/factorial.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/factorial.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null"].as_slice())] fn test_run_factorial_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(3628800)]); @@ -711,7 +724,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/array_get.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/array_get.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/array_get.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null"].as_slice())] fn test_run_array_get_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(3)]); @@ -719,7 +732,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/enum_flow.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/enum_flow.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/enum_flow.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null"].as_slice())] fn test_run_enum_flow_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(300)]); @@ -727,7 +740,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/enum_match.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/enum_match.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/enum_match.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null"].as_slice())] fn test_run_enum_match_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(10), MaybeRelocatable::from(felt_str("3618502788666131213697322783095070105623107215331596699973092056135872020471"))]); @@ -735,7 +748,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/hello.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/hello.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/hello.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null"].as_slice())] fn test_run_hello_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(1), MaybeRelocatable::from(1234)]); @@ -743,7 +756,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/ops.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/ops.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/ops.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null"].as_slice())] fn test_run_ops_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(6)]); @@ -751,7 +764,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/print.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/print.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/print.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null"].as_slice())] fn test_run_print_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![]); @@ -759,7 +772,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/recursion.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/recursion.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/recursion.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null"].as_slice())] fn test_run_recursion_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(felt_str("1154076154663935037074198317650845438095734251249125412074882362667803016453"))]); @@ -767,7 +780,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/sample.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/sample.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/sample.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null"].as_slice())] fn test_run_sample_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(felt_str("5050"))]); @@ -775,7 +788,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/poseidon.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/poseidon.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/poseidon.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null"].as_slice())] fn test_run_poseidon_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(felt_str("1099385018355113290651252669115094675591288647745213771718157553170111442461"))]); @@ -783,7 +796,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/poseidon_pedersen.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/poseidon_pedersen.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/poseidon_pedersen.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null"].as_slice())] fn test_run_poseidon_pedersen_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(felt_str("1036257840396636296853154602823055519264738423488122322497453114874087006398"))]); @@ -791,7 +804,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/pedersen_example.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/pedersen_example.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/pedersen_example.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null"].as_slice())] fn test_run_pedersen_example_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(felt_str("1089549915800264549621536909767699778745926517555586332772759280702396009108"))]); @@ -799,7 +812,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/simple.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/simple.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/simple.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null"].as_slice())] fn test_run_simple_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(1)]); @@ -807,7 +820,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/simple_struct.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/simple_struct.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/simple_struct.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null"].as_slice())] fn test_run_simple_struct_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(100)]); @@ -815,7 +828,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/dictionaries.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/dictionaries.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/dictionaries.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null"].as_slice())] fn test_run_dictionaries(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(1024)]); From b3c4cbdda24f7add5772bb1c3f3b61dccf558972 Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 4 Jan 2024 12:34:23 -0300 Subject: [PATCH 06/30] Progress --- cairo1-run/src/main.rs | 44 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/cairo1-run/src/main.rs b/cairo1-run/src/main.rs index 1eca8a1860..f17d6ca6e7 100644 --- a/cairo1-run/src/main.rs +++ b/cairo1-run/src/main.rs @@ -307,11 +307,6 @@ fn run(args: impl Iterator) -> Result, Erro // Run it until the end/ infinite loop in proof_mode runner.run_until_pc(end, &mut vm, &mut hint_processor)?; runner.end_run(false, false, &mut vm, &mut hint_processor)?; - vm.verify_auto_deductions()?; - runner.read_return_values(&mut vm)?; - if args.proof_mode { - runner.finalize_segments(&mut vm)?; - } // Fetch return type data let return_type_id = main_func @@ -360,6 +355,45 @@ fn run(args: impl Iterator) -> Result, Erro } } + // Set stop pointers for builtins + if args.proof_mode { + let ret_types_sizes = main_func + .signature + .ret_types + .iter() + .map(|id| type_sizes.get(id).cloned().unwrap_or_default()); + let ret_types_and_sizes = main_func + .signature + .ret_types + .iter() + .zip(ret_types_sizes.clone()); + let full_ret_types_size: i16 = ret_types_sizes.sum(); + let mut stack_pointer = (vm.get_ap() - (full_ret_types_size - 1) as usize) + .map_err(VirtualMachineError::Math)?; + for (id, size) in ret_types_and_sizes { + if let Some(ref name) = id.debug_name { + let mut builtin_name = name.to_lowercase(); + if builtin_name == "rangecheck" { + builtin_name = "range_check".to_string(); + } + builtin_name = format!("{}_builtin", builtin_name.to_lowercase()); + if let Some(builtin) = vm + .builtin_runners + .iter_mut() + .find(|b| dbg!(b.name()) == dbg!(&builtin_name)) + { + // Fetch pointer from vm_ret_values + builtin.final_stack(&vm.segments, stack_pointer)?; + } + } + stack_pointer.offset += size as usize; + } + // Set stop pointer for builtins that are not included + // for builtin in vm.get_builtin_runners_as_mut() { + // if builtin.include + // } + } + runner.relocate(&mut vm, true)?; if let Some(file_path) = args.air_public_input { From e41994be2c018065e17e8797316e052d079c3ac1 Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 4 Jan 2024 12:43:09 -0300 Subject: [PATCH 07/30] Update builtins stop ptrs when running cairo 1 --- cairo1-run/src/main.rs | 31 +++++++++++++++++-------------- vm/src/types/relocatable.rs | 4 +++- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/cairo1-run/src/main.rs b/cairo1-run/src/main.rs index f17d6ca6e7..12131245c7 100644 --- a/cairo1-run/src/main.rs +++ b/cairo1-run/src/main.rs @@ -355,8 +355,8 @@ fn run(args: impl Iterator) -> Result, Erro } } - // Set stop pointers for builtins - if args.proof_mode { + // Set stop pointers for builtins so we can obtain the air public input + if args.air_public_input.is_some() { let ret_types_sizes = main_func .signature .ret_types @@ -367,9 +367,13 @@ fn run(args: impl Iterator) -> Result, Erro .ret_types .iter() .zip(ret_types_sizes.clone()); + let full_ret_types_size: i16 = ret_types_sizes.sum(); let mut stack_pointer = (vm.get_ap() - (full_ret_types_size - 1) as usize) .map_err(VirtualMachineError::Math)?; + + // Calculate the stack_ptr for each return value as if it were a builtin + let mut builtin_name_to_stack_pointer = HashMap::new(); for (id, size) in ret_types_and_sizes { if let Some(ref name) = id.debug_name { let mut builtin_name = name.to_lowercase(); @@ -377,21 +381,20 @@ fn run(args: impl Iterator) -> Result, Erro builtin_name = "range_check".to_string(); } builtin_name = format!("{}_builtin", builtin_name.to_lowercase()); - if let Some(builtin) = vm - .builtin_runners - .iter_mut() - .find(|b| dbg!(b.name()) == dbg!(&builtin_name)) - { - // Fetch pointer from vm_ret_values - builtin.final_stack(&vm.segments, stack_pointer)?; - } + builtin_name_to_stack_pointer.insert(builtin_name, stack_pointer); } stack_pointer.offset += size as usize; } - // Set stop pointer for builtins that are not included - // for builtin in vm.get_builtin_runners_as_mut() { - // if builtin.include - // } + // Set stop pointer for each builtin + for builtin in vm.builtin_runners.iter_mut() { + builtin.final_stack( + &vm.segments, + builtin_name_to_stack_pointer + .get(builtin.name()) + .cloned() + .unwrap_or_default(), + )?; + } } runner.relocate(&mut vm, true)?; diff --git a/vm/src/types/relocatable.rs b/vm/src/types/relocatable.rs index 353be453ae..3ffe9d8c9f 100644 --- a/vm/src/types/relocatable.rs +++ b/vm/src/types/relocatable.rs @@ -15,7 +15,9 @@ use serde::{Deserialize, Serialize}; use arbitrary::Arbitrary; #[cfg_attr(all(feature = "arbitrary", feature = "std"), derive(Arbitrary))] -#[derive(Eq, Ord, Hash, PartialEq, PartialOrd, Clone, Copy, Debug, Serialize, Deserialize)] +#[derive( + Eq, Ord, Hash, PartialEq, PartialOrd, Clone, Copy, Debug, Serialize, Deserialize, Default, +)] pub struct Relocatable { pub segment_index: isize, pub offset: usize, From 378a0fe9e355251363d2fc82bd738f0474a2c144 Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 4 Jan 2024 12:43:56 -0300 Subject: [PATCH 08/30] Change visibility --- vm/src/vm/vm_core.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/src/vm/vm_core.rs b/vm/src/vm/vm_core.rs index 98b0c32904..a33fd37aa2 100644 --- a/vm/src/vm/vm_core.rs +++ b/vm/src/vm/vm_core.rs @@ -78,7 +78,7 @@ impl DeducedOperands { pub struct VirtualMachine { pub(crate) run_context: RunContext, - pub(crate) builtin_runners: Vec, + pub builtin_runners: Vec, pub(crate) segments: MemorySegmentManager, pub(crate) trace: Option>, pub(crate) current_step: usize, From f633fc480e5992eb0b9a055bf7eb575ee227f009 Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 4 Jan 2024 12:44:41 -0300 Subject: [PATCH 09/30] Change visibility --- vm/src/vm/vm_core.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/src/vm/vm_core.rs b/vm/src/vm/vm_core.rs index a33fd37aa2..100169c87b 100644 --- a/vm/src/vm/vm_core.rs +++ b/vm/src/vm/vm_core.rs @@ -79,7 +79,7 @@ impl DeducedOperands { pub struct VirtualMachine { pub(crate) run_context: RunContext, pub builtin_runners: Vec, - pub(crate) segments: MemorySegmentManager, + pub segments: MemorySegmentManager, pub(crate) trace: Option>, pub(crate) current_step: usize, pub(crate) rc_limits: Option<(isize, isize)>, From 20776b49d4c80bed75b394281663bd1dc493a4d5 Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 4 Jan 2024 12:51:27 -0300 Subject: [PATCH 10/30] Fix --- cairo1-run/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cairo1-run/src/main.rs b/cairo1-run/src/main.rs index 12131245c7..6267275b4d 100644 --- a/cairo1-run/src/main.rs +++ b/cairo1-run/src/main.rs @@ -369,7 +369,7 @@ fn run(args: impl Iterator) -> Result, Erro .zip(ret_types_sizes.clone()); let full_ret_types_size: i16 = ret_types_sizes.sum(); - let mut stack_pointer = (vm.get_ap() - (full_ret_types_size - 1) as usize) + let mut stack_pointer = (vm.get_ap() - (full_ret_types_size as usize).saturating_sub(1)) .map_err(VirtualMachineError::Math)?; // Calculate the stack_ptr for each return value as if it were a builtin From 9fbb0c648d18d39f92764230639d62c5d500a4d8 Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 4 Jan 2024 12:54:53 -0300 Subject: [PATCH 11/30] Fix trace not enables --- cairo1-run/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cairo1-run/src/main.rs b/cairo1-run/src/main.rs index 6267275b4d..3fe6b0d7fe 100644 --- a/cairo1-run/src/main.rs +++ b/cairo1-run/src/main.rs @@ -299,7 +299,7 @@ fn run(args: impl Iterator) -> Result, Erro let mut runner = CairoRunner::new_v2(&program, &args.layout, runner_mode)?; - let mut vm = VirtualMachine::new(args.trace_file.is_some()); + let mut vm = VirtualMachine::new(args.trace_file.is_some() || args.air_public_input.is_some()); let end = runner.initialize(&mut vm)?; additional_initialization(&mut vm, data_len)?; From c1779db44049be229e6620fc2d872f27867baf6a Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 4 Jan 2024 13:02:25 -0300 Subject: [PATCH 12/30] Build execution public memory --- cairo1-run/src/main.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cairo1-run/src/main.rs b/cairo1-run/src/main.rs index 3fe6b0d7fe..27e885dde0 100644 --- a/cairo1-run/src/main.rs +++ b/cairo1-run/src/main.rs @@ -395,6 +395,9 @@ fn run(args: impl Iterator) -> Result, Erro .unwrap_or_default(), )?; } + + // Build execution public memory + runner.finalize_segments(&mut vm)?; } runner.relocate(&mut vm, true)?; From 02df22eb324c2dafaa3232161545a4ba2801fe4e Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 8 Jan 2024 16:17:19 -0300 Subject: [PATCH 13/30] Handle EcOp case --- cairo1-run/src/main.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cairo1-run/src/main.rs b/cairo1-run/src/main.rs index 27e885dde0..6d87644d9b 100644 --- a/cairo1-run/src/main.rs +++ b/cairo1-run/src/main.rs @@ -377,9 +377,14 @@ fn run(args: impl Iterator) -> Result, Erro for (id, size) in ret_types_and_sizes { if let Some(ref name) = id.debug_name { let mut builtin_name = name.to_lowercase(); + // This could be avoided by propery converting between UpperCamelCase & snake_case + // But given the limited amount of cases it is possible to handle it manually instead of adding an external dependency if builtin_name == "rangecheck" { builtin_name = "range_check".to_string(); } + if builtin_name == "ecop" { + builtin_name = "ec_op".to_string(); + } builtin_name = format!("{}_builtin", builtin_name.to_lowercase()); builtin_name_to_stack_pointer.insert(builtin_name, stack_pointer); } From efda66e8253b383765dd4a23feba054109b44ca8 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 8 Jan 2024 16:19:30 -0300 Subject: [PATCH 14/30] Fix typo --- cairo1-run/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cairo1-run/src/main.rs b/cairo1-run/src/main.rs index 6d87644d9b..e5e864ab95 100644 --- a/cairo1-run/src/main.rs +++ b/cairo1-run/src/main.rs @@ -377,7 +377,7 @@ fn run(args: impl Iterator) -> Result, Erro for (id, size) in ret_types_and_sizes { if let Some(ref name) = id.debug_name { let mut builtin_name = name.to_lowercase(); - // This could be avoided by propery converting between UpperCamelCase & snake_case + // This could be avoided by properly converting between UpperCamelCase & snake_case // But given the limited amount of cases it is possible to handle it manually instead of adding an external dependency if builtin_name == "rangecheck" { builtin_name = "range_check".to_string(); From b3f71d00e671e260be2d09b330c23fd7386a5989 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 8 Jan 2024 16:31:58 -0300 Subject: [PATCH 15/30] Use cleaner solution --- cairo1-run/src/main.rs | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/cairo1-run/src/main.rs b/cairo1-run/src/main.rs index e5e864ab95..cab9b0235b 100644 --- a/cairo1-run/src/main.rs +++ b/cairo1-run/src/main.rs @@ -47,6 +47,10 @@ use cairo_vm::vm::errors::memory_errors::MemoryError; use cairo_vm::vm::errors::runner_errors::RunnerError; use cairo_vm::vm::errors::trace_errors::TraceError; use cairo_vm::vm::errors::vm_errors::VirtualMachineError; +use cairo_vm::vm::runners::builtin_runner::{ + BITWISE_BUILTIN_NAME, EC_OP_BUILTIN_NAME, HASH_BUILTIN_NAME, OUTPUT_BUILTIN_NAME, + POSEIDON_BUILTIN_NAME, RANGE_CHECK_BUILTIN_NAME, SIGNATURE_BUILTIN_NAME, +}; use cairo_vm::vm::runners::cairo_runner::RunnerMode; use cairo_vm::{ serde::deserialize_program::ReferenceManager, @@ -376,16 +380,16 @@ fn run(args: impl Iterator) -> Result, Erro let mut builtin_name_to_stack_pointer = HashMap::new(); for (id, size) in ret_types_and_sizes { if let Some(ref name) = id.debug_name { - let mut builtin_name = name.to_lowercase(); - // This could be avoided by properly converting between UpperCamelCase & snake_case - // But given the limited amount of cases it is possible to handle it manually instead of adding an external dependency - if builtin_name == "rangecheck" { - builtin_name = "range_check".to_string(); - } - if builtin_name == "ecop" { - builtin_name = "ec_op".to_string(); - } - builtin_name = format!("{}_builtin", builtin_name.to_lowercase()); + let builtin_name = match &*name.to_string() { + "RangeCheck" => RANGE_CHECK_BUILTIN_NAME, + "Poseidon" => POSEIDON_BUILTIN_NAME, + "EcOp" => EC_OP_BUILTIN_NAME, + "Bitwise" => BITWISE_BUILTIN_NAME, + "Pedersen" => HASH_BUILTIN_NAME, + "Output" => OUTPUT_BUILTIN_NAME, + "Ecdsa" => SIGNATURE_BUILTIN_NAME, + _ => break, + }; builtin_name_to_stack_pointer.insert(builtin_name, stack_pointer); } stack_pointer.offset += size as usize; From a9c67d53b6991fb6c8d172e6488352c2a3d8ce98 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 8 Jan 2024 16:36:19 -0300 Subject: [PATCH 16/30] Fix --- cairo1-run/src/main.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cairo1-run/src/main.rs b/cairo1-run/src/main.rs index cab9b0235b..45810d3ad7 100644 --- a/cairo1-run/src/main.rs +++ b/cairo1-run/src/main.rs @@ -388,7 +388,10 @@ fn run(args: impl Iterator) -> Result, Erro "Pedersen" => HASH_BUILTIN_NAME, "Output" => OUTPUT_BUILTIN_NAME, "Ecdsa" => SIGNATURE_BUILTIN_NAME, - _ => break, + _ => { + stack_pointer.offset += size as usize; + continue; + } }; builtin_name_to_stack_pointer.insert(builtin_name, stack_pointer); } From d821708b18cd7912a8a9403b016d1c47ea268d1d Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 8 Jan 2024 16:45:55 -0300 Subject: [PATCH 17/30] Improve comments --- cairo1-run/src/main.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cairo1-run/src/main.rs b/cairo1-run/src/main.rs index 45810d3ad7..b8d4c64a0c 100644 --- a/cairo1-run/src/main.rs +++ b/cairo1-run/src/main.rs @@ -361,6 +361,7 @@ fn run(args: impl Iterator) -> Result, Erro // Set stop pointers for builtins so we can obtain the air public input if args.air_public_input.is_some() { + // Cairo 1 programs have other return values aside from the used builtin's final pointers, so we need to hand-pick them let ret_types_sizes = main_func .signature .ret_types @@ -376,7 +377,7 @@ fn run(args: impl Iterator) -> Result, Erro let mut stack_pointer = (vm.get_ap() - (full_ret_types_size as usize).saturating_sub(1)) .map_err(VirtualMachineError::Math)?; - // Calculate the stack_ptr for each return value as if it were a builtin + // Calculate the stack_ptr for each return builtin in the return values let mut builtin_name_to_stack_pointer = HashMap::new(); for (id, size) in ret_types_and_sizes { if let Some(ref name) = id.debug_name { From b3bd50cd8bbd81fbf41c8f1721ca48aa3abb0d8b Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 8 Jan 2024 16:50:41 -0300 Subject: [PATCH 18/30] Add changelog entry --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ac6dd24a22..604f6a5abe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ #### Upcoming Changes +* feat: Add `air_public_input` flag to `cairo1-run` [#1539] (https://github.com/lambdaclass/cairo-vm/pull/1539) + * feat: Add `proof_mode` flag to `cairo1-run` [#1537] (https://github.com/lambdaclass/cairo-vm/pull/1537) * The cairo1-run crate no longer compiles and executes in proof_mode by default * Add flag `proof_mode` to cairo1-run crate. Activating this flag will enable proof_mode compilation and execution From 4ee531a0b837b1995bf1a9b01a20cd20a3df79cc Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 9 Jan 2024 14:24:06 -0300 Subject: [PATCH 19/30] Add args flag --- cairo1-run/src/main.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cairo1-run/src/main.rs b/cairo1-run/src/main.rs index b8d4c64a0c..8f01bbdadc 100644 --- a/cairo1-run/src/main.rs +++ b/cairo1-run/src/main.rs @@ -85,6 +85,8 @@ struct Args { proof_mode: bool, #[clap(long = "air_public_input", value_parser)] air_public_input: Option, + #[clap(long = "args", num_args=1.., value_delimiter = ' ')] + args: Vec, } fn validate_layout(value: &str) -> Result { From ab2d47f73b870e951919abaf2a39943ca538ec33 Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 9 Jan 2024 15:04:40 -0300 Subject: [PATCH 20/30] Handle arguments --- cairo1-run/src/main.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/cairo1-run/src/main.rs b/cairo1-run/src/main.rs index 8f01bbdadc..2fd9280bc0 100644 --- a/cairo1-run/src/main.rs +++ b/cairo1-run/src/main.rs @@ -220,6 +220,7 @@ fn run(args: impl Iterator) -> Result, Erro main_func, initial_gas, args.proof_mode, + &args.args, )?; // Get the user program instructions @@ -564,6 +565,7 @@ fn create_entry_code( func: &Function, initial_gas: usize, proof_mode: bool, + args: &Vec, ) -> Result<(Vec, Vec), Error> { let mut ctx = casm! {}; // The builtins in the formatting expected by the runner. @@ -571,6 +573,7 @@ fn create_entry_code( // Load all vecs to memory. let mut ap_offset: i16 = 0; let after_vecs_offset = ap_offset; + let mut arg_iter = args.iter(); if func.signature.param_types.iter().any(|ty| { get_info(sierra_program_registry, ty) .map(|x| x.long_id.generic_id == SegmentArenaType::ID) @@ -618,7 +621,8 @@ fn create_entry_code( casm_extend! {ctx, [ap + 0] = [ap + offset] + 3, ap++; } - // This code should be re enabled to make the programs work with arguments + + // This cli's args flag only supports single values, so we skip the array handling // } else if let Some(Arg::Array(_)) = arg_iter.peek() { // let values = extract_matches!(arg_iter.next().unwrap(), Arg::Array); @@ -639,6 +643,17 @@ fn create_entry_code( // } // } // } + } else { + let arg_size = ty_size; + //expected_arguments_size += arg_size as usize; + for _ in 0..arg_size { + if let Some(value) = arg_iter.next() { + let value = Felt252::from_dec_str(value).unwrap(); + casm_extend! {ctx, + [ap + 0] = (value.to_bigint()), ap++; + } + } + } }; ap_offset += ty_size; } From 169ed181446e5c979ae28c4e199eec3fa3bc663c Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 9 Jan 2024 15:11:42 -0300 Subject: [PATCH 21/30] Handle arg size & add tests --- cairo1-run/src/main.rs | 49 ++++++++++++++++--- .../cairo-1-programs/branching.cairo | 7 +++ 2 files changed, 49 insertions(+), 7 deletions(-) create mode 100644 cairo_programs/cairo-1-programs/branching.cairo diff --git a/cairo1-run/src/main.rs b/cairo1-run/src/main.rs index 2fd9280bc0..19c49d2aeb 100644 --- a/cairo1-run/src/main.rs +++ b/cairo1-run/src/main.rs @@ -144,6 +144,8 @@ enum Error { NoInfoForType(ConcreteTypeId), #[error("Failed to extract return values from VM")] FailedToExtractReturnValues, + #[error("Function expects arguments of size {expected} and received {actual} instead.")] + ArgumentsSizeMismatch { expected: usize, actual: usize }, } pub struct FileWriter { @@ -574,6 +576,7 @@ fn create_entry_code( let mut ap_offset: i16 = 0; let after_vecs_offset = ap_offset; let mut arg_iter = args.iter(); + let mut expected_arguments_size = 0; if func.signature.param_types.iter().any(|ty| { get_info(sierra_program_registry, ty) .map(|x| x.long_id.generic_id == SegmentArenaType::ID) @@ -645,7 +648,7 @@ fn create_entry_code( // } } else { let arg_size = ty_size; - //expected_arguments_size += arg_size as usize; + expected_arguments_size += arg_size as usize; for _ in 0..arg_size { if let Some(value) = arg_iter.next() { let value = Felt252::from_dec_str(value).unwrap(); @@ -657,12 +660,12 @@ fn create_entry_code( }; ap_offset += ty_size; } - // if expected_arguments_size != args.len() { - // return Err(RunnerError::ArgumentsSizeMismatch { - // expected: expected_arguments_size, - // actual: args.len(), - // }); - // } + if expected_arguments_size != args.len() { + return Err(Error::ArgumentsSizeMismatch { + expected: expected_arguments_size, + actual: args.len(), + }); + } let before_final_call = ctx.current_code_offset; let final_call_size = 3; @@ -903,4 +906,36 @@ mod tests { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(1024)]); } + + #[rstest] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/dictionaries.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--args", "0"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/dictionaries.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null", "--args", "0"].as_slice())] + fn test_run_branching_0(#[case] args: &[&str]) { + let args = args.iter().cloned().map(String::from); + assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(1)]); + } + + #[rstest] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/dictionaries.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--args", "17"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/dictionaries.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null", "--args", "96"].as_slice())] + fn test_run_branching_not_0(#[case] args: &[&str]) { + let args = args.iter().cloned().map(String::from); + assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(0)]); + } + + #[rstest] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/dictionaries.cairo", "--layout", "all_cairo"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/dictionaries.cairo", "--layout", "all_cairo", "--proof_mode"].as_slice())] + fn test_run_branching_no_args(#[case] args: &[&str]) { + let args = args.iter().cloned().map(String::from); + assert_matches!(run(args), Err(Error::ArgumentsSizeMismatch { expected, actual }) if expected == 1 && actual == 0); + } + + #[rstest] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/dictionaries.cairo", "--layout", "all_cairo","--args", "1, 2, 3"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/dictionaries.cairo", "--layout", "all_cairo", "--proof_mode", "--args", "1, 2, 3"].as_slice())] + fn test_run_branching_too_many_args(#[case] args: &[&str]) { + let args = args.iter().cloned().map(String::from); + assert_matches!(run(args), Err(Error::ArgumentsSizeMismatch { expected, actual }) if expected == 1 && actual == 3); + } } diff --git a/cairo_programs/cairo-1-programs/branching.cairo b/cairo_programs/cairo-1-programs/branching.cairo new file mode 100644 index 0000000000..639763b849 --- /dev/null +++ b/cairo_programs/cairo-1-programs/branching.cairo @@ -0,0 +1,7 @@ +fn main(argc: u32) -> u8 { + if argc == 0 { + 1_u8 + } else { + 0_u8 + } +} From 482ead4a223c6daccf1e60ac0cb7c0eb4d098466 Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 9 Jan 2024 17:37:03 -0300 Subject: [PATCH 22/30] Parse array arguments --- cairo1-run/README.md | 21 ++- cairo1-run/src/main.rs | 139 +++++++++++++----- .../cairo-1-programs/array_input_sum.cairo | 5 + 3 files changed, 124 insertions(+), 41 deletions(-) create mode 100644 cairo_programs/cairo-1-programs/array_input_sum.cairo diff --git a/cairo1-run/README.md b/cairo1-run/README.md index 95be3b5ecb..df881d3d6d 100644 --- a/cairo1-run/README.md +++ b/cairo1-run/README.md @@ -5,9 +5,10 @@ A cairo-vm crate to run Cairo 1 Programs Once you are inside the `./cairo1-run` folder, use the CLI with the following commands To install the required dependencies(cairo corelib) run + ```bash make deps -``` +``` Now that you have the dependencies necessary to run the tests, you can run: @@ -16,16 +17,32 @@ make test ``` To execute a cairo 1 program + ```bash cargo run ../cairo_programs/cairo-1-programs/fibonacci.cairo ``` Arguments to generate the trace and memory files + ```bash cargo run ../cairo_programs/cairo-1-programs/fibonacci.cairo --trace_file ../cairo_programs/cairo-1-programs/fibonacci.trace --memory_file ../cairo_programs/cairo-1-programs/fibonacci.memory ``` +To pass arguments to `main` + +* Separate arguments with a space in between +* In order to pass arrays, wrap array values inside brackets + +Example: + +```bash + +cargo run ../cairo_programs/cairo-1-programs/array_input_sum.cairo --args '2 [1 2 3 4] 0 [9 8]' + +``` + To execute all the cairo 1 programs inside `../cairo_programs/cairo-1-programs/` and generate the corresponding trace and the memory files + ```bash make run -``` +``` diff --git a/cairo1-run/src/main.rs b/cairo1-run/src/main.rs index 19c49d2aeb..a3bbe9b622 100644 --- a/cairo1-run/src/main.rs +++ b/cairo1-run/src/main.rs @@ -4,6 +4,7 @@ use cairo_lang_casm::casm; use cairo_lang_casm::casm_extend; use cairo_lang_casm::hints::Hint; use cairo_lang_casm::instructions::Instruction; +use cairo_lang_compiler::db; use cairo_lang_compiler::{compile_cairo_project_at_path, CompilerConfig}; use cairo_lang_sierra::extensions::bitwise::BitwiseType; use cairo_lang_sierra::extensions::core::{CoreLibfunc, CoreType}; @@ -30,6 +31,7 @@ use cairo_lang_sierra_to_casm::metadata::MetadataComputationConfig; use cairo_lang_sierra_to_casm::metadata::MetadataError; use cairo_lang_sierra_to_casm::{compiler::compile, metadata::calc_metadata}; use cairo_lang_sierra_type_size::get_type_size_map; +use cairo_lang_utils::extract_matches; use cairo_lang_utils::ordered_hash_map::OrderedHashMap; use cairo_lang_utils::unordered_hash_map::UnorderedHashMap; use cairo_vm::air_public_input::PublicInputError; @@ -85,8 +87,54 @@ struct Args { proof_mode: bool, #[clap(long = "air_public_input", value_parser)] air_public_input: Option, - #[clap(long = "args", num_args=1.., value_delimiter = ' ')] - args: Vec, + // Arguments should be spaced, with array elements placed between brackets + // For example " --args '1 2 [1 2 3]'" will yield 3 arguments, with the last one being an array of 3 elements + #[clap(long = "args", default_value = "", value_parser=process_args)] + args: FuncArgs, +} + +#[derive(Debug, Clone)] +enum FuncArg { + Array(Vec), + Single(Felt252), +} + +#[derive(Debug, Clone, Default)] +struct FuncArgs(Vec); + +fn process_args(value: &str) -> Result { + let mut args = Vec::new(); + if value.is_empty() { + return Ok(FuncArgs::default()); + } + let mut input = value.split(' '); + while let Some(value) = input.next() { + // First argument in an array + if value.starts_with('[') { + let mut array_arg = + vec![Felt252::from_dec_str(value.strip_prefix('[').unwrap()).unwrap()]; + // Process following args in array + let mut array_end = false; + while !array_end { + if let Some(value) = input.next() { + // Last arg in array + if value.ends_with(']') { + array_arg + .push(Felt252::from_dec_str(value.strip_suffix(']').unwrap()).unwrap()); + array_end = true; + } else { + array_arg.push(Felt252::from_dec_str(value).unwrap()) + } + } + } + // Finalize array + args.push(FuncArg::Array(array_arg)) + } else { + // Single argument + args.push(FuncArg::Single(Felt252::from_dec_str(value).unwrap())) + } + } + Ok(FuncArgs(args)) } fn validate_layout(value: &str) -> Result { @@ -222,7 +270,7 @@ fn run(args: impl Iterator) -> Result, Erro main_func, initial_gas, args.proof_mode, - &args.args, + &args.args.0, )?; // Get the user program instructions @@ -338,7 +386,7 @@ fn run(args: impl Iterator) -> Result, Erro { // Check the failure flag (aka first return value) if return_values.first() != Some(&MaybeRelocatable::from(0)) { - // In case of failure, extract the error from teh return values (aka last two values) + // In case of failure, extract the error from the return values (aka last two values) let panic_data_end = return_values .last() .ok_or(Error::FailedToExtractReturnValues)? @@ -567,15 +615,34 @@ fn create_entry_code( func: &Function, initial_gas: usize, proof_mode: bool, - args: &Vec, + args: &Vec, ) -> Result<(Vec, Vec), Error> { let mut ctx = casm! {}; // The builtins in the formatting expected by the runner. let (builtins, builtin_offset) = get_function_builtins(func); // Load all vecs to memory. + // Load all array args content to memory. + let mut array_args_data = vec![]; let mut ap_offset: i16 = 0; - let after_vecs_offset = ap_offset; - let mut arg_iter = args.iter(); + for arg in args { + let FuncArg::Array(values) = arg else { continue }; + array_args_data.push(ap_offset); + casm_extend! {ctx, + %{ memory[ap + 0] = segments.add() %} + ap += 1; + } + for (i, v) in values.iter().enumerate() { + let arr_at = (i + 1) as i16; + casm_extend! {ctx, + [ap + 0] = (v.to_bigint()); + [ap + 0] = [[ap - arr_at] + (i as i16)], ap++; + }; + } + ap_offset += (1 + values.len()) as i16; + } + let mut array_args_data_iter = array_args_data.iter(); + let after_arrays_data_offset = ap_offset; + let mut arg_iter = args.iter().peekable(); let mut expected_arguments_size = 0; if func.signature.param_types.iter().any(|ty| { get_info(sierra_program_registry, ty) @@ -620,38 +687,24 @@ fn create_entry_code( [ap + 0] = initial_gas, ap++; } } else if generic_ty == &SegmentArenaType::ID { - let offset = -ap_offset + after_vecs_offset; + let offset = -ap_offset + after_arrays_data_offset; casm_extend! {ctx, [ap + 0] = [ap + offset] + 3, ap++; } - - // This cli's args flag only supports single values, so we skip the array handling - - // } else if let Some(Arg::Array(_)) = arg_iter.peek() { - // let values = extract_matches!(arg_iter.next().unwrap(), Arg::Array); - // let offset = -ap_offset + vecs.pop().unwrap(); - // expected_arguments_size += 1; - // casm_extend! {ctx, - // [ap + 0] = [ap + (offset)], ap++; - // [ap + 0] = [ap - 1] + (values.len()), ap++; - // } - // } else { - // let arg_size = ty_size; - // expected_arguments_size += arg_size as usize; - // for _ in 0..arg_size { - // if let Some(value) = arg_iter.next() { - // let value = extract_matches!(value, Arg::Value); - // casm_extend! {ctx, - // [ap + 0] = (value.to_bigint()), ap++; - // } - // } - // } + } else if let Some(FuncArg::Array(_)) = arg_iter.peek() { + let values = extract_matches!(arg_iter.next().unwrap(), FuncArg::Array); + let offset = -ap_offset + array_args_data_iter.next().unwrap(); + expected_arguments_size += 1; + casm_extend! {ctx, + [ap + 0] = [ap + (offset)], ap++; + [ap + 0] = [ap - 1] + (values.len()), ap++; + } } else { let arg_size = ty_size; expected_arguments_size += arg_size as usize; for _ in 0..arg_size { if let Some(value) = arg_iter.next() { - let value = Felt252::from_dec_str(value).unwrap(); + let value = extract_matches!(value, FuncArg::Single); casm_extend! {ctx, [ap + 0] = (value.to_bigint()), ap++; } @@ -908,34 +961,42 @@ mod tests { } #[rstest] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/dictionaries.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--args", "0"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/dictionaries.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null", "--args", "0"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/branching.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--args", "0"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/branching.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null", "--args", "0"].as_slice())] fn test_run_branching_0(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(1)]); } #[rstest] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/dictionaries.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--args", "17"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/dictionaries.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null", "--args", "96"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/branching.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--args", "17"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/branching.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null", "--args", "96"].as_slice())] fn test_run_branching_not_0(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(0)]); } #[rstest] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/dictionaries.cairo", "--layout", "all_cairo"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/dictionaries.cairo", "--layout", "all_cairo", "--proof_mode"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/branching.cairo", "--layout", "all_cairo"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/branching.cairo", "--layout", "all_cairo", "--proof_mode"].as_slice())] fn test_run_branching_no_args(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Err(Error::ArgumentsSizeMismatch { expected, actual }) if expected == 1 && actual == 0); } #[rstest] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/dictionaries.cairo", "--layout", "all_cairo","--args", "1, 2, 3"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/dictionaries.cairo", "--layout", "all_cairo", "--proof_mode", "--args", "1, 2, 3"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/branching.cairo", "--layout", "all_cairo","--args", "1 2 3"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/branching.cairo", "--layout", "all_cairo", "--proof_mode", "--args", "1 2 3"].as_slice())] fn test_run_branching_too_many_args(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Err(Error::ArgumentsSizeMismatch { expected, actual }) if expected == 1 && actual == 3); } + + #[rstest] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/array_input_sum.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--args", "2 [1 2 3 4] 0 [9 8]"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/array_input_sum.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null", "--args", "2 [1 2 3 4] 0 [9 8]"].as_slice())] + fn test_array_input_sum(#[case] args: &[&str]) { + let args = args.iter().cloned().map(String::from); + assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(12)]); + } } diff --git a/cairo_programs/cairo-1-programs/array_input_sum.cairo b/cairo_programs/cairo-1-programs/array_input_sum.cairo new file mode 100644 index 0000000000..1c75b21549 --- /dev/null +++ b/cairo_programs/cairo-1-programs/array_input_sum.cairo @@ -0,0 +1,5 @@ +use array::ArrayTrait; + +fn main(index_a: u32, array_a: Array, index_b: u32, array_b: Array) -> u32 { + *array_a.at(index_a) + *array_b.at(index_b) +} From 3b81dd30ef58fd0ea1f5566a255c2d222447e2cd Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 9 Jan 2024 17:46:39 -0300 Subject: [PATCH 23/30] Fix language --- cairo1-run/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cairo1-run/README.md b/cairo1-run/README.md index df881d3d6d..374cbec981 100644 --- a/cairo1-run/README.md +++ b/cairo1-run/README.md @@ -30,8 +30,8 @@ cargo run ../cairo_programs/cairo-1-programs/fibonacci.cairo --trace_file ../cai To pass arguments to `main` -* Separate arguments with a space in between -* In order to pass arrays, wrap array values inside brackets +* Separate arguments with a whitespace inbetween +* In order to pass arrays, wrap array values between brackets Example: From a73b023c11d7506b8c51ff02e57dcae7a985be72 Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 9 Jan 2024 17:48:51 -0300 Subject: [PATCH 24/30] reorder --- cairo1-run/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cairo1-run/src/main.rs b/cairo1-run/src/main.rs index a3bbe9b622..0425297579 100644 --- a/cairo1-run/src/main.rs +++ b/cairo1-run/src/main.rs @@ -103,10 +103,10 @@ enum FuncArg { struct FuncArgs(Vec); fn process_args(value: &str) -> Result { - let mut args = Vec::new(); if value.is_empty() { return Ok(FuncArgs::default()); } + let mut args = Vec::new(); let mut input = value.split(' '); while let Some(value) = input.next() { // First argument in an array From fd93a34725c1c82329c1f769a275606f0672b8e6 Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 9 Jan 2024 17:50:53 -0300 Subject: [PATCH 25/30] Add changelog entry --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 604f6a5abe..fc8f15ebb9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ #### Upcoming Changes +* feat: Add `args` flag to `cairo1-run` [#15551] (https://github.com/lambdaclass/cairo-vm/pull/15551) + * feat: Add `air_public_input` flag to `cairo1-run` [#1539] (https://github.com/lambdaclass/cairo-vm/pull/1539) * feat: Add `proof_mode` flag to `cairo1-run` [#1537] (https://github.com/lambdaclass/cairo-vm/pull/1537) From 38070d8fb6d1d2e0da83db5827f228bc77d950c7 Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 9 Jan 2024 18:18:55 -0300 Subject: [PATCH 26/30] Move programs with args to an inner folder --- cairo1-run/src/main.rs | 20 +++++++++---------- .../{ => with_input}/array_input_sum.cairo | 0 .../{ => with_input}/branching.cairo | 0 3 files changed, 10 insertions(+), 10 deletions(-) rename cairo_programs/cairo-1-programs/{ => with_input}/array_input_sum.cairo (100%) rename cairo_programs/cairo-1-programs/{ => with_input}/branching.cairo (100%) diff --git a/cairo1-run/src/main.rs b/cairo1-run/src/main.rs index 0425297579..6ef3932dff 100644 --- a/cairo1-run/src/main.rs +++ b/cairo1-run/src/main.rs @@ -961,40 +961,40 @@ mod tests { } #[rstest] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/branching.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--args", "0"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/branching.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null", "--args", "0"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/with_input/branching.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--args", "0"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/with_input/branching.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null", "--args", "0"].as_slice())] fn test_run_branching_0(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(1)]); } #[rstest] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/branching.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--args", "17"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/branching.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null", "--args", "96"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/with_input/branching.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--args", "17"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/with_input/branching.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null", "--args", "96"].as_slice())] fn test_run_branching_not_0(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(0)]); } #[rstest] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/branching.cairo", "--layout", "all_cairo"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/branching.cairo", "--layout", "all_cairo", "--proof_mode"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/with_input/branching.cairo", "--layout", "all_cairo"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/with_input/branching.cairo", "--layout", "all_cairo", "--proof_mode"].as_slice())] fn test_run_branching_no_args(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Err(Error::ArgumentsSizeMismatch { expected, actual }) if expected == 1 && actual == 0); } #[rstest] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/branching.cairo", "--layout", "all_cairo","--args", "1 2 3"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/branching.cairo", "--layout", "all_cairo", "--proof_mode", "--args", "1 2 3"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/with_input/branching.cairo", "--layout", "all_cairo","--args", "1 2 3"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/with_input/branching.cairo", "--layout", "all_cairo", "--proof_mode", "--args", "1 2 3"].as_slice())] fn test_run_branching_too_many_args(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Err(Error::ArgumentsSizeMismatch { expected, actual }) if expected == 1 && actual == 3); } #[rstest] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/array_input_sum.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--args", "2 [1 2 3 4] 0 [9 8]"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/array_input_sum.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null", "--args", "2 [1 2 3 4] 0 [9 8]"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/with_input/array_input_sum.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--args", "2 [1 2 3 4] 0 [9 8]"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/with_input/array_input_sum.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null", "--args", "2 [1 2 3 4] 0 [9 8]"].as_slice())] fn test_array_input_sum(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(12)]); diff --git a/cairo_programs/cairo-1-programs/array_input_sum.cairo b/cairo_programs/cairo-1-programs/with_input/array_input_sum.cairo similarity index 100% rename from cairo_programs/cairo-1-programs/array_input_sum.cairo rename to cairo_programs/cairo-1-programs/with_input/array_input_sum.cairo diff --git a/cairo_programs/cairo-1-programs/branching.cairo b/cairo_programs/cairo-1-programs/with_input/branching.cairo similarity index 100% rename from cairo_programs/cairo-1-programs/branching.cairo rename to cairo_programs/cairo-1-programs/with_input/branching.cairo From fce43d24a2c14259f017113b91e4f0118495243d Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 11 Jan 2024 10:32:57 -0300 Subject: [PATCH 27/30] Fix README example --- cairo1-run/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cairo1-run/README.md b/cairo1-run/README.md index 374cbec981..dfa835af8c 100644 --- a/cairo1-run/README.md +++ b/cairo1-run/README.md @@ -37,7 +37,7 @@ Example: ```bash -cargo run ../cairo_programs/cairo-1-programs/array_input_sum.cairo --args '2 [1 2 3 4] 0 [9 8]' +cargo run ../cairo_programs/cairo-1-programs/with_input/array_input_sum.cairo --layout all_cairo --args '2 [1 2 3 4] 0 [9 8]' ``` From 27d54907912bf9bbdc9fb669f3f62f8a1c7ee451 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 15 Jan 2024 11:04:28 -0300 Subject: [PATCH 28/30] Apply input arguments fix from cairo_lang --- cairo1-run/src/main.rs | 70 +++++++++++++++++++++++++++++------------- 1 file changed, 49 insertions(+), 21 deletions(-) diff --git a/cairo1-run/src/main.rs b/cairo1-run/src/main.rs index 6ef3932dff..dbbbd76b5a 100644 --- a/cairo1-run/src/main.rs +++ b/cairo1-run/src/main.rs @@ -193,7 +193,12 @@ enum Error { #[error("Failed to extract return values from VM")] FailedToExtractReturnValues, #[error("Function expects arguments of size {expected} and received {actual} instead.")] - ArgumentsSizeMismatch { expected: usize, actual: usize }, + ArgumentsSizeMismatch { expected: i16, actual: i16 }, + #[error("Function param {param_index} only partially contains argument {arg_index}.")] + ArgumentUnaligned { + param_index: usize, + arg_index: usize, + }, } pub struct FileWriter { @@ -642,7 +647,8 @@ fn create_entry_code( } let mut array_args_data_iter = array_args_data.iter(); let after_arrays_data_offset = ap_offset; - let mut arg_iter = args.iter().peekable(); + let mut arg_iter = args.iter().enumerate(); + let mut param_index = 0; let mut expected_arguments_size = 0; if func.signature.param_types.iter().any(|ty| { get_info(sierra_program_registry, ty) @@ -666,7 +672,6 @@ fn create_entry_code( for ty in func.signature.param_types.iter() { let info = get_info(sierra_program_registry, ty) .ok_or_else(|| Error::NoInfoForType(ty.clone()))?; - let ty_size = type_sizes[ty]; let generic_ty = &info.long_id.generic_id; if let Some(offset) = builtin_offset.get(generic_ty) { let mut offset = *offset; @@ -677,46 +682,69 @@ fn create_entry_code( casm_extend! {ctx, [ap + 0] = [fp - offset], ap++; } + ap_offset += 1; } else if generic_ty == &SystemType::ID { casm_extend! {ctx, %{ memory[ap + 0] = segments.add() %} ap += 1; } + ap_offset += 1; } else if generic_ty == &GasBuiltinType::ID { casm_extend! {ctx, [ap + 0] = initial_gas, ap++; } + ap_offset += 1; } else if generic_ty == &SegmentArenaType::ID { let offset = -ap_offset + after_arrays_data_offset; casm_extend! {ctx, [ap + 0] = [ap + offset] + 3, ap++; } - } else if let Some(FuncArg::Array(_)) = arg_iter.peek() { - let values = extract_matches!(arg_iter.next().unwrap(), FuncArg::Array); - let offset = -ap_offset + array_args_data_iter.next().unwrap(); - expected_arguments_size += 1; - casm_extend! {ctx, - [ap + 0] = [ap + (offset)], ap++; - [ap + 0] = [ap - 1] + (values.len()), ap++; - } + ap_offset += 1; } else { - let arg_size = ty_size; - expected_arguments_size += arg_size as usize; - for _ in 0..arg_size { - if let Some(value) = arg_iter.next() { - let value = extract_matches!(value, FuncArg::Single); - casm_extend! {ctx, - [ap + 0] = (value.to_bigint()), ap++; + let ty_size = type_sizes[ty]; + let param_ap_offset_end = ap_offset + ty_size; + expected_arguments_size += ty_size; + while ap_offset < param_ap_offset_end { + let Some((arg_index, arg)) = arg_iter.next() else { + break; + }; + match arg { + FuncArg::Single(value) => { + casm_extend! {ctx, + [ap + 0] = (value.to_bigint()), ap++; + } + ap_offset += 1; + } + FuncArg::Array(values) => { + let offset = -ap_offset + array_args_data_iter.next().unwrap(); + casm_extend! {ctx, + [ap + 0] = [ap + (offset)], ap++; + [ap + 0] = [ap - 1] + (values.len()), ap++; + } + ap_offset += 2; + if ap_offset > param_ap_offset_end { + return Err(Error::ArgumentUnaligned { + param_index, + arg_index, + }); + } } } } + param_index += 1; }; - ap_offset += ty_size; } - if expected_arguments_size != args.len() { + let actual_args_size = args + .iter() + .map(|arg| match arg { + FuncArg::Single(_) => 1, + FuncArg::Array(_) => 2, + }) + .sum::(); + if expected_arguments_size != actual_args_size { return Err(Error::ArgumentsSizeMismatch { expected: expected_arguments_size, - actual: args.len(), + actual: actual_args_size, }); } From d21137ff1f4cf703b4a7c67e55cacd2c82c35bb6 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 15 Jan 2024 11:06:40 -0300 Subject: [PATCH 29/30] Add test --- cairo1-run/src/main.rs | 10 +++++++++- .../cairo-1-programs/with_input/tensor.cairo | 9 +++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 cairo_programs/cairo-1-programs/with_input/tensor.cairo diff --git a/cairo1-run/src/main.rs b/cairo1-run/src/main.rs index dbbbd76b5a..9b413f9b30 100644 --- a/cairo1-run/src/main.rs +++ b/cairo1-run/src/main.rs @@ -1022,9 +1022,17 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/with_input/array_input_sum.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--args", "2 [1 2 3 4] 0 [9 8]"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/with_input/array_input_sum.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null", "--args", "2 [1 2 3 4] 0 [9 8]"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/with_input/array_input_sum.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null", "--args", "[2 2] [1 2 3 4]"].as_slice())] fn test_array_input_sum(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(12)]); } + + #[rstest] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/with_input/tensor.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--args", "2 [1 2 3 4] 0 [9 8]"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/with_input/tensor.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null", "--args", "[2 2] [1 2 3 4]"].as_slice())] + fn test_tensor(#[case] args: &[&str]) { + let args = args.iter().cloned().map(String::from); + assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(12)]); + } } diff --git a/cairo_programs/cairo-1-programs/with_input/tensor.cairo b/cairo_programs/cairo-1-programs/with_input/tensor.cairo new file mode 100644 index 0000000000..6d35b905d5 --- /dev/null +++ b/cairo_programs/cairo-1-programs/with_input/tensor.cairo @@ -0,0 +1,9 @@ +#[derive(Copy, Drop)] +struct Tensor { + shape: Span, + data: Span +} + +fn main(tensor: Tensor) -> u32 { + *tensor.data.at(0) +} From 3db5d72ff4d68eaf9f1694de00365b99bccc68c6 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 15 Jan 2024 11:18:18 -0300 Subject: [PATCH 30/30] Fix tests --- cairo1-run/src/main.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cairo1-run/src/main.rs b/cairo1-run/src/main.rs index 9b413f9b30..76b156310b 100644 --- a/cairo1-run/src/main.rs +++ b/cairo1-run/src/main.rs @@ -1022,17 +1022,17 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/with_input/array_input_sum.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--args", "2 [1 2 3 4] 0 [9 8]"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/with_input/array_input_sum.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null", "--args", "[2 2] [1 2 3 4]"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/with_input/array_input_sum.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null", "--args", "2 [1 2 3 4] 0 [9 8]"].as_slice())] fn test_array_input_sum(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(12)]); } #[rstest] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/with_input/tensor.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--args", "2 [1 2 3 4] 0 [9 8]"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/with_input/tensor.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--args", "[2 2] [1 2 3 4]"].as_slice())] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/with_input/tensor.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null", "--args", "[2 2] [1 2 3 4]"].as_slice())] fn test_tensor(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); - assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(12)]); + assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(1)]); } }