From 979b7fdae3d2b6668c11b29fea74c6552dd7a950 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 4 Mar 2024 12:34:08 -0300 Subject: [PATCH] Revert "Add cairo1-run pretty printing (#1630)" This reverts commit 061ba872d94a0e49027132f2215b4d4ad4ee95d6. --- CHANGELOG.md | 2 - cairo1-run/src/main.rs | 77 +++++--- cairo1-run/src/serialize_output.rs | 169 ------------------ .../cairo-1-programs/felt_dict.cairo | 15 -- .../cairo-1-programs/felt_span.cairo | 6 - 5 files changed, 52 insertions(+), 217 deletions(-) delete mode 100644 cairo1-run/src/serialize_output.rs delete mode 100644 cairo_programs/cairo-1-programs/felt_dict.cairo delete mode 100644 cairo_programs/cairo-1-programs/felt_span.cairo diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f2aa00a4e..912a8eec75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,6 @@ #### Upcoming Changes -* feat: Add cairo1-run output pretty-printing for felts, arrays/spans and dicts [#1630](https://github.com/lambdaclass/cairo-vm/pull/1630) - * feat: output builtin features for bootloader support [#1580](https://github.com/lambdaclass/cairo-vm/pull/1580) #### [1.0.0-rc1] - 2024-02-23 diff --git a/cairo1-run/src/main.rs b/cairo1-run/src/main.rs index c970d113cb..3f2831e7de 100644 --- a/cairo1-run/src/main.rs +++ b/cairo1-run/src/main.rs @@ -6,24 +6,27 @@ use cairo_run::Cairo1RunConfig; use cairo_vm::{ air_public_input::PublicInputError, cairo_run::EncodeTraceError, - types::errors::program_errors::ProgramError, - vm::errors::{ - memory_errors::MemoryError, runner_errors::RunnerError, trace_errors::TraceError, - vm_errors::VirtualMachineError, + types::{errors::program_errors::ProgramError, relocatable::MaybeRelocatable}, + vm::{ + errors::{ + memory_errors::MemoryError, runner_errors::RunnerError, trace_errors::TraceError, + vm_errors::VirtualMachineError, + }, + vm_core::VirtualMachine, }, Felt252, }; use clap::{Parser, ValueHint}; use itertools::Itertools; -use serialize_output::serialize_output; use std::{ io::{self, Write}, + iter::Peekable, path::PathBuf, + slice::Iter, }; use thiserror::Error; pub mod cairo_run; -pub mod serialize_output; #[derive(Parser, Debug)] #[clap(author, version, about, long_about = None)] @@ -294,7 +297,7 @@ fn main() -> Result<(), Error> { Err(Error::Cli(err)) => err.exit(), Ok(output) => { if let Some(output_string) = output { - println!("{}", output_string); + println!("Program Output : {}", output_string); } Ok(()) } @@ -320,6 +323,48 @@ fn main() -> Result<(), Error> { } } +pub fn serialize_output(vm: &VirtualMachine, return_values: &[MaybeRelocatable]) -> String { + let mut output_string = String::new(); + let mut return_values_iter: Peekable> = return_values.iter().peekable(); + serialize_output_inner(&mut return_values_iter, &mut output_string, vm); + fn serialize_output_inner( + iter: &mut Peekable>, + output_string: &mut String, + vm: &VirtualMachine, + ) { + while let Some(val) = iter.next() { + if let MaybeRelocatable::RelocatableValue(x) = val { + // Check if the next value is a relocatable of the same index + if let Some(MaybeRelocatable::RelocatableValue(y)) = iter.peek() { + // Check if the two relocatable values represent a valid array in memory + if x.segment_index == y.segment_index && x.offset <= y.offset { + // Fetch the y value from the iterator so we don't serialize it twice + iter.next(); + // Fetch array + maybe_add_whitespace(output_string); + output_string.push('['); + let array = vm.get_continuous_range(*x, y.offset - x.offset).unwrap(); + let mut array_iter: Peekable> = + array.iter().peekable(); + serialize_output_inner(&mut array_iter, output_string, vm); + output_string.push(']'); + continue; + } + } + } + maybe_add_whitespace(output_string); + output_string.push_str(&val.to_string()); + } + } + + fn maybe_add_whitespace(string: &mut String) { + if !string.is_empty() && !string.ends_with('[') { + string.push(' '); + } + } + output_string +} + #[cfg(test)] mod tests { use super::*; @@ -517,22 +562,4 @@ mod tests { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(Some(res)) if res.is_empty()); } - - #[rstest] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/felt_dict.cairo", "--print_output", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--cairo_pie_output", "/dev/null"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/felt_dict.cairo", "--print_output", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null", "--air_private_input", "/dev/null"].as_slice())] - fn test_run_felt_dict(#[case] args: &[&str]) { - let args = args.iter().cloned().map(String::from); - let expected_output = "{\n\t0x10473: [0x8,0x9,0xa,0xb,],\n\t0x10474: [0x1,0x2,0x3,],\n}\n"; - assert_matches!(run(args), Ok(Some(res)) if res == expected_output); - } - - #[rstest] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/felt_span.cairo", "--print_output", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--cairo_pie_output", "/dev/null"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/felt_span.cairo", "--print_output", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null", "--air_private_input", "/dev/null"].as_slice())] - fn test_run_felt_span(#[case] args: &[&str]) { - let args = args.iter().cloned().map(String::from); - let expected_output = "[0x8,0x9,0xa,0xb,]"; - assert_matches!(run(args), Ok(Some(res)) if res == expected_output); - } } diff --git a/cairo1-run/src/serialize_output.rs b/cairo1-run/src/serialize_output.rs deleted file mode 100644 index 562f2dc832..0000000000 --- a/cairo1-run/src/serialize_output.rs +++ /dev/null @@ -1,169 +0,0 @@ -use cairo_vm::{ - types::relocatable::{MaybeRelocatable, Relocatable}, - vm::{errors::memory_errors::MemoryError, vm_core::VirtualMachine}, - Felt252, -}; -use itertools::Itertools; -use std::{collections::HashMap, iter::Peekable, slice::Iter}; -use thiserror::Error; - -#[derive(Debug)] -pub(crate) enum Output { - Felt(Felt252), - FeltSpan(Vec), - FeltDict(HashMap), -} - -#[derive(Debug, Error)] -pub struct FormatError; - -impl std::fmt::Display for FormatError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "Format error") - } -} - -impl Output { - pub fn from_memory( - vm: &VirtualMachine, - relocatable: &Relocatable, - ) -> Result { - match vm.get_relocatable(*relocatable) { - Ok(relocatable_value) => { - let segment_size = vm - .get_segment_size(relocatable_value.segment_index as usize) - .ok_or(FormatError)?; - let segment_data = vm - .get_continuous_range(relocatable_value, segment_size) - .map_err(|_| FormatError)?; - - // check if the segment data is a valid array of felts - if segment_data - .iter() - .all(|v| matches!(v, MaybeRelocatable::Int(_))) - { - let span_segment: Vec = segment_data - .iter() - .map(|v| Output::Felt(v.get_int().unwrap())) - .collect(); - Ok(Output::FeltSpan(span_segment)) - } else { - Err(FormatError) - } - } - Err(MemoryError::UnknownMemoryCell(relocatable_value)) => { - // here we assume that the value is a dictionary - let mut felt252dict: HashMap = HashMap::new(); - - let segment_size = vm - .get_segment_size(relocatable_value.segment_index as usize) - .ok_or(FormatError)?; - let mut segment_start = relocatable_value.clone(); - segment_start.offset = 0; - let segment_data = vm - .get_continuous_range(*segment_start, segment_size) - .map_err(|_| FormatError)?; - - for (dict_key, _, value_relocatable) in segment_data.iter().tuples() { - let key = dict_key.get_int().ok_or(FormatError)?; - let value_segment = value_relocatable.get_relocatable().ok_or(FormatError)?; - let value = Output::from_memory(vm, &value_segment)?; - felt252dict.insert(key, value); - } - Ok(Output::FeltDict(felt252dict)) - } - _ => Err(FormatError), - } - } -} - -impl std::fmt::Display for Output { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Output::Felt(felt) => write!(f, "{}", felt.to_hex_string()), - Output::FeltSpan(span) => { - write!(f, "[")?; - for elem in span { - write!(f, "{}", elem)?; - write!(f, ",")?; - } - write!(f, "]")?; - Ok(()) - } - Output::FeltDict(felt_dict) => { - let mut keys: Vec<_> = felt_dict.keys().collect(); - keys.sort(); - writeln!(f, "{{")?; - for key in keys { - writeln!(f, "\t{}: {},", key.to_hex_string(), felt_dict[key])?; - } - writeln!(f, "}}")?; - Ok(()) - } - } - } -} - -pub(crate) fn serialize_output(vm: &VirtualMachine, return_values: &[MaybeRelocatable]) -> String { - let mut output_string = String::new(); - let mut return_values_iter: Peekable> = return_values.iter().peekable(); - let result = serialize_output_inner(&mut return_values_iter, &mut output_string, vm); - if result.is_err() { - return result.err().unwrap().to_string(); - } - - output_string -} - -fn maybe_add_whitespace(string: &mut String) { - if !string.is_empty() && !string.ends_with('[') { - string.push(' '); - } -} - -fn serialize_output_inner( - iter: &mut Peekable>, - output_string: &mut String, - vm: &VirtualMachine, -) -> Result<(), FormatError> { - while let Some(val) = iter.next() { - match val { - MaybeRelocatable::Int(x) => { - maybe_add_whitespace(output_string); - output_string.push_str(&x.to_string()); - continue; - } - MaybeRelocatable::RelocatableValue(x) if ((iter.len() + 1) % 2) == 0 /* felt array */ => { - // Check if the next value is a relocatable of the same index - let y = iter.next().unwrap().get_relocatable().ok_or(FormatError)?; - // Check if the two relocatable values represent a valid array in memory - if x.segment_index == y.segment_index && x.offset <= y.offset { - // Fetch array - maybe_add_whitespace(output_string); - output_string.push('['); - let array = vm.get_continuous_range(*x, y.offset - x.offset).map_err(|_| FormatError)?; - let mut array_iter: Peekable> = - array.iter().peekable(); - serialize_output_inner(&mut array_iter, output_string, vm)?; - output_string.push(']'); - continue; - } - }, - MaybeRelocatable::RelocatableValue(x) if iter.len() > 1 => { - let mut segment_start = *x; - segment_start.offset = 0; - for elem in iter.into_iter() { - let output_value = Output::from_memory(vm, &elem.get_relocatable().ok_or(FormatError)?)?; - output_string.push_str(output_value.to_string().as_str()) - } - } - MaybeRelocatable::RelocatableValue(x) => { - match Output::from_memory(vm, x) { - Ok(output_value) => output_string.push_str(format!("{}", output_value).as_str()), - Err(_) => output_string.push_str("The output could not be formatted"), - } - } - } - } - Ok(()) -} diff --git a/cairo_programs/cairo-1-programs/felt_dict.cairo b/cairo_programs/cairo-1-programs/felt_dict.cairo deleted file mode 100644 index 9934d4dcc9..0000000000 --- a/cairo_programs/cairo-1-programs/felt_dict.cairo +++ /dev/null @@ -1,15 +0,0 @@ -use core::nullable::{nullable_from_box, match_nullable, FromNullableResult}; - -fn main() -> Felt252Dict>> { - // Create the dictionary - let mut d: Felt252Dict>> = Default::default(); - - // Create the array to insert - let a = array![8, 9, 10, 11]; - let b = array![1, 2, 3]; - - // Insert it as a `Span` - d.insert(66675, nullable_from_box(BoxTrait::new(a.span()))); - d.insert(66676, nullable_from_box(BoxTrait::new(b.span()))); - d -} diff --git a/cairo_programs/cairo-1-programs/felt_span.cairo b/cairo_programs/cairo-1-programs/felt_span.cairo deleted file mode 100644 index a1a9d708fe..0000000000 --- a/cairo_programs/cairo-1-programs/felt_span.cairo +++ /dev/null @@ -1,6 +0,0 @@ -use core::nullable::{nullable_from_box, match_nullable, FromNullableResult}; - -fn main() -> Nullable> { - let a = array![8, 9, 10, 11]; - nullable_from_box(BoxTrait::new(a.span())) -}