diff --git a/build/hint.json b/build/hint.json index 7bd8ba0b6..342d0802c 100644 --- a/build/hint.json +++ b/build/hint.json @@ -1,8 +1,15 @@ { "attributes": [], - "builtins": [], + "builtins": [ + "output" + ], "compiler_version": "0.12.2", "data": [ + "0x480680017fff8000", + "0x11", + "0x480280007ffd7fff", + "0x482680017ffd8000", + "0x1", "0x208b7fff7fff7ffe" ], "debug_info": { @@ -19,37 +26,127 @@ "offset": 0 }, "reference_ids": { - "__main__.main.a": 0 + "__main__.main.output_ptr": 0 + } + }, + "hints": [], + "inst": { + "end_col": 19, + "end_line": 4, + "input_file": { + "filename": "tests/contracts/hint.cairo" + }, + "start_col": 17, + "start_line": 4 + } + }, + "2": { + "accessible_scopes": [ + "__main__", + "__main__.main" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 0, + "offset": 1 + }, + "reference_ids": { + "__main__.main.a": 1, + "__main__.main.output_ptr": 0 + } + }, + "hints": [], + "inst": { + "end_col": 27, + "end_line": 5, + "input_file": { + "filename": "tests/contracts/hint.cairo" + }, + "start_col": 5, + "start_line": 5 + } + }, + "3": { + "accessible_scopes": [ + "__main__", + "__main__.main" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 0, + "offset": 2 + }, + "reference_ids": { + "__main__.main.a": 1, + "__main__.main.output_ptr": 2 } }, "hints": [ { "location": { "end_col": 23, - "end_line": 4, + "end_line": 8, "input_file": { "filename": "tests/contracts/hint.cairo" }, "start_col": 5, - "start_line": 4 + "start_line": 8 }, "n_prefix_newlines": 0 } ], "inst": { - "end_col": 15, - "end_line": 5, + "end_col": 36, + "end_line": 9, + "input_file": { + "filename": "tests/contracts/hint.cairo" + }, + "parent_location": [ + { + "end_col": 35, + "end_line": 11, + "input_file": { + "filename": "tests/contracts/hint.cairo" + }, + "start_col": 25, + "start_line": 11 + }, + "While expanding the reference 'output_ptr' in:" + ], + "start_col": 22, + "start_line": 9 + } + }, + "5": { + "accessible_scopes": [ + "__main__", + "__main__.main" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 0, + "offset": 3 + }, + "reference_ids": { + "__main__.main.a": 1, + "__main__.main.output_ptr": 2 + } + }, + "hints": [], + "inst": { + "end_col": 37, + "end_line": 11, "input_file": { "filename": "tests/contracts/hint.cairo" }, "start_col": 5, - "start_line": 5 + "start_line": 11 } } } }, "hints": { - "0": [ + "3": [ { "accessible_scopes": [ "__main__", @@ -59,10 +156,11 @@ "flow_tracking_data": { "ap_tracking": { "group": 0, - "offset": 0 + "offset": 2 }, "reference_ids": { - "__main__.main.a": 0 + "__main__.main.a": 1, + "__main__.main.output_ptr": 0 } } } @@ -76,8 +174,13 @@ }, "__main__.main.Args": { "full_name": "__main__.main.Args", - "members": {}, - "size": 0, + "members": { + "output_ptr": { + "cairo_type": "felt*", + "offset": 0 + } + }, + "size": 1, "type": "struct" }, "__main__.main.ImplicitArgs": { @@ -87,7 +190,7 @@ "type": "struct" }, "__main__.main.Return": { - "cairo_type": "()", + "cairo_type": "(output_ptr: felt*)", "type": "type_definition" }, "__main__.main.SIZEOF_LOCALS": { @@ -97,6 +200,21 @@ "__main__.main.a": { "cairo_type": "felt", "full_name": "__main__.main.a", + "references": [ + { + "ap_tracking_data": { + "group": 0, + "offset": 1 + }, + "pc": 2, + "value": "[cast(ap + (-1), felt*)]" + } + ], + "type": "reference" + }, + "__main__.main.output_ptr": { + "cairo_type": "felt*", + "full_name": "__main__.main.output_ptr", "references": [ { "ap_tracking_data": { @@ -104,7 +222,15 @@ "offset": 0 }, "pc": 0, - "value": "cast(17, felt)" + "value": "[cast(fp + (-3), felt**)]" + }, + { + "ap_tracking_data": { + "group": 0, + "offset": 2 + }, + "pc": 3, + "value": "cast([fp + (-3)] + 1, felt*)" } ], "type": "reference" @@ -120,7 +246,23 @@ "offset": 0 }, "pc": 0, - "value": "cast(17, felt)" + "value": "[cast(fp + (-3), felt**)]" + }, + { + "ap_tracking_data": { + "group": 0, + "offset": 1 + }, + "pc": 2, + "value": "[cast(ap + (-1), felt*)]" + }, + { + "ap_tracking_data": { + "group": 0, + "offset": 2 + }, + "pc": 3, + "value": "cast([fp + (-3)] + 1, felt*)" } ] } diff --git a/build/test.zip b/build/test.zip index a3b55fe07..9c8a8822c 100644 Binary files a/build/test.zip and b/build/test.zip differ diff --git a/tests/common.rs b/tests/common.rs index 960d3bf12..23f690d46 100644 --- a/tests/common.rs +++ b/tests/common.rs @@ -37,3 +37,28 @@ pub fn setup_pie() -> CairoPie { runner.get_cairo_pie(&vm).unwrap() } + +#[allow(unused)] +pub fn compare_python_output(program: &str, mut vm: VirtualMachine) { + let mut rs_output = String::new(); + vm.write_output(&mut rs_output).unwrap(); + let rs_output = rs_output.split('\n').filter(|&x| !x.is_empty()); + let python_output = std::process::Command::new("cairo-run") + .arg("--layout=small") + .arg(format!("--program={program:}")) + .arg("--print_output") + .output() + .expect("failed to run python vm"); + let python_output = unsafe { std::str::from_utf8_unchecked(&python_output.stdout) }.to_string(); + let python_output = python_output + .split('\n') + .into_iter() + .skip_while(|&x| x != "Program output:") + .skip(1) + .filter(|&x| !x.trim().is_empty()) + .into_iter(); + for (rs, py) in rs_output.zip(python_output) { + let py = py.to_string().trim().to_string(); + assert_eq!(*rs, py); + } +} diff --git a/tests/contracts/hint.cairo b/tests/contracts/hint.cairo index 31b816d0a..be24253fd 100644 --- a/tests/contracts/hint.cairo +++ b/tests/contracts/hint.cairo @@ -1,6 +1,12 @@ -func main() { - let a = 17; +%builtins output + +func main(output_ptr: felt*) -> (output_ptr: felt*) { + tempvar a = 17; + a = [output_ptr], ap++; + // Use custom hint to print the value of a %{ print(ids.a) %} - return (); -} \ No newline at end of file + let output_ptr = output_ptr + 1; + + return(output_ptr = output_ptr); +} diff --git a/tests/snos.rs b/tests/snos.rs index 07d6eb4ca..e65282d1e 100644 --- a/tests/snos.rs +++ b/tests/snos.rs @@ -1,3 +1,4 @@ +mod common; use cairo_vm::cairo_run::{cairo_run, CairoRunConfig}; use cairo_vm::felt::Felt252; use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::{ @@ -8,6 +9,7 @@ use cairo_vm::hint_processor::hint_processor_definition::HintReference; use cairo_vm::serde::deserialize_program::ApTracking; use cairo_vm::types::exec_scope::ExecutionScopes; use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}; +use common::compare_python_output; use snos::SnOsRunner; use std::collections::HashMap; use std::fs::File; @@ -30,6 +32,7 @@ fn print_a_hint( #[test] fn custom_hint_ok() { + let program_path = "build/hint.json"; // Wrap the Rust hint implementation in a Box smart pointer inside a HintFunc let hint = HintFunc(Box::new(print_a_hint)); @@ -39,13 +42,13 @@ fn custom_hint_ok() { //Add the custom hint, together with the Python code hint_processor.add_hint(String::from("print(ids.a)"), Rc::new(hint)); - let file = File::open(Path::new("build/hint.json")).expect("Couldn't load file"); + let file = File::open(Path::new(program_path)).expect("Couldn't load file"); let mut reader = BufReader::new(file); let mut buffer = Vec::::new(); reader.read_to_end(&mut buffer).expect("Couldn't read file"); //Run the cairo program - cairo_run( + let (_cairo_runner, virtual_machine) = cairo_run( &buffer, &CairoRunConfig { layout: "all_cairo", @@ -54,6 +57,7 @@ fn custom_hint_ok() { &mut hint_processor, ) .expect("Couldn't run program"); + compare_python_output(program_path, virtual_machine); } #[test]