From 0489bc0ef4cabb4915bbb648ff08784d8db78821 Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 12 Jun 2024 11:27:43 -0300 Subject: [PATCH 1/9] Load initial_gas & account for segment arena pointer --- cairo1-run/src/cairo_run.rs | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/cairo1-run/src/cairo_run.rs b/cairo1-run/src/cairo_run.rs index 048b7f484b..d9b1913320 100644 --- a/cairo1-run/src/cairo_run.rs +++ b/cairo1-run/src/cairo_run.rs @@ -254,10 +254,12 @@ pub fn cairo_run_program( cairo_run_config.trace_enabled, )?; let end = runner.initialize(cairo_run_config.proof_mode)?; - load_arguments(&mut runner, &cairo_run_config, main_func)?; + load_arguments(&mut runner, &cairo_run_config, main_func, initial_gas)?; // Run it until the end / infinite loop in proof_mode - runner.run_until_pc(end, &mut hint_processor)?; + let err = runner.run_until_pc(end, &mut hint_processor); + println!("{}", runner.vm.segments); + err?; if cairo_run_config.proof_mode { runner.run_for_steps(1, &mut hint_processor)?; } @@ -394,7 +396,7 @@ fn create_code_footer() -> Vec { } // Loads the input arguments into the execution segment, leaving the necessary gaps for the values that will be written by -// the instructions in the entry_code (produced by `create_entry_code`) +// the instructions in the entry_code (produced by `create_entry_code`). Also loads the initial gas if the GasBuiltin is present /* Example of execution segment before running the main function: Before calling this function (after runner.initialize): @@ -441,17 +443,20 @@ After the entry_code (up until calling main) has been ran by the VM: builtin_base_0 builtin_base_1 (*2) segment_arena_ptr + 3 (segment_arena base) + (*4) initial_gas (*3) arg_0 (*3) arg_1 ] (*1) if output builtin is added (if either proof_mode or append_return_values is enabled) (*2) if segment arena is present (*3) if args are used +(*4) if gas builtin is used */ fn load_arguments( runner: &mut CairoRunner, cairo_run_config: &Cairo1RunConfig, main_func: &Function, + initial_gas: usize, ) -> Result<(), Error> { if cairo_run_config.args.is_empty() { // Nothing to be done @@ -470,12 +475,26 @@ fn load_arguments( // * segment_arena_ptr // * info_segment_ptr // * 0 + // * segment_arena_ptr + 3 let mut ap_offset = runner.get_program().builtins_len(); if cairo_run_config.copy_to_output() { ap_offset += runner.get_program().builtins_len() - 1; } if got_segment_arena { - ap_offset += 3; + ap_offset += 4; + } + // Load initial gas if GasBuiltin is present + let got_gas_builtin = main_func + .signature + .param_types + .iter() + .any(|ty| ty.debug_name.as_ref().is_some_and(|n| n == "GasBuiltin")); + if got_gas_builtin { + runner.vm.insert_value( + (runner.vm.get_ap() + ap_offset).map_err(VirtualMachineError::Math)?, + Felt252::from(initial_gas), + )?; + ap_offset += 1; } for arg in cairo_run_config.args { match arg { @@ -583,9 +602,9 @@ fn create_entry_code( ap += 1; }; } else if generic_ty == &GasBuiltinType::ID { + // We already loaded the inital gas so we just advance AP casm_build_extend! {ctx, - const initial_gas = initial_gas; - tempvar _gas = initial_gas; + ap += 1; }; } else { let ty_size = type_sizes[ty]; From 119caaaa1a9b08186344ce6aba3ff0aefbbf24e1 Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 12 Jun 2024 11:30:57 -0300 Subject: [PATCH 2/9] Remove initial_gas arg from create_entry_code --- cairo1-run/src/cairo_run.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/cairo1-run/src/cairo_run.rs b/cairo1-run/src/cairo_run.rs index d9b1913320..920c1fb957 100644 --- a/cairo1-run/src/cairo_run.rs +++ b/cairo1-run/src/cairo_run.rs @@ -176,7 +176,6 @@ pub fn cairo_run_program( &casm_program, &type_sizes, main_func, - initial_gas, &cairo_run_config, )?; @@ -535,7 +534,6 @@ fn create_entry_code( casm_program: &CairoProgram, type_sizes: &UnorderedHashMap, func: &Function, - initial_gas: usize, config: &Cairo1RunConfig, ) -> Result<(CasmContext, Vec), Error> { let copy_to_output_builtin = config.copy_to_output(); From 23cdb09ea378c09c0f178bfa19087e04393696f6 Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 12 Jun 2024 11:39:22 -0300 Subject: [PATCH 3/9] Account for gas builtin when serializing input --- cairo1-run/src/cairo_run.rs | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/cairo1-run/src/cairo_run.rs b/cairo1-run/src/cairo_run.rs index 920c1fb957..74869958fb 100644 --- a/cairo1-run/src/cairo_run.rs +++ b/cairo1-run/src/cairo_run.rs @@ -538,6 +538,16 @@ fn create_entry_code( ) -> Result<(CasmContext, Vec), Error> { let copy_to_output_builtin = config.copy_to_output(); let signature = &func.signature; + let got_segment_arena = signature.param_types.iter().any(|ty| { + get_info(sierra_program_registry, ty) + .map(|x| x.long_id.generic_id == SegmentArenaType::ID) + .unwrap_or_default() + }); + let got_gas_builtin = signature.param_types.iter().any(|ty| { + get_info(sierra_program_registry, ty) + .map(|x| x.long_id.generic_id == GasBuiltinType::ID) + .unwrap_or_default() + }); // The builtins in the formatting expected by the runner. let (builtins, builtin_offset) = get_function_builtins(&signature.param_types, copy_to_output_builtin); @@ -555,11 +565,6 @@ fn create_entry_code( let offset: i16 = 2 + builtins.len().into_or_panic::(); ctx.add_var(CellExpression::Deref(deref!([fp - offset]))) }); - let got_segment_arena = signature.param_types.iter().any(|ty| { - get_info(sierra_program_registry, ty) - .map(|x| x.long_id.generic_id == SegmentArenaType::ID) - .unwrap_or_default() - }); if copy_to_output_builtin { // Leave a gap to write the builtin final pointers // We write them on a fixed cells relative to the starting FP pointer so we don't lose them after serializing outputs @@ -720,8 +725,10 @@ fn create_entry_code( // We lost the output_ptr var after re-scoping, so we need to create it again // The last instruction will write the last output ptr so we can find it in [ap - 1] let output_ptr = ctx.add_var(CellExpression::Deref(deref!([ap - 1]))); - // len(builtins - output) + len(builtins) + if segment_arena: segment_arena_ptr + info_ptr + 0 + (segment_arena_ptr + 3) - let offset = (2 * builtins.len() - 1 + 4 * got_segment_arena as usize) as i16; + // len(builtins - output) + len(builtins) + if segment_arena: segment_arena_ptr + info_ptr + 0 + (segment_arena_ptr + 3) + (gas_builtin) + let offset = (2 * builtins.len() - 1 + + 4 * got_segment_arena as usize + + got_gas_builtin as usize) as i16; let array_start_ptr = ctx.add_var(CellExpression::Deref(deref!([fp + offset]))); let array_end_ptr = ctx.add_var(CellExpression::Deref(deref!([fp + offset + 1]))); casm_build_extend! {ctx, From cb90598ae4a0c79d1f62abb63b687ba95b3ec404 Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 12 Jun 2024 11:49:16 -0300 Subject: [PATCH 4/9] Load initial_gas even if no args --- cairo1-run/src/cairo_run.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cairo1-run/src/cairo_run.rs b/cairo1-run/src/cairo_run.rs index 74869958fb..6e1a4fa4dc 100644 --- a/cairo1-run/src/cairo_run.rs +++ b/cairo1-run/src/cairo_run.rs @@ -457,7 +457,12 @@ fn load_arguments( main_func: &Function, initial_gas: usize, ) -> Result<(), Error> { - if cairo_run_config.args.is_empty() { + let got_gas_builtin = main_func + .signature + .param_types + .iter() + .any(|ty| ty.debug_name.as_ref().is_some_and(|n| n == "GasBuiltin")); + if cairo_run_config.args.is_empty() && !got_gas_builtin { // Nothing to be done return Ok(()); } @@ -483,11 +488,6 @@ fn load_arguments( ap_offset += 4; } // Load initial gas if GasBuiltin is present - let got_gas_builtin = main_func - .signature - .param_types - .iter() - .any(|ty| ty.debug_name.as_ref().is_some_and(|n| n == "GasBuiltin")); if got_gas_builtin { runner.vm.insert_value( (runner.vm.get_ap() + ap_offset).map_err(VirtualMachineError::Math)?, From 6e39c486bc425df765e411f6c45a7fa85efea4c2 Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 12 Jun 2024 12:10:01 -0300 Subject: [PATCH 5/9] Remove debug code --- cairo1-run/src/cairo_run.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cairo1-run/src/cairo_run.rs b/cairo1-run/src/cairo_run.rs index 6e1a4fa4dc..63ac0891e1 100644 --- a/cairo1-run/src/cairo_run.rs +++ b/cairo1-run/src/cairo_run.rs @@ -256,9 +256,7 @@ pub fn cairo_run_program( load_arguments(&mut runner, &cairo_run_config, main_func, initial_gas)?; // Run it until the end / infinite loop in proof_mode - let err = runner.run_until_pc(end, &mut hint_processor); - println!("{}", runner.vm.segments); - err?; + runner.run_until_pc(end, &mut hint_processor)?; if cairo_run_config.proof_mode { runner.run_for_steps(1, &mut hint_processor)?; } From 832fa5a932803ce25af2eb75b4fdb20c49ee797a Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 12 Jun 2024 12:24:26 -0300 Subject: [PATCH 6/9] Add test for reported case --- cairo1-run/src/main.rs | 7 +++++++ cairo_programs/cairo-1-programs/serialize_felt.cairo | 11 +++++++++++ .../with_input/dict_with_input.cairo | 4 ++++ .../cairo-1-programs/with_input/dict_with_input.cairo | 4 ++++ 4 files changed, 26 insertions(+) create mode 100644 cairo_programs/cairo-1-programs/serialize_felt.cairo create mode 100644 cairo_programs/cairo-1-programs/serialized_output/with_input/dict_with_input.cairo create mode 100644 cairo_programs/cairo-1-programs/with_input/dict_with_input.cairo diff --git a/cairo1-run/src/main.rs b/cairo1-run/src/main.rs index f2f34c2064..669ab067a8 100644 --- a/cairo1-run/src/main.rs +++ b/cairo1-run/src/main.rs @@ -414,6 +414,13 @@ mod tests { #[case("bitwise.cairo", "11772", "[11772]", None, None)] #[case("factorial.cairo", "3628800", "[3628800]", None, None)] #[case("fibonacci.cairo", "89", "[89]", None, None)] + #[case( + "with_input/dict_with_input.cairo", + "[17 18]", + "[17 18]", + Some("[17 18]"), + Some("[17 18]") + )] fn test_run_progarm( #[case] program: &str, diff --git a/cairo_programs/cairo-1-programs/serialize_felt.cairo b/cairo_programs/cairo-1-programs/serialize_felt.cairo new file mode 100644 index 0000000000..0926a630ac --- /dev/null +++ b/cairo_programs/cairo-1-programs/serialize_felt.cairo @@ -0,0 +1,11 @@ +use core::felt252; +use array::ArrayTrait; +use core::Serde; + + +fn main() -> Array { + let mut output: Array = ArrayTrait::new(); + let a : u32 = 10 - 2; + a.serialize(ref output); + output +} diff --git a/cairo_programs/cairo-1-programs/serialized_output/with_input/dict_with_input.cairo b/cairo_programs/cairo-1-programs/serialized_output/with_input/dict_with_input.cairo new file mode 100644 index 0000000000..795bcea6e0 --- /dev/null +++ b/cairo_programs/cairo-1-programs/serialized_output/with_input/dict_with_input.cairo @@ -0,0 +1,4 @@ +fn main(input:Array) -> Array { + let _elements: Felt252Dict>> = Default::default(); + input +} diff --git a/cairo_programs/cairo-1-programs/with_input/dict_with_input.cairo b/cairo_programs/cairo-1-programs/with_input/dict_with_input.cairo new file mode 100644 index 0000000000..795bcea6e0 --- /dev/null +++ b/cairo_programs/cairo-1-programs/with_input/dict_with_input.cairo @@ -0,0 +1,4 @@ +fn main(input:Array) -> Array { + let _elements: Felt252Dict>> = Default::default(); + input +} From b992489b50d7972f20c25fa06f767e671c2d2469 Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 12 Jun 2024 12:25:41 -0300 Subject: [PATCH 7/9] remove program added by accident --- cairo_programs/cairo-1-programs/serialize_felt.cairo | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 cairo_programs/cairo-1-programs/serialize_felt.cairo diff --git a/cairo_programs/cairo-1-programs/serialize_felt.cairo b/cairo_programs/cairo-1-programs/serialize_felt.cairo deleted file mode 100644 index 0926a630ac..0000000000 --- a/cairo_programs/cairo-1-programs/serialize_felt.cairo +++ /dev/null @@ -1,11 +0,0 @@ -use core::felt252; -use array::ArrayTrait; -use core::Serde; - - -fn main() -> Array { - let mut output: Array = ArrayTrait::new(); - let a : u32 = 10 - 2; - a.serialize(ref output); - output -} From 2e0008573fe8a9d4645143d0e7f23e936900823b Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 12 Jun 2024 12:26:36 -0300 Subject: [PATCH 8/9] Improve comment --- cairo1-run/src/cairo_run.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cairo1-run/src/cairo_run.rs b/cairo1-run/src/cairo_run.rs index 63ac0891e1..52a5ea2676 100644 --- a/cairo1-run/src/cairo_run.rs +++ b/cairo1-run/src/cairo_run.rs @@ -447,7 +447,7 @@ After the entry_code (up until calling main) has been ran by the VM: (*1) if output builtin is added (if either proof_mode or append_return_values is enabled) (*2) if segment arena is present (*3) if args are used -(*4) if gas builtin is used +(*4) if gas builtin is present */ fn load_arguments( runner: &mut CairoRunner, From c748f1dcf4cdee419e7a9ae3c97bc06d6cb34c0c Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 12 Jun 2024 12:31:22 -0300 Subject: [PATCH 9/9] Add CHANGELOG entry --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b89bacf8a..b0e1be6218 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ #### Upcoming Changes +* fix: Handle `GasBuiltin` in cairo1-run crate [#1789](https://github.com/lambdaclass/cairo-vm/pull/1789) + * Load `initial_gas` into vm instead of creating it via instructions. + * Fix bug affecting programs with input arguments and gas builtin. + * fix: Change (de)serialization of CairoPie's `OutputBuiltinAdditionalData`'s `PublicMemoryPage` to vectors of length 2. [#1781](https://github.com/lambdaclass/cairo-vm/pull/1781) * fix: Fixed deserialization issue when signature additional data is empty, and the name of the builtin range_check96 [#1785](https://github.com/lambdaclass/cairo-vm/pull/1785)